swain-dispatch

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese
<!-- swain-model-hint: sonnet, effort: low -->
<!-- swain-model-hint: sonnet, effort: low -->

Agent Dispatch

Agent 分发

Dispatches swain-design artifacts to background agents via GitHub Issues. The agent runs autonomously using
anthropics/claude-code-action@v1
on a GitHub Actions runner.
通过GitHub Issues将swain-design工件分发至后台Agent。该Agent在GitHub Actions运行器上通过
anthropics/claude-code-action@v1
自主运行。

Prerequisites

前提条件

Three things must be in place before dispatch works:
  1. Claude GitHub App — installed on the repo from https://github.com/apps/claude (grants Contents, Issues, Pull Requests read/write)
  2. Workflow file
    .github/workflows/claude.yml
    (or
    agent-dispatch.yml
    ) with the
    claude-code-action
    step
  3. ANTHROPIC_API_KEY
    repo secret
    — API key (not Max/Pro subscription; per-token billing required)
在进行分发前,必须满足以下三个条件:
  1. Claude GitHub App — 已从https://github.com/apps/claude安装到仓库(需授予Contents、Issues、Pull Requests的读写权限)
  2. 工作流文件 — 存在
    .github/workflows/claude.yml
    (或
    agent-dispatch.yml
    ),且包含
    claude-code-action
    步骤
  3. ANTHROPIC_API_KEY
    仓库密钥
    — API密钥(非Max/Pro订阅密钥;需使用按令牌计费的密钥)

Step 0 — Preflight check

步骤0 — 预检检查

Run this before every dispatch. If any check fails, stop and show the setup instructions.
bash
undefined
每次分发前运行此检查。若任何检查失败,请停止操作并查看设置说明。
bash
undefined

1. Check gh auth

1. 检查gh认证状态

gh auth status 2>/dev/null || { echo "FAIL: gh not authenticated"; exit 1; }
gh auth status 2>/dev/null || { echo "FAIL: gh未认证"; exit 1; }

2. Check workflow file

2. 检查工作流文件

WORKFLOW_FILE="" for f in .github/workflows/claude.yml .github/workflows/agent-dispatch.yml; do [[ -f "$f" ]] && WORKFLOW_FILE="$f" && break done
WORKFLOW_FILE="" for f in .github/workflows/claude.yml .github/workflows/agent-dispatch.yml; do [[ -f "$f" ]] && WORKFLOW_FILE="$f" && break done

3. Check API key secret

3. 检查API密钥

OWNER_REPO="$(gh repo view --json nameWithOwner -q .nameWithOwner)" HAS_KEY=$(gh api "repos/${OWNER_REPO}/actions/secrets" --jq '.secrets[].name' 2>/dev/null | grep -c ANTHROPIC_API_KEY || true)

**If workflow file is missing**, show:
> **Dispatch setup required.** No workflow file found.
>
> Create `.github/workflows/claude.yml`:
> ```yaml
> name: Claude Code
>
> on:
>   repository_dispatch:
>     types: [agent-dispatch]
>   issue_comment:
>     types: [created]
>   pull_request_review_comment:
>     types: [created]
>   issues:
>     types: [opened, assigned]
>
> jobs:
>   claude:
>     if: |
>       (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
>       (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
>       (github.event_name == 'issues' && contains(github.event.issue.body, '@claude'))
>     runs-on: ubuntu-latest
>     permissions:
>       contents: write
>       issues: write
>       pull-requests: write
>       id-token: write
>     steps:
>       - uses: actions/checkout@v4
>
>       - uses: anthropics/claude-code-action@v1
>         with:
>           anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
> ```
>
> Then commit and push before retrying dispatch.

**If API key secret is missing**, show:
> **Missing `ANTHROPIC_API_KEY` repo secret.**
>
> Set it with: `gh secret set ANTHROPIC_API_KEY --repo {owner}/{repo}`
>
> Note: This must be an API key (per-token billing), not a Max/Pro subscription token.
OWNER_REPO="$(gh repo view --json nameWithOwner -q .nameWithOwner)" HAS_KEY=$(gh api "repos/${OWNER_REPO}/actions/secrets" --jq '.secrets[].name' 2>/dev/null | grep -c ANTHROPIC_API_KEY || true)

