Skip to content

Proposal: add gh aw edit for schema-aware workflow configuration changes #55462

Description

@dsyme

Summary

@pelikhan A feature-request thought for discussion: I use gh aw as a control plane for operating agentic workflows, but several common control actions still require opening and manually editing the workflow Markdown.

Could we add a schema-aware gh aw edit command for changing operational frontmatter settings such as schedule frequency, cost limits, runtime, model, permissions, and network access?

The goal would not be to embed a generic YAML editor. The value would be typed shorthands, schema validation, atomic recompilation, and safe fleet-wide changes.

Motivating examples

The basic "how often does this need to run?" knob should be easy to turn:

gh aw edit repo-assist "on.schedule: 3h"
gh aw edit repo-assist "on.schedule: 1d"
gh aw edit repo-assist "on.schedule: 1w"
gh aw edit repo-assist --schedule "daily on weekdays"
gh aw edit repo-assist --schedule off

Likewise for cost and runtime controls:

gh aw edit repo-assist "max-ai-credits: 500"
gh aw edit repo-assist "max-daily-ai-credits: 15K"
gh aw edit repo-assist "max-turns: 20"
gh aw edit repo-assist "timeout-minutes: 15"
gh aw edit repo-assist "jobs.agent.timeout-minutes: 30"

Possible command shape

Human-friendly assignment syntax:

gh aw edit <workflow> "<path>: <value>"

Flag-based syntax for scripts and multiple mutations:

gh aw edit <workflow> --set <path>=<value>
gh aw edit <workflow> --unset <path>
gh aw edit <workflow> --add <path>=<value>
gh aw edit <workflow> --remove <path>=<value>

Workflow IDs could follow existing gh aw conventions:

gh aw edit repo-assist "model: small"
gh aw edit repo-assist.md "model: small"
gh aw edit .github/workflows/repo-assist.md "model: small"

Multiple edits could be atomic:

gh aw edit repo-assist \
  --set max-turns=20 \
  --set max-ai-credits=500 \
  --set timeout-minutes=15 \
  --schedule 6h

Schedule examples

Compact durations could canonicalize to fuzzy schedules:

gh aw edit repo-assist --schedule 1h
gh aw edit repo-assist --schedule 3h
gh aw edit repo-assist --schedule 1d
gh aw edit repo-assist --schedule 1w
gh aw edit repo-assist --schedule weekdays
gh aw edit repo-assist --schedule weekly

The general path syntax could support existing fuzzy forms and exact cron:

gh aw edit repo-assist "on.schedule: every 6 hours"
gh aw edit repo-assist "on.schedule: daily on weekdays"
gh aw edit repo-assist --set 'on.schedule=[{"cron":"0 9 * * 1"}]'
gh aw edit repo-assist --unset on.schedule

--schedule off or --unset on.schedule should remove only the schedule trigger while preserving workflow_dispatch, PR, issue, and other triggers.

Cost and runtime examples

gh aw edit repo-assist "max-ai-credits: 500"
gh aw edit repo-assist "max-ai-credits: 5K"
gh aw edit repo-assist "max-daily-ai-credits: 15K"
gh aw edit repo-assist "max-turns: 20"
gh aw edit repo-assist "max-turn-cache-misses: 3"
gh aw edit repo-assist "timeout-minutes: 15"
gh aw edit repo-assist "jobs.agent.timeout-minutes: 30"
gh aw edit repo-assist "jobs.detection.timeout-minutes: 5"

Restore inherited defaults by removing an override:

gh aw edit repo-assist --unset max-ai-credits
gh aw edit repo-assist --unset max-daily-ai-credits
gh aw edit repo-assist --unset max-turns

Potential convenience profiles could expand visibly into ordinary frontmatter changes:

gh aw edit repo-assist --cost-profile economical
gh aw edit repo-assist --cost-profile balanced
gh aw edit repo-assist --cost-profile intensive

Engine and model examples

gh aw edit repo-assist "engine: copilot"
gh aw edit repo-assist "engine: claude"
gh aw edit repo-assist "engine: codex"
gh aw edit repo-assist "model: small"
gh aw edit repo-assist "model: gpt-5.4-mini"
gh aw edit repo-assist "engine.model: claude-haiku-4-5"
gh aw edit repo-assist --unset engine.model

Model policy changes:

gh aw edit repo-assist --add models.allowed=gpt-5.4-mini
gh aw edit repo-assist --add 'models.allowed=claude-*'
gh aw edit repo-assist --add models.blocked=gpt-5.4
gh aw edit repo-assist --remove models.blocked=gpt-5.4

Engine-specific settings should be checked against the selected engine rather than accepted as arbitrary YAML.

Trigger examples

gh aw edit repo-assist --add-trigger workflow_dispatch
gh aw edit repo-assist --add-trigger issues
gh aw edit repo-assist --add-trigger pull_request
gh aw edit repo-assist --remove-trigger push
gh aw edit repo-assist --remove-trigger schedule
gh aw edit repo-assist --set 'on.issues.types=["opened","edited"]'
gh aw edit repo-assist --set 'on.pull_request.types=["opened","synchronize"]'
gh aw edit repo-assist --set 'on.pull_request.paths=["src/**","go.mod"]'
gh aw edit repo-assist --set 'on.push.branches=["main"]'
gh aw edit repo-assist --set 'on.workflow_run.workflows=["CI"]'
gh aw edit repo-assist --set 'on.workflow_run.types=["completed"]'
gh aw edit repo-assist "on.slash_command.name: repo-assist"
gh aw edit repo-assist --set 'on.slash_command.events=["issues","issue_comment"]'
gh aw edit repo-assist "on.label_command.name: ai-review"

Concurrency and rate-limit examples

