主線と支線:調整者ハンドブック
長いタスクを一つの会話でやり続けると、会話が何度も圧縮されて詳細が失われます。このスキルでは以下のように対応します。
- 調整者(本スキルを呼び出したセッション):要件理解、調査、分割、タスク記述書の作成、セッションの起動、報告の受領、マージ、検証、ユーザーとのコミュニケーションを担当します。調整者自身は大規模な実装は書かず、コンテキストを全体のために残します。マージコンフリクトや数行の軽微な修正は自身で行うことができます。
- 線:各線はサイドバーセッションであり、自身のワークツリーでタスク記述書に従って作業し、完了後調整者に報告を送信します。ユーザーはそのセッションに直接入って会話できます。
- 帳簿:
~/.claude/mods-data/task-lines/boards/<帳簿 id>/にすべての詳細が保存されます。会話は圧縮されますが、帳簿は圧縮されません。task-lines プラグインは圧縮後に帳簿を自動的にコンテキストに復元します:調整者は board.md と log.md の最新部分を、線は自身のタスク記述書と進捗を取得します。
以降の scripts/ は、本スキルディレクトリの scripts フォルダ(スキル読み込み時に表示される Base directory)を指します。
着手
-
帳簿を作成する:
task_boardを呼び出し、titleにタスクの短いタイトルを入力します。次にmcp__ccd_session_mgmt__get_session(session_idはself)を使って本セッションのデスクトップクライアントセッションID(local_で始まるもの)を取得し、board.md に記入します。線はこのIDを使って調整者に報告を送信します。 -
ユーザーの発言を記録する:ユーザーの要件を一字一句 board.md の「ユーザーの発言」に貼り付けます。言い換えたり、要約のみを記述したりしないでください。
-
調査する:関連するコード、ドキュメント、プロジェクトの CLAUDE.md を読み、タスク記述書を明確に書けるようになるまで調査します。現状、関連ファイル、プロジェクトの規約、検証コマンドを把握する必要があります。結論は「制約と確定事項」に記述します。
-
線に分割する:以下の「分割ルール」に従って分割し、「線」テーブルに記述します。
-
ベースラインを取得する:
scripts/snapshot.sh <メインディレクトリ> refs/task-lines/<帳簿 id>/base-1を実行し、出力されたコミットIDを「現在のベースライン」に記述します。スナップショットには、メインディレクトリの未コミットの変更と追跡されていないファイルが含まれますが、ステージングエリア、HEAD、ブランチは変更されません。 -
タスク記述書を書く:現在着手可能な各線に対して、
lines/<線 id>/brief.mdを以下のテンプレートに従って作成します。 -
セッションを起動する:各線に対して
mcp__ccd_session__spawn_taskを一度呼び出します。title:[L1] 動詞で始まる短いタイトル、60文字以内。[線 id]プレフィックスは後でこのセッションを見つけるために使用します。tldr:この線が何をするか、簡潔な説明。prompt:タスク記述書の全文。prompt は単独で理解可能でなければならず、「帳簿を読め」だけではいけません。
各線はカードとして表示され、ユーザーがクリックするとセッションが開きます。新しいセッションには自動的に独立したワークツリーが付属します。
-
ユーザーに伝える:どのような線に分割したか、各線が何をするか、どの線が今すぐ起動可能で、どの線が前の線のマージを待つ必要があるかを伝え、カードをクリックするようユーザーに依頼します。分割後すぐに作業を開始し、ユーザーの計画承認を待つ必要はありません。ユーザーはいつでも中断や変更を指示できます。
-
ログを記録する:
task_noteで記録します。
分割ルール
- 主線はタスクの幹です。非常に長い主線はL1、L2…とフェーズに分割し、各フェーズは新しいセッションを開き、最新のベースラインから作業を開始します。各セッションは1つのフェーズのコンテキストのみを保持し、これが詳細を失わないための鍵です。
- フェーズ間は直列:前のフェーズがマージされ検証された後、新しいベースラインを取得し、次のフェーズのタスク記述書を書き、そのタスク記述書に前のフェーズの引き継ぎ事項を記載します。
- 支線は主線から比較的独立した作業です(別のモジュール、ツールスクリプト、テスト補完、調査など)。支線は主線と並行して実行でき、IDはS1、S2…とします。
- 線のサイズ:1つのセッションで最初から最後まで完了でき、複数回圧縮されない程度のサイズにします。迷ったら小さめに分割します。
- 並行して実行する線は、できるだけ同じファイルを変更しないようにする:ワークツリーは実行環境を分離するだけで、同じ場所を変更するとマージ時にコンフリクトが発生します。
- 共有インターフェース(関数シグネチャ、データ形式、ファイルパス)は着手前に確定し、原文を関連する各タスク記述書に記載します。
- 同時に起動する線の数:通常2~3本です。各線がユーザーの承認を求めたり質問したりする可能性があり、多すぎるとユーザーが対応しきれません。
- 分割する価値がない場合は分割しない:1つのセッションで問題なく完了できるタスクは、直接実行し、帳簿は作成しません。
タスク記述書テンプレート
山括弧内の内容は調整者が記入します。該当しないセクションは「なし」と書き、削除しないでください。
# [<線 id>] <タイトル>
あなたはタスク帳簿 <帳簿 id> の1つの線であり、調整者は別のセッションです。以下の手順に従い、完了したら調整者に報告を送信してください。
## 着手前の手順
1. task_line_attach を呼び出し、board に "<帳簿 id>"、line に "<線 id>" を設定します。このツールは task-lines プラグインに含まれています。ツールがない場合はこの手順をスキップし、報告書にその旨を記載してください。
2. 自身のワークツリー内にいることを確認:`git rev-parse --show-toplevel` の出力が <メインディレクトリ> でないことを確認します。もしそうであれば、停止しユーザーに伝えてください。
3. ベースラインに合わせる:まず `git status --porcelain` の出力が空であることを確認し、次に `git reset --hard <ベースラインコミット>` を実行します。ベースラインにはメインディレクトリの未コミットの変更が含まれています。合わせないと、あなたの変更はマージできません。
4. 環境を準備する:<例:pnpm install。ワークツリーには node_modules がなく、Rust の target ディレクトリも空なので、初回コンパイルは遅くなります。>
## 背景と目標
<ユーザーの発言のうち、この線に関連する部分を一字一句そのままコピー。この線が完了した後の状態、なぜ行うのか。>
## 既知の事実
<調査結果:関連ファイルと行番号、現状、プロジェクトの規約、参考にできる既存の実装、確定した決定事項。>
## 範囲
- 変更してよい:<ファイルまたはディレクトリ>
- 変更してはならない:<ファイルまたはディレクトリ>
- 並行して実行中の他の線:<線 id:どのファイルを変更しているか>
- メインディレクトリ <パス> は一切変更せず、自身のワークツリー内のみで変更してください。
## インターフェースの取り決め
<他の線と共有するシグネチャ、形式を原文のまま記載。>
## 検証
<具体的なコマンド:テスト、型チェック、ビルド、実際の実行。UI が関係する場合はスクリーンショットを撮って目視確認。>
## 規律
- 自身のブランチでコミットして保存しても構いませんが、push しないでください。他のブランチを操作しないでください。
- プロジェクトの CLAUDE.md の規約に従ってください。
- 重要な決定、発見、進捗は task_note で記録してください。会話が圧縮された後、それを頼りに作業を続けます。
- ユーザーがこのセッションで直接新しい要求を出した場合は、それに従い、報告書にその要求(原文)を調整者に伝えてください。
- 調整者またはユーザーの判断が必要なこと、または範囲外のことは、まず task_note で記録し、次に調整者にメッセージを送って質問し、自分で範囲を広げないでください。
## 完了時
SendMessage を使って調整者に送信し、to に "<調整者のデスクトップセッションID>" を設定します。SendMessage がない場合は mcp__ccd_session_mgmt__send_message を使用し、session_id に同じIDを設定します。
1行目は「[<線 id>] 完了:<一言>」と書き、以下を順に記載します:
- ワークツリーのパス(`git rev-parse --show-toplevel` の出力)とブランチ名
- 変更内容(ファイルごと)、なぜそのように変更したか、自分が行ったトレードオフ
- 検証:実行したコマンドと実際の結果。失敗した場合はその旨を記載。
- 残存問題、および調整者またはユーザーの判断が必要なこと
- ユーザーがこのセッションで出した新しい要求(原文)
同じ報告を task_note にも記録してください。送信したら停止し、調整者の返信を待ちます。調整者は手直しを依頼する可能性があります。
線の実行中
- ポーリングしない。線が完了するとメッセージが送信され、そのセッションからのメッセージとして表示されます。
- 進捗確認:ユーザーが進捗を尋ねた場合、
mcp__ccd_session_mgmt__list_sessionsでタイトルのプレフィックス[線 id]を使ってセッションを検索し、mcp__ccd_session_mgmt__list_eventsで最近の活動を確認します。見つかったセッションIDは線テーブルに記録します。 - 線から質問が来た場合:決定できることはそのセッションに直接返信し、帳簿にも記録します。ユーザーの判断が必要なものは、ユーザーに転送します。
- ユーザーがメイン会話で新しい要求を出した場合:まず board.md の「ユーザーの発言」に日時を付けて一字一句追加します。次に、どの線に影響するか判断し、その線にメッセージを送信するか、次のフェーズまで保留します。
- 線が停滞または逸脱している場合:メッセージで修正を指示します。
報告受領とマージ(各線に対して)
-
予行演習:まず報告を読み、次に以下を実行します。
scripts/merge-line.sh --check <メインディレクトリ> <この線のベースライン> <線のワークツリーパス>これにより、更新、三方マージ、追加、削除されるファイルと、コンフリクトが発生するファイルが一覧表示されます。最後の行に、この線の完全な差分を確認するコマンドが表示されます。 -
レビュー:
- 範囲外のファイルが変更されていないか
- ロジックが正しいか、プロジェクトの既存コードと調和しているか
- 不要なものが含まれていないか
- コメントや文言がプロジェクトの規約に従っているか
不合格の場合は、線に手直しを依頼するメッセージを送信し、どこがなぜ悪いか、どのように修正すべきかを明確に記述します。手直し後、手順1からやり直します。
-
マージ:
scripts/merge-line.sh <メインディレクトリ> <ベースライン> <線のワークツリーパス>を実行します。このスクリプトはメインディレクトリの作業ツリー内のファイルのみを変更し、ステージングエリア、HEAD、ブランチは変更しません。- コンフリクトがある場合、ファイル内にコンフリクトマーカー(
<<<<<<< 現在から>>>>>>> 線)が残ります。コンフリクトが少なければ自分で解決し、多いか理解できない場合は、一旦停止してユーザーに伝え、対応を相談します。 - スクリプトがマージを拒否した場合(終了コード2、「ベースラインから開始されていない」というメッセージ):その線が着手時にベースラインに合わせていなかったことを示します。その線に何が起こったのか尋ね、無理にマージしないでください。
- コンフリクトがある場合、ファイル内にコンフリクトマーカー(
-
検証:メインディレクトリでプロジェクトのテスト、型チェック、ビルドを含む全量チェックを実行します。スクリプトはファイルレベルのマージのみを行い、検証を実行しなければマージ完了とは見なされません。
-
帳簿に記録する:線テーブルのステータスを「マージ済み」に変更します。「マージ記録」に以下を記述します:日時、線、ベースライン、スナップショットID、マージ結果(コンフリクトの解決方法)、検証結果。
-
ユーザーに伝える:この線がマージされた内容を伝えます。コミットするかどうかはユーザーが決定します。ユーザーが要求しない限りコミットしません。コミットする場合は、プロジェクトのコミット規約に従います。
-
線のセッション:マージが完了し、ユーザーが再度参照する必要がなくなった場合、ユーザーにアーカイブするかどうか尋ねます(
mcp__ccd_session_mgmt__archive_session)。自分でワークツリーを削除しないでください。
次のフェーズ
主線の次のフェーズ、またはマージ済みの線に依存する支線は、以下の順序で起動します。
- 新しいベースラインを取得:
scripts/snapshot.sh <メインディレクトリ> refs/task-lines/<帳簿 id>/base-<n>。 - board.md の「現在のベースライン」を更新します。
- タスク記述書を書き、新しいベースラインと、前のフェーズの引き継ぎ事項(何をしたか、何が残っているか、注意すべき点)を明記します。
- 新しいカードを起動します。
まだ実行中の古い線は、自身のベースラインを引き続き使用します。マージスクリプトは各線のベースラインに基づいて三方マージを行うため、相互に影響しません。
圧縮後
task-lines プラグインは board.md と log.md の最新部分をコンテキストに復元します。続行する前に:
- 帳簿の線テーブルを参照し、
list_sessionsで各線のセッション(タイトルプレフィックス[線 id])を検索し、list_eventsで現在の状態を確認します。 - 要約にはあるが帳簿にはまだないもの(新しい決定、ユーザーの新しい要求)を、まず帳簿に追加します。
- その後、続行します。
要約と帳簿が一致しない場合、帳簿と実際の状態を優先し、実際の状態はセッション記録とgitで確認します。
帳簿の記録方法
- board.md は総勘定元帳:ユーザーの発言、目標、制約、確定事項、線テーブル、マージ記録、ユーザーの判断待ち事項。このファイルを直接編集し、常に現在の本当の状態を反映させます。
- log.md はログ:
task_noteを使って追加し、いつ何が決定されたか、どのような報告を受け取ったか、マージ結果などを記録します。 - 各マイルストーン後に必ず更新する:線を分割した後、カードを起動した後、報告を受け取った後、マージが完了した後、ユーザーが要件を変更した後。帳簿が会話より遅れていると、圧縮時に詳細が失われます。
- 帳簿に秘密鍵、パスワード、トークンは記述しないでください。
調整者セッションの変更
元の調整者セッションが長くなりすぎた場合、新しいセッションを開いて引き継ぐことができます。
task_boardを呼び出し、boardに帳簿IDを設定します。- 「圧縮後」のセクションに従って確認します。
- 線が報告を送信する際の宛先は元の調整者のセッションIDです。board.md のセッションIDを新しいセッションのものに変更し、実行中の各線にメッセージを送信し、今後は新しいセッションに報告を送信するよう指示します。
注意点
- 線は、ユーザーがデスクトップクライアントで開いたことのあるプロジェクト内でのみ起動できます。Claude がスクラッチパッドや他のセッションの書き込み可能ディレクトリに作成したリポジトリは、デスクトップクライアントがセキュリティ上の理由でワークツリーを作成できないため、ユーザーがカードをクリックしても「Couldn't start the suggested task」と表示されます。spawn_task の
cwdを指定しない場合(デフォルトは現在のプロジェクト)、またはユーザーが開いたことのあるプロジェクトのパスを指定します。 - カードが起動できない場合、Claude側では通知を受け取れません。ユーザーからの報告に依存します。原因はデスクトップクライアントのログ
~/Library/Logs/Claude/main.logにあり、createWorktreeまたはWorktree creation failedを検索してください。 - 線セッションのワークツリーには、node_modules や Rust の target のような無視されるディレクトリが含まれません。タスク記述書の「環境を準備する」に、どのように補充するかを明記する必要があります。
- ベースラインスナップショットは
refs/task-lines/<帳簿 id>/の下に保存され、ブランチ一覧には表示されません。タスク全体が終了した後、git for-each-ref refs/task-lines/<帳簿 id>で一覧表示し、git update-ref -dで削除できます。削除する前にユーザーに確認してください。 - 2つのセッションの権限モードが異なる場合、それらの間のメッセージはユーザーの承認を待つ必要があります。線を起動する際、ユーザーに注意を促します。
- merge-line.sh はテキストファイルと通常のファイルを処理します。シンボリックリンク、および両方で変更されたバイナリファイルは「手動処理が必要」とリストアップされます。
終了処理
すべての線がマージされ、全量検証も通過した後:
- board.md を「完了」としてマークします。
- ユーザーに報告します:各線が何をしたか、マージ結果、検証結果、残存問題、ユーザーの判断待ち事項。
- ユーザーに、各線のセッションをアーカイブするかどうか、ベースラインスナップショットをクリーンアップするかどうかを尋ねます。