New to FORGE? Start a free 30-day trial

Command Customization

Updated on Oct 1, 2026

You customize workflow commands in .forge/config/commands.toml. You can replace the role or task prompt of a built-in operation, add operations or entire command targets, and attach context or hooks. This page covers the common customizations; for every field, see the Configuration Reference.

Prerequisites

  • Forge is initialized in the repository (.forge/config/ exists).
  • For custom prompts: prompt files you write, or prompts exported with frg config export --prompts.

Quick start

  1. Export a commented template:
bash
frg config export --commands
  1. Uncomment and edit sections in .forge/config/commands.toml.

  2. Validate your changes:

bash
frg config validate
  1. Optional: lock the configuration.
bash
frg config lock

frg config lock validates all configuration files and writes .forge/.config_lock with the SHA-256 hash of each file. If a configuration file changes after locking, workflow commands are blocked until you run frg config lock again.

Override prompts for a built-in operation

Use [[prompt_overrides]] to change the role or task prompt of an existing operation:

toml
[[prompt_overrides]]
target = "issue"
operation = "draft"
role = "scrum_master"

[[prompt_overrides]]
target = "code"
operation = "review"
role = "senior_reviewer"
task = "thorough_code_review"

Example: Disable role prompting for one operation

toml
[[prompt_overrides]]
target = "issue"
operation = "draft"
role = "none"          # Reserved value - no role prompt is composed

none is a reserved value, not a prompt file name. frg never looks for none.role.xml / none.role.md; the role section is omitted from the composed prompt entirely, including its separator, which reduces input and cached token cost.

Requirements:

  • target must be a built-in target (issue, code, pr, etc.)
  • operation must exist under that target
  • At least one of role or task must be specified
  • Referenced prompts must exist in .forge/prompts/ or be built-in
  • role may be a custom role prompt name or the reserved value "none" to disable role prompting

Disabling role prompting

Role prompts give the AI a persona. Disabling them reduces input and cached token cost and can be preferable with newer models where role framing adds little value.

There are three ways to disable role prompting:

MechanismScopeExample
--role noneOne invocationfrg issue draft --role none
role = "none" in [[prompt_overrides]]One target/operationsee above
roles = "disabled" in commands.tomlEvery operationsee below
toml
# .forge/config/commands.toml
roles = "disabled"

Precedence

Highest to lowest:

  1. The --role <name> command-line flag (--role none disables).
  2. A per-operation role from [[prompt_overrides]], [[custom_commands]] or [[commands]].
  3. The global roles = "disabled" setting.
  4. The built-in role for the operation.

An explicit per-operation role therefore overrides a global roles = "disabled":

toml
roles = "disabled"          # no role prompt anywhere ...

[[prompt_overrides]]
target = "code"
operation = "review"
role = "security_analyst"   # ... except for `frg code review`

Notes and limits

  • none is the only reserved value. off, disable and nil remain invalid role names and are rejected with the usual Invalid role error, so a typo can never silently disable role prompting.
  • --role and --custom-agent remain mutually exclusive. --role none is not a way around that rule. Custom agents already skip the role prompt, so combining a custom agent with a disabled role produces exactly the same prompt.
  • frg workflow run does not accept --role at all, but configuration-level settings (roles = "disabled" and role = "none") do apply to it.
  • Resumed (delta) sessions already omit the role prompt; disabling roles changes nothing for them.
  • The global setting is read from commands.toml at the system, user and repository levels using the normal configuration hierarchy. There is no per-service (monorepo) role switch.

Built-in targets and operations:

TargetOperations
issuedraft, publish, review, plan, triage, split, ask
backlogcreate, review, rank, ask
codecreate, review, refactor, document, build, test, ask
prdraft, publish, review, merge, ask
docscreate, build, ask
tickettriage, respond, ask, correlate
secaudit, patch, ask
askdefault
rundefault

Note: frg config validate doesn't report a misspelled target or operation in [[prompt_overrides]]. Compare the names with the table above.

Every referenced prompt must exist. See Create custom prompts.

Add custom commands

Use [[custom_commands]] to add an operation to a built-in target or to define a new target. Forge adds the command to its CLI, with the standard workflow flags (--clear, --retry, --auto-retry, --agent, --role, --custom-agent, --model, --print-prompt, --context-file, --context-dir, --bypass-safety-checks).

FieldRequiredDescription
targetYesExisting or new target name.
operationYesOperation name.
roleYesRole prompt name.
taskYesTask prompt name.
descriptionNoText shown in --help.

Add an operation to a built-in target

toml
[[custom_commands]]
target = "issue"
operation = "estimate"
role = "product_manager"
task = "story_point_estimate"
description = "Estimate issue using story points"