gh aw edit repo-assist "concurrency.group: repo-assist"
gh aw edit repo-assist "concurrency.cancel-in-progress: true"
gh aw edit repo-assist "concurrency.queue: max"
gh aw edit repo-assist --unset concurrency
gh aw edit repo-assist "user-rate-limit.max-runs-per-window: 3"
gh aw edit repo-assist "user-rate-limit.window: 60"
gh aw edit repo-assist --set 'user-rate-limit.events=["workflow_dispatch","issue_comment"]'
gh aw edit repo-assist --unset user-rate-limit

Network examples

gh aw edit repo-assist --add network.allowed=github
gh aw edit repo-assist --add network.allowed=node
gh aw edit repo-assist --add network.allowed=go
gh aw edit repo-assist --add network.allowed=java
gh aw edit repo-assist --add network.allowed=api.example.com
gh aw edit repo-assist --add 'network.allowed=*.example.com'
gh aw edit repo-assist --remove network.allowed=node
gh aw edit repo-assist --add network.blocked=tracking.example.com
gh aw edit repo-assist --set 'network.allowed=[]'
gh aw edit repo-assist "network: defaults"

This seems like a useful place for domain knowledge: suggest java instead of accepting gradle, node instead of npm, and so on.

Permissions and security examples

gh aw edit repo-assist "permissions: read-all"
gh aw edit repo-assist "permissions.contents: read"
gh aw edit repo-assist "permissions.actions: read"
gh aw edit repo-assist "permissions.pull-requests: read"
gh aw edit repo-assist --unset permissions.actions
gh aw edit repo-assist "strict: true"
gh aw edit repo-assist "private: true"

Permission expansion should never be silent. In strict mode, unsafe writes should either be rejected with a safe-output recommendation or require a clearly explicit approval mechanism.

Tools and safe-output examples

gh aw edit repo-assist "tools.github: read"
gh aw edit repo-assist --add tools.github.toolsets=issues
gh aw edit repo-assist --add tools.github.toolsets=pull_requests
gh aw edit repo-assist --remove tools.github.toolsets=actions
gh aw edit repo-assist "tools.timeout: 300"
gh aw edit repo-assist --unset tools.playwright
gh aw edit repo-assist --enable-output add-comment
gh aw edit repo-assist --enable-output create-issue
gh aw edit repo-assist --disable-output create-pull-request
gh aw edit repo-assist "safe-outputs.create-issue.close-older-issues: true"
gh aw edit repo-assist "safe-outputs.threat-detection.max-ai-credits: 200"

Where deterministic, enabling a safe output could add its required permissions, with all resulting changes visible in the preview.

Runner, environment, and metadata examples

gh aw edit repo-assist "runs-on: ubuntu-latest"
gh aw edit repo-assist "runs-on-slim: ubuntu-slim"
gh aw edit repo-assist --set 'runs-on=["self-hosted","linux","x64"]'
gh aw edit repo-assist "runner.topology: arc-dind"
gh aw edit repo-assist "environment: production"
gh aw edit repo-assist "env.LOG_LEVEL: debug"
gh aw edit repo-assist --unset env.LOG_LEVEL
gh aw edit repo-assist --add excluded-env=MY_DISPATCH_TOKEN
gh aw edit repo-assist --remove excluded-env=MY_DISPATCH_TOKEN
gh aw edit repo-assist "name: Repository assistant"
gh aw edit repo-assist "description: Reviews repository health each weekday"
gh aw edit repo-assist --add labels=automation
gh aw edit repo-assist --remove labels=experimental
gh aw edit repo-assist 'run-name: Repo assist for ${{ github.repository }}'

Interactive mode

With no mutation arguments, the command could open a schema-driven editor:

gh aw edit repo-assist

Possible sections:

  • Schedule and triggers
  • Cost and runtime
  • Engine and model
  • Concurrency and rate limits
  • Permissions
  • Network
  • Tools and safe outputs
  • Runner and environment
  • Metadata

The final screen would show source and compiled diffs before writing.

Preview and automation

gh aw edit repo-assist "max-turns: 20" --dry-run
gh aw edit repo-assist "max-turns: 20" --diff
gh aw edit repo-assist "max-turns: 20" --json
gh aw edit repo-assist "max-turns: 20" --yes

Potential default transaction:

  1. Resolve the workflow source.
  2. Parse its YAML frontmatter.
  3. Apply typed mutations while preserving the Markdown body and, ideally, comments and formatting.
  4. Validate against the workflow schema.
  5. Compile to temporary output.
  6. Show the source and generated-file diff.
  7. Replace both files only if every step succeeds.

Source-managed workflows should probably be rejected with guidance to update the upstream source or pin rather than silently breaking provenance.

Fleet operations

The same abstraction could eventually support bulk control-plane changes:

gh aw edit --all --set max-turns=20 --dry-run
gh aw edit --all --set strict=true
gh aw edit --all --add network.allowed=github
gh aw edit --match 'weekly-*' --schedule weekly
gh aw edit --engine copilot --set model=small

Bulk edits should preview by default and require explicit confirmation before writing.

Questions for discussion

  • Is edit the right command name, or would config, set, or tune communicate the intent better?
  • Should the first version expose only high-value typed flags such as --schedule, --max-turns, and --max-ai-credits, or also support general schema paths?
  • Should recompilation be automatic and mandatory, or should an advanced --no-compile escape hatch exist?
  • How important is comment and YAML formatting preservation?
  • Should interactive mode be part of the initial feature or follow after non-interactive edits?
  • Which settings form the smallest useful v1: schedule, cost controls, timeout, engine/model, and enable/disable triggers?
  • Should fleet operations be in scope, or should v1 intentionally edit one workflow at a time?

Interested in reactions and alternative command shapes, especially from people using gh aw as an operational control plane.

Metadata

Metadata

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions