关于 ws-tend
ws-tend 是用于维护 Obsidian 风格知识库的技能,可检查状态、审计结构,并按需规范标签或链接。它以只读脚本扫描结构,由 Agent 判断内容,仅执行安全修复。
主要功能
- 01生成知识库状态与结构报告
- 02审计导航偏差和文件大小
- 03规范标签与交叉链接
- 04使用只读 Python 结构扫描器
- 05安全修复后重新审计
适用场景
- 01查看空间结构和页面数量
- 02查找导航错误或超限页面
- 03依据分类规范统一标签
- 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
操作流程
-
解析 wiki(核心区块);如果根目录取自 CWD,或存在歧义,应告知用户根目录位置。刚搭建好的 wiki 无需维护——应直接说明这一点,而不是凭空编造工作。
-
检测范围根目录中的约定(核心区块)。存在标记(
log.md、分类法、hot.md)不会从父级继承;_meta/limits.md、_meta/ignore.md和_template.md遵循最近祖先规则。标记缺失时,跳过对应的所有模式。 -
选择模式,依据用户的表述:
用户表述 模式 "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"。
-
状态。 使用
list和files查看结构(仅在用户选择查看外部空间时添加--external)。报告:空间及其单行说明、各顶层文件夹的页面数、标签数量和使用量最高的前 10 个标签(启用 frontmatter 时,通过grep '^tags:'扫描获取)、log.md的最后一行(如存在),以及 git 状态(存在.git时;只读,绝不提交或推送)。 -
审计。 运行
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的重组说明)。
-
结构修复(收尾)。 自行应用安全的结构修复,每轮只做一项编辑,并在轮次之间重新审计,直到结构问题消失——每次重新审计都会根据磁盘内容重新推导问题,因此各轮会逐步收敛:
- 添加
missing entry问题所打印的准确条目行,并在后面加上— description——后续每项操作都会读取此位置提示。 - 在已注册但缺少
## Spaces标题的子空间中插入该标题——仅在问题提示要求插入时操作;若提示要求改名,则属于接近但不完全匹配的情况,应作为作者意图继续报告。 - 移除审计指出跨越另一个空间边界的条目——更深层的列表归该空间所有;若该条目尚未在那里注册,则在那里注册。
其他情况均属于作者意图——格式错误或重复的条目、无法注册的子空间名称、指向文件的条目、接近但不完全匹配的标题、第二个无效标题、未声明的裸索引、过期条目、不健康的挂载、超限或无法读取的文件,以及你自行检查发现的任何失效链接——都应继续报告给用户(如果用户表示可以,则提出将其作为常规编辑修复;未声明的裸索引属于提升决策)。
- 添加
-
规范化:标签。 仅当作用域根目录中存在
_meta/taxonomy.md时才执行,且只处理该作用域自己的页面——子空间使用各自的 taxonomy,应排除在外。- 使用
grep '^tags:' --wiki <root>扫描清单;如果扫描结果有歧义,则读取相关页面的 frontmatter——由你判断 YAML 格式。 - 未加标签的页面 =
files中的页面减去扫描命中的页面,再排除免于检查 frontmatter 的特殊文件:索引、log.md、hot.md、_template.md。 - 标记非规范标签、标签过多(>5)的页面以及未加标签的页面;应用 taxonomy 中定义的别名映射。
- 某个未知标签出现在 2 个或更多页面中:建议将其加入 taxonomy。只出现一次:建议改用最接近的规范标签。
- 使用
-
规范化:交叉链接。 建立仅包含作用域自有页面的注册表(名称、标题,以及存在时的 frontmatter 别名);特殊文件(索引、
log.md、hot.md、_template.md)既不纳入注册表,也不参与扫描——导航、历史、草稿和模板内容都不应提供链接,也不应成为链接目标。扫描正文,找出首次出现但未链接的注册表条目,并将最明确的匹配项包装为 Wiki 链接——每页最多新增 2 个链接,绝不放在代码块或 frontmatter 内,也不添加自链接。优先采用行内链接;如果没有自然提及,则以## Related分节作为后备方案。在大型 Wiki 中,扫描本轮会触及的空间,并说明跳过了哪些内容。 -
如果存在
log.md,按核心区块的要求添加一行TEND,并以报告收尾。
输出
每种模式:一张状态表;一份审计报告,引用脚本的发现并附上你的建议;规范化表格(标签 → 操作、添加的链接 → 位置)。完整检查结束时,用一行列出差异:问题数:之前 → 之后;留给你处理:<n>。