ws-tend
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseWiki Tend
Wiki Tend
One-shot maintenance: status, audit, normalize (tags + cross-links). Report first, repair only what's safe, and degrade gracefully wherever a convention the step depends on is absent.
<!-- ws:core -->一次性维护:状态、审计、规范化(标签 + 交叉链接)。先报告,仅修复安全项;当某个步骤所依赖的约定不存在时,应安全降级。
<!-- ws:core -->The wiki model
Wiki 模型
A wiki is a folder whose carries a heading. is the navigation contract: every space directly inside is listed there as , and tools traverse only what it lists. Spaces nest recursively; each space is itself a wiki one level down. Plain folders (no ) just group files. The markdown dialect is Obsidian — wikilinks, frontmatter, callouts, embeds; the companion and skills cover the syntax.
index.md## Spaces## Spaces- [label](path/index.md) — descriptionindex.mdobsidian-markdownobsidian-baseswiki 是一个文件夹,其中 包含一个 标题。 是导航约定:每个直接位于其中的 space 都在这里列为 ,工具也只遍历这里列出的内容。space 可以递归嵌套;每个 space 本身也是下一层的 wiki。普通文件夹(没有 )仅用于归组文件。Markdown 方言为 Obsidian——支持 wikilinks、frontmatter、callouts 和 embeds;配套的 与 skill 介绍了相关语法。
index.md## Spaces## Spaces- [label](path/index.md) — descriptionindex.mdobsidian-markdownobsidian-basesResolving the wiki
解析 wiki
Resolution order: an explicit path from the user → the nearest CWD-ancestor folder that is a wiki, or carries a folder that is one (a folder's own space) → the key in . The user's words override the mechanics: "my wiki" means the configured one even when CWD sits inside another wiki (a company repo, say). When a CWD wiki and a different configured wiki both exist, announce which root you resolved; ask once if intent is ambiguous. Never silently operate on the wrong wiki.
.wiki-spaces/wiki~/.config/wiki-spaces/config解析顺序:用户提供的显式路径 → 最近的 CWD 祖先文件夹,该文件夹要么本身是 wiki,要么包含一个作为 space 的 文件夹 → 中的 键。用户的措辞优先于机制:即使 CWD 位于另一个 wiki(例如公司仓库)中,“我的 wiki”也指已配置的 wiki。当 CWD wiki 与另一个已配置 wiki 同时存在时,应声明解析到的根目录;如果意图不明确,只询问一次。绝不能悄悄操作错误的 wiki。
.wiki-spaces/~/.config/wiki-spaces/configwikiThe bundled script
随附脚本
scripts/ws.py- — spaces reachable via the
python3 <skill-dir>/scripts/ws.py list --wiki <root>contract, each with its entry description (## Spacesto cross mounts).--external - — markdown files reachable via the contract.
… files --wiki <root> - — regex line search over those files,
… grep <pattern> [-i] [-F] --wiki <root>for a literal string (a name carrying metacharacters sweeps exact); prints-F, exits 1 on no match. The sweep primitive: a link worklist, a tag inventory, an escaping-reference check are each a pattern plus your judgment on the hits.rel:line: text - — cap verdict for a file; pipe planned content with
… check-size <target> [--stdin] --wiki <root>to check before writing.--stdin - — contract drift, entries crossing a space boundary, over-cap or unreadable files, unhealthy mounts. Findings name their repair where one is safe to name (a
… audit --wiki <root>prints the exact line to add); apply repairs as ordinary edits and re-run the audit to verify — the script never writes.missing entry
Trust the script's output over re-deriving structure by hand. Stdout is data; stderr carries the resolved root ( prints it as its stdout header instead) and advisories naming whatever a walk skipped, the enclosing wiki when the root is nested inside one, and the configured wiki when the root is another — relay them when they could change the answer.
auditnote:scripts/ws.py- ——列出通过
python3 <skill-dir>/scripts/ws.py list --wiki <root>约定可访问的 space,以及每个 space 的条目描述(## Spaces可用于跨挂载点查询)。--external - ——列出通过该约定可访问的 Markdown 文件。
… files --wiki <root> - ——对这些文件执行正则行搜索;
… grep <pattern> [-i] [-F] --wiki <root>用于字面字符串搜索(可精确清理名称中含元字符的内容);输出-F,无匹配时退出码为 1。扫描原语:链接工作列表、标签清单和转义引用检查,均由模式搜索加上你对结果的判断构成。rel:line: text - ——判断文件是否超出上限;可通过
… check-size <target> [--stdin] --wiki <root>传入计划写入的内容,在写入前进行检查。--stdin - ——检查约定漂移、跨越 space 边界的条目、超限或无法读取的文件,以及不健康的挂载点。发现的问题会在能够安全确定修复方式时指出修复方法(
… audit --wiki <root>会打印需要添加的确切行);将修复作为普通编辑应用,然后重新运行 audit 进行验证——脚本本身绝不写入。missing entry
应信任脚本输出,而不是手动重新推导结构。Stdout 是数据;stderr 会携带解析到的根目录( 则将其作为 stdout 标题输出),以及以 开头的建议,说明遍历跳过了哪些内容、根目录嵌套在另一个 wiki 中时的外层 wiki,或根目录不是已配置 wiki 时的已配置 wiki——当这些信息可能改变结论时应进行转述。
auditnote:Trust scope and size discipline
信任范围与大小约束
Owned vs external is relative to the resolved root: anything under a folder named (at any depth), a git submodule, or a symlink into either is external; a symlink to a folder outside the tree answers to where it sits, like a clone. Reads cross owned spaces by default and enter external ones only when the user explicitly asks. Writes stay inside the targeted space; any other space — owned or external — is written only on explicit instruction.
shared/Caps are UTF-8 bytes including frontmatter, keyed by basename: 5000, and 100000, any other 15000.
index.mdlog.mdhot.md*.md- Caps belong to the user: a wiki that wants different ones sets them in , and
_meta/limits.mdreads them.check-size - Check caps with : pipe the planned content via
check-sizebefore every write, new page or edit — a write that shrinks an over-cap file reports--stdin, progress, so repairs converge; a file checked on disk answers to the cap alone.ok - An overflow is a signal about shape, not just size: distill the page, reshape the space, or promote a page that has grown into one — never truncate, never raise the cap.
- The exception is : an over-cap log rolls — move it whole to
log.mdand start a fresh one — so the history archives, never shrinks._archives/log-<YYYYMMDD>.md
Conventions are opt-in per wiki. Read the markers present at the scope root (the space the user targeted, else the resolved root) — , , , , frontmatter on pages, , , — and degrade gracefully when one is absent. If exists, append one line per operation:
log.md_meta/taxonomy.md_meta/limits.md_meta/ignore.md_template.mdhot.md.gitlog.mdsh
printf '%s %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" '<OP> <details>' >> <scope-root>/log.md归属与外部状态均相对于解析到的根目录判断:任何位于名为 的文件夹下(无论深度如何)、属于 git submodule,或是指向这两类位置的 symlink,都视为外部内容;指向树外文件夹的 symlink 则以其实际所在位置为准,就像 clone 一样。默认情况下,读取操作可跨越归属范围内的 space;只有用户明确要求时才能进入外部 space。写入操作仅限目标 space;任何其他 space——无论归属内还是外部——都只能在用户明确指示后写入。
shared/上限按包含 frontmatter 在内的 UTF-8 字节数计算,并以文件 basename 为键: 为 5000, 和 为 100000,其他所有 为 15000。
index.mdlog.mdhot.md*.md- 上限归用户所有:wiki 如需采用不同上限,可在 中设置,
_meta/limits.md会读取这些值。check-size - 使用 检查上限:每次写入、创建新页面或编辑前,都应通过
check-size传入计划写入的内容——将超限文件缩减到上限以内的一次写入会报告--stdin,使修复逐步收敛;磁盘上的文件仅依据上限进行判断。ok, progress - 溢出不仅表示文件过大,也是在提示结构形态:应提炼页面、重构 space,或将已 grown 成独立主题的页面提升为独立 space——绝不能截断,也绝不能提高上限。
- 是例外:超限日志需要滚动归档——将整个文件移动到
log.md,然后新建一个日志文件——这样历史会被完整归档,而不会缩水。_archives/log-<YYYYMMDD>.md
约定由每个 wiki 自行选择启用。读取作用域根目录(用户指定的 space,否则为解析到的根目录)中存在的标记——、、、、页面上的 frontmatter、、、——当某项不存在时应安全降级。如果存在 ,每次操作追加一行:
log.md_meta/taxonomy.md_meta/limits.md_meta/ignore.md_template.mdhot.md.gitlog.mdsh
printf '%s %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" '<OP> <details>' >> <scope-root>/log.mdProcedure
操作流程
-
Resolve the wiki (core block) and announce the root when it came from CWD or could be ambiguous. A freshly scaffolded wiki has nothing to tend — say so plainly rather than inventing work.
-
Detect conventions at the scope root (core block). Presence markers (, taxonomy,
log.md) never inherit from a parent;hot.md,_meta/limits.md, and_meta/ignore.mdfollow their nearest-ancestor rule. Skip every mode whose marker is absent._template.md -
Pick the mode from the user's words:
User says Mode "wiki status", "what's in my wiki" status "audit", "health check", "what needs fixing" audit "fix tags", "normalize tags" normalize: tags "link pages", "cross-reference" normalize: links "tend wiki", "clean wiki" full sweep: status → audit → ask → normalize Status and audit only report. Normalize previews its changes and asks before writing — unless the user already said "fix" or "apply". -
Status.+
listfor the shape (addfilesonly when the user opted in). Report: spaces and their one-line descriptions, page counts per top-level folder, tag counts and the top 10 by usage (from a--externalsweep, when frontmatter is in use), the lastgrep '^tags:'line (when present), and git status (whenlog.mdexists — read-only; never commit or push)..git -
Audit. Runand relay its findings in its own vocabulary. The script is the source of truth for these; don't re-derive them:
audit- — a bare index (registered or not), a near-miss heading, a malformed or duplicate entry, an unregistrable child name, an entry naming a file rather than a space, an entry crossing another space's boundary, a dead second heading.
contract - — an on-disk space not listed, or a listed entry with nothing on disk.
drift - — a registered external mount that is no longer a wiki.
mount - and
over-capfiles.unreadable
Add the judgment the script can't make:- Remediation suggestions. For each over-cap file, suggest what its diagnosis calls for — distill (bloat) or reshape the space (siblings under a hub, a promotion, a regrouped layout), per 's overflow procedure; an over-cap
ws-updatetakes the archive roll instead (core block).log.md - Link integrity — content, so yours: sweep the link shapes (,
grep -F '[[' …), judge each hit against thegrep -F '](' …inventory and the disk, and report dead ones with the nearest-named page as the likely target — afilesbody is exempt, its placeholder links being examples, not dead links. On a large wiki, sweep the spaces this pass touches and say what you skipped._template.md - Frontmatter completeness — only on pages that already carry frontmatter, only when the wiki uses a schema; mixed adoption is allowed.
- Structural prompts — a page pressing its cap (any page you suspect) with several distinct H2 sections is outgrowing its shape and is reshape-ready; a space whose index lists many accreted siblings wants a sub-space; a long-grown opt-in
check-sizewants distilling into cold pages; a space holding one small page and no sub-spaces reads as over-structure — suggest demoting it to a page (hot.md's restructure reference).ws-update
-
Structural repair (close-out). Apply the safe structural repairs yourself, one edit each, re-auditing between rounds until the structural findings are gone — each re-audit re-derives findings from disk, so the rounds converge:<!-- ws:safe-repairs -->
- Add the exact entry line a finding prints, then trail it with a
missing entry— the placement hint every later operation reads.— description - Insert the heading a registered bare child lacks — only where the finding's hint asks for the insert; a near-miss hint asks for a rename, which stays reported as author intent.
## Spaces - Remove an entry the audit says crosses another space's boundary — that space owns the deeper listing; register it there instead when it is missing.
Everything else is author intent — malformed or duplicate entries, unregistrable child names, entries naming files, near-miss headings, dead second headings, undeclared bare indexes, stale entries, unhealthy mounts, over-cap or unreadable files, and any dead links your own sweep surfaced — and stays reported for the user (offer to fix as a normal edit if the user says go; an undeclared bare index is a promotion decision). - Add the exact entry line a
-
Normalize: tags. Only whenexists at the scope root, and only over the scope's own pages — children spaces keep their own taxonomies; leave them out.
_meta/taxonomy.md- Sweep the inventory with ; read the frontmatter of any page the sweep leaves ambiguous — YAML shapes are yours to judge.
grep '^tags:' --wiki <root> - Untagged pages are minus the sweep's pages, less the frontmatter-exempt special files: indexes,
files,log.md,hot.md._template.md - Flag non-canonical tags, over-tagged (>5) pages, and untagged pages; apply the alias mappings the taxonomy defines.
- An unknown tag on 2+ pages: suggest adding it to the taxonomy. A one-off: suggest the closest canonical tag.
- Sweep the inventory with
-
Normalize: cross-links. Build a registry of scope-own pages (names, titles, frontmatter aliases when present); the special files (indexes,,
log.md,hot.md) stay out of both the registry and the scan — navigation, history, scratch, and boilerplate neither give nor take links. Scan bodies for unlinked first mentions of registry entries and wrap the strongest matches as wikilinks — at most 2 new links per page, never inside code blocks or frontmatter, no self-links. Prefer inline linking; a trailing_template.mdsection is the fallback when no natural mention exists. On a large wiki, scan the spaces this pass touches and say what you skipped.## Related -
Log oneline per the core block when
TENDexists, and close with the report.log.md
-
解析 wiki(核心区块),当根目录来自 CWD 或可能存在歧义时予以声明。刚搭建好的 wiki 没有需要维护的内容——应直接说明,而不要凭空创造工作。
-
检测作用域根目录中的约定(核心区块)。存在性标记(、taxonomy、
log.md)绝不从父级继承;hot.md、_meta/limits.md和_meta/ignore.md遵循最近的祖先规则。缺少相应标记的模式一律跳过。_template.md -
根据用户的措辞选择模式:
用户说 模式 “wiki status”“what's in my wiki” status “audit”“health check”“what needs fixing” audit “fix tags”“normalize tags” normalize: tags “link pages”“cross-reference” normalize: links “tend wiki”“clean wiki” full sweep: status → audit → ask → normalize status 和 audit 只进行报告。normalize 会先预览变更,并在写入前询问——除非用户已经说过“fix”或“apply”。 -
Status。 使用和
list获取结构概况(仅在用户选择加入外部内容时添加files)。报告:各 space 及其单行描述、每个顶层文件夹的页面数量、标签数量及使用率最高的前 10 个标签(当 wiki 使用 frontmatter 时,通过--external扫描获取)、grep '^tags:'的最后一行(如果存在),以及 git status(当存在log.md时;只读,绝不 commit 或 push)。.git -
Audit。 运行,并使用脚本自身的术语转述发现的问题。这些结果是脚本的事实来源;不要重新推导:
audit- ——裸 index(无论是否已注册)、近似但不完全匹配的标题、格式错误或重复的条目、无法注册的子项名称、指向文件而非 space 的条目、跨越另一个 space 边界的条目,以及失效的第二个标题。
contract - ——磁盘上存在但未列出的 space,或已列出但磁盘上不存在的条目。
drift - ——已注册但已不再是 wiki 的外部挂载点。
mount - 和
over-cap文件。unreadable
补充脚本无法判断的内容:- 修复建议。 对于每个超限文件,根据其诊断结果给出建议——内容膨胀时进行提炼,或重构 space(将同级页面归入 hub、提升为独立页面或重新组织布局),具体遵循 的溢出处理流程;超限的
ws-update则采用归档滚动方式(核心区块)。log.md - 链接完整性——这属于内容判断,由你负责:扫描链接形态(、
grep -F '[[' …),根据grep -F '](' …清单和磁盘内容判断每个命中项,并报告失效链接及其最可能对应的近似名称页面——files正文中的占位链接属于示例,不算失效链接。对于大型 wiki,只扫描本次涉及的空间,并说明跳过了哪些内容。_template.md - Frontmatter 完整性——只检查已经包含 frontmatter 的页面,并且仅当 wiki 使用 schema 时检查;允许采用程度不一致的情况。
- 结构性提示——某个页面接近大小上限(对任何可疑页面运行 ),且包含多个不同的 H2 章节,说明其结构已难以承载内容,可以进行重构;某个 space 的 index 列出了大量不断累积的同级页面,意味着应创建子 space;长期增长的 opt-in
check-size应提炼为冷页面;某个 space 仅包含一个小型页面且没有子 space,说明结构过度,应建议将其降级为普通页面(参考hot.md的 restructure 流程)。ws-update
-
结构修复(收尾)。 自行应用安全的结构修复,每次只做一项编辑,并在每轮修复之间重新运行 audit,直到结构问题消失——每次重新 audit 都会从磁盘重新推导发现的问题,因此各轮修复会逐步收敛:<!-- ws:safe-repairs -->
- 添加 发现项所打印的确切条目行,并在后面补上
missing entry——这是后续所有操作都会读取的放置提示。— description - 为缺少标题的已注册裸子项插入 标题——仅在发现项的提示明确要求插入时执行;如果提示要求重命名近似标题,则保留为待作者确认的意图。
## Spaces - 删除 audit 判定为跨越另一个 space 边界的条目——更深层的列表应由该 space 管理;如果那里缺少注册项,则改为在那里注册。
其他所有问题都属于作者意图——格式错误或重复的条目、无法注册的子项名称、指向文件的条目、近似标题、失效的第二个标题、未声明的裸 index、过期条目、不健康的挂载点、超限或无法读取的文件,以及你的扫描发现的任何失效链接——这些应继续报告给用户(如果用户说“go”,可将其作为普通编辑进行修复;未声明的裸 index 属于是否提升的决策)。 - 添加
-
Normalize:标签。 仅当作用域根目录中存在时执行,并且只处理该作用域自己的页面;子 space 保留各自的 taxonomy,不纳入本次处理。
_meta/taxonomy.md- 使用 扫描清单;读取扫描结果无法明确判断的页面的 frontmatter——YAML 结构由你判断。
grep '^tags:' --wiki <root> - 未加标签的页面为 减去扫描得到的页面,再减去免用 frontmatter 的特殊文件:index、
files、log.md和hot.md。_template.md - 标记非规范标签、标签过多的页面(超过 5 个)以及未加标签的页面;应用 taxonomy 定义的别名映射。
- 如果未知标签出现在 2 个或更多页面上,建议将其加入 taxonomy;如果只出现一次,建议使用最接近的规范标签。
- 使用
-
Normalize:交叉链接。 建立作用域自有页面的注册表,包括名称、标题和存在时的 frontmatter aliases;特殊文件(index、、
log.md、hot.md)既不加入注册表,也不参与扫描——导航、历史、临时内容和模板既不提供链接,也不接收链接。扫描正文,查找注册表条目在首次出现时未加链接的情况,并将最合适的匹配项包装为 wikilinks——每页最多新增 2 个链接,绝不放在代码块或 frontmatter 中,也不得添加自链接。优先使用行内链接;只有在没有自然提及位置时,才使用末尾的_template.md章节。对于大型 wiki,只扫描本次涉及的空间,并说明跳过了哪些内容。## Related -
当存在时,按照核心区块记录一行
log.md日志,并以报告结束。TEND
Output
输出
Per mode: a status table; an audit report quoting the script's findings plus your suggestions; normalize tables (tag → action, link added → where). End the full sweep with the one-line delta: .
issues before → after; left for you: <n>根据模式输出:status 表格;引用脚本发现项并附上建议的 audit 报告;normalize 表格(标签 → 操作,新增链接 → 位置)。完整扫描最后以一行变化摘要结束:。
issues before → after; left for you: <n>