关于 archive-crawler
archive-crawler 是用于探索个人档案并筛选有价值内容、导入 brain 的技能。它要求明确设置扫描路径白名单,用清单跟踪进度,并过滤噪声及敏感文档类型。
主要功能
- 01要求明确设置扫描路径白名单
- 02盘点并分类档案内容
- 03用清单跟踪审阅与导入状态
- 04展示前筛选内容
- 05将选定内容导入 brain 页面
适用场景
- 01审阅本地档案中的写作和通信
- 02整理 .mbox 等邮件导出文件
- 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。本 Skill 是模式通用的:它从规则 JSON 中读取用户的归档规则,而不是硬编码任何特定的时代或档案结构。
安全闸门(必需,无例外)
除非在 gbrain.yml 中明确设置了 archive-crawler.scan_paths:,否则 archive-crawler 拒绝运行。这是一道有意设置的安全防线,用于防止 Agent 过度划定扫描范围,从而摄入敏感内容(税务 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 为空或缺失,Skill 将以如下信息退出:
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:一个用于追踪进度的 brain 页面,位于
projects/<archive-slug>/STATUS.md
清单
每次档案探索都会生成一个清单 brain 页面,用于追踪以下内容:
- 目录树清点:文件夹 / 文件 / 大小 / 类型
- 分拣状态:每一项的状态为
⬜ 未查看/👀 已审阅/✅ 已摄入/⏭️ 跳过/🔥 高信号 - 用户反应:用户做出反应时的原话引文(遵循 conventions/quality.md 的精确措辞规则)
- 优先队列:接下来探索的内容,按优先级排序
- 会话日志:每次会话中所展示内容的带时间戳记录
金矿过滤器
在向用户展示任何内容之前,先应用金矿过滤器:
| 保留(展示) | 跳过(仅记录存在,不展示) |
|---|---|
| 个人写作(日记、信件、感想、随笔) | 系统文件、配置、package.json、node_modules |
| 对话(即时通讯记录、有实质内容的邮件往来) | 二进制文件(图片 / 视频) |
| 想法、论点、框架 | 收据、发票、税务文件 |
| 人际关系材料(写给重要之人或来自重要之人的信件) | 垃圾邮件、新闻简报、邮件列表群发 |
| 创作作品(诗歌、故事、有灵魂的代码) | 起源故事(后来变得重要之事物的最初版本) |
| 情感内容(愤怒、爱、悲伤、发现) | 损坏 / 空文件 |
协议
第一阶段:清点
当指向一个新来源时:
- 确认已设置 scan_paths(安全闸门)。若未设置则退出。
- 绘制目录树:列出文件夹 + 文件 + 大小 + 日期范围。
- 对文件夹分类:按可能的内容类型分组(写作、邮件、代码、照片、文档、系统)。
- 创建清单:编写
projects/<archive-slug>/STATUS.md,包含完整清点内容。 - 提出优先队列:按可能的金矿密度对文件夹排序。
- 呈现给用户:展示目录图和建议的顺序,并允许用户进行调整。
Phase 2: Crawl
按优先级顺序处理各文件夹:
- 先读后展示:打开每个候选文件,应用 gold 过滤器,跳过噪声内容。
- 逐个展示:将 gold 条目逐一呈现,供用户审阅。
- 记录原始反应:按照 conventions/quality.md 的要求,在清单中用用户的原话记录其反应。
- 值得保留则入库:立即创建 brain 页面。
- 更新清单:每次交互后标记条目状态。
- 绝不重复展示:展示任何内容前,先检查清单。
Phase 3: Ingest
当某条目值得保留时,依据 _brain-filing-rules.md,按主要主题归档:
- 用户自己的写作 / 想法 / 起源故事类内容 →
originals/<slug>.md - 感悟 / 个人生活类内容 →
personal/<slug>.md - 产品 / 商业想法 →
ideas/<slug>.md - 关于某特定人物的信件或往来 → 在
people/<person>/timeline添加反向链接,并将信件本身放在personal/<slug>.md或originals/<slug>.md
该 Skill 与具体架构无关。 它不会内置任何特定的年代文件夹结构(例如 2003 年前的 originals/archive/、2019 年后的 originals/yc-era/ 等)。运行时会读取 _brain-filing-rules.json 中用户的归档规则;由 Agent 在每个页面上决定内容放置在这些许可目录中的哪个位置。
Brain 页面格式:
---
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] 代码块或通知代码块,请遵循 agent operator protocol。本 Skill 特有的情况如下:
- 未设置
archive-crawler.scan_paths:允许列表:这是本 Skill 自身的硬性拒绝。应询问用户哪些目录可以扫描;切勿擅自扩大列表以绕过此限制。 - 归档挂载点、takeout 或存储桶不可读取(权限不足、令牌过期):报告失败的确切路径并停止该数据源;不要退而扫描父目录。
- 归档某条发现时返回
write_pending(退出码 10)或revision_conflict:对前者,轮询gbrain write-request <request_id>;对后者,重新读取页面并合并。切勿以新的 slug 重新归档。
反模式
- ❌ 未设置
archive-crawler.scan_paths:就运行。这是硬性拒绝。这是安全约定,绝不可绕过。 - ❌ 硬编码特定年代的归档路径(例如
originals/archive/、originals/yc-era/)。应在运行时读取归档规则。 - ❌ 重复展示清单中已标记的条目。用户的时间是最稀缺的资源。
- ❌ 改写用户的反应。只能使用用户的原话。
- ❌ 将找到的内容包装成经验教训或收获。让故事自然呈现。
- ❌ 当内容提及已有 brain 页面的人物或公司时,遗漏反向链接。依据 conventions/quality.md 中的铁律,必须添加。
相关 Skill
skills/voice-note-ingest/SKILL.md:用于音频采集的相同原话记录模式skills/idea-ingest/SKILL.md:单个链接或文章的入库,采用相同的主要主题归档规则skills/conventions/quality.md:引用、反向链接、语气
契约
本技能保证:
- 路由与 frontmatter 中的标准触发词一致。
- 输出写入
writes_to:中列出的目录(如适用)。 - 所引用的约定(
quality.md、brain-first.md、_brain-filing-rules.md)均得到遵循。 - 隐私契约得到保持:不包含真实姓名、不包含分叉特定的文件系统路径字面量,也不包含上游分叉引用。
完整的行为契约记录在上方正文各节中;本节存在的目的是供一致性测试使用。
输出格式
本技能的输出结构在正文各节中有内联说明(参见“Output”“Brain page format”或同类章节)。此处的字面章节标题存在的目的是供一致性测试(test/skills-conformance.test.ts)使用。