mcpField
A
archive-crawler

archive-crawler

github.com/garrytan生産性31.3k203 回インストール今日更新
リポジトリ

archive-crawler について

archive-crawler は、個人アーカイブを調べ、価値のある内容を選んで brain に取り込むためのスキルです。明示的なパス許可リストを必須とし、マニフェストで進捗を管理しながら、ノイズや機微な文書を除外します。

主な機能

  1. 01スキャン対象パスの許可リストを必須化
  2. 02アーカイブの内容を一覧化・分類
  3. 03マニフェストで確認と取り込みを管理
  4. 04提示前に内容をフィルタリング
  5. 05選択した項目を brain ページに取り込み

活用シーン

  1. 01ローカルアーカイブの文章や通信を確認
  2. 02.mbox などのメールエクスポートを整理
  3. 03許可された Dropbox や Backblaze のアーカイブを調査

インストール

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

$npx skills add https://github.com/garrytan/gbrain --skill archive-crawler

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

同梱ファイルrouting-eval.jsonl

詳細

archive-crawler — 万能アーキビスト

規約: 引用ルール、ユーザーの反応を記録する際の正確な表現の要件、バックリンクの適用については、conventions/quality.md を参照してください。

規約: _brain-filing-rules.md を参照してください。このスキルはスキーマに依存しません。特定の時代やアーカイブのレイアウトをハードコードするのではなく、ルール JSON からユーザーのファイリングルールを読み取ります。

安全ゲート(必須、例外なし)

archive-crawler は、gbrain.yml に archive-crawler.scan_paths: が明示的に設定されていない限り、実行を拒否します。これは、エージェントがスキャンの範囲を広げすぎて機密コンテンツ(税務 PDF、医療記録、認証情報)を取り込むことを防ぐための、意図的な安全措置です。

# gbrain.yml — the allow-list is mandatory
archive-crawler:
  scan_paths:
    - ~/Documents/writing/
    - ~/Dropbox/Archive/
    - /mnt/backup/old-letters/
  # Optional deny-list inside the allow-list:
  # deny_paths:
  #   - ~/Documents/finances/
  #   - ~/Documents/medical/

scan_paths が空または未設定の場合、スキルは次のメッセージを出力して終了します。

archive-crawler: refusing to run. No `archive-crawler.scan_paths:` allow-list
in gbrain.yml. Add explicit paths the agent is permitted to scan, then re-run.
This is a safety fence — the agent will not infer what's safe to read.

この契約は src/core/storage-config.ts によって適用されます(v0.22.11 のストレージ階層化における db_tracked / db_only の許可リストパターンを反映しています)。

これは何か

明示的な許可リスト内にある、あらゆる個人コンテンツのツリーを探索する汎用エンジンです。ローカルマウント、Dropbox API の対象、Backblaze B2、Gmail のエクスポートデータ(.mbox)など、類似のアーカイブで動作します。「価値あるもの」(ユーザー自身の文章、アイデア、人間関係)をフィルタリングし、レビュー用に対話形式で提示します。ノイズ(システムファイル、設定、バイナリデータ)はスキップします。

概念

ソース

ソースとは、探索対象となるファイルのツリーです。ソースには以下が含まれます。

  • type:local | dropbox | backblaze | gmail-takeout | mbox | pst
  • root:ファイルシステムのパス、Dropbox のパス、B2 のプレフィックス、mbox のパス
  • manifest:進捗を記録するブレインページ。場所は projects/<archive-slug>/STATUS.md
マニフェスト

アーカイブを探索するたびに、進捗を記録するマニフェスト用のブレインページが作成されます。記録する内容は次のとおりです。

  1. ツリーのインベントリ — フォルダー/ファイル/サイズ/種類
  2. トリアージ状況 — 各項目:⬜ 未確認/👀 レビュー済み/ ✅ 取り込み済み/⏭️ スキップ/🔥 重要度高
  3. ユーザーの反応 — 反応があった場合は正確な引用(conventions/quality.md の正確な表現に関するルールに準拠)
  4. 優先キュー — 次に探索する対象とその優先順位
  5. セッションログ — 各セッションで提示した内容のタイムスタンプ付き記録
価値あるもののフィルター

ユーザーに何かを提示する前に、価値あるもののフィルターを適用します。

