Community编程与开发github.com

wiki-smith — 仓库记忆守护者

维护仓库的 `.wiki/` 目录,作为AI代理可读写的长期记忆。自动解析会话,生成日记、主题页或内容地图,并完成索引更新、格式检查和提交同步。

wiki-smith — 仓库记忆守护者 是什么?

wiki-smith 是一个专门为AI代理(如Claude Code、Cursor等)设计的技能,用于维护仓库中的 `.wiki/` 目录作为持久化的共享记忆。该技能的核心价值在于:代理通过查阅wiki可以获知项目规则和上下文,而无需反复向用户询问。它能自动分析当前会话发生了什么,并智能判断应创建哪种类型的笔记:日常日记(记录发生了什么)、主题页面(记录当前有效的规则或知识)、还是内容地图(当涉及多个子主题时)。此外,它还能维护索引、修复日期、执行格式检查(lint)、仅提交自身修改的文件,并通过同步脚本进行安全推送。查询时优先使用 `rg` 进行关键词搜索,成本低廉。该技能适用于任何使用 `.wiki/` 作为知识库的仓库,通过 `scripts/` 目录下的脚本完成所有操作,并遵守 `wiki.config` 中的自定义规则。

兼容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/biliboss/wiki-smith/tree/HEAD

Installed? Explore more 编程与开发 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

wiki-smith — 维护仓库的 .wiki/

Wiki 是仓库的记忆,专为代理书写:它们在这里找到规则,而无需再次询问。日记记录发生了什么;主题页面记录当前不变的知识。只存在于日记中的经验将会丢失。wiki-smith 会判断当前会话需要哪种记录,按照此 wiki 自身的规则进行编写,并完成检查。

完整方法(文件类型、笔记格式、导入、链接、日期、提交):references/method.md。配置键:references/config.md。致谢:ATTRIBUTION.md。变更:CHANGELOG.md。自身记忆:.wiki/。

<skill> 下为此技能文件夹(例如 ~/.claude/skills/wiki-smith)。每个脚本接受 -w <wiki dir>(默认为 ./.wiki)和 -c <config>(默认为 <wiki>/wiki.config)。

步骤 0 — 找到 wiki 及其规则

  1. Wiki 位于仓库根目录下的 .wiki/。如果仓库没有 wiki,则说明情况并提供从 templates/ 创建的机会(首先创建 wiki.config.example);切勿未经询问就创建。
  2. 如果存在 .wiki/wiki.config,则读取它(配置项:日记文件夹、收件箱、索引、页脚标签、日期键、主分支)。如果没有该文件,则使用默认的通用英文配置:journal/、inbox.md、index.md、Map:、## History、created/updated。
  3. Wiki 自身的规则优先。 如果仓库中有关于如何维护 wiki 的页面(通过 rg -n -i 'maintain|manter' .wiki -l 查找),或者 AGENTS.md 中有关于 wiki 的规则,则读取该部分并遵循其中与本技能不同的部分。
  4. 如果用户要求“更新 wiki”,并且 wiki(通常是索引)规定需要先确认,则仅将步骤 1 和步骤 2 作为计划提出:每个页面一行,说明更改内容、新笔记的标题,然后询问“是否应用?”,仅在获得肯定答复后才进行编辑。否则直接执行。

步骤 1 — 查看发生了什么,然后路由

读取会话内容(以及 git diff、git log 以了解完成的工作)。选择所有适用的行,不要多选:

会话内容操作
一项决策、交付、方向变更、事故或研究创建日常笔记:使用 scripts/note.sh -b "Title that says what changed" 并将段落内容通过管道传入。然后在收件箱中添加当天的行。
一条超越当日有效的规则、经验教训或事实同时更新主题页面:写入当前有效的规则,不包含历史(历史保留在笔记和页面的历史部分中)。修正页面之前所说的内容;切勿叠加“曾经是…”。
涉及多个方面的新主题(它会再次出现,用一个页面会混杂不同类型的内容)创建内容地图 moc-<topic>.md 以及页面 <topic>-<facet>.md(速查表、安装、集成、与当前工具的对比……)。参见下方“新主题”。
没有值得记录的内容(仅是中间步骤,或提交信息已说明的内容)用一行说明,不创建任何内容。填充日记会使其难以阅读。

