wikikit
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesewikikit
wikikit
The documentation a reader opens: how do I run this, how do I do the one task I came here for, how is it put together, and what do I do at 3am when it's down. wikikit generates that set from the codebase as it actually is, keeps it true as the code changes, and reports honestly when it has gone stale. It is not the GitHub Wiki tab — everything it writes is in-repo Markdown, versioned with the code and reviewed in the same pull request. Mirroring that set out to the wiki tab is available as an opt-in mode, which never fires unless you ask for it by name.
publishA repo built by agents accumulates plans, reviews, QA docs, and decision records, and still ships a README that says because that's what the scaffold wrote a year ago. The knowledge exists; it's just scattered across artifacts nobody outside the project will ever read. wikikit is the half that faces outward.
npm install这是面向读者的文档:我该如何运行这个项目?我该如何完成特定任务?项目的架构是怎样的?凌晨3点出问题时该怎么处理?wikikit从实际代码库生成这套文档,在代码变更时保持文档准确,当文档过时会如实报告。它不是GitHub Wiki标签页——所有编写的内容都是仓库内的Markdown文件,与代码版本同步,并在同一个Pull Request中接受评审。仅当你主动选择模式时,才会将文档镜像到Wiki标签页,该模式不会自动触发,必须明确调用。
publish由代理构建的仓库会积累计划、评审、QA文档和决策记录,但README仍停留在一年前脚手架生成的。知识是存在的,只是分散在项目外部人员永远不会查看的工件中。wikikit负责构建面向外部的那部分文档。
npm installWhat wikikit is not
wikikit 不做什么
- Not the GitHub Wiki. In-repo Markdown is the source of truth in every mode — versioned with the code, reviewed in the same PR. The wiki tab is at most a derived, disposable mirror, and only when is asked for by name. wikikit never reads the wiki as input and never treats it as canonical.
publish - Not the domain model. A glossary () and decision records (
CONTEXT.md) have one owner — domainkit when it's installed, the human otherwise. A page that needs a term links to the glossary instead of defining it; an architecture page that needs a rationale links the ADR by number instead of paraphrasing it. A term missing from the glossary is routed, never invented inline.docs/adr/ - Not process artifacts. Plans, QA plans, reviews, handoffs, and agent instruction files (and its equivalents) are written for a maintainer mid-flow, expire, and are never read as sources of truth for reader docs or written by this skill.
CLAUDE.md - Not an API reference generator. Where a generator exists — TypeDoc, Sphinx autodoc, an OpenAPI spec — wikikit links its output unchanged rather than hand-writing reference material that drifts within a week.
- 不是GitHub Wiki:在所有模式下,仓库内的Markdown都是唯一的事实来源——与代码版本同步,在同一个PR中评审。Wiki标签页最多只是派生的、可丢弃的镜像,且仅在明确调用模式时才会生成。wikikit从不将Wiki作为输入来源,也不会将其视为权威。
publish - 不是领域模型:术语表()和决策记录(
CONTEXT.md)有专属维护者——安装domainkit时由其维护,否则由人工维护。需要术语的页面会链接到术语表,而非自行定义;需要决策依据的架构页面会按编号链接ADR,而非转述内容。术语表中缺失的术语会被引导至对应维护工具,绝不会在页面内凭空创建。docs/adr/ - 不是流程工件:计划、QA计划、评审、交接文档和代理指令文件(如及其同类文件)是为流程中的维护者编写的,会过期,且永远不会作为读者文档的来源,也不会由本工具生成。
CLAUDE.md - 不是API参考生成器:如果已有现成的生成器——如TypeDoc、Sphinx autodoc、OpenAPI规范——wikikit会直接链接其输出结果,而非手动编写会在一周内过时的参考资料。
When this fires
触发场景
- — "write docs for this project", "document this repo", "we have no docs", "generate a getting-started guide". Bootstraps the set from the codebase.
init - — "update the docs", "the docs are out of date after this change", or a docs pass right after a feature lands. Refreshes only what the change invalidated.
update - — "are our docs stale", "check the docs against the code", "what's undocumented". Read-only sweep. Writes nothing, ever.
audit - — explicit ask only. "publish the docs to the GitHub wiki", "sync
publishto the wiki tab", "set up the wiki action". Installs a workflow that mirrors the set to the wiki.docs/wiki/
If no mode is clear, ask. is free and writes a dozen files; never guess between them.
auditinitpublishupdate- —— “为这个项目编写文档”、“为这个仓库生成文档”、“我们没有文档”、“生成入门指南”。从代码库初始化文档集。
init - —— “更新文档”、“这次变更后文档过时了”,或功能上线后进行文档更新。仅刷新因变更而失效的内容。
update - —— “我们的文档是否过时”、“检查文档与代码是否一致”、“哪些内容未文档化”。只读扫描,永远不会写入任何内容。
audit - —— 仅接受明确请求。“将文档发布到GitHub Wiki”、“将
publish同步到Wiki标签页”、“设置Wiki同步工作流”。安装一个工作流,将文档集镜像到Wiki。docs/wiki/
如果模式不明确,请询问用户。是无成本操作,会生成十几个文件;切勿自行猜测模式。
auditinitpublishupdatepublishLocate the doc sets
定位文档集
Every mode opens the same way, so all three agree on where docs live before anything reads or writes. Name every set found in the mode's first line of output — a missing set has to be visible immediately, not inferred from an empty result.
所有模式的启动流程一致,因此在读写操作前,三者都会确认文档的存储位置。在模式输出的第一行列出所有找到的文档集——缺失的文档集必须立即可见,不能从空结果中推断。
Find existing sets
查找现有文档集
One glob, scoped to the repo root plus the workspace globs (, , , a Cargo workspace), honoring so a vendored tree can't inject a set. No root registry: the manifest travels with the set it describes, and a set added later is found automatically.
**/.wikimap.yamlpnpm-workspace.yamlpackage.jsonworkspacesgo.work.gitignore使用通配符,范围限定在仓库根目录及工作区配置文件(如、中的、、Cargo工作区),同时遵循规则,避免依赖目录注入文档集。没有根注册表:清单与其描述的文档集共存,新增的文档集会被自动识别。
**/.wikimap.yamlpnpm-workspace.yamlpackage.jsonworkspacesgo.work.gitignoreRun the detection ladder for a repo with no set
无文档集仓库的检测流程
Take the first rung that matches, and say which rung matched before writing anything:
| # | Rung | Where docs go |
|---|---|---|
| 1 | A configured docs engine — | that engine's configured content directory, with its nav/sidebar updated in the same pass |
| 2 | An existing reader-doc tree — a populated | adopt it as-is; do not migrate |
| 3 | Fallback | |
docs/wiki/docs/In a workspace, the root set is always written; a package earns its own set only when it is independently published or independently runnable. Run the ladder once for the root, then once per qualifying package (). State the split before writing anything: root-only makes an architecture page unusable past about four packages, and always-per-package is wrong for an app monorepo where the reader wants one getting-started.
packages/<x>/docs/选择首个匹配的层级,在编写任何内容前说明匹配的层级:
| # | 层级 | 文档存储位置 |
|---|---|---|
| 1 | 已配置的文档引擎 —— | 该引擎配置的内容目录,同时更新其导航/侧边栏 |
| 2 | 已存在的读者文档树 —— 已填充内容的 | 直接沿用现有结构,不进行迁移 |
| 3 | ** fallback 方案** | |
docs/wiki/docs/在工作区中,始终会生成根文档集;只有当包可独立发布或独立运行时,才会为其生成单独的文档集。先为根目录执行一次检测流程,再为每个符合条件的包()执行一次。在编写前说明拆分方式:仅根文档集在包数量超过4个时会导致架构页面无法使用,而为每个包都生成文档集对于单体应用仓库来说并不合适,因为读者只需要一份入门指南。
packages/<x>/docs/Reconcile the manifest against disk
协调清单与磁盘内容
A central manifest is the one map shape that can be wrong while looking right, so every mode pays this price up front, before any work starts:
- pages on disk with no manifest entry,
- entries whose page is gone,
- globs matching nothing,
documents: - a that no longer matches the ladder — usually a docs engine that arrived after
home:.init
initupdateauditgit mv中央清单可能存在与实际情况不符的情况,因此所有模式在开始任何工作前都需要执行以下检查:
- 磁盘上存在但清单中无记录的页面,
- 清单中有记录但页面已不存在的条目,
- 通配符匹配不到任何内容,
documents: - 配置与检测流程结果不符——通常是
home:后新增了文档引擎。init
initupdateauditgit mvThe doc map
文档映射
The doc map is the unit all three modes operate on. It lives at — dotfile-prefixed so GitHub's folder view and every engine build skip it without a config edit — and carries one entry per page with its Diátaxis mode and the globs of code it documents:
<doc home>/.wikimap.yamlyaml
home: docs/wiki
engine: none # or mkdocs | docusaurus | vitepress | starlight | sphinx | nextra
pages:
- path: getting-started.md
mode: tutorial
documents: [package.json, src/index.ts, .env.example]
- path: how-to/deploy-to-staging.md
mode: how-to
documents: [.github/workflows/deploy.yml, infra/**]
- path: architecture.md
mode: explanation
adopted: true # a human wrote it; wikikit maps it, never claims it
documents: [src/**]documents:updateaudit文档映射是所有模式的操作单元,存储在——以点文件命名,这样GitHub的文件夹视图和所有引擎构建都会默认跳过它——每个页面对应一个条目,包含其Diátaxis模式和所文档化的代码通配符:
<doc home>/.wikimap.yamlyaml
home: docs/wiki
engine: none # 或 mkdocs | docusaurus | vitepress | starlight | sphinx | nextra
pages:
- path: getting-started.md
mode: tutorial
documents: [package.json, src/index.ts, .env.example]
- path: how-to/deploy-to-staging.md
mode: how-to
documents: [.github/workflows/deploy.yml, infra/**]
- path: architecture.md
mode: explanation
adopted: true # 人工编写的页面;wikikit仅进行映射,不声称拥有其所有权
documents: [src/**]documents:updateauditThe page vocabulary
页面词汇表
| Page | Diátaxis mode | Documents |
|---|---|---|
| — | entry point and table of contents |
| tutorial | install → run → first successful thing |
| how-to | one task per page, goal-shaped |
| how-to | the derivable half of contributor docs |
| how-to | release steps that actually exist in the repo |
| explanation | components, boundaries, data flow, links to ADRs |
| how-to (operator) | deploy, rollback, incident response, backup/restore |
| reference | declared surface only — commands, flags, env vars, config keys |
This table is the vocabulary, not a quota. The map is derived from the repo: a library with no deployment gets no runbooks, a CLI gets a commands page, a repo with a TypeDoc build gets no at all.
reference.mdDiátaxis governs internally and stays out of the reader's face — the four modes are the rule that keeps doc types unmixed, not jargon to print on the page. A how-to must not drift into explanation; an architecture page must not turn into a tutorial.
Two boundaries the vocabulary encodes:
- is linked, never written. Dev-environment setup and release steps are in the repo and verify like any other how-to. PR etiquette, a code of conduct, and review norms are a social contract that exists nowhere in code — writing them would break the grounding rule on the repo's most visible contributor page.
CONTRIBUTING.mdlinks the file if it exists.index.md - covers declared surface only — things declared in a single place and re-verifiable in a single grep: CLI commands, flags, env vars, config keys. Library symbols and hand-maintained HTTP endpoint tables are refused and routed to a generator. This narrow exception exists so a CLI with twenty flags and no docs tooling gets something rather than nothing.
reference.md
| 页面 | Diátaxis模式 | 文档化内容 |
|---|---|---|
| — | 入口点和目录 |
| tutorial(教程) | 安装 → 运行 → 首次成功操作 |
| how-to(操作指南) | 每页一个任务,以目标为导向 |
| how-to(操作指南) | 贡献者文档中可推导的部分 |
| how-to(操作指南) | 仓库中实际存在的发布步骤 |
| explanation(说明) | 组件、边界、数据流、ADR链接 |
| how-to(运维指南) | 部署、回滚、事件响应、备份/恢复 |
| reference(参考) | 仅包含已声明的内容——命令、标志、环境变量、配置键 |
此表是词汇表,而非配额。映射由仓库内容决定:无部署流程的库不会生成运行手册,CLI工具会生成命令页面,已有TypeDoc构建的仓库不会生成。
reference.mdDiátaxis规则在内部生效,不会暴露给读者——四种模式是保持文档类型不混合的规则,而非打印在页面上的术语。操作指南不能混入说明内容;架构页面不能变成教程。
词汇表包含两个边界:
- 仅被链接,不会被编写。开发环境设置和发布步骤属于仓库内容,会像其他操作指南一样被验证。PR规范、行为准则和评审准则是社交契约,不存在于代码中——编写这些内容会违反仓库最显眼贡献者页面的基于代码的规则。
CONTRIBUTING.md会在该文件存在时链接它。index.md - 仅覆盖已声明的内容——在单一位置声明且可通过grep重新验证的内容:CLI命令、标志、环境变量、配置键。库符号和人工维护的HTTP端点表会被拒绝,并引导至对应生成器。这个窄例外是为了让没有文档工具的CLI(带有20个标志)至少能获得一些文档。
reference.md
The provenance stamp
来源标记
Every page wikikit authors ends with one line:
markdown
_Verified against `main`@`a1b2c3d` on 2026-08-06._Both halves earn their place. diffs from the SHA while it is still reachable, and falls back to the date when a rebase or squash-merge has orphaned it — precise when it can be, degrading instead of lying when it can't.
auditA page with no stamp is not stale, it is unverified. That's how adopted pages are marked: a page found under rung 2 gets a manifest entry with globs and , and no stamp. wikikit can see it and route to it, and has never checked a claim on it. It earns its first stamp the first time a verification pass genuinely covers it. Adoption is a mapping act, not an authorship claim over prose a human wrote.
documents:adopted: truewikikit编写的每个页面末尾都会有一行:
markdown
_Verified against `main`@`a1b2c3d` on 2026-08-06._两部分内容都有其作用。模式会在SHA仍可访问时与该SHA进行对比,当rebase或 squash-merge导致SHA失效时,会回退到日期——尽可能精确,无法精确时也不会提供错误信息。
audit没有标记的页面不是过时的,而是未验证的。这是已采用页面的标记方式:在层级2下找到的页面会在清单中添加条目,包含通配符和,但没有标记。wikikit可以识别并链接到该页面,但从未验证过其内容。只有当验证流程真正覆盖该页面时,它才会获得第一个标记。采用是一种映射行为,而非对人工编写内容的所有权声明。
documents:adopted: trueGrounding: verify before you write
基于代码验证:编写前先确认
Every factual claim is verified against the repo before it ships. Commands come from the actual , , , or ; paths exist; env vars are actually read somewhere; endpoints are actually routed. A feature wikikit cannot find in code does not get documented. This is the single rule that separates a doc set from plausible fiction, and it holds in all three modes.
package.jsonMakefilepyproject.tomljustfileStatic reading is the default, and it proves a script is declared, not that it runs. So wikikit may also execute a fixed allowlist of side-effect-free probes, after one consent ask per run:
| Allowed | Never |
|---|---|
| anything that installs ( |
| anything that builds, compiles, or bundles |
| anything that migrates a database or seeds data |
bare script listings — | anything that deploys, publishes, or pushes |
read-only git — | anything that writes outside the doc set, or calls a live service |
The allowlist is written here and never inferred. A command that looks harmless but isn't on the list is not run — report the claim as unverified instead. 's "read-only" means it writes no files, so probes are available there too; that is where they pay off most.
audit所有事实性声明在发布前都会与仓库内容进行验证。命令来自实际的、、或;路径真实存在;环境变量确实在某处被读取;端点确实已路由。wikikit在代码中找不到的功能不会被文档化。这是区分真实文档与虚构内容的唯一规则,适用于所有模式。
package.jsonMakefilepyproject.tomljustfile默认使用静态读取,这可以证明脚本已声明,但无法证明其可运行。因此,wikikit在每次运行获得用户同意后,还可以执行固定的无副作用探测白名单:
| 允许执行 | 禁止执行 |
|---|---|
| 任何安装操作( |
| 任何构建、编译或打包操作 |
| 任何数据库迁移或数据填充操作 |
裸脚本列表 —— | 任何部署、发布或推送操作 |
只读git操作 —— | 任何向文档集外写入内容或调用实时服务的操作 |
白名单在此明确列出,绝不会自动推断。看似无害但不在白名单中的命令不会被执行——而是报告该声明未验证。模式的“只读”指它不会写入任何文件,因此探测操作也适用于该模式;在该模式下,探测操作的价值最大。
auditMode: init
init模式:init
initFor a repo with no doc set, or a partial one.
适用于无文档集或文档集不完整的仓库。
1. Ground it
1. 基于代码验证
The research pass, and the bulk of the work. Read the manifests and their declared commands, entry points, CLI surface, routes, env vars, config, /compose, CI workflows, deploy config, the existing README, and / when they exist. Ask once for probe consent and use it to confirm the commands that will end up in — a getting-started whose first command doesn't exist is worse than no getting-started.
DockerfileCONTEXT.mddocs/adr/getting-started.md这是研究阶段,也是主要工作内容。读取清单及其声明的命令、入口点、CLI界面、路由、环境变量、配置、/compose、CI工作流、部署配置、现有README,以及/(如果存在)。询问一次探测操作的同意,并用它确认将写入的命令——入门指南的第一个命令不存在比没有入门指南更糟糕。
DockerfileCONTEXT.mddocs/adr/getting-started.md2. Adopt what's already there
2. 采用已有内容
Pages found under rung 2 get manifest entries with globs, , and no stamp. wikikit does not rewrite them and does not claim them.
documents:adopted: true在层级2下找到的页面会在清单中添加条目,包含通配符、,但没有标记。wikikit不会重写这些页面,也不会声称拥有其所有权。
documents:adopted: true3. Propose the map
3. 提出映射方案
Consent-gated, and this is the gate that matters. Show the page list with a one-line scope each, which entries are newly authored versus adopted, and what wikikit could not determine from code. The user accepts, trims, or redirects before a single file is written.
需要用户同意,这是关键的审核环节。显示页面列表及每个页面的一行范围说明,区分新编写的条目和已采用的条目,以及wikikit无法从代码中确定的内容。用户接受、删减或调整后,才会写入文件。
4. Write the accepted pages
4. 编写已接受的页面
Each grounded per Grounding: verify before you write, each held to the Writing standards, each stamped with and the date.
<ref>@<sha>5. Rewrite the README front door
5. 重写README入口
wikikit owns exactly one zone of the README — what this is, the quickstart, and the links into the doc set. It does not touch badges, license, acknowledgments, or anything else. The README is the most-read page in any repo; leaving it out of the maintained set is how it ends up lying about the install command.
The zone is delimited by marker comments. The first run infers the boundary positionally, shows the exact proposed boundary, and writes the markers on consent:
markdown
<!-- wikikit:front-door:start -->
...
<!-- wikikit:front-door:end -->Every later run is exact rather than positional. Refuse the markers and wikikit writes nothing to the README at all, and says so.
wikikit仅负责README的一个区域——项目介绍、快速入门和文档集链接。不会修改徽章、许可证、致谢或其他内容。README是任何仓库中阅读量最高的页面;不将其纳入维护范围会导致安装命令过时。
该区域由标记注释界定。首次运行会根据位置推断边界,显示确切的提议边界,并在获得同意后写入标记:
markdown
<!-- wikikit:front-door:start -->
...
<!-- wikikit:front-door:end -->后续每次运行都会精确匹配标记,而非根据位置推断。如果用户拒绝标记,wikikit不会向README写入任何内容,并会告知用户。
6. Write the manifest and update the nav
6. 编写清单并更新导航
Write , then update the docs engine's nav or sidebar config when one was detected. A page an engine can't reach is a page nobody reads.
<doc home>/.wikimap.yaml写入,然后在检测到文档引擎时更新其导航或侧边栏配置。引擎无法访问的页面不会被读者看到。
<doc home>/.wikimap.yaml7. Hand off
7. 交接
Write every hand-off in this skill in the procedural register: one instruction per sentence, active voice, present tense, no metaphor.
What changed — pages authored, pages adopted (mapped, not stamped), the README zone written or declined, and what could not be determined from code.
Where it landed — the doc home, which ladder rung chose it, the manifest path, and the engine config touched.
Next — read the set. It is new prose about your project and it is the one thing here a human should actually check. Then commit it with commitkit when installed, otherwise a plain and commit. If a term surfaced that belongs in the glossary, route to domainkit rather than defining it on a page.
git add本工具的所有交接内容均采用流程化表述:每句一个指令,主动语态,现在时,无隐喻。
变更内容——编写的页面、已采用的页面(仅映射,无标记)、README区域是否写入或拒绝,以及无法从代码中确定的内容。
存储位置——文档主目录、选择的检测层级、清单路径,以及修改的引擎配置。
下一步——阅读文档集。这是关于你的项目的新内容,也是人类实际需要检查的部分。如果已安装commitkit,使用它提交;否则使用普通的和commit。如果出现属于术语表的术语,引导至domainkit,而非在页面内定义。
git addMode: update
update模式:update
updateFor a change that just landed. Resolve the target the same way a review does: uncommitted working-tree changes first ( non-empty → , plus the untracked files never shows), otherwise the branch diff against the base ref — from gitkit when it's installed, else the repo's default branch via . Never assume . Say which target you chose in one line.
git status --porcelaingit diff HEADgit diffgh repo view --json defaultBranchRefmain适用于刚完成变更的场景。像评审一样确定目标:优先处理未提交的工作区变更(非空 → ,加上不会显示的未跟踪文件),否则处理分支与基准引用的差异——已安装gitkit时从其获取,否则通过获取仓库的默认分支。切勿假设默认分支是。用一行说明你选择的目标。
git status --porcelaingit diff HEADgit diffgh repo view --json defaultBranchRefmain1. Read the diff, not the whole repo
1. 读取差异,而非整个仓库
The diff is the input. Reading the repo instead is how a one-flag change turns into a six-page rewrite.
差异是输入来源。读取整个仓库会导致一个标志的变更演变成六页内容的重写。
2. Map changed code to affected pages
2. 将变更的代码映射到受影响的页面
Through the manifest's globs. State which pages are affected and which are deliberately untouched — before editing, not in the report afterward. The untouched list is the load-bearing half; it's what tells the user the skill knew what it was leaving alone.
documents:通过清单的通配符实现。在编辑前说明受影响的页面和故意未修改的页面——而非在报告中事后说明。未修改的页面列表是关键部分;它告诉用户工具清楚自己未修改哪些内容。
documents:3. Edit the affected pages, surgically and directly
3. 精准直接地编辑受影响的页面
A changed flag edits the flag. It does not regenerate the page. These edits need no gate: they are bounded by the restraint rule and land in a reviewable diff. An adopted (unstamped) page is edited only for a claim the diff actually broke — never restyled, never expanded.
The discipline here is restraint. A skill that rewrites six pages because one function moved is worse than no skill, because now the PR diff is unreviewable.
变更的标志仅编辑该标志,不会重新生成页面。这些编辑无需审核:它们受约束规则限制,会生成可评审的差异。已采用的(无标记)页面仅在差异确实破坏了某个声明时才会被编辑——绝不会重新排版或扩展内容。
此处的原则是克制。因一个函数移动而重写六页内容的工具比没有工具更糟糕,因为PR差异会变得无法评审。
4. Flag the documentation-shaped gaps the diff created
4. 标记差异导致的文档缺口
A new command with no how-to, a new env var absent from getting-started, a new failure mode with no runbook. New pages and deletions are consent-gated — propose, then write. That split is the whole write-mode policy: edits go straight in, creation and destruction ask.
新增命令但无操作指南、新增环境变量但未在入门指南中提及、新增故障模式但无运行手册。新页面的创建和页面删除需要用户同意——先提出方案,再写入内容。这是整个写入模式的策略:编辑直接生效,创建和删除需要询问。
5. Re-stamp and reconcile
5. 重新标记并协调
Re-stamp every page touched, and update the manifest for anything created or removed.
重新标记所有被修改的页面,并更新清单中新增或删除的内容。
6. Hand off
6. 交接
What changed — pages edited (one line each, naming the claim that moved), pages proposed and their verdict, pages deliberately untouched.
Where it landed — the paths, and the manifest if it moved.
Next — commitkit, then prkit (otherwise and ). Docs land in the same PR as the code that changed them; that's the whole point of in-repo docs.
git commitgh pr create变更内容——编辑的页面(每个页面一行,说明修改的声明)、提出的页面及其处理结果、故意未修改的页面。
存储位置——文件路径,以及清单是否变更。
下一步——使用commitkit,然后使用prkit(否则使用和)。文档与变更代码在同一个PR中提交;这正是仓库内文档的意义所在。
git commitgh pr createMode: audit
audit模式:audit
auditRead-only. Writes nothing, ever. It reports, and routes to or for the fixing. Reporting a problem and fixing it are separate invocations, deliberately.
updateinitThree checks per page, cheapest first:
- Recency — the page's stamp against the commits touching the code it documents, diffing from the stamped SHA while it is reachable and falling back to the date when it isn't. Grep-cheap, so it runs over every page. It is a prefilter, not a verdict: a stale stamp on an unchanged concept is fine.
- Claim verification — the load-bearing one. Every command, path, env var, flag, and endpoint on the page checked against the repo, with the allowlisted probes available on consent. A command that no longer exists is broken; a described behavior that changed is stale. This pass is budgeted and spends highest-risk-first, ordered by the recency prefilter.
- Coverage — documentable surface with no page at all: an undocumented CLI command, a deploy path with no runbook, a public entry point missing from the architecture page.
每个页面进行三项检查,按成本从低到高排序:
- 时效性——页面标记与文档化代码的提交记录对比,在标记的SHA可访问时使用SHA对比,不可访问时回退到日期。通过grep即可完成,因此会对所有页面执行。这是预过滤条件,而非最终结论:概念未变更但标记过时是可以接受的。
- 声明验证——核心检查。页面上的每个命令、路径、环境变量、标志和端点都会与仓库内容进行验证,获得同意后可使用白名单中的探测操作。命令不存在则为损坏;描述的行为已变更则为过时。此检查有预算限制,按时效性预过滤结果从高风险到低风险执行。
- 覆盖率——有文档化价值但无对应页面的内容:未文档化的CLI命令、无运行手册的部署流程、架构页面中缺失的公共入口点。
The report
报告
A table per page with a verdict, plus quoted evidence for anything that isn't :
current| Verdict | Means |
|---|---|
| claims check out against the code |
| a described behavior changed |
| a command, path, or var on the page no longer exists |
| an adopted page wikikit has never claim-checked — distinct from stale |
| documentable surface with no page |
Add a manifest-drift row from the reconcile pass, and crown one next move.
Every report opens with a mandatory coverage line, because an audit that silently covered 12% reads exactly like a clean bill of health:
Recency: 312/312 · Claims verified: 40/312 (highest-risk first) · Not claim-checked: 272 (listed below)The not-claim-checked pages are listed, not summarized as a count. A scope argument () narrows the run explicitly; the coverage line reports the narrowing either way.
audit how-to/每个页面对应一个表格,包含结论,非的结论需附上引用证据:
current| 结论 | 含义 |
|---|---|
| 声明与代码一致 |
| 描述的行为已变更 |
| 页面上的命令、路径或变量已不存在 |
| wikikit从未验证过的已采用页面——与过时不同 |
| 有文档化价值但无对应页面的内容 |
添加协调流程中的清单差异行,并给出首要建议。
每份报告开头必须包含覆盖率说明,因为仅覆盖12%却未说明的审计看起来完全像健康报告:
时效性检查:312/312 · 声明验证:40/312(高风险优先) · 未验证声明:272(如下所列)未验证声明的页面会被列出,而非仅汇总数量。范围参数(如)会明确缩小检查范围;覆盖率说明会报告缩小后的范围。
audit how-to/Hand off
交接
What changed — nothing. Say that outright; is read-only and a reader should never have to wonder.
auditWhere it landed — inline in this reply. Offer to save it only if asked; there is no audit artifact by default.
Mode: publish
publish模式:publish
publishOpt-in, explicit-ask-only. Mirrors the doc set out to the repo's GitHub Wiki tab by installing a workflow that syncs on every push to the doc home. wikikit writes the workflow file; GitHub Actions does the syncing, so nothing here pushes to a wiki from your machine.
The in-repo set stays the source of truth. The wiki is a derived, disposable mirror: delete it and re-sync and you lose nothing, because nothing originates there.
可选模式,仅接受明确请求。通过安装工作流,在每次推送文档主目录时将文档集镜像到仓库的GitHub Wiki标签页。wikikit负责编写工作流文件;GitHub Actions负责同步,因此不会从你的机器向Wiki推送内容。
仓库内的文档集始终是事实来源。Wiki是派生的、可丢弃的镜像:删除并重新同步不会丢失任何内容,因为没有内容起源于Wiki。
What you are agreeing to
你需要了解的内容
Three properties of GitHub wikis make this sharper than it looks. Say all three out loud before writing anything — a user who learns them from the aftermath will not thank you.
- The sync is destructive and one-way. The action clears the wiki repo, copies the doc set in, and force-pushes. Any page created or edited in the wiki's web UI is deleted on the next sync — including on private repos, and including pages nobody in the doc set has ever heard of. The wiki becomes read-only in practice; the edit button stays there and lies. (This is true under both of the action's strategies, notwithstanding its own documentation, which describes force-push as -only.)
init - The page namespace is flat. Wiki source files may sit in folders, but page URLs are built from the title alone, so and
how-to/deploy.mdboth resolve torunbooks/deploy.mdand one silently wins. The template below flattens path segments into the page name to make collisions impossible; the collision scan catches the residue before anything is installed./wiki/deploy - The wiki must be created by hand, once. A repo's wiki has no git backend until a first page exists, and there is no API or command that creates one. The workflow will fail until a human clicks through the UI.
gh
Editing permissions are not on this list. GitHub restricts public-repo wiki editing to collaborators by default, so the "strangers overwrite each other" hazard is gone — but note that property 1 makes collaborator edits just as doomed.
GitHub Wiki的三个特性让此操作比看起来更复杂。在编写任何内容前明确说明这三点——用户事后才了解这些特性会不满。
- 同步是破坏性且单向的。工作流会清空Wiki仓库,复制文档集,然后强制推送。在Wiki网页UI中创建或编辑的任何页面都会在下次同步时被删除——包括私有仓库,以及文档集中从未出现过的页面。Wiki实际上变成了只读;编辑按钮仍然存在,但会误导用户。(无论工作流的文档如何描述,这两种策略都是如此,尽管其文档称强制推送仅在模式下使用。)
init - 页面命名空间是扁平的。Wiki源文件可能存放在文件夹中,但页面URL仅由标题生成,因此和
how-to/deploy.md都会解析到runbooks/deploy.md,其中一个会被静默覆盖。下面的模板会将路径段扁平化为页面名称,避免冲突;冲突扫描会在安装前检测剩余冲突。/wiki/deploy - Wiki必须手动创建一次。仓库的Wiki在创建第一个页面之前没有git后端,且没有API或命令可以创建它。在人类通过UI创建页面之前,工作流会失败。
gh
编辑权限不在此列表中。GitHub默认限制公共仓库的Wiki编辑权限为协作者,因此“陌生人互相覆盖”的风险已不存在——但请注意,特性1会导致协作者的编辑同样会被删除。
1. Preflight
1. 预检
Establish that publishing is even possible, and say which of these failed rather than installing a workflow that will go red on its first run:
sh
gh repo view --json nameWithOwner,visibility,hasWikiEnabled
git ls-remote "$(gh repo view --json url -q .url).wiki.git" 2>&1 | head -1| State | Do this |
|---|---|
| Wiki feature disabled | Stop. It's a repo setting (Settings → Features → Wikis); name the path and let the user flip it. |
Wiki enabled but never initialized — | Stop before writing the workflow. Tell the user to open the wiki tab and save any page (the action's own docs call this the "dummy page"), then re-run. Do not install a workflow that is guaranteed to fail. |
| Wiki already has pages wikikit didn't write | This is the dangerous case. Those pages will be destroyed by the first sync. Offer the rescue below before anything else, and get an explicit yes on the destruction. |
No | Print the workflow for the user to add by hand, and name the preflight checks they should run themselves. Never claim a wiki state you couldn't read. |
The rescue for existing wiki content — pull it into the repo first, so the mirror doesn't eat it:
sh
git clone "$(gh repo view --json url -q .url).wiki.git" /tmp/wiki-rescueAnything worth keeping becomes a page in the doc set (mapped in the manifest as , no stamp — a human wrote it). Anything not worth keeping is confirmed as deliberate loss. Only then continue.
adopted: true确认发布是否可行,若失败需说明原因,避免安装首次运行就失败的工作流:
sh
gh repo view --json nameWithOwner,visibility,hasWikiEnabled
git ls-remote "$(gh repo view --json url -q .url).wiki.git" 2>&1 | head -1| 状态 | 处理方式 |
|---|---|
| Wiki功能已禁用 | 停止操作。这是仓库设置(Settings → Features → Wikis);告知用户路径,让用户自行开启。 |
Wiki已启用但未初始化—— | 在编写工作流前停止操作。告知用户打开Wiki标签页并保存任意页面(工作流文档称其为“占位页面”),然后重新运行。切勿安装必然失败的工作流。 |
| Wiki已有wikikit未编写的页面 | 这是危险场景。这些页面会在首次同步时被销毁。在执行任何操作前提供以下补救方案,并获得用户明确同意销毁这些页面。 |
无 | 打印工作流内容供用户手动添加,并告知用户应自行执行的预检检查。切勿声称无法确认的Wiki状态。 |
现有Wiki内容的补救方案——先将其拉取到仓库,避免镜像操作删除内容:
sh
git clone "$(gh repo view --json url -q .url).wiki.git" /tmp/wiki-rescue值得保留的内容会成为文档集中的页面(在清单中映射为,无标记——由人工编写)。不值得保留的内容需确认是故意丢弃。之后才能继续操作。
adopted: true2. Scan for page-name collisions
2. 扫描页面名称冲突
Flatten every page path in the doc set to its wiki page name — path separators become , becomes — and check for duplicates before installing anything:
-index.mdHomedocs/wiki/index.md → Home
docs/wiki/getting-started.md → getting-started
docs/wiki/how-to/deploy-to-staging.md → how-to-deploy-to-staging
docs/wiki/runbooks/rollback.md → runbooks-rollbackFlattening makes a collision nearly impossible, since the source paths are already unique — but it isn't a proof ( and both flatten to ). Report any collision and stop. Renaming a source page is the fix, and that's the user's call, not a silent tiebreak.
how-to/deploy.mdhow/to-deploy.mdhow-to-deploy将文档集中的每个页面路径扁平化为Wiki页面名称——路径分隔符变为,变为——并在安装前检查是否有重复:
-index.mdHomedocs/wiki/index.md → Home
docs/wiki/getting-started.md → getting-started
docs/wiki/how-to/deploy-to-staging.md → how-to-deploy-to-staging
docs/wiki/runbooks/rollback.md → runbooks-rollback扁平化几乎可以避免冲突,因为源路径已经是唯一的——但并非绝对(和都会扁平化为)。报告任何冲突并停止操作。修复方法是重命名源页面,这由用户决定,而非自动解决冲突。
how-to/deploy.mdhow/to-deploy.mdhow-to-deploy3. Write the workflow, on consent
3. 获得同意后编写工作流
Show the file, name its path, and write it only on a yes. Default target ; adapt to the doc home the ladder actually resolved, and the branch to the repo's real default.
.github/workflows/publish-wiki.ymldocs/wikiyaml
name: Publish wiki
on:
push:
branches: [main]
paths:
- 'docs/wiki/**'
- '.github/workflows/publish-wiki.yml'
workflow_dispatch:
permissions:
contents: write
concurrency:
group: publish-wiki
cancel-in-progress: false
jobs:
publish-wiki:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
# The wiki page namespace is flat: docs/wiki/how-to/deploy.md and
# docs/wiki/runbooks/deploy.md would both land on /wiki/deploy. Flatten
# each path into a unique page name and rewrite in-repo links to match.
- name: Flatten the doc set into wiki page names
run: |
set -euo pipefail
src=docs/wiki
out=.wiki-build
mkdir -p "$out"
find "$out" -mindepth 1 -delete # scoped to the staging dir only
find "$src" -name '*.md' -type f | while read -r f; do
rel="${f#"$src"/}"
page="${rel%.md}"
flat="${page//\//-}"
if [ "$page" = "index" ]; then flat="Home"; fi
dir="$(dirname "$rel")"
if [ "$dir" = "." ]; then dir=""; fi
# [Deploy](how-to/deploy.md) -> [Deploy](how-to-deploy), resolving
# ../ against the page's own directory first. Anchors are kept;
# absolute URLs and links to non-page files are left alone.
WIKI_DIR="$dir" perl -pe '
s{\]\(([^):#]+?)\.md(#[^)]*)?\)}{
my ($p, $anchor) = ($1, $2 // "");
$p = "$ENV{WIKI_DIR}/$p" if $ENV{WIKI_DIR} ne "";
$p =~ s{^\./}{};
$p =~ s{/\./}{/}g;
1 while $p =~ s{[^/]+/\.\./}{};
$p = ($p eq "index") ? "Home" : do { $p =~ s{/}{-}g; $p };
"]($p$anchor)"
}ge
' "$f" > "$out/$flat.md"
done
- uses: Andrew-Chen-Wang/github-wiki-action@v5
with:
path: .wiki-build
# The flatten step above owns page naming and link rewriting, so the
# action's own preprocessing would fight it.
preprocess: false
disable-empty-commits: true
# Start safe: prints what it would push without touching the wiki.
# Flip to false once the first run's output looks right.
dry-run: trueFour choices in there are load-bearing, so don't quietly drop them:
- on install. The first run is a rehearsal. A destructive force-push should never be something the user discovers happening. Say clearly that publishing is not live until they flip it.
dry-run: true - . The action's own link rewriting assumes wiki paths mirror source paths, which is exactly what the flatten step breaks. One owner for the transformation.
preprocess: false - without
concurrency— two force-pushes racing on one wiki repo is how a sync lands half-applied.cancel-in-progress - , and nothing else. The built-in
permissions: contents: writeis enough; a wiki sync never needs a PAT, and being asked for one is a signal something is wrong.GITHUB_TOKEN
Pinning follows the action's documented usage. For a repo that pins actions to commit SHAs, match that convention instead and say you did.
@v5显示文件内容,说明其路径,仅在用户同意后写入。默认路径为;根据检测流程确定的文档主目录调整,根据仓库实际默认分支调整分支。
.github/workflows/publish-wiki.ymldocs/wikiyaml
name: Publish wiki
on:
push:
branches: [main]
paths:
- 'docs/wiki/**'
- '.github/workflows/publish-wiki.yml'
workflow_dispatch:
permissions:
contents: write
concurrency:
group: publish-wiki
cancel-in-progress: false
jobs:
publish-wiki:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
# The wiki page namespace is flat: docs/wiki/how-to/deploy.md and
# docs/wiki/runbooks/deploy.md would both land on /wiki/deploy. Flatten
# each path into a unique page name and rewrite in-repo links to match.
- name: Flatten the doc set into wiki page names
run: |
set -euo pipefail
src=docs/wiki
out=.wiki-build
mkdir -p "$out"
find "$out" -mindepth 1 -delete # scoped to the staging dir only
find "$src" -name '*.md' -type f | while read -r f; do
rel="${f#"$src"/}"
page="${rel%.md}"
flat="${page//\//-}"
if [ "$page" = "index" ]; then flat="Home"; fi
dir="$(dirname "$rel")"
if [ "$dir" = "." ]; then dir=""; fi
# [Deploy](how-to/deploy.md) -> [Deploy](how-to-deploy), resolving
# ../ against the page's own directory first. Anchors are kept;
# absolute URLs and links to non-page files are left alone.
WIKI_DIR="$dir" perl -pe '
s{\]\(([^):#]+?)\.md(#[^)]*)?\)}{
my ($p, $anchor) = ($1, $2 // "");
$p = "$ENV{WIKI_DIR}/$p" if $ENV{WIKI_DIR} ne "";
$p =~ s{^\./}{};
$p =~ s{/\./}{/}g;
1 while $p =~ s{[^/]+/\.\./}{};
$p = ($p eq "index") ? "Home" : do { $p =~ s{/}{-}g; $p };
"]($p$anchor)"
}ge
' "$f" > "$out/$flat.md"
done
- uses: Andrew-Chen-Wang/github-wiki-action@v5
with:
path: .wiki-build
# The flatten step above owns page naming and link rewriting, so the
# action's own preprocessing would fight it.
preprocess: false
disable-empty-commits: true
# Start safe: prints what it would push without touching the wiki.
# Flip to false once the first run's output looks right.
dry-run: true其中四个选择至关重要,请勿随意修改:
- 安装时。首次运行是演练。破坏性的强制推送绝不应是用户意外发现的操作。明确说明在用户将其改为
dry-run: true之前,发布不会生效。false - 。工作流自身的链接重写假设Wiki路径与源路径一致,而扁平化步骤正好打破了这一点。转换操作应由单一模块负责。
preprocess: false - 不设置
concurrency——两个强制推送在同一个Wiki仓库中竞争会导致同步仅部分生效。cancel-in-progress - ,无需其他权限。内置的
permissions: contents: write已足够;Wiki同步永远不需要PAT,若被要求提供PAT则说明存在问题。GITHUB_TOKEN
固定使用遵循工作流的文档化用法。对于将工作流固定到提交SHA的仓库,需匹配该约定并说明。
@v54. Hand off
4. 交接
What changed — the workflow written (or the preflight gate that stopped you), whether existing wiki pages were rescued or knowingly abandoned, and any collisions found.
Where it landed — the workflow path, the doc home it syncs, the branch that triggers it, and — stated plainly — that it is in dry-run, so nothing has been published yet.
Next — push the workflow and run it once from the Actions tab () to read the dry-run output. If it looks right, flip to ; that's the commit that makes the wiki live. Commit with commitkit when installed, otherwise and commit. If the preflight stopped you, the crowned move is the thing that unblocks it — creating the first wiki page by hand, or enabling the wiki feature.
workflow_dispatchdry-runfalsegit add变更内容——编写的工作流(或阻止操作的预检环节)、现有Wiki页面是否被补救或故意丢弃、发现的冲突。
存储位置——工作流路径、同步的文档主目录、触发同步的分支,以及明确说明工作流处于dry-run模式,因此尚未发布任何内容。
下一步——推送工作流并从Actions标签页手动运行一次(),查看dry-run输出。若结果正确,将改为;此提交会使Wiki正式生效。已安装commitkit时使用它提交;否则使用和commit。若预检环节阻止了操作,首要任务是解决阻塞问题——手动创建第一个Wiki页面,或启用Wiki功能。
workflow_dispatchdry-runfalsegit addWriting standards
编写标准
The rules that separate documentation from generated filler, stated as bans:
- No restating the code. A page that narrates what a function does line by line is worse than the function.
- No documenting the aspirational. If it isn't in the repo, it isn't in the docs.
- No unmixed modes. A how-to answers one goal and does not explain the architecture; an explanation does not become a tutorial halfway down.
- No ceremonial preamble. "This document provides an overview of…" — cut it. Start at the first useful sentence.
- Every command copy-pasteable and verified. Real flags, real paths, real names.
- Task-shaped how-to titles — "Deploy to staging", not "Deployment".
For general AI-writing tells — em-dash overuse, rule-of-three cadence, hedging, promotional puffery — offer a humankit pass when it's installed. wikikit does not re-carry that list.
区分真实文档与生成式填充内容的规则,以禁令形式呈现:
- 不要复述代码。逐行叙述函数功能的页面比函数本身更糟糕。
- 不要文档化预期内容。不在仓库中的内容,不会出现在文档中。
- 不要混合模式。操作指南应回答一个目标,不应混入架构说明;说明内容不应中途变成教程。
- 不要添加仪式性开场白。“本文档概述了……”——删掉。从第一个有用的句子开始。
- 每个命令都可复制粘贴并经过验证。真实的标志、真实的路径、真实的名称。
- 操作指南标题以任务为导向——“部署到预发布环境”,而非“部署”。
对于通用AI写作特征——过度使用破折号、三段式节奏、含糊其辞、宣传性文字——已安装humankit时可提供人工优化环节。wikikit不会重复列出这些特征。
Notes
注意事项
- GitHub Wiki publishing is opt-in and fenced, not a default. exists, and nothing routes into it: the loop never suggests it, and a request has to name the wiki to reach it. The fence is there because the mirror is destructive and one-way — the wiki's edit button keeps working and every edit made through it dies at the next sync. A repo that treats its wiki as a place people write should not install this; a repo that treats it as a rendered view of
publishshould.docs/wiki/ - The wiki is downstream, always. wikikit never reads the wiki as a source of truth, never round-trips edits back into the repo automatically, and never runs against it. If the wiki and the doc set disagree, the doc set is right by definition.
audit - Consent, by operation. The map, new pages, deletions, the README markers, a doc-home migration, and the probe run all ask. Edits to existing pages in
initdo not — they're bounded by the restraint rule and land in a reviewable diff.updateasks for nothing except probes, because it changes nothing.audit - No mutating execution, ever. The probe allowlist is fixed and side-effect-free. wikikit never installs, builds, migrates, or deploys to verify a claim — an unverifiable claim is reported as unverified, not tested into existence.
- No doc-site scaffolding. wikikit writes content and updates nav for an engine that already exists. It never adds one.
- No marketing copy, no translation. Landing pages, feature blurbs, changelogs, and localization are all out.
- Existing project convention wins. A repo with its own docs location, page naming, or engine layout gets followed, not overridden — and wikikit says which convention it followed.
- No filesystem (e.g. a browser-based agent)? Print each page as a fenced block labeled with its path, print the manifest the same way, and name the probes the user should run themselves. Never report a page written that you could not write.
- GitHub Wiki发布是可选且受限制的,并非默认功能。模式存在,但不会被其他模式触发:流程不会主动建议它,只有请求明确提到Wiki时才会触发。限制存在是因为镜像是破坏性且单向的——Wiki的编辑按钮仍然可用,但通过它进行的所有编辑都会在下次同步时被删除。将Wiki视为用户编写内容的仓库不应安装此模式;将Wiki视为
publish渲染视图的仓库可以安装。docs/wiki/ - Wiki始终是下游。wikikit从不将Wiki作为事实来源,从不自动将Wiki编辑同步回仓库,也从不针对Wiki运行模式。若Wiki与文档集不一致,文档集默认是正确的。
audit - 通过操作获得同意。模式的映射方案、新页面、页面删除、README标记、文档主目录迁移和探测操作都需要询问用户。
init模式下对现有页面的编辑不需要——它们受约束规则限制,会生成可评审的差异。update模式除探测操作外不需要任何同意,因为它不会变更任何内容。audit - 绝不执行有副作用的操作。探测白名单是固定且无副作用的。wikikit从不通过安装、构建、迁移或部署来验证声明——无法验证的声明会被报告为未验证,而非通过测试使其“存在”。
- 不生成文档站点脚手架。wikikit为已存在的引擎编写内容并更新导航,绝不会新增引擎。
- 不生成营销文案或翻译内容。着陆页、功能介绍、变更日志和本地化都不在范围内。
- 现有项目约定优先。有自己文档位置、页面命名或引擎布局的仓库会遵循其约定,不会被覆盖——wikikit会说明遵循的约定。
- 无文件系统权限(如基于浏览器的代理)?将每个页面打印为带路径标签的代码块,清单也按此方式打印,并告知用户应自行执行的探测操作。绝不要报告已写入实际上无法写入的页面。