mcpField
W
ws-tend

ws-tend

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

关于 ws-tend

ws-tend 是用于维护 Obsidian 风格知识库的技能,可检查状态、审计结构,并按需规范标签或链接。它以只读脚本扫描结构,由 Agent 判断内容,仅执行安全修复。

主要功能

  1. 01生成知识库状态与结构报告
  2. 02审计导航偏差和文件大小
  3. 03规范标签与交叉链接
  4. 04使用只读 Python 结构扫描器
  5. 05安全修复后重新审计

适用场景

  1. 01查看空间结构和页面数量
  2. 02查找导航错误或超限页面
  3. 03依据分类规范统一标签
  4. 04为相关知识库页面添加链接

安装

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

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

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

附带文件scripts/ws.py

详细介绍

Wiki Tend

一站式维护:查看状态、审计、规范化(标签 + 交叉链接)。先报告,只修复安全的内容;当步骤依赖的约定缺失时,应妥善降级处理。

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 无需维护——应直接说明这一点,而不是凭空编造工作。

  2. 检测范围根目录中的约定(核心区块)。存在标记(log.md、分类法、hot.md)不会从父级继承;_meta/limits.md、_meta/ignore.md 和 _template.md 遵循最近祖先规则。标记缺失时,跳过对应的所有模式。

  3. 选择模式,依据用户的表述:

    用户表述模式
    "wiki status", "what's in my wiki"状态
    "audit", "health check", "what needs fixing"审计
    "fix tags", "normalize tags"规范化:标签
    "link pages", "cross-reference"规范化:链接
    "tend wiki", "clean wiki"全面检查:状态 → 审计 → 询问 → 规范化

    状态和审计仅报告结果。规范化会预览变更并在写入前征求确认——除非用户已经说了 "fix" 或 "apply"。

  4. 状态。 使用 list 和 files 查看结构(仅在用户选择查看外部空间时添加 --external)。报告:空间及其单行说明、各顶层文件夹的页面数、标签数量和使用量最高的前 10 个标签(启用 frontmatter 时,通过 grep '^tags:' 扫描获取)、log.md 的最后一行(如存在),以及 git 状态(存在 .git 时;只读,绝不提交或推送)。

  5. 审计。 运行 audit 并沿用其自身术语报告发现的问题。脚本是这些结果的权威来源;不要自行推导:

    • contract——空白索引(无论是否已注册)、近似匹配但不完全符合的标题、格式错误或重复条目、无法注册的子级名称、指向文件而非空间的条目、越过其他空间边界的条目、无效的第二级标题。
    • drift——磁盘上的空间未列出,或列出的条目在磁盘上不存在。
    • mount——已注册的外部挂载点不再是 wiki。
    • 超限文件和不可读文件。 补上脚本无法判断的部分:
    • 修复建议。 对每个超限文件,根据其诊断结果建议采取的措施——内容臃肿则精简,空间结构不合理则重塑(将同级页面归到一个中心页面下、提升页面,或重新分组布局),遵循 ws-update 的溢出处理流程;超限的 log.md 则按存档流程处理(核心区块)。
    • 链接完整性——这是内容判断,由你负责:检查各种链接形式(grep -F '[[' …、grep -F '](' …),根据 files 清单和磁盘上的文件逐一判断每个匹配项,并报告失效链接,同时指出名称最接近的页面作为可能的目标——_template.md 正文中的链接占位符是示例,不属于失效链接。在大型 Wiki 中,检查本轮会触及的空间,并说明跳过了哪些内容。
    • Frontmatter 完整性——仅检查已有 frontmatter 的页面,且仅在 Wiki 使用 schema 时检查;允许部分页面采用 schema。
    • 结构提示——如果某个页面已接近容量上限(对你怀疑的页面运行 check-size),且有多个不同的 H2 分节,则说明其结构已不堪负荷,可以重塑;索引中列出许多逐渐累积的同级页面,说明该空间需要子空间;长期增长的选择性加入 hot.md 需要精简并拆分到冷页面中;空间只包含一个小页面且没有子空间,说明结构过度——建议将其降级为页面(参见 ws-update 的重组说明)。
  6. 结构修复(收尾)。 自行应用安全的结构修复,每轮只做一项编辑,并在轮次之间重新审计,直到结构问题消失——每次重新审计都会根据磁盘内容重新推导问题,因此各轮会逐步收敛:

    • 添加 missing entry 问题所打印的准确条目行,并在后面加上 — description——后续每项操作都会读取此位置提示。
    • 在已注册但缺少 ## Spaces 标题的子空间中插入该标题——仅在问题提示要求插入时操作;若提示要求改名,则属于接近但不完全匹配的情况,应作为作者意图继续报告。
    • 移除审计指出跨越另一个空间边界的条目——更深层的列表归该空间所有;若该条目尚未在那里注册,则在那里注册。

    其他情况均属于作者意图——格式错误或重复的条目、无法注册的子空间名称、指向文件的条目、接近但不完全匹配的标题、第二个无效标题、未声明的裸索引、过期条目、不健康的挂载、超限或无法读取的文件,以及你自行检查发现的任何失效链接——都应继续报告给用户(如果用户表示可以,则提出将其作为常规编辑修复;未声明的裸索引属于提升决策)。

  7. 规范化:标签。 仅当作用域根目录中存在 _meta/taxonomy.md 时才执行,且只处理该作用域自己的页面——子空间使用各自的 taxonomy,应排除在外。

    • 使用 grep '^tags:' --wiki <root> 扫描清单;如果扫描结果有歧义,则读取相关页面的 frontmatter——由你判断 YAML 格式。
    • 未加标签的页面 = files 中的页面减去扫描命中的页面,再排除免于检查 frontmatter 的特殊文件:索引、log.md、hot.md、_template.md。
    • 标记非规范标签、标签过多(>5)的页面以及未加标签的页面;应用 taxonomy 中定义的别名映射。
    • 某个未知标签出现在 2 个或更多页面中:建议将其加入 taxonomy。只出现一次:建议改用最接近的规范标签。
  8. 规范化:交叉链接。 建立仅包含作用域自有页面的注册表(名称、标题,以及存在时的 frontmatter 别名);特殊文件(索引、log.md、hot.md、_template.md)既不纳入注册表,也不参与扫描——导航、历史、草稿和模板内容都不应提供链接,也不应成为链接目标。扫描正文,找出首次出现但未链接的注册表条目,并将最明确的匹配项包装为 Wiki 链接——每页最多新增 2 个链接,绝不放在代码块或 frontmatter 内,也不添加自链接。优先采用行内链接;如果没有自然提及,则以 ## Related 分节作为后备方案。在大型 Wiki 中,扫描本轮会触及的空间,并说明跳过了哪些内容。

  9. 如果存在 log.md,按核心区块的要求添加一行 TEND,并以报告收尾。

输出

每种模式:一张状态表;一份审计报告,引用脚本的发现并附上你的建议;规范化表格(标签 → 操作、添加的链接 → 位置)。完整检查结束时,用一行列出差异:问题数:之前 → 之后;留给你处理:<n>。

评论

支持 Markdown