仅创建新笔记作为日记条目;永远不重写其他代理的笔记。

步骤 2 — 编写

日常笔记。 scripts/note.sh "<title>" 在 UTC 时间创建 <DIARY_DIR>/<today>/<HHMM>-<slug>.md 并输出路径(slug 规则和碰撞时的 -2 处理在脚本中)。stdin 仅在 -b 参数下读取:代理 shell 和 CI 会永远保持 stdin 打开,因此没有 -b 时脚本不会等待输入。通过管道传入正文:printf '%s\n' '<paragraph>' | scripts/note.sh -b '<title>';-b 会在标题和正文之间放置一个空行。如果没有 -b,则文件仅包含标题行;如需后续添加段落,请以空行开头:printf '\n%s\n' '<paragraph>' >> "$path"。正文是一个写得通顺的段落:发生了什么、为什么重要、证据在哪里(提交、PR、问题),并包含指向主题页面的链接。链接相对于日记文件夹(../../page.md)。模板:templates/note.md。

当天第一条笔记: scripts/day-index.sh 创建当天的索引;然后在“最近天数”列表顶部添加当天。如果笔记改变了仓库的工作方式,还需在收件箱的“重点内容”中添加一行。收件箱从不包含笔记正文。

主题页面(导入)。 查找它(rg -n -i '<word>' .wiki);如果不存在且该主题会再次出现,则创建它(模板:templates/page.md);如果内容较少,则放入附近页面中的一个章节。写入当前有效的规则。如果某次更改改变了页面所声称的内容,则在其历史部分顶部添加一行。笔记中需链接到该页面。

新主题。

  1. 首先编写页面,每个方面一个页面,每个页面自第一句起即自成一体。典型的方面包括:速查表(最优先:地址、命令、快捷键)、安装、集成、与当前所用工具的对比。
  2. 创建 moc-<topic>.md(templates/moc.md):一段开场白、“页面”(每行一个,速查表优先)、“需要首先了解的内容”(几个关键的规则)。
  3. 为每个页面添加页脚(Map: [moc-<topic>](moc-<topic>.md) · Related: ...),将内容地图和每个页面添加到索引中,并确保至少从一个其他内容地图链接到该地图。
  4. 在日记中创建一个笔记,说明创建了什么并链接到内容地图。

步骤 3 — 收尾(始终按此顺序)

  1. scripts/dates.sh — 从 git 获取 created/updated 前置元数据。幂等操作。
  2. scripts/day-index.sh — 重新生成日常索引。永远不要手动编辑。
  3. python3 -I scripts/lint.py — 修正它输出的每一个 file:line: type: message 直到退出码为 0(退出码 2 表示问题)。不要提交 lint 失败的状态。
  4. 提交仅你自己的文件,通过路径指定,永远不要使用 git add -A:scripts/sync.sh -m "wiki: <what>" <path>...。当检出的仓库位于主分支、为最新状态且你的路径之外没有更改时,它会在原地提交;否则,它会将你的路径带入一个从 origin/<main> 创建的新的 git worktree 中。无论哪种方式,它都会对即将提交的内容进行 lint 检查,并拒绝 lint 失败的情况(退出码 1,不修改原检出,移除 carry worktree)。在 carry 情况下,生成的日常索引不会被复制:它会在 worktree 中重新生成,因此只会列出本次提交中的笔记。将仓库或你的主机要求的署名行添加到提交信息中。
    • 共享文件(索引、收件箱)可能被其他会话同时编辑: 不要将它们传入 carry。scripts/sync.sh -W 会从 origin/<main> 打印一个新的 worktree;在其中进行你的编辑(wiki 位于相同的相对路径),运行 dates.sh、day-index.sh、lint.py,然后在此 worktree 内运行 sync.sh -m ... [-p] <paths>。它会在该 worktree 中提交,并且使用 -p 时,会变基、推送、尽可能快进主仓库的检出,并移除 worktree。一个 carry 如果携带了其他会话的行(例如指向仅存在于检出中的页面的链接)会导致 lint 失败并在提交之前停止;该失败是使用 -W 的信号。
  5. 仅在用户要求同步时推送: 相同的调用加上 -p(fetch、rebase、push HEAD:<main>、快进检出、移除 worktree)。永远不要强制推送,永远不要触碰其他人修改的文件:对于与你推送的内容不同且可能包含其他会话编辑内容的文件(索引、收件箱),保持原样。如果检出无法快进(本地主分支分歧,或本地编辑冲突),它会说明情况,但依然以退出码 0 退出,因为推送已成功。仅在用户要求时打开 PR。