This adds frg issue estimate.

Add a new target

The following user-defined example adds a deployment target. deployment isn't a built-in Forge command; it exists only when your commands.toml defines it.

toml
[[custom_commands]]
target = "deployment"
operation = "plan"
role = "devops_engineer"
task = "deployment_plan"
description = "Plan a deployment"

After you add the prompt files, frg deployment --help lists it as Custom target: deployment, and you run it with frg deployment plan.

Add a modifier flag

A modifier adds a flag that switches the command to a different task prompt:

toml
[[custom_commands]]
target = "deployment"
operation = "execute"
role = "devops_engineer"
task = "deployment_execute"
description = "Execute a deployment"

[[custom_commands.modifiers]]
name = "dry_run"
task_override = "deployment_execute_dryrun"
description = "Simulate deployment without changes"

Forge uses the modifier name as the flag name: frg deployment execute --dry_run.

Reserved targets

You can't define commands for these targets: config, guide, shell, status, workflow, app, learn, and diagnose. frg config validate reports Cannot define workflow for reserved target '<name>'.

Extend operations with the full schema

Use [[commands]] when you need context, hooks, flags, options, or multi-repository settings. Forge also accepts [[workflows]] as an alias.

A partial entry extends a built-in operation. Fields you omit keep their built-in values, and context you add is appended to the built-in context:

toml
[[commands]]
target = "issue"

[[commands.operations]]
name = "draft"

[[commands.operations.context]]
type = "file"
path = "docs/issue-template.md"
description = "Standard issue template"

A complete entry defines a new target with its own prompts, flags, and modifiers:

toml
schema_version = "2.1.0"

[metadata]
name = "Release commands"
version = "1.0.0"
author = "platform-team"

[[commands]]
target = "release"
description = "Release operations"

[[commands.operations]]
name = "plan"
description = "Plan a release"
flags = ["role", "custom_agent"]

[commands.operations.prompts]
role = "software_engineer"
task = "release_plan"

[[commands.operations.modifiers]]
name = "dry_run"
description = "Simulate the release"
task_override = "release_plan_dryrun"

Other operation keys include hooks (see Command Hooks), options, and app_workflow (see Multi-Repository Application Commands). For context entries, see Using Context Effectively.

Create custom prompts

  1. Export built-in prompts as a starting point:
bash
frg config export --prompts --target issue

Forge writes the prompts in both formats, organized by target:

.forge/prompts/
├── xml/
│ ├── role/product_manager.role.xml
│ └── issue/
│ ├── issue_draft.task.xml
│ └── issue_draft_delta.task.xml
└── markdown/
├── role/product_manager.role.md
└── issue/
├── issue_draft.task.md
└── issue_draft_delta.task.md

Files with a _delta suffix are used when you run the same command again in a session. See Session Context and Token Optimization.

  1. Save your prompt as .forge/prompts/<name>.role.xml or .forge/prompts/<name>.task.xml. For a modifier, create the prompt named in task_override.

  2. Reference the prompt by name, without the suffix:

toml
[[prompt_overrides]]
target = "issue"
operation = "draft"
role = "custom_role" # .forge/prompts/custom_role.role.xml
task = "custom_issue_draft" # .forge/prompts/custom_issue_draft.task.xml
  1. Run frg config validate.

Forge uses a prompt file only when your configuration references it, so stray files in .forge/prompts/ don't change built-in behavior. For prompt format selection, see Prompt Formats.

Troubleshooting

Role prompt <name> not found or Task prompt <name> not found

Cause: The configuration references a prompt that Forge can't find. The error lists the paths Forge searched and suggests a file to create.

Solution:

  1. Create the file at the suggested path, for example .forge/prompts/<name>.task.xml.
  2. Or remove the reference from commands.toml.
  3. Run frg config validate.

Modifier task prompt <name> not found

Cause: A modifier's task_override references a missing prompt.

Solution: Create .forge/prompts/<name>.task.xml, then run frg config validate.

Prompt override for <target>.<operation> must specify at least 'role' or 'task'

Cause: A [[prompt_overrides]] entry has neither role nor task.

Solution: Add role, task, or both, or remove the entry.

Cannot define workflow for reserved target <name>

Cause: A custom command uses a reserved target name.

Solution: Rename the target. See Reserved targets.

Configuration has changed since last lock.

Cause: You edited a configuration file after running frg config lock.

Solution:

  1. Run frg config validate.
  2. Run frg config lock to update the lockfile.

Changes don't take effect

Cause: The file is in the wrong location, or a target or operation name is misspelled.

Solution:

  1. Check that the file is .forge/config/commands.toml.
  2. Run frg config validate.
  3. Run frg <target> --help and confirm that the operation is listed.

See Also