cto-heartbeat

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

cto-heartbeat

cto-heartbeat

Flow optimizer operating loop for a repo. Unblocks WIP first, triages unlabeled issues, and dispatches exactly one task per run.
This skill implements the operating principles defined in the
cto
role skill.
针对代码仓库的工作流优化操作循环。优先疏通在制品(WIP),对未标记问题进行分类,每次运行仅分派一项任务。
本技能实现了
cto
角色技能中定义的操作原则。

Invocation

调用方式

/cto-heartbeat org/repo [goal-context]
Examples:
/cto-heartbeat fellowship-dev/booster-pack
/cto-heartbeat fellowship-dev/booster-pack "focus: Vercel deployment pipeline"
/cto-heartbeat org/repo [goal-context]
示例:
/cto-heartbeat fellowship-dev/booster-pack
/cto-heartbeat fellowship-dev/booster-pack "focus: Vercel deployment pipeline"

Token

令牌配置

bash
export GH_TOKEN=$(grep "GH_PAT_FELLOWSHIP" $HOME/projects/fellowship-dev/claude-buddy/.env | cut -d= -f2)
bash
export GH_TOKEN=$(grep "GH_PAT_FELLOWSHIP" $HOME/projects/fellowship-dev/claude-buddy/.env | cut -d= -f2)

Or for specific teams, use the team's token_var from crew.yml

针对特定团队,请使用 crew.yml 中的 team's token_var


---

---

Step 0: Bootstrap Labels (idempotent)

步骤0:初始化标签(幂等操作)

Create labels in the target repo if they do not exist. Run every time —
gh label create
is idempotent (errors silently if label exists).
bash
export REPO=$1
export GOAL_CONTEXT="${@:2}"
export GH_TOKEN=$(grep "GH_PAT_FELLOWSHIP" $HOME/projects/fellowship-dev/claude-buddy/.env | cut -d= -f2)
如果目标仓库中不存在指定标签则创建它们。每次运行此步骤——
gh label create
是幂等操作(如果标签已存在则静默忽略错误)。
bash
export REPO=$1
export GOAL_CONTEXT="${@:2}"
export GH_TOKEN=$(grep "GH_PAT_FELLOWSHIP" $HOME/projects/fellowship-dev/claude-buddy/.env | cut -d= -f2)

Priority labels

优先级标签

gh label create "P0" --repo $REPO --color "b60205" --description "Production broken, revenue impact, security — fix now" 2>/dev/null || true gh label create "P1" --repo $REPO --color "d93f0b" --description "Important but not urgent — fix this week" 2>/dev/null || true gh label create "P2" --repo $REPO --color "fbca04" --description "Nice to have — fix when convenient" 2>/dev/null || true
gh label create "P0" --repo $REPO --color "b60205" --description "Production broken, revenue impact, security — fix now" 2>/dev/null || true gh label create "P1" --repo $REPO --color "d93f0b" --description "Important but not urgent — fix this week" 2>/dev/null || true gh label create "P2" --repo $REPO --color "fbca04" --description "Nice to have — fix when convenient" 2>/dev/null || true

Status labels

状态标签

gh label create "dispatched" --repo $REPO --color "5319e7" --description "Work sent to a crew member" 2>/dev/null || true gh label create "blocked" --repo $REPO --color "c5def5" --description "Waiting on external input or another issue" 2>/dev/null || true
undefined
gh label create "dispatched" --repo $REPO --color "5319e7" --description "Work sent to a crew member" 2>/dev/null || true gh label create "blocked" --repo $REPO --color "c5def5" --description "Waiting on external input or another issue" 2>/dev/null || true
undefined

Step 1: WIP Scan (unblock before new work)

步骤1:在制品(WIP)扫描(先疏通再启动新工作)

Check the current state of in-flight work before doing anything else. The principle: stop starting, start finishing.
bash
undefined
在执行其他操作前,先检查当前进行中工作的状态。原则:停止启动新任务,先完成现有任务。
bash
undefined

Open PRs across the repo

仓库中所有开放的PR

gh pr list --repo $REPO --state open --json number,title,labels,createdAt,url
gh pr list --repo $REPO --state open --json number,title,labels,createdAt,url

Issues with dispatched label (work in progress)

带有dispatched标签的问题(进行中工作)

gh issue list --repo $REPO --label "dispatched" --state open --json number,title,labels,assignees,url
gh issue list --repo $REPO --label "dispatched" --state open --json number,title,labels,assignees,url

Issues with blocked label

带有blocked标签的问题

