mcpField
W
ws-search

ws-search

github.com/anfreire生产力1162 次安装7 周前更新
代码仓库

关于 ws-search

用于搜索用户 Wiki 并依据其中内容作答的 Skill,面向需要可追溯笔记答案的 Agent。它按 Wiki 导航结构和信任范围检索,引用页面并明确指出内容缺口。

主要功能

  1. 01解析 Wiki 空间导航结构
  2. 02按文件名与内容检索页面
  3. 03遵守外部挂载的读取边界
  4. 04检查文件大小限制与结构偏差
  5. 05基于页面引用并标明知识缺口

适用场景

  1. 01从个人 Wiki 查找主题笔记
  2. 02为回答附上可跳转的页面引用
  3. 03确认 Wiki 是否包含某项信息
  4. 04审计导航结构和文件大小限制

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/anfreire/wiki-spaces --skill ws-search

安装后在 Claude Code 中输入/ws-search确认已加载。

附带文件scripts/ws.py

详细介绍

Wiki 搜索

在用户的 Wiki 中查找内容,并根据其中存储的信息作答。引用页面,方便用户跳转。如果 Wiki 未涵盖相关主题,请明确指出信息缺口——切勿用 Wiki 中没有的知识凑答案。

Wiki 模型

Wiki 是一个文件夹,其中的 index.md 文件包含 ## Spaces 标题。## Spaces 是导航契约:其中直接包含的每个空间都必须按 - [label](path/index.md) — description 的格式列出,工具只会遍历其中列出的空间。空间可以递归嵌套;每个空间本身都是下一层的 Wiki。普通文件夹(没有 index.md)只用于归类文件。Markdown 方言是 Obsidian——包括 wikilinks、frontmatter、callouts 和 embeds;配套的 obsidian-markdown 和 obsidian-bases 技能介绍了相关语法。

解析 Wiki

解析顺序:用户明确指定的路径 → 最近的 CWD 祖先文件夹(该文件夹是 Wiki,或包含一个作为 Wiki 的 .wiki-spaces/ 文件夹,即该文件夹自身的空间)→ ~/.config/wiki-spaces/config 中的 wiki 键。用户的措辞优先于机制:当用户说“我的 Wiki”时,指的是配置的 Wiki,即便 CWD 位于另一个 Wiki 内(例如公司代码库)。如果 CWD 中的 Wiki 和另一个已配置的 Wiki 同时存在,请告知解析出的根目录;如果意图不明确,只询问一次。切勿在用户不知情的情况下操作错误的 Wiki。

随附脚本

scripts/ws.py 与此 SKILL.md 位于同一目录——使用 Python 3 标准库(3.9+),零依赖,只读。它解析契约,而非内容:结构——遍历、范围、上限、偏差——由脚本负责;阅读内容并判断其含义由你负责。请使用绝对路径调用它(你的工作目录通常在别处):

  • python3 <skill-dir>/scripts/ws.py list --wiki <root> — 列出通过 ## Spaces 契约可访问的空间及各自的入口描述(使用 --external 跨越挂载点)。
  • … files --wiki <root> — 列出通过契约可访问的 Markdown 文件。
  • … grep <pattern> [-i] [-F] --wiki <root> — 在这些文件中按行进行正则搜索;-F 用于匹配字面字符串(包含元字符的名称会按精确字符串搜索);输出格式为 rel:line: text,无匹配时退出码为 1。搜索原语:链接任务列表、标签清单、转义引用检查,都可通过一个模式配合你对匹配结果的判断来完成。
  • … check-size <target> [--stdin] --wiki <root> — 检查文件是否超出上限;写入前,可通过管道传入计划写入的内容并使用 --stdin 进行检查。
  • … audit --wiki <root> — 检查契约偏差、跨越空间边界的条目、超出上限或无法读取的文件,以及不健康的挂载点。如果某项问题有明确且安全的修复方法,检查结果会给出修复内容(例如,missing entry 会输出需要添加的确切行);请像普通编辑一样应用修复,然后重新运行审计进行验证——脚本不会写入任何内容。

请相信脚本的输出,不要手动重新推导结构。stdout 是数据;stderr 会显示解析出的根目录(但 audit 会将它作为 stdout 的标题输出),以及 note: 提示,其中会列出遍历时跳过的内容、根目录嵌套在其他 Wiki 中时的外层 Wiki,以及根目录为另一个 Wiki 时的已配置 Wiki——如果这些提示可能影响答案,请转达给用户。

信任范围与大小控制

所属与外部的判定相对于解析后的根目录:shared/ 目录(任意深度)下的内容、Git 子模块或指向其中任一位置的符号链接均属于外部;指向目录树外部文件夹的符号链接则按其所在位置判定,与克隆目录相同。默认情况下,读取会跨越所属空间,但只有在用户明确要求时才会进入外部空间。写入仅限目标空间;任何其他空间(无论属于内部还是外部)都只有在收到明确指示时才会写入。

大小上限按 UTF-8 字节计算,包含 frontmatter,并按基本文件名设定:index.md 为 5000,log.md 和 hot.md 为 100000,其他任何 *.md 为 15000。

  • 大小上限由用户决定:需要不同上限的 wiki 可在 _meta/limits.md 中设置,check-size 会读取这些设置。
  • 每次写入(无论是新建页面还是编辑页面)之前,都要使用 check-size 检查大小上限:通过 --stdin 传入计划写入的内容。缩小超限文件的写入会报告 ok 和进度,因此修复会逐步收敛;磁盘上已存在的文件则仅按大小上限判定。
  • 超限意味着内容结构需要调整,而不只是大小问题:精简页面、重塑空间,或将已发展成独立空间的页面提升为新空间——切勿截断内容,也切勿提高大小上限。
  • log.md 是例外:超限的日志需要滚动归档——将其整体移至 _archives/log-<YYYYMMDD>.md,然后新建一个空日志——这样历史记录会被归档,而不会被缩减。

各项约定均为 wiki 可选。读取范围根目录(用户指定的空间;若未指定,则为解析后的根目录)中存在的标记——log.md、_meta/taxonomy.md、_meta/limits.md、_meta/ignore.md、页面上的 frontmatter、_template.md、hot.md、.git——若某项缺失,则应妥善处理并继续运行。如果存在 log.md,每次操作都要追加一行:

printf '%s %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" '<OP> <details>' >> <scope-root>/log.md

流程

  1. 解析 wiki(上方的核心区块)。如果根目录来自 CWD 或可能存在歧义,请说明根目录。身处某个文件夹自己的空间时,在此处搜索与该文件夹相关的内容;如果问题超出该范围,则搜索脚本注明的已配置 wiki。若完全没有 wiki,请说明并提出通过 ws-update 创建一个。
  2. 了解整体结构。 运行 list 查看空间结构,运行 files 查看页面清单。这两项成本都很低;请在任何内容搜索之前运行。
    • 对于大型 wiki,请按空间切分清单,而不要重新设定根目录:files 会按空间分组输出路径,因此只需查看候选空间对应的部分——只遍历一次,根目录的信任范围和 _meta/ 规则始终适用。
    • 绝不要重新设定搜索根目录。将某个空间作为独立的 --wiki 使用时,该空间会遵循自己的边界——根目录遍历判定为外部的挂载点,在此处可能会被视为自有内容;执行时,脚本会注明其所属的 wiki。只有在将空间作为独立空间进行评估时(ws-update 的共享预检),才应采用重新设定根目录的方式,而非用于搜索。
    • 除非用户提出要求,否则不要搜索外部挂载点;stderr 中的 note: 行会注明跳过了哪些内容,以及哪些空间无法访问。如果被跳过或无法访问的空间可能包含答案,请说明这一点,并提出跨越边界访问或修复访问问题。
  3. 选择深度。 对于“只检查一下”“我有关于 X 的内容吗”或 Agent 的预先研究探查等请求,进行快速查找:按结构对候选项排序(第 4 步),不读取内容,根据名称和摘要作答,并说明这一点。对于实际问题,进行深入查询:继续执行第 6 步。
  4. 按结构排列候选项。 将查询与空间标签和描述(## Spaces 条目)、文件名及路径段进行匹配。如果使用了 frontmatter,summary、aliases 和 tags 可以在不读取正文的情况下帮助页面排序——通过 grep '^(tags|aliases|summary):' --wiki <root> 一次性扫描这些元数据。
  5. 在仅凭结构无法得出结论时搜索内容,并优先使用成本最低的方式:
    1. 如果可用,使用支持 Markdown 的搜索后端(例如 qmd MCP——基于 Markdown 的 BM25 + 语义搜索);其索引不了解信任范围,因此应剔除根目录的 files 遍历不会列出的命中项。
    2. … grep '<term>' -i --wiki <root>——通用备用方案,始终随附;仅搜索信任范围内的页面集(不包括 shared/、子模块或 _archives/),仅在用户提出要求时使用 --external。
  6. 完整阅读排名靠前的命中页面。 页面有长度上限,因此读取整个文件成本可控。优先完整阅读 2–4 个页面,而不是查看十几个片段。
  7. 仅依据 wiki 作答。 每项陈述都要通过 wiki 链接注明来源页面([[path/to/page]])。如果 wiki 使用了 %%inferred%% / %%ambiguous%% 来源标记,请保留。将 wiki 缺少的信息明确指出为缺口,然后提出通过 ws-update 进行研究并记录。
  8. 记录日志:如果存在 log.md,请按核心区块的要求记录一行 SEARCH。

输出

From your wiki (<root>):
- <finding> — [[page]]
- <finding> — [[page]]
Gaps: <topics the wiki doesn't cover, or "none">

评论

支持 Markdown