**若缺少工作流文件**,显示:
> **需配置分发功能** 未找到工作流文件。
>
> 创建`.github/workflows/claude.yml`文件:
> ```yaml
> name: Claude Code
>
> on:
>   repository_dispatch:
>     types: [agent-dispatch]
>   issue_comment:
>     types: [created]
>   pull_request_review_comment:
>     types: [created]
>   issues:
>     types: [opened, assigned]
>
> jobs:
>   claude:
>     if: |
>       (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
>       (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
>       (github.event_name == 'issues' && contains(github.event.issue.body, '@claude'))
>     runs-on: ubuntu-latest
>     permissions:
>       contents: write
>       issues: write
>       pull-requests: write
>       id-token: write
>     steps:
>       - uses: actions/checkout@v4
>
>       - uses: anthropics/claude-code-action@v1
>         with:
>           anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
> ```
>
> 提交并推送后,再重试分发操作。

**若缺少API密钥**,显示:
> **缺少`ANTHROPIC_API_KEY`仓库密钥**
>
> 使用以下命令设置:`gh secret set ANTHROPIC_API_KEY --repo {owner}/{repo}`
>
> 注意:此密钥必须是按令牌计费的API密钥,而非Max/Pro订阅令牌。

Dispatch workflow

分发工作流

Step 1 — Resolve the artifact

步骤1 — 解析工件

Parse the user's request to identify the artifact ID (e.g.,
SPEC-025
,
SPIKE-007
).
bash
ARTIFACT_ID="SPEC-025"  # from user input
ARTIFACT_PATH="$(find docs/ -path "*${ARTIFACT_ID}*" -name "*.md" -print -quit)"
If not found, report the error and stop.
解析用户请求以识别工件ID(例如:
SPEC-025
SPIKE-007
)。
bash
ARTIFACT_ID="SPEC-025"  # 来自用户输入
ARTIFACT_PATH="$(find docs/ -path "*${ARTIFACT_ID}*" -name "*.md" -print -quit)"
若未找到工件,报告错误并停止操作。

Step 2 — Read the artifact

步骤2 — 读取工件内容

Read the full artifact content. This becomes the issue body.
读取完整的工件内容,该内容将作为Issue的正文。

Step 3 — Read dispatch settings

步骤3 — 读取分发设置

Check
swain.settings.json
for dispatch configuration:
bash
jq -r '.dispatch // {}' swain.settings.json 2>/dev/null
Defaults:
  • model
    :
    claude-sonnet-4-6
  • maxTurns
    :
    15
  • labels
    :
    ["agent-dispatch", "swain"]
  • autoTrigger
    :
    true
检查
swain.settings.json
中的分发配置:
bash
jq -r '.dispatch // {}' swain.settings.json 2>/dev/null
默认配置:
  • model
    :
    claude-sonnet-4-6
  • maxTurns
    :
    15
  • labels
    :
    ["agent-dispatch", "swain"]
  • autoTrigger
    :
    true

Step 4 — Create the GitHub Issue

步骤4 — 创建GitHub Issue

bash
gh issue create \
  --title "[dispatch] ${ARTIFACT_TITLE}" \
  --body "$(cat <<EOF
bash
gh issue create \
  --title "[dispatch] ${ARTIFACT_TITLE}" \
  --body "$(cat <<EOF

Dispatched Artifact: ${ARTIFACT_ID}

已分发工件: ${ARTIFACT_ID}

This issue was created by
swain-dispatch
for background agent execution.
此Issue由
swain-dispatch
创建,用于后台Agent执行。

Instructions

说明

Implement the artifact below. Follow the acceptance criteria. Create a PR when done.

${ARTIFACT_CONTENT} EOF )"
--label "agent-dispatch" --label "swain"