gh issue list --repo $REPO --label "blocked" --state open --json number,title,labels,url
gh issue list --repo $REPO --label "blocked" --state open --json number,title,labels,url

Check if any dispatched issues have associated merged PRs (work completed but label not cleaned up)

检查是否有已分派的问题关联了已合并的PR(工作已完成但标签未清理)

For each dispatched issue, check if there is a recently merged PR that references it

针对每个已分派的问题,检查是否存在引用它的近期合并PR


Actions:
- **Dispatched issue has a merged PR?** → Close the issue or remove `dispatched` label, acknowledge completion
- **Dispatched issue has an open PR stuck >2 days?** → Flag as blocker, investigate
- **Dispatched issue has no PR at all and was dispatched >3 days ago?** → Flag as stale dispatch
- **Blocked issue** → Check if the blocker is resolved; if so, remove `blocked` label and re-prioritize
- **PR stuck without progressing through review pipeline** → Flag

**Output**: List of WIP items and their status. Any actions taken (labels removed, issues closed).

操作:
- **已分派问题关联了已合并的PR?** → 关闭该问题或移除`dispatched`标签,确认工作完成
- **已分派问题关联的PR停滞超过2天?** → 标记为阻塞项并调查原因
- **已分派问题未关联任何PR且已超过3天?** → 标记为陈旧分派
- **阻塞的问题** → 检查阻塞是否已解决;若已解决,移除`blocked`标签并重新排优先级
- **PR停滞未通过审核流程** → 标记出来

**输出**:在制品列表及其状态,以及已执行的操作(如移除标签、关闭问题)。

Step 2: Active Epic Focus

步骤2:活跃史诗级任务(epic)聚焦

Determine which epic is currently in progress. An "active epic" is one that has at least one open issue with the
dispatched
label.
bash
undefined
确定当前正在进行的史诗级任务。“活跃史诗级任务”指至少有一个带有
dispatched
标签的开放问题的史诗级任务。
bash
undefined

Find which epic labels have dispatched issues

找出包含已分派问题的史诗级标签

gh issue list --repo $REPO --label "dispatched" --state open --json labels --jq ".[].labels[].name" | sort -u

Filter out metadata labels (P0, P1, P2, dispatched, blocked, bug, enhancement, documentation, etc.) — whatever remains is an epic label.

Rules:
- If exactly one epic has dispatched work → that is the **active epic**. Focus all subsequent steps on it.
- If multiple epics have dispatched work → the one with the most dispatched issues is active. Flag the split as a concern.
- If no epic has dispatched work (WIP=0) → no active epic. Step 4 will pick from highest-priority across all epics.

**Output**: Active epic name (or "none — WIP is clear").
gh issue list --repo $REPO --label "dispatched" --state open --json labels --jq ".[].labels[].name" | sort -u

过滤掉元数据标签(P0、P1、P2、dispatched、blocked、bug、enhancement、documentation等)——剩余的即为史诗级标签。

规则:
- 如果恰好有一个史诗级任务包含已分派工作 → 这就是**活跃史诗级任务**。后续所有步骤都聚焦于此。
- 如果多个史诗级任务包含已分派工作 → 已分派问题最多的那个为活跃任务。标记这种分散情况为需要关注的问题。
- 如果没有史诗级任务包含已分派工作(WIP=0)→ 无活跃史诗级任务。步骤4将从所有史诗级任务中选择最高优先级的任务。

**输出**:活跃史诗级任务名称(或“无——在制品已清理完毕”)。

Step 3: Triage New Issues (max 5)

步骤3:分类新问题(最多5个)

Find issues that lack priority labels and triage them.
bash
undefined
找出缺少优先级标签的问题并进行分类。
bash
undefined

All open issues

所有开放问题

gh issue list --repo $REPO --state open --json number,title,labels,body,createdAt --limit 50
gh issue list --repo $REPO --state open --json number,title,labels,body,createdAt --limit 50

Filter: issues without P0, P1, or P2 labels (done in code/logic, not pure CLI)

过滤:没有P0、P1或P2标签的问题(通过代码/逻辑实现,而非纯CLI命令)


For each unlabeled issue (up to 5):
1. Read the issue title and body
2. Assign a priority label: P0, P1, or P2
3. Assign an epic label if it fits an existing epic, or create a new epic label if the issue represents a new workstream
4. Apply the labels:
```bash
gh issue edit $ISSUE_NUM --repo $REPO --add-label "P1,epic-name"
Skip issues that already have a priority label (P0/P1/P2). The heartbeat does not re-triage.
Output: Table of triaged issues with assigned priority and epic.

针对每个未标记的问题(最多5个):
1. 阅读问题标题和内容
2. 分配优先级标签:P0、P1或P2
3. 如果问题符合现有史诗级任务则分配对应的史诗级标签,若问题代表新的工作流则创建新的史诗级标签
4. 应用标签:
```bash
gh issue edit $ISSUE_NUM --repo $REPO --add-label "P1,epic-name"
跳过已带有优先级标签(P0/P1/P2)的问题。本heartbeat不会重新分类已标记的问题。
输出:已分类问题的表格,包含分配的优先级和史诗级任务。

