Crowi Kickoff (spec → worktree 実装開始)
SkillAI & modelsTurns an approved spec into a one-command start of worktree implementation. ready check → gw start (hook auto-launches a tmux window + claude session) → queue initialization → sends implementation instructions to that window via send-keys. Run in the main worktree. If a spec is not ready, lists the
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Crowi Kickoff (spec → worktree 実装開始) skill
What this skill tells your AI
The instructions your AI receives, as published by crowi/crowi in .claude/skills/crowi-kickoff/SKILL.md and read by ahel’s review.
承認済み spec の実装着手を 1 コマンドにする skill。これまで手動だった
「gw start → tmux window → エージェント起動 → /crowi-feature 手打ち」を自動化し、
開発ループの入口を閉じる(出口は /crowi-complete-feature + orchestrate A)。
起動例
/crowi-kickoff feature-attachment-thumbnail
/crowi-kickoff attachment-thumbnail # feature- prefix は省略可
/crowi-kickoff feature-foo --no-launch # worktree 作成まで。指示投入はしない
/crowi-kickoff feat-a feat-b feat-c # 直列チェーン: 先頭だけ起動し、integrate 完了ごとに次を自動 kickoff
直列チェーン(複数 spec を順番に)
複数の spec id を渡すと、1 本ずつ直列に流す(並列に全部起動しない)。先頭だけを
今 kickoff し、/integrate-worktree がそれを main に統合し終えた時点で次を自動 kickoff
する。整合の要る feature を順に着地させたい / 並列 worktree を増やしたくないときに使う。
- 前提チェックは全 spec ぶん先にやる(Step 1-3 を渡された全 id に対して実行)。1 つでも not-ready / 重複なら、チェーンを一切開始せず欠落を列挙して中止する(途中で詰まる 連鎖を作らない)。全 id が ready のときだけ進む。
- 先頭 id だけ Step 4-5(worktree 作成・起動・指示投入)を行う。残りは起動しない。
- チェーン状態を
<stateDir>/kickoff-chain.jsonに atomic (tmp+rename) で書く:{ "after": "feature-<先頭id>", "then": ["feature-<2番目>", "feature-<3番目>"], "createdAt": "<UTC>" }after= 「これが integrate されたら次へ」の現在待ち id、then= 以降のキュー。thenが空になる単一 id 指定のときはこのファイルを作らない(通常の単発 kickoff と同じ)。 - Step 5.7 の watch は先頭 1 回だけ張ればよい(以降のチェーン前進は integrate 側が担う)。
- チェーンの前進は
/integrate-worktreeの最終ステップ (Step 9) が行う — integrate がafterに一致する id を統合し終えたら、then[0]を次として/crowi-kickoffし、 ファイルを更新/削除する。詳細は integrate-worktree Step 9。 - 途中の spec が NEEDS_WORK/ESCALATE で READY にならなければ、そこで連鎖は自然に一時停止 する(次に進まない)。再開したい場合は当該 spec を仕上げて integrate すれば連鎖が続く。
- 報告(Step 6)には「チェーン: 先頭 起動、以降 を integrate ごとに自動着手」 と 1 行含める。
前提(実測済みの環境)
gw start <id>は post_start_hook で.gw/feature-state-link.sh— worktree 側.feature-state/を作成し specs/ tasks/ config.json を main store へ symlink、queue.jsonを{ "currentTask": null }で seed(worktree ローカル).gw/tmux-claude.shでtmux new-window -n <window 名>に claude セッションを自動起動 を実行する。したがって kickoff がセッションを spawn する必要はない — gw が開いた window に指示を send-keys で投入するだけでよい (agmsg spawn で別セッションを立てると二重になる。やらない)。
- 起動フラグ・hook は crowi の project-local
.gwrc(repo root・gitignore 済み)で overrideしている。hook スクリプトは./.gw/(repo-local・home 非依存) に置き、.gwrcは$GW_WORKTREE_PATHから main worktree root を導出して$MAIN/.gw/*.shを 呼ぶ(CWD にも~にも依存しない)。.gw/tmux-claude.shはclaude --remote-control '<repo>:<id>' --name '<repo>:<id>'で起動し、RC 有効 + session/terminal title =<repo>:<id>(例crowi:live-page-sync-reconcile)にする。 kickoff 後に質問で止まった session を picker/title で見つけて remote で動かすため。 crowi の.gwrcだけの override で~/.gwrc(global)は触らない。 前提: gw が project-local.gwrcを読むビルドであること(gw のfeature-project-local-config機能。未対応バイナリでは global の素claude起動に fall back = RC/name 無し)。.gwrcを編集すると direnv 式 trust hash が変わるので、 次のgw startで trust 再承認プロンプトが出る(承認まで global 値に fall back)。 - なお claude は RC/name 付きでも
pane_current_commandは version 文字列(2.x.x)の ままなので、Step 5 の pane 検出は不変。
- hook 構成によってはさらに 右 pane に
pnpm devが自動分割起動される (split-window -d— dev-portal の anchor 自動採番で port 衝突しない。GW_NO_DEV=1 gw start <id>でスキップ可)。このため指示の投入先は window ではなく claude の pane_id を明示指定する(Step 5)。 - worktree dir は
../crowi-<id>、branch は<id>/impl形式、window 名は branch から/implを落としたもの(=<id>)。全 worktree branch が/implで終わる以上この suffix は情報量ゼロで、ただでさえ切り詰められる tab bar を 5 桁食うだけなので落とす。 window 名に依存する処理は無い — kickoff も integrate-worktree もpane_current_pathで window を引くので、名前は表示専用と考えてよい。
ワークフロー
Step 1: 引数解決 + 実行コンテキスト確認
-
spec-id は
feature-prefix の有無どちらも受ける:ls .feature-state/specs/*.md 2>/dev/null | grep -E "(^|/)(feature-)?<入力>\.md$"複数一致なら列挙して中止。
-
0 件なら wiki を確認(pull・一方向): crowi CLI の直リダイレクトで materialize する (取得本文をモデルが Write で書き起こす転記経路を、実装の入口に置かない):
mkdir -p .feature-state/specs # bash redirect は親ディレクトリを作らない crowi -p local get "/crowi/spec/<入力>" > ".feature-state/specs/<id>.md" \ || crowi -p local get "/crowi/spec/feature-<入力>" > ".feature-state/specs/<id>.md" # 検証: live と一致するか (末尾改行 1 行だけの差は一致とみなす) crowi -p local get "/crowi/spec/<id>" | diff - ".feature-state/specs/<id>.md"見つかったら「wiki から pull した」と報告して続行。pull した spec も Step 2 の ready 判定は通常どおり行う(wiki にあるからと言って ready とは限らない)。CLI が使えない環境に限り
crowi_get_page(MCP) を fallback にしてよいが、その場合も書き出した内容を live と diff で突合してから進む。wiki にも無ければ「spec が無い」で中止。wiki との正本ルール(crowi-design と共通): 作業中の正本は
.feature-state/specs/、 wiki/crowi/spec/<id>は耐久スナップショット。同期は一方向のみ(design → wiki の publish / wiki → specs/ のこの pull)。食い違ったら.feature-state/specs/が勝つ。 -
main worktree で実行していること(
git worktree listの先頭パスとgit rev-parse --show-toplevelが一致)。worktree 内からの実行は中止 (「kickoff は main セッションから」)。main が dirty でも kickoff 自体は可 (worktree を切るだけで main を触らない)。
Step 2: implementation-ready 判定(orchestrate B と同一基準)
.claude/skills/_shared/spec-contract.md が正本。repo root で validator を実行する:
bash .claude/skills/_shared/validate-implementation-spec.sh ".feature-state/specs/<id>.md"
exit 0 のときだけ続行する(WARN: が stderr に出ていても exit 0 なら着手を止めない — symbol 粒度の freshness 判定が「共有ファイルへの無関係な変更」を soft に落としたもので、hard stale ではない)。validator は次をまとめて検証する:
- contract v2 marker(
spec_contract: 2/status: approved/implementation_ready: true) scope/ AC / blocking open question 無し- path + symbol 単位の実装マップ、処理フロー、契約・不変条件、実装順序
- stable AC ID と test file/case/level の対応
grounded_atが有効で、参照 path が以後の commit / working tree で変化していない(生成物 — lockfile / OpenAPI /**/generated/**— は staleness 判定から除外される。参照 path が symbol 単位で保守的な 5 条件を満たせば、シンボル行が変わっていない限りWARN:に落ちる — 詳細は.claude/skills/_shared/spec-contract.mdの freshness の symbol 粒度節)
複数 spec を preflight する場合は、各 spec の validator 実行について stdout・stderr・exit status を spec id と対応づけてリクエスト内に保持する(spec をまたいで混ざらないようにするため)。exit 0 の全 spec について、保持した stderr に WARN: 行があれば spec id ごとに原文のまま保持しておく(Step 6 で報告するため)。
umbrella spec(kind: umbrella)はこの経路に入らない。umbrella は運用契約とフェーズ表だけを持ち AC も実装マップも持たないのが正しい形なので、validator は代わりに phases: の各 sub-spec が実在しそれ自体が v2 を通ることを検証する(厳しさは sub-spec へ委譲される)。kickoff 側の手順は変わらず、worktree 名も umbrella の id を使う — 単一 worktree で全フェーズを回す運用契約は umbrella が持っており、sub-spec を個別に kickoff するとその契約が失われるため。
失敗時は validator の ERROR: を欠落・stale 理由として列挙して中止する。
kickoff 側で spec を補完・書き換えない。 legacy spec は直接 /crowi-feature の
planner fallback で実装できるが、安価なモデルへ設計判断を残さない kickoff 経路には入れない。
/crowi-design spec <topic> で v2 に作り直すか、既存 spec を強いモデルで v2 へ更新して
再レビューする。
Step 3: 重複ガード
git worktree listにcrowi-<id>を含む行があれば中止(「着手済み。続きはその worktree で」)。.feature-state/tasks/<id>.jsonが存在し status がPLANNED / IN_PROGRESS / REVIEW / NEEDS_WORK / READY_TO_INTEGRATEなら中止(進行中 or 統合待ち)。COMMITTED/INTEGRATEDの化石なら警告つきで続行可(再着手のケース)。
Step 4: worktree 作成 + queue 初期化
gw start <id> # hook が .feature-state 配線 + tmux window + claude 起動までやる
- gw が無い環境では中止(
git worktree add直呼びはしない — 既存規約)。 - hook が seed した worktree 側
queue.jsonのcurrentTaskを上書き。queue.jsonへの直接 Write/Edit は PreToolUse hook が拒否するので、 worktree 側のtask-state.shを経由する(script 自身が tmp+不変条件検証+atomic rename+.bakを行う):
WT="../crowi-<id>"
bash "$WT/.claude/scripts/task-state.sh" queue set-current "<id>"
Step 5: 実装指示の投入(gw が開いた window へ send-keys)
-
window を特定:
pane_current_pathが worktree 配下にある window を探す (window 名ではなくパスで引く — 名前は表示上の都合でいつでも変わりうるが、 パスは worktree の同一性そのもの。integrate-worktree Step 6.5 も同じ引き方):tmux list-panes -a -F '#{window_id}|#{pane_current_path}' \ | awk -F'|' -v p="<worktree-abs-path>" '$2 ~ "^"p"(/|$)" {print $1}' | sort -u補助的に window 名(= branch から
/implを除いたもの)でも引けるが、 一致しないことを理由に中止しない。 -
claude の pane を特定して起動完了を待つ: hook 構成によっては window に dev pane(右・
pnpm dev)が併設されるため、window 宛(= アクティブ pane 宛)の send-keys は使わない。tmux list-panes -t <window> -F '#{pane_id}|#{pane_current_command}'でpane_current_commandがバージョン形式(2.x.x)の pane が現れるまで 2 秒間隔で poll(上限 60 秒)し、その pane_id を投入先にする。 -
まず実装モデルへ切り替える(hook の plain
claudeは既定モデル = 高価な session model で起動するため。実装は sonnet で十分な設計 — spec が implementation-ready であることは ready 判定済み):
tmux send-keys -t "<claude の pane_id>" "/model sonnet"
sleep 1
tmux send-keys -t "<claude の pane_id>" Enter
sleep 2
- agmsg の受信を自分宛だけに絞る。
watch.shは role 名を渡さないと そのプロジェクトに登録された全 (team, agent) ペアを購読するので、既定のままだと worktree セッションに manager⇄planner のやり取りまで流れ込む(実測。impl セッションが 自分宛でない版数の議論を読まされ、そのぶんのトークンと注意を払っていた)。role 名は spec id をそのまま使う(worktree 名・task id と同じ値にして、どのセッションの role かを一意にする)。actasは未登録なら join も行うので事前の join は要らない:
tmux send-keys -t "<claude の pane_id>" "/agmsg actas <id>"
sleep 1
tmux send-keys -t "<claude の pane_id>" Enter
sleep 3
投入した role は worktree セッション自身が終端で drop する
(/crowi-complete-feature か /crowi-handoff)。actas の排他ロックは
セッション ID に紐づくので、main 側から外して回ることはできない。
- 指示を投入(入力 → 1 秒待ち → Enter。slash メニューの誤発火を避けるため
平文で書き、行頭を
/にしない):
tmux send-keys -t "<claude の pane_id>" \
"crowi-kickoff からの指示です。/crowi-feature <id> を実行してください。COMMITTED まで完走したら /crowi-complete-feature、中断・引き継ぎ時は /crowi-handoff を実行。push は禁止(ユーザー指示待ち)。"
sleep 1
tmux send-keys -t "<claude の pane_id>" Enter
送信確認(必須): セッション初期化直後は Enter が入力欄に届かず、指示文が
未送信のまま入力欄に残ることがある(実例 2026-07-19: redis-docs-page が
1 時間 0 commit — capture-pane で入力欄に指示が残っているのを発見)。Enter の
2-3 秒後に tmux capture-pane -t <pane_id> -p | tail -8 で入力欄(❯ 行)が
空になっていることを確認し、指示文が残っていれば Enter を 1 回だけ再送
して再確認する。それでも残る場合は追いパンチせず「投入したが未送信の可能性」
として報告する(このリトライは初回指示の配送完了であり、鉄則の「指示は 1 通
のみ」の例外ではない — 新しい内容は送らない)。
- fallback: tmux 環境でない / window が見つからない / 60 秒待っても claude が 起動しない → 投入せず、手動手順を表示して終わる(中止ではない — worktree は 作成済みなので Step 6 の報告に含める):
cd <worktree-abs-path> && claude
→ 最初に: /agmsg actas <id> (受信を自分宛に絞る。省くと他 role 宛まで流れ込む)
→ 次に: /crowi-feature <id>
→ 完了時: /crowi-complete-feature / 中断時: /crowi-handoff
--no-launch 指定時は Step 5 全体を skip して手動手順の表示のみ。
Step 5.7: orchestrate watch を張る(main セッション側・未起動なら)
worktree 側の完了は /crowi-complete-feature が .feature-state/tasks/<id>.json に立てる
READY_TO_INTEGRATE signal で伝わる(shared store 経由 = agmsg 等のチーム基盤に依存しない
repo-native の契約)。ただし signal は push されないので、kickoff した main セッションは
orchestrate-watch.sh を Monitor で常駐させて検知する(TaskList に「orchestrate watch」が
既にあれば張り直さない。event 対応表は crowi-orchestrate の「運用モード: watch」節が正本):
Monitor({ command: 'bash .claude/scripts/orchestrate-watch.sh',
description: 'orchestrate watch (A/C/D/E lanes)', persistent: true })
signal を受けたら orchestrate A と同じ裏取り(clean / headSha 一致 / main clean)をして
/integrate-worktree <id> へ。agmsg の完了通知(handoff skill の任意送信)は
二次チャネル — 正はこの signal file。
Step 6: 報告
- worktree path / branch / window(投入済み or 手動手順)
- signal watcher を張った(or 既存)ことを 1 行
- 次に人間がやること(通常なし。spec が multi-phase で gated phase を含むならその旨)
- staleness warnings: Step 2 で保持した
WARN:がある spec id ごとに見出しを立て、配下に validator の rawWARN:行を原文のまま転記する(要約・書き換えしない)。WARN:が無かった spec には見出しを出さない。
staleness warnings:
## feature-<id>
WARN: referenced path changed but grounded symbol lines are identical: <path> (symbols: <...>)
鉄則
- push しない / spec を書き換えない / not ready を勝手に ready 扱いしない
- worktree は gw 経由のみ(
git worktree add/remove直呼び禁止) - 投入する指示は最初の 1 通のみ。以後 worktree セッションの作業に割り込まない (進捗の把握は orchestrate A/E と agmsg 側に任せる)
エッジケース
| ケース | 挙動 |
|---|---|
| spec が specs/ に無い | wiki /crowi/spec/<id> から pull を試みる(Step 1)。wiki にも無ければ中止 |
| legacy / incomplete spec | validator の欠落を列挙して中止。/crowi-design spec で v2 化するか、直接 /crowi-feature の planner fallback を明示的に使う |
引用 symbol の行が grounded_at 後に変わった(symbol line hard stale) | ERROR: で中止(exit 1)。安価な planner で黙って再設計せず、spec を再 ground / review する |
| path-only 参照、または symbol 粒度の 5 条件を満たさない変化(mode 不一致・binary・dirty 等、file-level hard stale) | ERROR: で中止(exit 1)。symbol hard stale と同様に再 ground / review する |
| symbol 外の変更だけが起きた(共有ファイルへの無関係な追加など) | WARN: は出るが exit 0。着手は止めない。Step 6 の staleness warnings に転記する |
| gw start 失敗(同名 branch 残骸等) | gw のエラーを提示して中止。-f 系は使わずユーザーに委ねる |
| claude 起動待ち timeout | 手動手順を表示(worktree は残す) |
| send-keys 後に反応が無い | 追いパンチしない。報告に「投入したが未確認」と書き、ユーザーに window 確認を促す |
| spec が umbrella(他 spec をフェーズとして参照する形式) | kickoff の手順自体は変わらない(通常どおり /crowi-feature <id> を投入)。umbrella は spec_contract の値に関わらず crowi-feature SKILL 側で needsPlanner=true に倒される(v2 fast path はどの spec からも sub-spec phases を機械導出できないため)。feature-planner が phases: の sub-spec 群から実装順序 / extraGates / longLived 相当を task state へ seed する。 |
crowi-feature / complete-feature との関係
- worktree 名 = spec id にするのは、
/crowi-complete-featureの id 解決 (dir basename からcrowi-除去)と orchestrate A の worktree 特定 (worktree 名 = task id)を成立させるため。変えない。 - kickoff は planner を起動しない(それは worktree 側の
/crowi-featureが scope 判定して行う)。kickoff の責務は「入口を開けて最初の指示を渡す」まで。
Signals
- GitHub stars
- 1k
- Forks
- 165
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
crowi-kickoff- Source
- github.com/crowi/crowi