mcpField
P
pi-history-ingest

pi-history-ingest

github.com/ar9av生産性3.6k1.2k 回インストール2 日前に更新
リポジトリ

pi-history-ingest について

pi-history-ingest は、Pi のコーディングエージェントのセッションから長期的に有用な知識を抽出し、Obsidian wiki に整理するスキルです。セッションツリーのアクティブブランチをたどり、各情報をセッション内の根拠に結び付け、プライバシーフィルターを適用します。

主な機能

  1. 01JSONL セッションツリーのアクティブブランチ解析
  2. 02マニフェストによる新規・変更セッションの検出
  3. 03トピック別の wiki ページ作成
  4. 04抽出した情報の出典根拠の保持
  5. 05認証情報や機密情報の除外

活用シーン

  1. 01Pi コーディングエージェントの決定事項を wiki に記録
  2. 02セッション履歴の差分同期
  3. 03根拠のある複数セッションの反復パターンの要約

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/ar9av/obsidian-wiki --skill pi-history-ingest

インストール後、Claude Code で/pi-history-ingestを入力して読み込まれたか確認します。

詳細

Pi 履歴の取り込み — セッションの分析

ユーザーの Pi コーディングエージェントのセッションから知識を抽出し、Obsidian の Wiki にまとめます。Pi のセッションはツリー構造を持つ構造化 JSONL として保存されています。アクティブなブランチをたどり、長期的に有用な知識を抽出して、整理するのが役割です。

セッション知識の範囲: このスキルでは、Pi のセッションファイルのみを事実情報の出典とします。選択したセッションのエントリーに記載されていない限り、モデルの学習内容、その他のツール、パッケージのドキュメント、ローカルファイル、現在の会話から背景知識を追加しないでください。外部のコンテキストが役立ちそうな場合は、未解決の質問として記すか、省略してください。セッションから抽出した知識として提示してはいけません。

このスキルは直接、または wiki-history-ingest ルーター(/wiki-history-ingest pi)経由で呼び出せます。

始める前に

執筆プロファイル: 自然言語の Markdown を作成または書き換える前に、llm-wiki/SKILL.md の「執筆プロファイルの解決」セクションを読み、その指示に従ってください。フレームワークのスキーマ、出典情報、安全性、操作ごとの要件が優先されます。 WRITING.md の設定が適用されるのは、新たに作成または書き換える自然言語の Markdown に限られます。原文の内容と構造化された記録は維持してください。

  1. 設定を解決する — llm-wiki/SKILL.md の「設定解決プロトコル」に従います(インラインの @name による上書き → CWD から上の階層へ .env を検索 → グローバル設定 → プロンプトによるセットアップ)。これにより OBSIDIAN_VAULT_PATH と PI_HISTORY_PATH(デフォルトは ~/.pi/agent/sessions)を取得します
  2. Vault のルートにある .manifest.json を読み、すでに取り込まれた内容を確認します
  3. Vault のルートにある index.md を読み、Wiki にすでに含まれている内容を確認します

取り込みモード

追記モード(デフォルト)

各ソースファイルについて .manifest.json を確認します。次のファイルのみを処理します。

  • マニフェストにないファイル(新しいセッション)
  • マニフェストの ingested_at より更新日時が新しいファイル

通常の同期ではこのモードを使用します。

全件モード

マニフェストに関係なく、すべてを処理します。wiki-rebuild の後、またはユーザーが全件再取り込みを明示的に依頼した場合に使用します。

Pi のデータ構造

Pi はセッションを ~/.pi/agent/sessions/(または PI_CODING_AGENT_SESSION_DIR で設定されたパス)に保存します。

~/.pi/agent/sessions/
├── --<cwd-path>--/                    # Working directory with / replaced by -
│   └── <timestamp>_<uuid>.jsonl       # Session JSONL file
└── ...

セッションのファイル名には ISO 形式のタイムスタンプと UUID が含まれます。親ディレクトリには、セッションの作成時に使用された作業ディレクトリが記録されています。

セッションの JSONL 形式

各 .jsonl ファイルは、JSON オブジェクトの並びです。最初の行は常に session ヘッダーで、それ以降の行は id と parentId を持つツリーエントリーです。

type目的取り込み対象?
sessioncwd、version、id、timestamp を含むヘッダーメタデータのみ
message会話のターン(user、assistant、toolResult、bashExecution など)主な情報源
session_info/name で設定された表示名セッションのタイトルに使用
compactionコンテキストの圧縮要約重要な情報
branch_summary/tree によるブランチ切り替え時の要約重要な情報
model_changeモデル切り替えイベントスキップ
thinking_level_change思考レベルの変更スキップ
custom拡張機能の状態(LLM のコンテキストには含まれない)スキップ
custom_message拡張機能によって挿入されたメッセージコンテキストのみ
labelユーザーのブックマーク/ラベルスキップ
message エントリー内のメッセージロール
  • user — ユーザー入力。content は文字列または (TextContent \| ImageContent)[] です
  • assistant — アシスタントの応答。content は (TextContent \| ThinkingContent \| ToolCall)[] です
  • toolResult — ツールの実行結果。content は (TextContent \| ImageContent)[] です
  • bashExecution — bash コマンドと出力。command、output、exitCode を含みます
  • branchSummary — ブランチ切り替え時の要約。summary 文字列を含みます
  • compactionSummary — 圧縮の要約。summary 文字列を含みます
価値順に並べた主要なデータソース
  1. message エントリー(user + assistant) — 会話の完全なトランスクリプト。情報量は豊富ですが、ノイズも多く含みます
  2. compaction エントリー — 古いコンテキストを事前に要約したもの。特に価値があります
  3. branch_summary エントリー — 破棄された分岐の要約。有用な情報が含まれています
  4. bashExecution エントリー — 実行された具体的なコマンド。ワークフローのパターンを把握するのに役立ちます
  5. session_info エントリー — トピック推定に使うセッション名

model_change、thinking_level_change、custom(拡張機能の状態)、label エントリーはスキップします。

ステップ 1:調査して差分を算出する

PI_HISTORY_PATH をスキャンし、.manifest.json と比較します。

# List all session files
find ~/.pi/agent/sessions -name "*.jsonl" -type f

# Or with custom path
find "$PI_HISTORY_PATH" -name "*.jsonl" -type f

インベントリーを作成します。各セッションファイルについて、以下を記録します。

  • path — 絶対パス
  • cwd — 親ディレクトリ名からデコードした値(--<path>-- → /path)
  • session_name — 最新の session_info エントリーから取得(存在する場合)
  • modified_at — ファイルの更新日時
  • already_ingested — .manifest.json に記録されているかどうか

各ファイルを分類します。

  • 新規 — マニフェストに存在しない
  • 変更あり — マニフェストに存在するが、ファイルが ingested_at より新しい
  • 変更なし — すでに取り込まれており、変更されていない

詳細な解析の前に、差分の概要を簡潔に報告します。

「Pi セッションが N 件、K 個のプロジェクトで見つかりました。差分:新規 X 件、変更あり Y 件。」

ステップ 2:セッション JSONL を解析する

選択した各セッションファイルを 1 行ずつ読み取ります。セッションはツリー構造を使用するため、まずアクティブなブランチを構築します。

  1. すべてのエントリーを id をキーとするマップに解析する
  2. 現在のリーフ(子を持たないエントリー、または最後の message エントリー)を見つける
  3. リーフからルートまで parentId のチェーンをたどり、アクティブなパスを取得する
  4. パスを逆順にして時系列に並べる
抽出ルール

アクティブなパスから、以下を抽出します。

  • session ヘッダー — cwd、timestamp、parentSession(フォークされている場合)
  • session_info — セッションのタイトルやトピックを推定するための name フィールド
  • role: "user" を持つ message エントリー — content テキストを抽出する(画像はスキップ)
  • role: "assistant" を持つ message エントリー — text コンテンツブロックを抽出する。thinking ブロックはノイズのためスキップし、エージェントが実際に行ったことが分かる toolCall ブロックは記録する
  • role: "toolResult" を持つ message エントリー — 出力全体ではなく、結果を要約する
  • role: "bashExecution" を持つ message エントリー — コマンドと終了コードを抽出する。繰り返し実行されるコマンドから、ビルド/テスト/デプロイのワークフローが分かります
  • compaction エントリー — summary をそのまま読み取る。すでに要約されています
  • branch_summary エントリー — summary をそのまま読み取る。破棄されたアプローチが記録されています
根拠台帳

Wiki ページを作成する前に解析しながら、非公開の根拠台帳を作成します。記載する可能性のある、長期的に有用な事実や決定事項には、それぞれ少なくとも 1 つの出典参照を付けます。

pi:<session-file-basename>#<entry-id>

エントリーに id がない場合は、JSONL の行番号を使って pi:<session-file-basename>:line<N> を使用します。草稿の作成中は、引用したテキストの抜粋または要約した所見を参照の隣に残し、記載内容を確認できるようにします。

スキップ/ノイズのフィルター
  • thinking コンテンツブロック — 内部推論であり、長期的に有用な知識ではありません
  • 画像コンテンツブロック — ユーザーが画像の文字起こしを明示的に求めている場合を除き、スキップします
  • 500 文字を超える生のツール出力 — 結果を要約します
  • トークンの使用状況(usage フィールド)— メタデータにすぎません
  • 繰り返される計画の反復や状況報告
重要なプライバシーフィルター

セッションログには、注入された指示、ツールのペイロード、機密情報が含まれることがあります。内容をそのまま取り込まないでください。

  • API キー、トークン、パスワード、認証情報を削除します
  • 個人を特定できる情報は、関連性があり、ユーザーが許可した場合を除き、伏せ字にします
  • パス、環境変数、秘密情報を含む bash の出力は要約します
  • 機密情報が含まれる場合は、生の toolCall 引数をそのまま引用しないでください

ステップ 3:トピックごとにクラスタリングする

セッションごとに Wiki ページを 1 つ作成しないでください。

  • 複数のセッションにまたがる安定したトピックごとに知識をグループ化します
  • 複数のテーマが混在するセッションは、テーマごとに分割します
  • 日付やプロジェクトをまたいで繰り返されるパターンを統合するのは、各パターンのメンバーに根拠台帳の参照がある場合に限ります
  • セッションヘッダーの cwd からプロジェクトの範囲を推定します
  • 利用可能な場合は、トピックのヒントとして session_info.name を使用します
  • 主張の根拠を選択したセッションファイルまでたどれないクラスタは破棄します

ステップ 4:知識を Wiki ページにまとめる

既存の Wiki の規約に沿って、抽出した知識を振り分けます。

  • プロジェクト固有のアーキテクチャ/プロセス → projects/<name>/...
  • 一般的な概念 → concepts/
  • 繰り返し使われる手法/デバッグ手順書 → skills/
  • ツール/サービス/フレームワーク → entities/
  • 複数セッションにまたがるパターン → synthesis/

影響を受けるプロジェクトごとに、projects/<name>/<name>.md を作成または更新します。

執筆ルール
  • 時系列ではなく、知識を要約してまとめます
  • 日付が重要な文脈でない限り、「日付 X に話し合った」のような記述は避けます
  • 手法が選ばれた理由の説明に役立つ場合は、セッション固有の意思決定の背景を残します。一般的なツールのアドバイスに単純化しないでください。
  • 新規作成または更新する各ページに summary: のフロントマターを追加します(1~2 文、200 文字以内)
  • すべての新規ページに confidence フィールドと lifecycle フィールドを追加します。
    base_confidence: 0.42
    lifecycle: draft
    lifecycle_changed: <obsidian-wiki memory now --date>
    
    更新時は lifecycle を変更しないでください。
  • llm-wiki の規約に沿って、出典を示すマーカーを追加します。
    • 抽出した主張には、特に指定がなければインラインマーカーを付けませんが、近くに出典参照コメントを必ず付けます。
    • 複数のセッションにまたがるパターンを統合する場合や、ツール呼び出しから推論する場合は ^[inferred] を付けます。
    • セッション間で矛盾がある場合、または圧縮サマリーが後の会話と矛盾する場合は ^[ambiguous] を付けます。
  • 抽出した各段落または箇条書きの近くに、以下の形式で出典参照コメントを追加します。
    - Durable fact from the session. 
    
    複数の出典はカンマで区切ります。これらのコメントは監査証跡です。抽出した主張に付け忘れないでください。
  • 変更した各ページの provenance: フロントマターの内訳を追加/更新します。

llm-wiki の規約に従って出典を示します。

  • compaction と branch_summary のエントリーは事前に要約済みです。ほとんどは抽出内容として扱い、出典参照コメントを付けます。
  • 会話の要約はほとんどが ^[inferred] です。対話から内容を統合するため、統合を裏付けるターンへの出典参照も必要です。
  • ユーザーがセッション間で意見を変えた場合や、圧縮サマリーと後の会話が食い違う場合は ^[ambiguous] を使用します。