Step 4: Dispatch One Task

步骤4:分派一项任务

Pick exactly one issue to dispatch. Dispatch means: add the
dispatched
label so the crew lead knows to assign it.
Priority order:
  1. Active epic, highest priority first: P0 > P1 > P2, within the active epic
  2. If no active epic: highest priority issue across all epics
  3. If nothing to dispatch: report "backlog clear" or "all dispatched"
bash
undefined
选择恰好一个问题进行分派。分派指添加
dispatched
标签,让团队负责人知道需要分配该任务。
优先级顺序:
  1. 活跃史诗级任务,最高优先级优先:P0 > P1 > P2,在活跃史诗级任务范围内
  2. 若无活跃史诗级任务:所有史诗级任务中的最高优先级问题
  3. 若无任务可分派:报告“待办事项已清空”或“所有任务已分派”
bash
undefined

Find undispatched issues in the active epic, sorted by priority

找出活跃史诗级任务中未分派的问题,按优先级排序

gh issue list --repo $REPO --label "$ACTIVE_EPIC" --state open --json number,title,labels --limit 20
gh issue list --repo $REPO --label "$ACTIVE_EPIC" --state open --json number,title,labels --limit 20

Filter out issues that already have "dispatched" label

过滤掉已带有"dispatched"标签的问题

Pick the highest priority one

选择最高优先级的问题

Add dispatched label

添加dispatched标签

gh issue edit $ISSUE_NUM --repo $REPO --add-label "dispatched"
undefined
gh issue edit $ISSUE_NUM --repo $REPO --add-label "dispatched"
undefined

Build-train suggestion

Build-train建议

If 2+ undispatched issues exist on the same repo (after filtering out
dispatched
and
blocked
), consider dispatching
/build-train org/repo --issues N,M,...
instead of a single issue. This bundles work into one build branch and runs the review pipeline once instead of per-PR. Use your judgement — build-train makes sense when the issues are independent and can be worked in parallel. Skip it for tightly coupled issues that need sequential implementation.
Rules:
  • Never dispatch if WIP > 3 — too much in flight. Focus on unblocking instead.
  • One dispatch per heartbeat — do not batch (unless using build-train, which counts as one dispatch).
Output: Issue number, title, priority, epic — or reason nothing was dispatched. If suggesting build-train, list the bundled issues.
如果同一仓库中存在2个及以上未分派的问题(过滤掉
dispatched
blocked
标签后),考虑使用
/build-train org/repo --issues N,M,...
来分派任务,而非单个问题。这会将工作打包到一个构建分支中,只需运行一次审核流程,而非每个PR单独运行。请根据情况判断——当问题相互独立且可并行处理时,使用build-train是合理的。对于需要按顺序实现的紧密耦合问题,请跳过此方式。
规则:
  • 当WIP > 3时,切勿分派新任务——进行中的任务过多。此时应专注于疏通阻塞,而非添加新任务。
  • 每次heartbeat仅分派一项任务——不要批量分派(除非使用build-train,这算作一次分派)。
输出:问题编号、标题、优先级、史诗级任务——或无法分派任务的原因。如果建议使用build-train,请列出打包的问题。

Step 5: Report

步骤5:生成报告

bash
REPORT_DIR="$(git rev-parse --show-toplevel)/reports"
REPORT_PATH="$REPORT_DIR/$(date +%Y-%m-%d)-cto-heartbeat-$(echo $REPO | tr "/" "-").md"
Report structure:
markdown
undefined
bash
REPORT_DIR="$(git rev-parse --show-toplevel)/reports"
REPORT_PATH="$REPORT_DIR/$(date +%Y-%m-%d)-cto-heartbeat-$(echo $REPO | tr "/" "-").md"
报告结构:
markdown
undefined

CTO Heartbeat: [repo name]

CTO Heartbeat: [repo name]

Date: YYYY-MM-DD HH:MM Repo: $REPO Active epic: [epic name or "none"] Goal context: $GOAL_CONTEXT (or "N/A")
日期: YYYY-MM-DD HH:MM 仓库: $REPO 活跃史诗级任务: [epic名称或“无”] 目标上下文: $GOAL_CONTEXT(或“无”)