Capture the issue number from the output.
请实现以下工件内容。遵循验收标准。完成后创建PR。

${ARTIFACT_CONTENT} EOF )"
--label "agent-dispatch" --label "swain"

从输出中捕获Issue编号。

Step 5 — Trigger the workflow

步骤5 — 触发工作流

If
autoTrigger
is true (default):
bash
OWNER_REPO="$(gh repo view --json nameWithOwner -q .nameWithOwner)"
gh api "repos/${OWNER_REPO}/dispatches" \
  -f event_type="agent-dispatch" \
  -f client_payload[artifact]="${ARTIFACT_ID}" \
  -f client_payload[issue_number]="${ISSUE_NUMBER}" \
  -f client_payload[model]="${MODEL}" \
  -f client_payload[max_turns]="${MAX_TURNS}"
autoTrigger
为true(默认值):
bash
OWNER_REPO="$(gh repo view --json nameWithOwner -q .nameWithOwner)"
gh api "repos/${OWNER_REPO}/dispatches" \
  -f event_type="agent-dispatch" \
  -f client_payload[artifact]="${ARTIFACT_ID}" \
  -f client_payload[issue_number]="${ISSUE_NUMBER}" \
  -f client_payload[model]="${MODEL}" \
  -f client_payload[max_turns]="${MAX_TURNS}"

Step 6 — Report

步骤6 — 反馈结果

Tell the user:
Dispatched ${ARTIFACT_ID} to background agent. Issue: ${ISSUE_URL} Workflow will run on the next available runner. Monitor progress in the issue comments.
告知用户:
已将${ARTIFACT_ID}分发至后台Agent。 Issue地址: ${ISSUE_URL} 工作流将在下一个可用的运行器上执行。 请在Issue评论中监控执行进度。

Manual dispatch

手动分发

If the user prefers manual dispatch (or
autoTrigger
is false), skip Step 5 and tell them:
Issue created: ${ISSUE_URL} To trigger the agent, comment
@claude
on the issue.
若用户偏好手动分发(或
autoTrigger
为false),跳过步骤5并告知用户:
Issue已创建: ${ISSUE_URL} 如需触发Agent,请在Issue中评论
@claude

Checking dispatch status

检查分发状态

When the user asks about dispatch status:
bash
gh issue list --label agent-dispatch --state open --json number,title,updatedAt
Show open dispatch issues with their last update time.
当用户询问分发状态时:
bash
gh issue list --label agent-dispatch --state open --json number,title,updatedAt
显示所有处于打开状态的分发Issue及其最后更新时间。

Trigger timing

触发时机

The Claude Code Action workflow fires on different GitHub events depending on how
@claude
is mentioned:
Mention locationEventWhen it fires
Issue body at creation
issues.opened
Immediately when issue is created
Comment on existing issue
issue_comment.created
When the comment is posted
Gotcha: If the workflow file didn't exist when the issue was created, the
issues.opened
event was missed. In that case, add a follow-up comment containing
@claude
to trigger via
issue_comment.created
instead.
The default dispatch workflow (Step 4 + Step 5) uses
repository_dispatch
which is independent of
@claude
mentions. The timing gotcha only applies when:
  • Using manual dispatch (Step 5 skipped)
  • The workflow relies on
    issues.opened
    or
    issue_comment.created
    events
Claude Code Action工作流会根据
@claude
的提及位置,响应不同的GitHub事件:
提及位置事件触发时机
Issue创建时的正文中
issues.opened
Issue创建后立即触发
现有Issue的评论中
issue_comment.created
评论发布时触发
注意事项:若Issue创建时工作流文件尚未存在,则会错过
issues.opened
事件。此时,需添加包含
@claude
的后续评论,通过
issue_comment.created
事件触发工作流。
默认的分发工作流(步骤4 + 步骤5)使用
repository_dispatch
,该事件与
@claude
提及无关。上述注意事项仅适用于以下场景:
  • 使用手动分发(跳过步骤5)
  • 工作流依赖
    issues.opened
    issue_comment.created
    事件