/handoff — クロスツールワークハンドオフ
どのAIコーディングツールも、他のツールのトランスクリプトを読むことはできません。Claude Codeはセッションを~/.claude/projects/<munged-cwd>/<uuid>.jsonlにロックし、Codex/OpenCodeは独自のストアに、Antigravityは暗号化された.pbに保存します。ツール間で移植可能な唯一のものは、自己完結型の文書です。このスキルはその文書を作成します — 現在の目標、決定事項、そして正確な未コミットの編集差分 — これにより、他のAIエージェントが再説明なしで中断したところから作業を再開できます。
このスキルを使用するタイミング: ユーザーのトークンが少なくなった場合、タスクの途中でツールを切り替えたい場合、別のマシンに移動する場合、「handoff」「continue elsewhere」「out of tokens」と言った場合。
このスキルは自己完結型です。git + シェルのみで動作します。specweave handoffがPATH上にある場合は、オプションのアクセラレータとして呼び出します(高忠実度、インクリメント認識)— ただし、SpecWeaveのインストールへのハードな依存関係はありません。
決定: どのパスを取るか
command -v specweave >/dev/null 2>&1 && echo "ACCELERATOR" || echo "STANDALONE"
- ACCELERATOR (
specweaveがPATH上にある場合) → エンジンを実行し、その出力を表示します。パスAに進みます。 - STANDALONE (
specweaveがない場合) →git+ 簡単なインタビューから自分で文書を作成します。パスBに進みます。
どちらのパスも同じ文書形式と同じ貼り付けプロンプトを出力するため(以下の正規テンプレートを参照)、どちらのパスで生成されたハンドオフでも、任意のツールで続行可能です。
パスA — アクセラレータ (specweaveがPATH上にある場合)
エンジンを実行し、安価に提供できる短いコンテキストを転送します:
specweave handoff [incrementId] [--reason "..."] [--summary "..."] [--next "..."] [--gotcha "..."] [--decision "..."] [--inline]
次に、そのstdoutをそのまま、順序通りに表示します(並べ替えたり言い換えたりしないでください):
- 絶対文書パス(プレーンテキスト)(最初) 2. クリック可能なマークダウンリンク 3.
.diffパス - フェンスで囲まれたコピペ再開プロンプト 5. ツールごとの「ソースセッションを見つける」ヒント
完了。エンジンがワークスペース検出、タスク/AC解析、gitキャプチャ、完全差分ダンプ、機密スクラブ、レンダリングを処理しました。
パスB — スタンドアロン (specweaveなし)
シェルのみを使用して、バイト互換の文書を構築します。
B1. git状態のキャプチャ(無料 — トークン不要)
ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
mkdir -p "$ROOT/.handoff"
printf '*\n' > "$ROOT/.handoff/.gitignore" # ハンドオフとその差分がgitに入るのを防ぐ
BRANCH="$(git -C "$ROOT" rev-parse --abbrev-ref HEAD 2>/dev/null || echo '(no git)')"
SHA="$(git -C "$ROOT" rev-parse --short HEAD 2>/dev/null || echo '(no commits)')"
STATUS="$(git -C "$ROOT" status --porcelain 2>/dev/null)"
STAT="$(git -C "$ROOT" diff --stat 2>/dev/null)"
# 未コミットの編集全体 → 兄弟.diff(ワーキングツリー + ステージング)、主要な忠実性成果物
{ git -C "$ROOT" diff HEAD 2>/dev/null; git -C "$ROOT" diff --cached 2>/dev/null; } > "$ROOT/.handoff/handoff.diff"
B2. 5つの質問インタビュー(導出不可能なフィールドのみ)
ユーザーに尋ねます(〜5つの短い文字列に抑える — トークン枯渇時でも安価):
- reason — なぜハンドオフするのですか?(例:「トークン切れ」)
- summary — 一行で: 状況はどうですか?
- next — 正確な次のステップ。
- gotcha — 次のエージェントが絶対にやってはいけないこと / 知っておくべきこと?
- decisions — すでに行われた重要な決定(セミコロン区切り)。
B3. 機密スクラブ(書き込み前 — フリーテキストと差分の両方に対して)
一致箇所を[REDACTED-<type>]に置き換え、パターンごとにカウントします。パターン(12種類):
sk-, ghp_, gho_, ghs_, AKIA, ASIA, -----BEGIN, vsk_, xox[bap]-, Bearer , password=, api_key=.
# キャプチャした差分をその場でスクラブ、例:
sed -i.bak -E \
-e 's/sk-[A-Za-z0-9_-]+/[REDACTED-sk]/g' \
-e 's/gh[pos]_[A-Za-z0-9_-]+/[REDACTED-gh-token]/g' \
-e 's/(A[KS]IA[0-9A-Z]{16})/[REDACTED-aws-key]/g' \
-e 's/vsk_[A-Za-z0-9_-]+/[REDACTED-vsk]/g' \
-e 's/xox[bap]-[A-Za-z0-9-]+/[REDACTED-slack]/g' \
-e 's/Bearer [A-Za-z0-9._-]+/Bearer [REDACTED-bearer]/g' \
-e 's/(password=)[^[:space:]]+/\1[REDACTED-password]/g' \
-e 's/(api_key=)[^[:space:]]+/\1[REDACTED-api_key]/g' \
"$ROOT/.handoff/handoff.diff" && rm -f "$ROOT/.handoff/handoff.diff.bak"
スクラブはヒューリスティックです — 空の編集リストはファイルがクリーンであることを保証しません。
B4. 文書の書き込み
以下の正規テンプレートを$ROOT/.handoff/HANDOFF.mdに書き込み、キャプチャした+インタビューフィールドを埋めます。
所有権センチネル: ルートの./HANDOFF.mdがすでに存在し、Doc format v1マーカーを含まない場合、それは外部ファイルです — 上書きしないでください。代わりに.handoff/HANDOFF.mdに書き込みます(これがデフォルトです)。
B5. 出力の表示 — 絶対パスを最初に、この順序で
.handoff/HANDOFF.mdの絶対パス(プレーンテキスト)- それへのクリック可能なマークダウンリンク
.handoff/handoff.diffの絶対パス- フェンスで囲まれた貼り付けプロンプト(以下を参照)
- ツールごとの「ソースセッションを見つける」ヒント
正規ハンドオフ文書テンプレート(インライン — 単一の真実の情報源)
これらのセクションをこの正確な順序でレンダリングし、最後にDoc format v1フッターマーカーを付けます。角括弧のプレースホルダーは、キャプチャしたgit状態+インタビューから埋められます。これはspecweaveのhandoff-doc-format.tsをミラーリングしているため、ここで生成された文書はCLIで生成されたものとバイト互換です。
# ワークハンドオフ[: <既知のタイトル>]
- Doc path: <ABSOLUTE_DOC_PATH>
- Doc link: [<ABSOLUTE_DOC_PATH>](<ABSOLUTE_DOC_PATH>)
- Diff file: <ABSOLUTE_DIFF_PATH>
- Generated: <ISO_TIMESTAMP>
- Workspace: <ROOT> (非SpecWeave)
- Git: ブランチ `<BRANCH>` @ `<SHA>`
## 中断した場所
**ハンドオフ理由:** <reason>
**サマリー:** <summary>
_アクティブなSpecWeaveインクリメントはありません — これはgit + インタビューのハンドオフです。_
## 完了 / 保留
_インクリメントタスク/AC状態は利用できません。_
## 重要な決定と注意点
- <decision 1>
- <decision 2>
**注意点:** <gotcha>
## 触れたファイル
**未コミット** — 破壊的な操作を行う前に、コミット、スタッシュ、または編集を続けてください。
<git status --porcelain>
<git diff --stat>
完全な未コミット差分: `<ABSOLUTE_DIFF_PATH>` — これを読むか、`git apply --check`を実行して正確な編集内容を確認してください。
## 正確な次のステップ
<next>
## 再開方法
上記の文書パスがこれを読んでいるマシンに存在しない場合は、停止し、ユーザーにハンドオフを貼り付けるよう依頼してください — コンテキストを推測しないでください。
元のトランスクリプトを復元するには(オプション)、ツールごとにソースセッションを見つけてください:
### Claude Code
- セッションを見つける: ls ~/.claude/projects/<munged-cwd>/(マングル: すべての非英数字 → "-"、連続は圧縮されません; 例: /Users/antonabyzov/Projects/github/specweave-umb/.claude-worktrees/x → -Users-antonabyzov-Projects-github-specweave-umb--claude-worktrees-x)
- 再開: `claude -r <uuid>`
### Codex
- セッションを見つける: ls ~/.codex/sessions/(最新のディレクトリ = 最新のセッション)
- 再開: `codex resume <uuid> (または: codex resume --last)`
### OpenCode
- セッションを見つける: opencode sessions list
- 再開: `opencode -s <id> (長い形式: opencode --session <id>)`
### Gemini CLI
- セッションを見つける: Geminiセッション内で/chat listを実行し、保存されたタグを確認
- 再開: `/chat resume <tag>`
### Antigravity
- セッションを見つける: Antigravity Agent Managerを開き、以前のタスクスレッドを選択
- 再開: `Antigravity Agent Managerからスレッドを再開`
### Aider
- セッションを見つける: aiderは.aider.chat.history.mdをリポジトリルートに保持
- 再開: `aider --restore-chat-history`
## 編集(秘匿化)
- <N> `<type>` 文字列がマスクされました
_スクラブはヒューリスティック(正規表現ベースライン)です。空の編集リストはこのファイルがクリーンであることを保証しません — 共有またはコミットする前に確認してください。_
---
<!-- Doc format v1 -->
テンプレートに関する注意:
- 未コミットの変更がない場合、「Files Touched」本文を
_ワーキングツリーはクリーン — 未コミットの編集はありません。_に置き換えます(gitがない場合は_gitリポジトリではありません — 差分はキャプチャされませんでした。_)。 - 決定事項がない場合、「Key Decisions」本文は
_決定は記録されていません。_とします。gotchaがない場合、**Gotcha:**行は省略します。 - 何もマスクされなかった場合、「Redaction」本文は
_トークン風の文字列は検出されませんでした。_とします。 - フッターマーカー
<!-- Doc format v1 -->は必須であり、最後の行でなければなりません — これが所有権センチネルです。
貼り付けプロンプト
デフォルト(ファイルにアクセス可能):
作業を再開してください。ハンドオフ文書を読んでください: <ABSOLUTE_DOC_PATH>
そのパスがこのマシンに存在しない場合は、停止し、ハンドオフを貼り付けるよう私に依頼してください — コンテキストを推測しないでください。
正確な未コミットの編集差分は次の場所にあります: <ABSOLUTE_DIFF_PATH>
--inline(マシン間、ファイルにアクセス不可能): マーカーの間に完全な文書本文を埋め込み、プロンプト自体に含めます:
以下の自己完結型ハンドオフを使用して作業を再開してください。
これは完全なハンドオフ文書です — マーカー間のすべてを事実として扱ってください。このマシンに存在しない`.diff`パスを参照している場合は、差分を貼り付けるよう私に依頼してください。
BEGIN HANDOFF
<完全にレンダリングされたハンドオフ文書、Doc format v1フッターを含む>
END HANDOFF
セーフティデフォルト
- 文書と差分はデフォルトでgitignoreされます(
.handoff/.gitignore=*)ので、自動的にコミットされることはありません。git addのヒントは表示しないでください。 - 機密スクラブは、書き込み前にフリーテキストと差分の両方に対して実行されます。
- スクラブはヒューリスティックです — 共有またはコミットする前に確認するようユーザーにアドバイスしてください。