WIP Status

在制品状态

IssueTitleStatusEpicPriority
#N...dispatched / blocked / staleepic-nameP1
问题标题状态史诗级任务优先级
#N...dispatched / blocked / staleepic-nameP1

Actions Taken

已执行操作

  • Closed #N (resolved by PR #M)
  • Removed dispatched from #N (stale >3 days)
  • Unblocked #N (blocker resolved)
  • 关闭#N(由PR #M解决)
  • 移除#N的dispatched标签(已超过3天未更新)
  • 疏通#N(阻塞已解决)

Triage

分类结果

IssueTitlePriorityEpic
#N...P1epic-name
问题标题优先级史诗级任务
#N...P1epic-name

Dispatched

已分派任务

  • #N — [title] (P1, epic: [name]) — dispatched for crew execution
  • #N — [标题] (P1, epic: [名称]) — 已分派给团队执行

Blockers

阻塞项

  • [blocker description — what is stuck and why]
  • [阻塞项描述——哪些任务停滞以及原因]

Recommendations

建议

  1. [highest priority action]
  2. [second priority]

Post report to Quest:
```bash
QUEST_TOKEN=$(grep "^QUEST_TOKEN=" $HOME/projects/fellowship-dev/claude-buddy/.env | cut -d= -f2)
curl -s -X POST "http://127.0.0.1:4242/api/event" \
  -H "Authorization: Bearer $QUEST_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(python3 -c "
import json
content = open('$REPORT_PATH').read()
print(json.dumps({
  'source': 'commander',
  'type': 'commander.report',
  'title': 'CTO Heartbeat: $REPO',
  'meta': {'content': content, 'report_type': 'cto-heartbeat'}
}))
")" 2>/dev/null || true

  1. [最高优先级操作]
  2. [次优先级操作]

将报告发布到Quest:
```bash
QUEST_TOKEN=$(grep "^QUEST_TOKEN=" $HOME/projects/fellowship-dev/claude-buddy/.env | cut -d= -f2)
curl -s -X POST "http://127.0.0.1:4242/api/event" \
  -H "Authorization: Bearer $QUEST_TOKEN" \
  -H "Content-Type: application/json" \
  -d "$(python3 -c "
import json
content = open('$REPORT_PATH').read()
print(json.dumps({
  'source': 'commander',
  'type': 'commander.report',
  'title': 'CTO Heartbeat: $REPO',
  'meta': {'content': content, 'report_type': 'cto-heartbeat'}
}))
")" 2>/dev/null || true

Verdict Reference

判定参考

VerdictEmojiLabelMerge?
LGTM
approved
No (heartbeat dispatches issues, not PRs)
REWORK🔄
needs-work
No
BLOCKED⏸️
needs-work
No
NEW_ISSUE📋Create separate issue
STALE
needs-work
No

判定结果表情标签合并?
LGTM
approved
否(heartbeat仅分派问题,不处理PR)
需要返工🔄
needs-work
阻塞⏸️
needs-work
新建问题📋创建单独问题
陈旧
needs-work

Notes

注意事项

  • Heartbeat is a flow optimizer, not a scanner. It unblocks WIP first (stop starting, start finishing), triages unlabeled issues with P0/P1/P2 and epic labels, and dispatches exactly one task per run. One-at-a-time dispatch keeps the team focused and prevents WIP sprawl.
  • The heartbeat acts on backlog hygiene. Close issues resolved by merged PRs, flag duplicates, and keep the backlog clean. The lead owns dispatch decisions for new work.
  • Never dispatch if WIP > 3 — too much in flight. The heartbeat's job in that case is to unblock, not to add more.
  • For PR review functionality, see
    /cto-review
    . For CTO role principles, see the
    cto
    role skill.
  • Heartbeat是工作流优化器,而非扫描器。 它优先疏通在制品(WIP)(停止启动新任务,先完成现有任务),为未标记问题添加P0/P1/P2和史诗级标签进行分类,每次运行仅分派一项任务。单次分派可保持团队专注,避免在制品泛滥。
  • Heartbeat负责维护待办事项的整洁。 关闭已被合并PR解决的问题,标记重复项,保持待办事项干净。团队负责人拥有新工作的分派决策权。
  • 当WIP > 3时,切勿分派新任务——进行中的任务过多。此时heartbeat的职责是疏通阻塞,而非添加新任务。
  • 如需PR审核功能,请查看
    /cto-review
    。如需CTO角色原则,请查看
    cto
    角色技能。