# Conversation Context Export

> 対話コンテキストをexportする。 会話で共有された目的・意図・設計判断・制約条件を `.dev/contexts/` ディレクトリに書き出し、PRが存在する場合はPRコメントにも投稿する。次の作業者（レビュワー、別セッションのAI、バグハンティングのAIなど）に引き継ぐ。 ユーザーが「コンテキストを書き出して」「対話コンテキストをexport」「会話した内容を.devに保存して」と言った時に使用する。

- Skill: `shokai/conversation-context-export` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add shokai/conversation-context-export`
- Raw SKILL.md: https://api.skillmd.com/api/skills/shokai/conversation-context-export/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: shokai (https://skillmd.com/u/shokai)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/shokai/conversation-context-export

---


# 対話コンテキストのexport手順書

会話を通じて共有された開発コンテキスト（目的・意図・設計判断・制約条件など）を `.dev/contexts/{サニタイズ済みブランチ名}.md` に書き出す。PRが存在する場合はPRコメントにも投稿する。

## 用途

このファイルは以下の場面で活用される:

- **PR概要欄のレビュー**: 人間が書いたPR概要を、AIが実装コンテキストと照合して誤りや説明不足を指摘する
- **feature PRでのAI対AIバグハンティング**: 弁護側AIが設計意図を理解するためのブリーフィング資料
- **新セッションでの開発継続**: 前セッションのコンテキストを引き継ぐ
- **PRコメントでの共有**: PRが存在する場合にコメントとしても投稿し、他の作業者やsanity-reviewが直接参照できるようにする

## 手順

### 1. メタデータを取得する

Bashツールで以下を実行する:

```
git branch --show-current && git rev-parse --short HEAD && gh pr view --json number -q .number
```

ブランチ名、source commit、PR番号を取得する。Updated atには現在の日時（YYYY-MM-DD HH:mm:ss）を記入する。

- PRが存在すれば番号を取得してメタデータのPRフィールドに記入する
- コマンドがエラーになった場合（PRが未作成）は「export時点でPR未作成」と記入する

### ブランチ名のサニタイズ

ブランチ名をファイル名として使う際、以下の文字を `-` に置換する:

```
/ \ : * ? " < > |
```

例: `dependabot/npm_and_yarn/feed-5.2.0` → `dependabot-npm_and_yarn-feed-5.2.0`

以降の手順では、サニタイズ後のブランチ名を「サニタイズ済みブランチ名」と呼ぶ。

### 出力先ディレクトリの決定

出力先をgit worktreeの状況に応じて決める。

Bashツールで `git worktree list` を実行し、現在の作業ツリーがmain worktree（リポジトリ本体の作業ツリー）か、リンクされたworktreeかを判断する。worktreeで作業している場合はmain worktreeのパスも把握する。

main treeで作業中の場合は、出力先ディレクトリを `.dev/contexts/` とする。

worktree内で作業中の場合は、AskUserQuestionツールで出力先を確認する:

- **main treeに出力**: 出力先ディレクトリを `{main treeのパス}/.dev/contexts/` とする。worktreeを破棄してもローカルファイルが残る
- **現在のworktreeに出力**: 出力先ディレクトリを `.dev/contexts/` とする

以降の手順では、決定したパスを「出力先ディレクトリ」と呼ぶ。

### 2. 既存ファイルの確認

`{出力先ディレクトリ}/{サニタイズ済みブランチ名}.md` が既に存在するか確認する。

存在する場合は、Readツールで読み込む。次に、そのファイルが **この会話内で自分がexportしたものか（同一セッション）、それとも別のセッションが書き出したものか（別セッション）** を判定する。

- **同一セッション**: この会話内で自分がWriteツールで書き出したファイルである
- **別セッション**: それ以外（前セッションのAI、別のAIが書き出したもの）

この判定に基づき、ステップ3で「既存ファイルの更新ルール」を適用する。

### 3. コンテキストの書き出し

このSKILL.mdと同じディレクトリにある [TEMPLATE.md](TEMPLATE.md) を読み込み、その構造に従ってファイルを作成する。

出力先ディレクトリが存在しない場合は作成する。

Writeツールで `{出力先ディレクトリ}/{サニタイズ済みブランチ名}.md` に書き出す。

### 4. PRコメントへの投稿

ステップ1でPR番号が取得できなかった場合（PRが未作成）は、この手順をスキップする。

#### 4-1. リポジトリ情報と現在のGitHubユーザーを取得する

Bashツールで以下を実行する:

```
gh repo view --json owner,name -q '.owner.login + "/" + .name' && gh api user -q .login
```

1行目がリポジトリの `{owner}/{repo}`、2行目が現在のGitHubユーザー名となる。

#### 4-2. 既存の対話コンテキストコメントを検索する

Bashツールで以下を実行し、PRコメント一覧から対話コンテキストのコメントを検索する。TEMPLATE.mdの見出し形式 `# {ブランチ名} 対話コンテキスト` で始まるコメントのみを対象とする:

```
gh api repos/{owner}/{repo}/issues/{PR番号}/comments --paginate -q '.[] | select(.body | startswith("# {ブランチ名} 対話コンテキスト")) | {id: .id, login: .user.login}'
```

`{ブランチ名}` にはカレントブランチ名（サニタイズ前）を埋め込む。`startswith` で見出し行の完全一致を確認することで、「対話コンテキスト」という文字列を含むだけの無関係なコメントを除外する。

複数見つかった場合は、自分のコメントを優先して対象とする。自分のコメントが複数ある場合は最新のものを使う。自分のコメントがなく別ユーザーのコメントのみの場合は、最新のものを対象とする。

#### 4-3. 投稿の判定と実行

検索結果に応じて以下のように分岐する。コメント本文はファイルから読み込む方式を使い、シェルのエスケープ問題を避ける。

##### 既存コメントが見つからない場合

新規コメントを投稿する:

```
gh pr comment {PR番号} --body-file "{出力先ディレクトリ}/{サニタイズ済みブランチ名}.md"
```

##### 既存コメントが見つかり、投稿者が自分の場合

既存コメントを更新する:

```
gh api repos/{owner}/{repo}/issues/comments/{コメントID} --method PATCH -F "body=@{出力先ディレクトリ}/{サニタイズ済みブランチ名}.md"
```

##### 既存コメントが見つかり、投稿者が別のユーザーの場合

別ユーザーのコメントは権限上編集できないため、AskUserQuestionツールで以下の選択肢を提示する:

- **別コメントとして投稿する**: `gh pr comment` で新規コメントを投稿する
- **GitHub投稿をスキップする**: ローカルファイルへの書き出しのみで終了する

#### 4-4. 結果の報告

投稿または更新が完了した場合、PRコメントのURLをユーザーに報告する。スキップした場合はその旨を報告する。

## 書き出し内容のガイドライン

### 重点を置くべき内容

- **実装の挙動の正確な記述**: 「こう動く」ではなく「こういう入力の時にこう動く」のレベルで記述する
- **却下した代替案とその理由**: 人間が後から「なぜこうしなかったんだっけ」となりがちな判断
- **発見された制約と難所**: 次の作業者が同じ罠を踏まないための情報

### 薄くて良い内容

- コードを読めば自明なこと（使った関数名、変更したファイル一覧など）

### 各セクションの「書かないもの」ルール

- **設計方針**: コード/設定を読めばわかる設定値の選択理由は書かない（例: ファイル名の命名、envバージョンの選択）
- **新たに確認できた事実**: 感想、進め方の反省、苦労話は書かない。将来の意思決定に影響する事実のみ
- **注意が必要な難所**: 制約（変えられない事実）は「発見された制約」に書く。ポジティブな発見は「新たに確認できた事実」に書く

### セクション間の判定ガイド

**「設計方針」と「却下した代替案」の境界:**

- 設計方針 = 採用したアプローチとその根拠
- 却下した代替案 = 検討したが採用しなかったアプローチとその理由

**「発見された制約」と「注意が必要な難所」の境界:**

- 制約 = 作業者が注意しても消えない、判断を縛る事実
- 難所 = 知っていれば手順や進め方で回避できる事故

### 既存ファイルの更新ルール

#### 同一セッション内での再export

- 会話の全文脈に基づいて全面再生成する
- 既存ファイルの内容に縛られない。現時点の理解が権威

#### 別セッションの記録を更新する場合

先行セッションの記録は「先人の発見」として尊重する。

- 既存の項目は原則として残す
- 新たに発見した情報を追記する
- **修正・削除は、自分の作業で実際に追試・検証して反証した場合のみ**許可する。推論だけでは削除しない
- 項目の誤分類が明らかな場合はセクション間で移動してよい（内容は保持される）
- 意図・方針・スコープ判断の変更を推定する場合はユーザーに確認する

#### 共通ルール

- ファイルは常に「現時点で正しい状態」を表す。取り消し線や変更履歴は残さない（履歴はgitに任せる）
- **Exported byは貢献者名を累積する**: ローカルファイルと既存のPRコメント本文の両方に残っているExported byエントリを保持し、自分のエントリが無ければ追記する。「同一セッション内での再export」で全面再生成するときも、過去の貢献者名は残す

## 関連スキル

- **conversation-context-import**: 保存された対話コンテキストを読み込むスキル。新セッションでの開発継続やfeature PRのレビュー時に使用する。
- **sanity-review**: PRレビュー報告書を作成するスキル。PRコメントに投稿された対話コンテキストを読み込んでレビューに活用する。

