关于 squad
squad 是用于管理项目任务与项目上下文的技能,通过命令操作看板、任务生命周期和项目资料,并提供会话交接信息。
主要功能
- 01查看看板与任务进度
- 02创建、编辑和流转任务
- 03完成、取消及重新打开任务
- 04查看统计和项目上下文
- 05管理项目简介与关联
- 06上传任务图片附件
适用场景
- 01开始会话时了解任务进展
- 02按流程推进或调整任务状态
- 03维护项目简介及项目关系
- 04为任务添加图片并查看统计
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ steloit/ squad-skills --skill squad安装后在 Claude Code 中输入/squad确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
models.jsonprinciples.mdschema.mdshared.mdscripts/api_smoke.pyapi.mdapi.pycoach_smoke.pyobserve_smoke.pyobserve.mdobserve.pyrefine_ledger_smoke.pyrefine_ledger.mdrefine_ledger.pyrender_agent_prompt.pytemplates/coach.mdreviewer.mdworker.md详细介绍
共享上下文:阅读
shared.md,了解项目配置与身份验证、流水线级别、状态转换、API 端点、错误处理和 Agent 上下文流。 安全原则:阅读principles.md——必须遵守,不可选。
命令
/squad 或 /squad list — 查看看板
BOARD=$(api GET /board?summary=true)
输出:包含 ID、状态、优先级和标题的 Markdown 表格。
史诗任务:看板响应包含一个 epics 汇总(每项都有 children_progress 和派生的 epic_status)。使用此汇总和嵌入的 parent/children 关系,将子任务归组到各自的史诗任务下——绝不要通过解析标签来判断(参见 shared.md → 任务关系与史诗任务)。显示每个史诗任务的 children_progress(例如 2/5 done)。
/squad context — 会话交接
**开始新会话时首先运行。**获取看板并输出流水线状态: Implementing / Plan Review / Impl Review / Testing / Recently Done / Next Todo。
BOARD=$(api GET /board?summary=true)
/squad add <title> — 添加任务
- 使用 AskUserQuestion 询问用户优先级、级别(L1/L2/L3)、描述和标签
- 使用
jq安全地构建 JSON(参见 shared.md → JSON Safety),POST 到 API,并捕获新任务 ID。tags必须是 JSON 数组——看板渲染时使用的规范存储格式。将用户以逗号分隔的输入拆分为数组,例如在 jq 请求体中使用--arg tags "$TAGS",然后设置tags: ($tags | split(",") | map(gsub("^ +| +$";"")))(没有标签时,省略该字段或传入[],绝不要传入"")。 - 图片:如果用户提供了图片文件路径(例如
/squad add "Login bug" --image ./bug.png,或“附上 ./shot.png”),通过附件 API 将每张图片上传到新任务(参见 shared.md → "Upload an image attachment")。输出任务 ID 和返回的附件url(可有多个)。如果用户粘贴了图片但没有路径 → 请用户先将图片保存为文件(上传需要读取本地文件)。
/squad move <ID> <status> — 移动任务
始终按顺序遵循
shared.md→ Move Protocol。 步骤 1(检查当前状态和级别)→ 步骤 2(查阅矩阵)→ 步骤 3(执行移动)。 遇到 400 错误时:根据响应中的.allowed[0]自行修正一次;失败 2 次后通知用户。
/squad edit <ID> — 编辑任务
询问用户要修改哪些字段,然后通过 API 发送 PATCH。要为现有任务附加图片,请通过附件 API 上传本地图片文件(shared.md → "Upload an image attachment")。
/squad complete <ID> [note] — 完成任务(管理性完成)
将任意非终止状态的任务标记为已完成。此操作无需交互——不调用
AskUserQuestion,也不需要确认提示;完成操作会保留历史记录且可撤销,因此直接执行即可。
NOTE="$*" # everything after the ID; may be empty
# omit/empty note → send {} ; otherwise send {"completion_note": "<note>"}
if [ -n "$NOTE" ]; then
api POST /task/$ID/complete --json "$(jq -n --arg n "$NOTE" '{completion_note:$n}')"
else
api POST /task/$ID/complete --json '{}'
fi
# → {"success":true,"status":"done","version":<int>}
Complete 是 /squad cancel 的配对操作:complete = 已完成,cancel = 不再执行。两者都会保留历史记录(保留计划、备注、评论、计数和结果),并且可通过 /squad reopen 撤销;这与不可撤销的 /squad remove(硬删除)不同。对已完成的任务再次执行完成操作是安全的空操作;若目标任务已取消,则返回 409——请先重新打开任务。任务卡片会记录 completed_via:"admin"(通过受限流水线 finalize 时则为 "pipeline"),以及可选的 completion_note。
/squad cancel <ID> [reason] — 取消任务(首选的放弃操作)
可取消任意状态的任务。此操作无需交互——不调用 AskUserQuestion,也不需要确认提示;取消操作会保留历史记录且可撤销,因此直接执行即可。
REASON="$*" # everything after the ID; may be empty
# omit/empty reason → send {} ; otherwise send {"cancel_reason": "<reason>"}
if [ -n "$REASON" ]; then
api POST /task/$ID/cancel --json "$(jq -n --arg r "$REASON" '{cancel_reason:$r}')"
else
api POST /task/$ID/cancel --json '{}'
fi
# → {"success":true,"status":"cancelled","version":<int>}
取消是放弃工作的首选方式:它会保留历史记录(保留计划、备注、评论、计数和结果),并且可通过 /squad reopen 撤销。对已取消的任务再次执行取消操作是安全的空操作。对于不再执行、已被取代或优先级已降低的工作,应使用此操作,而不是 /squad remove。
/squad reopen <ID> — 重新打开任务(取消取消/取消完成状态)
将终态任务(cancelled 或 done)恢复为 todo。这是取消取消状态和
取消完成状态的操作路径——重新打开会清除生命周期时间戳、current_agent、cancel_reason、
completion_note 和 completed_via,并保留之前的工作。
api POST /task/$ID/reopen --json '{"reason": "<why reopening>"}'
# → {"success":true,"status":"todo","version":<int>}
重新打开非终态任务(除 cancelled/done 之外的任何状态)会返回 409,且不做任何更改。
/squad remove <ID> — 删除任务
api DELETE /task/$ID
remove是硬性DELETE操作——不可撤销(卡片及其附件都会消失)。仅用于从未开始的错误任务/重复任务。对于不再执行或已被取代的工作,优先使用/squad cancel(保留历史记录且可撤销)。
/squad stats — 统计信息
各列的任务数量来自看板摘要;每位参与者的令牌/事件总数来自单次
GET /api/activity/stats 调用(服务端按 actor 分组——不会逐个任务循环,也不会为统计令牌数据获取看板)。
export BOARD=$(api GET /board?summary=true)
export STATS=$(api GET /activity/stats)
python3 << 'PY'
import json, os
board = json.loads(os.environ['BOARD'])
stats = json.loads(os.environ['STATS'])
columns = ['todo', 'plan', 'plan_review', 'impl', 'impl_review', 'test', 'done', 'cancelled']
# Column counts (summary is keyed by status, each an array of cards)
counts = {col: len(board.get(col, [])) for col in columns}
counts['total'] = sum(counts.values())
print("## Column Counts\n")
print("| Status | Count |")
print("|--------|-------|")
for col in columns:
print(f"| {col} | {counts[col]} |")
print(f"| **total** | **{counts['total']}** |")
# Per-actor token/event stats — tolerant reader: pull only the fields we use,
# treat a null/missing per-actor `tokens` as unknown (render —, never coerce to 0,
# never do arithmetic over a null), and ignore any unknown/extra fields the server adds.
rows = stats.get('stats', [])
totals = stats.get('totals', {})
print("\n## Agent Token Usage\n")
if not rows:
print("No token data")
else:
print("| Actor | Events | Tokens | Coverage |")
print("|-------|--------|--------|----------|")
for r in sorted(rows, key=lambda r: r.get('actor', '')):
events = r.get('events', 0)
tok = r.get('tokens')
reported = r.get('reported')
tok_cell = "—" if tok is None else f"{tok:,}"
if reported is None:
cov_cell = "—"
elif reported < events:
cov_cell = f"{reported}/{events} (partial)"
else:
cov_cell = f"{reported}/{events}"
print(f"| {r.get('actor', 'unknown')} | {events} | {tok_cell} | {cov_cell} |")
tot_tok = totals.get('tokens')
tot_tok_cell = "—" if tot_tok is None else f"{tot_tok:,}"
print(f"| **Total** | **{totals.get('events', 0)}** | **{tot_tok_cell}** | |")
PY
/squad project — 当前项目上下文(AI 上下文对接)
从项目表中获取当前项目的上下文。在会话开始时使用此命令,通过一次调用加载项目目标、技术栈、简介、关联关系和任务数量。
PROJECT_DATA=$(api GET /projects/$PROJECT)
输出:格式化的项目上下文,包括:
- 目标(此项目存在的原因)
- 技术栈(使用的技术)
- 简介(压缩后的当前状态、方向和近期决策)
- 类别和状态
- 按状态分类的任务数量
- 相关项目的链接
如果项目尚未注册,建议运行 /squad-init 进行注册。
/squad project all — 完整项目概览
获取按类别分组的所有项目。可用于了解完整的项目布局。
ALL_PROJECTS=$(api GET /projects)
输出:按类别(例如个人、工具、技能)分组的项目及其名称和目标。
/squad project brief — 查看/更新项目简介
简介是压缩后的上下文摘要(200–500 个字符),Agent 可以低成本地使用它。
查看当前简介:
api GET /projects/$PROJECT | jq -r '.brief // "No brief set"'
直接设置简介:
api PATCH /projects/$PROJECT --json '{"brief": "..."}'
借助 AI 更新(/squad project brief update):
- 获取当前项目信息和近期已完成的任务(
GET /api/board?project=$PROJECT&summary=true) - 分析:当前状态、近期完成事项、当前方向
- 起草简洁的简介(200–500 个字符),涵盖:当前已有内容、未来方向、近期重要决策
- 提交给用户确认 → PATCH 保存
/squad project update <field> <value> — 编辑项目元数据
通过 PATCH 更新任意项目字段:
# Update purpose
api PATCH /projects/$PROJECT --json '{"purpose": "new purpose"}'
# Archive project
api PATCH /projects/$PROJECT --json '{"status": "archived"}'
支持的字段:name、purpose、stack、brief、status、category、repo_url。
/squad project link — 管理项目关联关系
# Add relationship
api POST /projects/$PROJECT/links --json '{"target_id": "other-project", "relation": "depends_on"}'
# Remove relationship
api DELETE /projects/$PROJECT/links --json '{"target_id": "other-project", "relation": "depends_on"}'
关联类型:extends、serves、depends_on、shares_data。
/squad observe status|dry-run — 观察授权(只读)
检查观察授权门控。此命令只读——选择加入/退出的操作仅在Web 应用中进行(Settings → Observation & Consent);此技能不会授予或撤销授权。参见 shared.md → Observation & Consent。
observe() { python3 ../squad/scripts/observe.py "$@"; }
# status — effective on/off, the source that decided it (env override / server
# consent / default), the policy_version on record, and the web-app manage pointer.
observe status # human-readable; add --json for the decision object
# dry-run — print the ABSTRACTED user_steering payload that WOULD be recorded to
# stdout (pipeable to jq) + a `# DRY RUN` banner to stderr. Writes/sends NOTHING,
# in any consent state — inspect before opting in.
observe dry-run | jq .
这里没有 grant/withdraw——请在 Web 应用中选择加入或退出。
设置与 Web 看板
先运行 /squad-init 注册此项目——它会在仓库根目录写入 .squadrc(SQUAD_PROJECT=…,以及可选的 SQUAD_ORG=<label> 组织选择器),并将其提交,以便整个团队的 Agent 都指向同一个看板项目。令牌不会写入项目文件——它是一个个人访问令牌,按 SQUAD_AUTH_TOKEN 环境变量 > ~/.squad/auth 中不带前缀的 SQUAD_AUTH_TOKEN= 的顺序解析(参见 shared.md)。
打开已部署的看板:https://squad.steloit.com/?project=<PROJECT>(或通过配置的 SQUAD_BASE_URL)。
功能:7 列工作流、拖放(仅限有效状态转换)、卡片生命周期模态框、Agent 日志查看器、每 10 秒自动刷新。