在同一会话中提交你所写的内容,无需等待指示;发布由用户决定。

查询 wiki

使用 rg -n -i '<keyword>' .wiki(或浏览索引),然后只读取匹配的页面或章节,绝不读取整个 wiki。要了解发生了什么:查看收件箱(简短),然后仅查看相关的天数;每天对应其索引和其中列出的笔记。如果仓库有规格说明,它们会说明系统承诺的内容:rg -n -i '<keyword>' <specs dir>。

陷阱

  • 日记不是页面。 仅写在笔记中的规则会丢失;在同一会话中将其导入到主题页面。
  • 规则不包含历史。 应该是“创建卡片前先搜索现有卡片”,而不是“我们过去常常重复创建卡片”。故事保留在笔记中。
  • 一个文件一个笔记。 多个代理可能会在同一天进行写入;它们绝不能编辑同一个文件。日常索引用 day-index.sh 重新生成即可解决冲突。
  • 跨会话的共享文件。 日常索引、index.md 和收件箱在一个检出中包含了所有会话的未提交编辑。sync.sh 永远不会 carry 日常索引(它会在 worktree 中重新生成),并在提交前进行 lint,但它无法区分手动编辑的 index.md 或收件箱中哪些块是你的:carry 会带走整个差异。当其他会话可能接触过它们时,请使用 sync.sh -W 并在 worktree 中进行编辑。一个恰好没有破坏 lint 的外部行仍然会被 carry 带走;这是 carry 的文档化限制。
  • 永远不要在 stdin 上等待。 note.sh 仅在 -b 参数下读取正文;在代理 shell 中,无参数的读取会永久阻塞。这同样适用于你添加的任何脚本。
  • 不要记录瞬态信息: 一次失败但重试成功的命令、环境小故障、一次性任务。在主题页面上记录有效的修复方法,而不是“X 坏了”(当原因消失后,这可能会固化成一个拒绝)。
  • 链接: 使用相对链接,每个章节仅首次出现时提及;锚点是 GitHub 对标题的 slug 化处理(小写,无标点,保留重音符号,空格变为连字符)。重命名标题会破坏其锚点;lint 会指出这一点。将链接示例放在反引号内,以便 lint 不读取它。
  • 重命名或删除页面: 使用 rg -l 'old-name' .wiki 并修复所有链接,包括锚点;仅在所有内容迁移后才删除。
  • 页面大小: 大约超过 150 行,或当规则、过程、参考资料和历史混合时,按类型拆分。
  • 私有数据不能放进去。 Wiki 页面会被提交;将秘密、令牌和个人数据排除在外,并引述秘密存放的位置。
  • Lint 的局限性: 它不能发现页面间的矛盾或过时的声明;这需要代理在时间允许时进行审查。
  • day-index.sh 的限制: 包含手动书写旧格式笔记的日记文件是一个错误(file:line),不会自动迁移;使用 note.sh 将每个笔记移动到其自己的文件中,然后重新运行。

步骤 4 — 维护你自己的 wiki

如果本次运行教会了你关于 wiki-smith 本身的一些东西(路由错误、脚本怪癖),在 .wiki/lessons.md 中添加一行:- YYYY-MM-DD — <规则 + 原因>。编辑源代码克隆(biliboss/wiki-smith)并重新安装(npx skills add biliboss/wiki-smith -g --copy -a claude-code -y),而不是编辑已安装的副本(重新安装会覆盖它)。设计决策记录在 .wiki/design.md 中。

相关技能