出典検証ゲート

ページを書く前に、根拠台帳と照合して下書きを検証します。

  1. すべての主張(抽出/^[inferred]/^[ambiguous])に、少なくとも 1 つの pi:... 出典参照があること。抽出した主張には、近くに `` コメントを付ける必要があります。
  2. すべての出典参照が、選択したセッションファイルとアクティブなブランチのエントリー(または引用された compaction/branch_summary)を指していること。
  3. 主張に含まれる固有名詞、ツール名、コマンド名、ファイル名、URL、パッケージ名、エラー文字列が、引用先のエントリーテキストまたはコマンドフィールドに記載されていること。確信が持てない場合は、セッションファイル内で特徴的な文字列をリテラル検索(grep/rg)します。
  4. 主張を検証できない場合は削除するか、裏付けとなる出典参照を付けて ^[inferred]/^[ambiguous] とマークします。検証できない内容を、これらのマーカーなしで残さないでください(マーカーがない場合は抽出内容とみなされます)。
  5. モデルのトレーニングデータまたは現在のエージェントセッションから得た事実は、Pi セッションの根拠に明示されていない限り記載しないでください。

ステップ 5:マニフェスト、ログ、インデックスを更新する

.manifest.json を更新する

処理した各ソースファイルについて、以下を更新します。

  • ingested_at、size_bytes、modified_at
  • source_type:pi_session
  • project:デコードした cwd から推定したプロジェクト名
  • pages_created、pages_updated

トップレベルのサマリーブロックを追加/更新します。

{
  "pi": {
    "source_path": "~/.pi/agent/sessions/",
    "last_ingested": "TIMESTAMP",
    "sessions_ingested": 12,
    "sessions_total": 40,
    "pages_created": 5,
    "pages_updated": 12
  }
}
特殊ファイルの更新

index.md、log.md、hot.md を 1 回のロックされた呼び出しで更新します:

obsidian-wiki memory sync PI_HISTORY_INGEST \
  sessions=<sessions> pages_updated=<pages_updated> \
  pages_created=<pages_created> mode=<mode> \
  --takeaways "Ingested 12 Pi sessions across 3 projects; surfaced patterns in CLI tooling and API design."

index.md、log.md、hot.md を決して手動で編集しないでください。このコマンドは、並行して書き込むライターがあなたの更新を失うのを防ぐロックを取得します。--takeaways は Recent Activity に記載する 1 行の概念的概要です。 省略すると、以前の takeaways がそのまま残ります。

手順の詳細については .skills/llm-wiki/references/MEMORY.md を参照してください。

プライバシーとコンプライアンス

  • 蒸留して統合し、生の文字起こしのダンプは避ける
  • 疑わしいものはデフォルトで墨消しする
  • 個人情報や機微な詳細を保存する前に確認する
  • 他の人物への言及は最小限にとどめ、目的に沿ったものにする

リファレンス

フィールドレベルの解析と抽出のガイダンスについては references/pi-data-format.md を参照してください。

Vault 書き込み後の QMD リフレッシュ

QMD は検索インデックスであり、信頼できる唯一の情報源ではありません。$QMD_WIKI_COLLECTION が空または未設定の場合は、この手順をスキップしてください。このスキルが Vault の Markdown を書き込みまたは書き換えた後にのみ実行してください。QMD のリフレッシュが失敗した場合でも、Vault の変更をロールバックしないでください。QMD のステータスを別途報告してください。

$QMD_CLI が設定されている場合はそれを使用し、そうでなければ qmd を使用します。

${QMD_CLI:-qmd} update

出力にベクターが必要、または埋め込みが古い可能性があると表示された場合は、次を実行します:

${QMD_CLI:-qmd} embed

次のいずれかでコレクションを検証します:

${QMD_CLI:-qmd} ls "$QMD_WIKI_COLLECTION"

または、特定のページパスが判明している場合:

${QMD_CLI:-qmd} get "qmd://$QMD_WIKI_COLLECTION/<page>.md" -l 5

次のいずれかを記録します:

  • QMD refreshed: update + embed + verify
  • QMD refreshed: update only + verified
  • QMD skipped: QMD_WIKI_COLLECTION unset
  • QMD skipped: qmd CLI unavailable
  • QMD failed: <short error summary>

コメント