残す(提示する)スキップする(存在のみ記録し、提示しない)
個人的な文章(日記、手紙、振り返り、エッセイ)システムファイル、設定、package.json、node_modules
会話(メッセージログ、内容のあるメールスレッド)バイナリデータ(画像/動画)
アイデア、テーゼ、フレームワーク領収書、請求書、税務書類
人間関係に関する資料(大切な人とのやり取りや、その人に宛てた手紙)スパム、ニュースレター、メーリングリストの大量配信
創作物(詩、物語、魂のこもったコード)破損ファイル/空ファイル
重要なものへと発展した事柄の始まり(初期バージョン)
感情を含む内容(怒り、愛、悲しみ、発見)

プロトコル

フェーズ 1:インベントリ

新しいソースを指定された場合:

  1. scan_paths が設定されていることを確認する(安全ゲート)。未設定の場合は終了します。
  2. ツリーをマッピングする — フォルダーとファイル、サイズ、日付範囲を一覧表示します。
  3. フォルダーを分類する — 内容の種類(文章、メール、コード、写真、文書、システムなど)ごとにグループ化します。
  4. マニフェストを作成する — 全インベントリを projects/<archive-slug>/STATUS.md に記録します。
  5. 優先キューを提案する — 価値あるものが多く含まれていそうな順にフォルダーを並べます。
  6. ユーザーに提示する — マップと提案する順序を示します。ユーザーが変更できるようにします。
フェーズ 2:クロール

優先順位に従ってフォルダーを確認します。

  1. 表示する前に読む — 候補ファイルをそれぞれ開き、ゴールドフィルターを適用して、ノイズを除外します。
  2. 1 件ずつ表示する — ゴールド項目を個別に提示してレビューしてもらいます。
  3. 正確な反応を記録する — ユーザーの反応を、本人の正確な言葉でマニフェストに記録します(conventions/quality.md の規約に従います)。
  4. 保存する価値があれば取り込む — すぐにブレインページを作成します。
  5. マニフェストを更新する — やり取りのたびに項目のステータスを更新します。
  6. 再表示しない — 何かを提示する前に、マニフェストを確認します。
フェーズ 3:取り込み

項目を保存する価値がある場合は、_brain-filing-rules.md に従い、主要な主題に基づいて格納します。

  • ユーザー自身の文章/アイデア/オリジンストーリーに関するコンテンツ → originals/<slug>.md
  • 内省/個人的な生活に関するコンテンツ → personal/<slug>.md
  • 製品/ビジネスのアイデア → ideas/<slug>.md
  • 特定の人物に関する手紙やスレッド → people/<person>/timeline へのバックリンクと、personal/<slug>.md または originals/<slug>.md に手紙を格納

このスキルのスキーマは汎用的です。 特定の時代別フォルダー構造(例:2003 年以前は originals/archive/、2019 年以降は originals/yc-era/ など)を組み込んでいません。ユーザーの格納ルールは実行時に _brain-filing-rules.json から読み込み、エージェントが許可されたディレクトリ内でページごとに格納先を決定します。

ブレインページの形式:

---
title: "[Title or first line]"
type: original
source_type: "[local|dropbox|backblaze|gmail-takeout|mbox|pst]"
source_path: "[path within the allow-listed scan_paths]"
date: "YYYY-MM-DD"  # date from the file metadata or content
people: ["person-1", "person-2"]
tags: ["tag-1", "tag-2"]
---

# [Title]

[Summary: what it is, when it's from, why it matters]

**User's reaction:** [exact quote, no paraphrasing]

## Context

[Cross-links to people, concepts, projects.]

---

[Raw source material below the line — full text]

ファイル形式別の処理

プレーンテキスト/HTML/Markdown

直接読み取ります。表示する際は HTML タグを取り除きます。

.mbox(メールアーカイブ)
import mailbox
mbox = mailbox.mbox('/path/to/file.mbox')
for msg in mbox:
    body = ''
    if msg.is_multipart():
        for part in msg.walk():
            if part.get_content_type() == 'text/plain':
                body = part.get_payload(decode=True).decode('utf-8', errors='replace')
                break
    else:
        body = msg.get_payload(decode=True).decode('utf-8', errors='replace')
    # Apply gold filter
.doc/.docx
# .docx (modern)
python3 -c "
import zipfile, xml.etree.ElementTree as ET
with zipfile.ZipFile('/path/to/file.docx') as z:
    tree = ET.parse(z.open('word/document.xml'))
    print(''.join(t.text or '' for t in tree.iter('{http://schemas.openxmlformats.org/wordprocessingml/2006/main}t')))
"

# .doc (legacy, requires antiword or catdoc)
antiword /path/to/file.doc 2>/dev/null || catdoc /path/to/file.doc 2>/dev/null
.pst(Outlook アーカイブ)
# Validate first; many PSTs are null bytes
python3 -c "
with open('/path/to/file.pst', 'rb') as f:
    print('Valid PST' if f.read(4) == b'!BDN' else 'CORRUPT/NULL')
"
# If valid:
readpst -o /tmp/pst-output /path/to/file.pst
.zip/.tar/.tar.gz

一時ディレクトリに展開してから、展開したツリーを再帰的に処理します。

画像

存在することとメタデータ(ファイル名、サイズ、日付)を記録します。ユーザーから求められない限り表示しません。スキャン画像やポートレートは、個人的な内容である可能性があると記録します。

マニフェストのテンプレート

---
title: "[Archive Name] — Ingestion Status"
type: project
created: YYYY-MM-DD
updated: YYYY-MM-DD
source_type: "[local|dropbox|...]"
scan_paths: ["paths from gbrain.yml"]
---

# [Archive Name] — Ingestion Status

## Source
- **Type:** [local|dropbox|...]
- **Allow-listed paths:** [from gbrain.yml]
- **Total files:** [N]
- **Total size:** [X GB]
- **Date range:** [earliest] — [latest]

## Inventory

### [Folder 1]
| Item | Type | Size | Status | Reaction |
|------|------|------|--------|----------|
| file1.txt | text | 2KB | ✅ ingested | 🔥 "exact quote" |
| file2.doc | doc | 15KB | ⏭️ skip | — |
| file3.html | html | 4KB | ⬜ unseen | — |

### [Folder 2]
...

## Priority Queue
1. [Highest priority — why]
2. [Next — why]
...

## Session Log

### YYYY-MM-DD — [Session topic]
- Reviewed: [list]
- Reactions: [exact quotes]
- Ingested: [brain pages created]
- Next: [what's queued]

失敗した場合

gbrain のエラー code、終了コード、[AGENT] ブロック、または通知ブロックが発生した場合は、エージェント運用者プロトコルに従います。このスキル固有の対応は次のとおりです。

  • archive-crawler.scan_paths: の許可リストがない場合:これはスキル独自の厳格な拒否です。スキャンを許可するディレクトリをユーザーに尋ねます。拒否を回避するために、自分の判断でリストを拡張してはいけません。
  • アーカイブのマウント、テイクアウト、またはバケットが読み取れない場合(権限、期限切れのトークン):失敗した正確なパスを報告し、そのソースの処理を停止します。親ディレクトリのスキャンに切り替えてはいけません。
  • 検索結果の格納で write_pending(終了コード 10)または revision_conflict が返された場合:前者では gbrain write-request <request_id> をポーリングします。後者ではページを再読み込みしてマージします。新しいスラッグで再度格納してはいけません。

アンチパターン

  • ❌ archive-crawler.scan_paths: を設定せずに実行する。厳格な拒否です。 これは安全性を守るための契約です。決して回避してはいけません。
  • ❌ 時代固有の格納パス(例:originals/archive/、originals/yc-era/)をハードコードする。代わりに、実行時に格納ルールを読み込みます。
  • ❌ マニフェストに記録済みの項目を再表示する。ユーザーの時間は最も貴重なリソースです。
  • ❌ 反応を言い換える。正確な言葉のみを記録します。
  • ❌ 見つかったコンテンツを教訓や要点としてまとめる。ストーリーそのものを尊重します。
  • ❌ コンテンツがブレインページのある人物/企業に言及しているのに、バックリンクを省略する。conventions/quality.md に定められた鉄則です。

関連スキル

  • skills/voice-note-ingest/SKILL.md — 音声の記録に同じ正確な表現のパターンを使用
  • skills/idea-ingest/SKILL.md — 主要な主題に基づく同じ格納ルールを使用する、単一リンクまたは記事の取り込み
  • skills/conventions/quality.md — 引用、バックリンク、文体

契約

このスキルでは、次のことを保証します。

  • ルーティングがフロントマターの正規トリガーに一致します。
  • (該当する場合)writes_to: に記載されたディレクトリ配下に出力を書き込みます。
  • 参照されている規約(quality.md、brain-first.md、_brain-filing-rules.md)に従います。
  • プライバシー契約を維持します。実名、フォーク固有のファイルシステムパスを示すリテラル、上流フォークへの言及は含めません。

動作契約の全文は上記の本文セクションに記載されています。このセクションは適合性テスト用に設けられています。

出力形式

スキルの出力形式は、本文セクション内に記載されています(「Output」、「Brain page format」または同等の項目を参照)。ここにある見出しは、適合性テスト(test/skills-conformance.test.ts)用のものです。

コメント