@erclx/canon 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (643) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +129 -0
  3. package/claude/.claude-plugin/plugin.json +19 -0
  4. package/claude/skills/bash-cli-script/REQUIREMENT.md +42 -0
  5. package/claude/skills/bash-cli-script/SKILL.md +48 -0
  6. package/claude/skills/bash-cli-script/references/template.md +43 -0
  7. package/claude/skills/bash-script/REQUIREMENT.md +36 -0
  8. package/claude/skills/bash-script/SKILL.md +100 -0
  9. package/claude/skills/bash-script/references/patterns.md +349 -0
  10. package/claude/skills/canon-cli/REQUIREMENT.md +41 -0
  11. package/claude/skills/canon-cli/SKILL.md +103 -0
  12. package/claude/skills/canon-feedback-file/REQUIREMENT.md +40 -0
  13. package/claude/skills/canon-feedback-file/SKILL.md +80 -0
  14. package/claude/skills/canon-feedback-triage/REQUIREMENT.md +40 -0
  15. package/claude/skills/canon-feedback-triage/SKILL.md +63 -0
  16. package/claude/skills/canon-operator/REQUIREMENT.md +61 -0
  17. package/claude/skills/canon-operator/SKILL.md +108 -0
  18. package/claude/skills/canon-rollout/REQUIREMENT.md +59 -0
  19. package/claude/skills/canon-rollout/SKILL.md +147 -0
  20. package/claude/skills/canon-screencast/REQUIREMENT.md +39 -0
  21. package/claude/skills/canon-screencast/SKILL.md +167 -0
  22. package/claude/skills/canon-slides-draft/REQUIREMENT.md +39 -0
  23. package/claude/skills/canon-slides-draft/SKILL.md +62 -0
  24. package/claude/skills/ci-workflow/REQUIREMENT.md +40 -0
  25. package/claude/skills/ci-workflow/SKILL.md +65 -0
  26. package/claude/skills/ci-workflow/references/workflows.md +98 -0
  27. package/claude/skills/claude-address-review/REQUIREMENT.md +57 -0
  28. package/claude/skills/claude-address-review/SKILL.md +212 -0
  29. package/claude/skills/claude-address-review/references/rebase-conflicts.md +39 -0
  30. package/claude/skills/claude-autoship/REQUIREMENT.md +50 -0
  31. package/claude/skills/claude-autoship/SKILL.md +207 -0
  32. package/claude/skills/claude-design-extract/REQUIREMENT.md +42 -0
  33. package/claude/skills/claude-design-extract/SKILL.md +102 -0
  34. package/claude/skills/claude-diagram/REQUIREMENT.md +45 -0
  35. package/claude/skills/claude-diagram/SKILL.md +177 -0
  36. package/claude/skills/claude-docs/REQUIREMENT.md +60 -0
  37. package/claude/skills/claude-docs/SKILL.md +287 -0
  38. package/claude/skills/claude-docs/references/anchor-sweep.md +58 -0
  39. package/claude/skills/claude-docs/references/wireframe-sweep.md +45 -0
  40. package/claude/skills/claude-feature/REQUIREMENT.md +36 -0
  41. package/claude/skills/claude-feature/SKILL.md +115 -0
  42. package/claude/skills/claude-groundwork/REQUIREMENT.md +48 -0
  43. package/claude/skills/claude-groundwork/SKILL.md +142 -0
  44. package/claude/skills/claude-intake/REQUIREMENT.md +49 -0
  45. package/claude/skills/claude-intake/SKILL.md +114 -0
  46. package/claude/skills/claude-intake-answer/REQUIREMENT.md +48 -0
  47. package/claude/skills/claude-intake-answer/SKILL.md +90 -0
  48. package/claude/skills/claude-markdown-propose/REQUIREMENT.md +48 -0
  49. package/claude/skills/claude-markdown-propose/SKILL.md +118 -0
  50. package/claude/skills/claude-markdown-propose/references/format.md +107 -0
  51. package/claude/skills/claude-memory-capture/REQUIREMENT.md +50 -0
  52. package/claude/skills/claude-memory-capture/SKILL.md +101 -0
  53. package/claude/skills/claude-memory-review/REQUIREMENT.md +50 -0
  54. package/claude/skills/claude-memory-review/SKILL.md +210 -0
  55. package/claude/skills/claude-memory-review/references/receipt-format.md +48 -0
  56. package/claude/skills/claude-orchestrate/REQUIREMENT.md +121 -0
  57. package/claude/skills/claude-orchestrate/SKILL.md +241 -0
  58. package/claude/skills/claude-orchestrate/references/orchestrator-dispatch.md +132 -0
  59. package/claude/skills/claude-orchestrate/references/orchestrator-handoff.md +32 -0
  60. package/claude/skills/claude-orchestrate/references/orchestrator-parked.md +72 -0
  61. package/claude/skills/claude-orchestrate/references/orchestrator-poll.md +87 -0
  62. package/claude/skills/claude-orchestrate/references/orchestrator-resume.md +30 -0
  63. package/claude/skills/claude-orchestrate/references/orchestrator-sweep.md +21 -0
  64. package/claude/skills/claude-orchestrate/scripts/poll.sh +373 -0
  65. package/claude/skills/claude-orchestrate/scripts/watch.sh +181 -0
  66. package/claude/skills/claude-pr-review/REQUIREMENT.md +47 -0
  67. package/claude/skills/claude-pr-review/SKILL.md +295 -0
  68. package/claude/skills/claude-review/REQUIREMENT.md +39 -0
  69. package/claude/skills/claude-review/SKILL.md +142 -0
  70. package/claude/skills/claude-seed-sync/REQUIREMENT.md +45 -0
  71. package/claude/skills/claude-seed-sync/SKILL.md +156 -0
  72. package/claude/skills/claude-standards-audit/REQUIREMENT.md +33 -0
  73. package/claude/skills/claude-standards-audit/SKILL.md +99 -0
  74. package/claude/skills/claude-tasks/REQUIREMENT.md +43 -0
  75. package/claude/skills/claude-tasks/SKILL.md +161 -0
  76. package/claude/skills/claude-teach/REQUIREMENT.md +56 -0
  77. package/claude/skills/claude-teach/SKILL.md +196 -0
  78. package/claude/skills/claude-teach/references/lesson-craft.md +59 -0
  79. package/claude/skills/claude-teach/references/pedagogy.md +67 -0
  80. package/claude/skills/claude-teach/references/promotion.md +54 -0
  81. package/claude/skills/claude-ui-test/REQUIREMENT.md +40 -0
  82. package/claude/skills/claude-ui-test/SKILL.md +77 -0
  83. package/claude/skills/claude-ux-audit/REQUIREMENT.md +40 -0
  84. package/claude/skills/claude-ux-audit/SKILL.md +79 -0
  85. package/claude/skills/claude-ux-measure/REQUIREMENT.md +48 -0
  86. package/claude/skills/claude-ux-measure/SKILL.md +122 -0
  87. package/claude/skills/claude-worker/REQUIREMENT.md +54 -0
  88. package/claude/skills/claude-worker/SKILL.md +96 -0
  89. package/claude/skills/claude-worktree/REQUIREMENT.md +58 -0
  90. package/claude/skills/claude-worktree/SKILL.md +136 -0
  91. package/claude/skills/create-rule/REQUIREMENT.md +45 -0
  92. package/claude/skills/create-rule/SKILL.md +68 -0
  93. package/claude/skills/create-skill/REQUIREMENT.md +38 -0
  94. package/claude/skills/create-skill/SKILL.md +32 -0
  95. package/claude/skills/create-snippet/REQUIREMENT.md +39 -0
  96. package/claude/skills/create-snippet/SKILL.md +30 -0
  97. package/claude/skills/create-standard/REQUIREMENT.md +35 -0
  98. package/claude/skills/create-standard/SKILL.md +29 -0
  99. package/claude/skills/decision-escalate/REQUIREMENT.md +45 -0
  100. package/claude/skills/decision-escalate/SKILL.md +79 -0
  101. package/claude/skills/docs-sync/REQUIREMENT.md +41 -0
  102. package/claude/skills/docs-sync/SKILL.md +95 -0
  103. package/claude/skills/git-branch/REQUIREMENT.md +38 -0
  104. package/claude/skills/git-branch/SKILL.md +60 -0
  105. package/claude/skills/git-commit/REQUIREMENT.md +36 -0
  106. package/claude/skills/git-commit/SKILL.md +49 -0
  107. package/claude/skills/git-followup/REQUIREMENT.md +43 -0
  108. package/claude/skills/git-followup/SKILL.md +48 -0
  109. package/claude/skills/git-issue/REQUIREMENT.md +38 -0
  110. package/claude/skills/git-issue/SKILL.md +65 -0
  111. package/claude/skills/git-pr/REQUIREMENT.md +50 -0
  112. package/claude/skills/git-pr/SKILL.md +164 -0
  113. package/claude/skills/git-pr/references/labels.md +95 -0
  114. package/claude/skills/git-ship/REQUIREMENT.md +42 -0
  115. package/claude/skills/git-ship/SKILL.md +55 -0
  116. package/claude/skills/git-split/REQUIREMENT.md +39 -0
  117. package/claude/skills/git-split/SKILL.md +162 -0
  118. package/claude/skills/git-stage/REQUIREMENT.md +39 -0
  119. package/claude/skills/git-stage/SKILL.md +73 -0
  120. package/claude/skills/git-worktree/REQUIREMENT.md +38 -0
  121. package/claude/skills/git-worktree/SKILL.md +130 -0
  122. package/claude/skills/migration-claude-md/REQUIREMENT.md +40 -0
  123. package/claude/skills/migration-claude-md/SKILL.md +76 -0
  124. package/claude/skills/migration-context/REQUIREMENT.md +36 -0
  125. package/claude/skills/migration-context/SKILL.md +95 -0
  126. package/claude/skills/migration-standards-drop/REQUIREMENT.md +55 -0
  127. package/claude/skills/migration-standards-drop/SKILL.md +113 -0
  128. package/claude/skills/migration-superseded/REQUIREMENT.md +44 -0
  129. package/claude/skills/migration-superseded/SKILL.md +115 -0
  130. package/claude/skills/project-commands/REQUIREMENT.md +42 -0
  131. package/claude/skills/project-commands/SKILL.md +85 -0
  132. package/claude/skills/restate-plainly/REQUIREMENT.md +41 -0
  133. package/claude/skills/restate-plainly/SKILL.md +39 -0
  134. package/claude/skills/session-map/REQUIREMENT.md +57 -0
  135. package/claude/skills/session-map/SKILL.md +70 -0
  136. package/claude/skills/session-resume/REQUIREMENT.md +49 -0
  137. package/claude/skills/session-resume/SKILL.md +51 -0
  138. package/claude/skills/setup-gov/REQUIREMENT.md +37 -0
  139. package/claude/skills/setup-gov/SKILL.md +77 -0
  140. package/claude/skills/setup-indexes/REQUIREMENT.md +45 -0
  141. package/claude/skills/setup-indexes/SKILL.md +153 -0
  142. package/claude/skills/setup-init/REQUIREMENT.md +45 -0
  143. package/claude/skills/setup-init/SKILL.md +127 -0
  144. package/claude/skills/setup-plugins/REQUIREMENT.md +42 -0
  145. package/claude/skills/setup-plugins/SKILL.md +81 -0
  146. package/claude/skills/setup-plugins/references/plugin-catalog.md +53 -0
  147. package/claude/skills/setup-verify/REQUIREMENT.md +39 -0
  148. package/claude/skills/setup-verify/SKILL.md +51 -0
  149. package/claude/skills/systematic-debugging/REQUIREMENT.md +41 -0
  150. package/claude/skills/systematic-debugging/SKILL.md +70 -0
  151. package/claude/skills/write-human/REQUIREMENT.md +46 -0
  152. package/claude/skills/write-human/SKILL.md +68 -0
  153. package/claude/skills/write-human/references/density.md +38 -0
  154. package/claude/skills/write-human/references/machine-tells.md +107 -0
  155. package/claude/skills/write-human/references/source-material.md +37 -0
  156. package/claude/skills/youtube-transcripts/REQUIREMENT.md +38 -0
  157. package/claude/skills/youtube-transcripts/SKILL.md +34 -0
  158. package/docs/agents/audits.md +98 -0
  159. package/docs/agents/capture.md +37 -0
  160. package/docs/agents/census.md +23 -0
  161. package/docs/agents/commands.md +146 -0
  162. package/docs/agents/comments.md +34 -0
  163. package/docs/agents/context-audit-checks.md +120 -0
  164. package/docs/agents/context-audit.md +83 -0
  165. package/docs/agents/counts.md +76 -0
  166. package/docs/agents/demo.md +86 -0
  167. package/docs/agents/docs.md +17 -0
  168. package/docs/agents/gate.md +84 -0
  169. package/docs/agents/index.md +47 -0
  170. package/docs/agents/indexes.md +35 -0
  171. package/docs/agents/install-and-sync.md +385 -0
  172. package/docs/agents/intake.md +81 -0
  173. package/docs/agents/key-changes.md +103 -0
  174. package/docs/agents/label-coverage.md +73 -0
  175. package/docs/agents/markdown-audit.md +197 -0
  176. package/docs/agents/output-shape.md +70 -0
  177. package/docs/agents/overview.md +26 -0
  178. package/docs/agents/records.md +170 -0
  179. package/docs/agents/restated.md +81 -0
  180. package/docs/agents/review-classification.md +77 -0
  181. package/docs/agents/routing.md +61 -0
  182. package/docs/agents/rule-citations.md +98 -0
  183. package/docs/agents/sandbox.md +71 -0
  184. package/docs/agents/scripting.md +149 -0
  185. package/docs/agents/sessions.md +120 -0
  186. package/docs/agents/skills-audit.md +94 -0
  187. package/docs/agents/skills-reach.md +64 -0
  188. package/docs/agents/standards-audit.md +38 -0
  189. package/docs/agents/state-scoped-risk.md +105 -0
  190. package/docs/agents/superseded.md +85 -0
  191. package/docs/agents/targets.md +83 -0
  192. package/docs/agents/tasks.md +200 -0
  193. package/docs/agents/teach.md +158 -0
  194. package/docs/agents/test-order.md +56 -0
  195. package/docs/agents/worktrees.md +62 -0
  196. package/docs/ai-workflow.md +317 -0
  197. package/docs/index.md +23 -0
  198. package/docs/operating-model.md +223 -0
  199. package/docs/target-projects.md +258 -0
  200. package/docs/visual-design-workflow.md +151 -0
  201. package/docs/zshrc-aliases.md +65 -0
  202. package/governance/rules/ci/700-ci-workflow.md +44 -0
  203. package/governance/rules/claude/500-prose.md +15 -0
  204. package/governance/rules/claude/501-markdown.md +14 -0
  205. package/governance/rules/claude/510-context.md +28 -0
  206. package/governance/rules/claude/511-indexes.md +14 -0
  207. package/governance/rules/claude/520-wireframes.md +12 -0
  208. package/governance/rules/claude/530-requirements.md +11 -0
  209. package/governance/rules/claude/540-architecture.md +11 -0
  210. package/governance/rules/claude/550-design.md +11 -0
  211. package/governance/rules/claude/555-tasks.md +12 -0
  212. package/governance/rules/claude/556-groundwork.md +11 -0
  213. package/governance/rules/claude/557-intake.md +11 -0
  214. package/governance/rules/claude/558-plan.md +22 -0
  215. package/governance/rules/claude/559-memory.md +11 -0
  216. package/governance/rules/claude/560-diagrams.md +18 -0
  217. package/governance/rules/claude/561-teach.md +13 -0
  218. package/governance/rules/claude/562-session.md +15 -0
  219. package/governance/rules/claude/570-skill.md +24 -0
  220. package/governance/rules/claude/575-hooks.md +17 -0
  221. package/governance/rules/claude/576-settings.md +14 -0
  222. package/governance/rules/claude/580-readme.md +11 -0
  223. package/governance/rules/claude/590-rule-authoring.md +12 -0
  224. package/governance/rules/claude/591-standard-authoring.md +12 -0
  225. package/governance/rules/claude/592-claude-md.md +19 -0
  226. package/governance/rules/core/000-constitution.md +30 -0
  227. package/governance/rules/core/005-behavior.md +27 -0
  228. package/governance/rules/core/010-testing.md +35 -0
  229. package/governance/rules/core/015-output.md +20 -0
  230. package/governance/rules/core/020-concurrency.md +22 -0
  231. package/governance/rules/core/025-indexes.md +9 -0
  232. package/governance/rules/core/030-error-handling.md +31 -0
  233. package/governance/rules/core/035-tasks.md +13 -0
  234. package/governance/rules/core/040-performance.md +20 -0
  235. package/governance/rules/core/045-memory.md +12 -0
  236. package/governance/rules/core/050-logging.md +20 -0
  237. package/governance/rules/core/055-scratch.md +9 -0
  238. package/governance/rules/core/060-naming.md +19 -0
  239. package/governance/rules/core/065-spelling.md +19 -0
  240. package/governance/rules/core/070-planning.md +18 -0
  241. package/governance/rules/core/075-dependencies.md +25 -0
  242. package/governance/rules/core/080-config-comments.md +22 -0
  243. package/governance/rules/core/085-worktrees.md +17 -0
  244. package/governance/rules/core/087-git.md +11 -0
  245. package/governance/rules/core/090-code-comments.md +39 -0
  246. package/governance/rules/framework/200-react.md +51 -0
  247. package/governance/rules/framework/210-astro.md +41 -0
  248. package/governance/rules/framework/220-fastapi.md +43 -0
  249. package/governance/rules/framework/230-nextjs.md +48 -0
  250. package/governance/rules/framework/250-tailwind.md +32 -0
  251. package/governance/rules/framework/260-shadcn.md +34 -0
  252. package/governance/rules/lang/100-typescript.md +40 -0
  253. package/governance/rules/lang/110-python.md +42 -0
  254. package/governance/rules/lang/120-bash.md +19 -0
  255. package/governance/rules/lib/300-testing-ts.md +39 -0
  256. package/governance/rules/lib/305-e2e-reliability.md +34 -0
  257. package/governance/rules/lib/306-test-scope.md +25 -0
  258. package/governance/rules/lib/310-zod.md +25 -0
  259. package/governance/rules/lib/320-tanstack-query.md +32 -0
  260. package/governance/rules/lib/330-testing-py.md +44 -0
  261. package/governance/rules/lib/340-pydantic.md +38 -0
  262. package/governance/rules/lib/350-security-web.md +32 -0
  263. package/governance/rules/lib/360-security-server.md +39 -0
  264. package/governance/rules/lib/370-database.md +35 -0
  265. package/governance/rules/snippets/505-at-references.md +9 -0
  266. package/governance/rules/ui/400-ui.md +36 -0
  267. package/governance/rules/ui/410-a11y.md +48 -0
  268. package/governance/rules/ui/420-forms.md +36 -0
  269. package/governance/rules/ui/430-ux-completeness.md +65 -0
  270. package/governance/rules/ui/440-surface-capture.md +34 -0
  271. package/governance/rules/ui/450-link-behavior.md +19 -0
  272. package/governance/stacks/astro.toml +2 -0
  273. package/governance/stacks/base.toml +8 -0
  274. package/governance/stacks/node-server.toml +2 -0
  275. package/governance/stacks/node.toml +2 -0
  276. package/governance/stacks/python-fastapi.toml +2 -0
  277. package/governance/stacks/python.toml +2 -0
  278. package/governance/stacks/react.toml +2 -0
  279. package/package.json +69 -0
  280. package/scripts/config.sh +11 -0
  281. package/scripts/core/bootstrap.sh +81 -0
  282. package/scripts/core/check-color-source.sh +41 -0
  283. package/scripts/core/check-ignore-parity.sh +162 -0
  284. package/scripts/core/check-plugin-boundary.sh +45 -0
  285. package/scripts/core/check-seed-independence.sh +59 -0
  286. package/scripts/core/check-skill-paths.sh +24 -0
  287. package/scripts/core/clean.sh +36 -0
  288. package/scripts/core/install-check.sh +101 -0
  289. package/scripts/core/list-seed-roots.sh +18 -0
  290. package/scripts/core/regen-claude-copies.sh +10 -0
  291. package/scripts/core/regen-hero.sh +217 -0
  292. package/scripts/core/regen-indexes.sh +10 -0
  293. package/scripts/core/regen-tooling-paths.sh +61 -0
  294. package/scripts/core/repair-bare-flag.sh +19 -0
  295. package/scripts/core/snapshot.sh +134 -0
  296. package/scripts/core/update.sh +35 -0
  297. package/scripts/docs/list.sh +165 -0
  298. package/scripts/lib/frontmatter.sh +30 -0
  299. package/scripts/lib/gov.sh +14 -0
  300. package/scripts/lib/sandbox-fixtures.sh +191 -0
  301. package/scripts/lib/sandbox-git.sh +125 -0
  302. package/scripts/lib/sandbox-path.sh +206 -0
  303. package/scripts/lib/tooling.sh +35 -0
  304. package/scripts/lib/ui.sh +266 -0
  305. package/scripts/lib/worktree.sh +20 -0
  306. package/scripts/manage-sandbox.sh +466 -0
  307. package/scripts/snippets/create.sh +156 -0
  308. package/scripts/standards/list.sh +115 -0
  309. package/scripts/tooling/create.sh +109 -0
  310. package/scripts/tooling/verify.sh +179 -0
  311. package/snippets/align.md +12 -0
  312. package/snippets/claude/decision-memo.md +39 -0
  313. package/snippets/claude/feature-recap.md +19 -0
  314. package/snippets/claude/figma-steps.md +24 -0
  315. package/snippets/compact-summary.md +5 -0
  316. package/snippets/decision-help.md +6 -0
  317. package/snippets/meta-prompt.md +14 -0
  318. package/snippets/research-prompt.md +7 -0
  319. package/snippets/session-notes.md +11 -0
  320. package/snippets/snippets.toml +5 -0
  321. package/snippets/step-by-step.md +10 -0
  322. package/snippets/web-research.md +21 -0
  323. package/src/audits/baseline.ts +201 -0
  324. package/src/audits/catalog.ts +876 -0
  325. package/src/audits/run.ts +204 -0
  326. package/src/autoship/classify.ts +75 -0
  327. package/src/autoship/paths.ts +51 -0
  328. package/src/binary.ts +16 -0
  329. package/src/browser/engine.ts +40 -0
  330. package/src/census/count.ts +113 -0
  331. package/src/claude/cases/all.ts +24 -0
  332. package/src/claude/cases/authoring.ts +53 -0
  333. package/src/claude/cases/claude-workflow.ts +158 -0
  334. package/src/claude/cases/git.ts +44 -0
  335. package/src/claude/cases/misc.ts +27 -0
  336. package/src/claude/cases/setup.ts +94 -0
  337. package/src/claude/gitignore.ts +51 -0
  338. package/src/claude/routing.ts +283 -0
  339. package/src/claude/seeds-list.ts +47 -0
  340. package/src/claude/seeds.ts +150 -0
  341. package/src/claude/settings.ts +151 -0
  342. package/src/claude/skills-audit.ts +228 -0
  343. package/src/claude/skills-drift.ts +156 -0
  344. package/src/claude/skills-list.ts +99 -0
  345. package/src/claude/skills-rank.ts +320 -0
  346. package/src/claude/skills-reach.ts +227 -0
  347. package/src/cli-run.ts +43 -0
  348. package/src/cli.ts +200 -0
  349. package/src/commands/audits.ts +350 -0
  350. package/src/commands/autoship.ts +129 -0
  351. package/src/commands/capture.ts +133 -0
  352. package/src/commands/census.ts +105 -0
  353. package/src/commands/claude.ts +1286 -0
  354. package/src/commands/comments.ts +240 -0
  355. package/src/commands/context.ts +857 -0
  356. package/src/commands/demo.ts +389 -0
  357. package/src/commands/deps.ts +173 -0
  358. package/src/commands/design.ts +36 -0
  359. package/src/commands/docs.ts +60 -0
  360. package/src/commands/feedback-format.ts +23 -0
  361. package/src/commands/feedback.ts +112 -0
  362. package/src/commands/gate.ts +189 -0
  363. package/src/commands/gov.ts +1265 -0
  364. package/src/commands/indexes.ts +184 -0
  365. package/src/commands/init.ts +113 -0
  366. package/src/commands/intake.ts +406 -0
  367. package/src/commands/inventory.ts +256 -0
  368. package/src/commands/labels.ts +361 -0
  369. package/src/commands/markdown.ts +544 -0
  370. package/src/commands/migrate.ts +175 -0
  371. package/src/commands/pass-through.ts +39 -0
  372. package/src/commands/pr.ts +411 -0
  373. package/src/commands/records.ts +728 -0
  374. package/src/commands/sandbox.ts +468 -0
  375. package/src/commands/secrets.ts +132 -0
  376. package/src/commands/serve.ts +159 -0
  377. package/src/commands/sessions.ts +408 -0
  378. package/src/commands/slides.ts +126 -0
  379. package/src/commands/snippets.ts +84 -0
  380. package/src/commands/standards.ts +247 -0
  381. package/src/commands/sync.ts +428 -0
  382. package/src/commands/targets.ts +319 -0
  383. package/src/commands/tasks.ts +743 -0
  384. package/src/commands/teach.ts +786 -0
  385. package/src/commands/tooling.ts +573 -0
  386. package/src/commands/transcripts.ts +44 -0
  387. package/src/commands/upgrade.ts +231 -0
  388. package/src/commands/wiki.ts +100 -0
  389. package/src/commands/worktrees.ts +191 -0
  390. package/src/comments/scan.ts +338 -0
  391. package/src/comments/trend.ts +207 -0
  392. package/src/comments/vocabulary.ts +85 -0
  393. package/src/context/architecture.ts +364 -0
  394. package/src/context/audit.ts +790 -0
  395. package/src/context/citations.ts +196 -0
  396. package/src/context/folders.ts +186 -0
  397. package/src/context/gate.ts +57 -0
  398. package/src/context/index-drift.ts +64 -0
  399. package/src/context/narration.ts +99 -0
  400. package/src/copy.ts +30 -0
  401. package/src/counts/catalogs.ts +96 -0
  402. package/src/counts/numbers.ts +79 -0
  403. package/src/counts/scan.ts +314 -0
  404. package/src/demo/beats.ts +135 -0
  405. package/src/demo/compile.ts +326 -0
  406. package/src/demo/container.ts +63 -0
  407. package/src/demo/cursors.ts +55 -0
  408. package/src/demo/drive.ts +357 -0
  409. package/src/demo/pointer.ts +178 -0
  410. package/src/demo/theme.ts +112 -0
  411. package/src/deps/audit.ts +153 -0
  412. package/src/design/parse.ts +116 -0
  413. package/src/design/render.ts +249 -0
  414. package/src/docs/read.ts +77 -0
  415. package/src/exec.ts +16 -0
  416. package/src/exempt-marker.ts +43 -0
  417. package/src/frontmatter.ts +13 -0
  418. package/src/gate/measures.ts +682 -0
  419. package/src/gate/sequencer.ts +386 -0
  420. package/src/gate/stages.ts +412 -0
  421. package/src/git-env.ts +36 -0
  422. package/src/git-files.ts +105 -0
  423. package/src/git-ignore.ts +46 -0
  424. package/src/github-format.ts +13 -0
  425. package/src/github.ts +24 -0
  426. package/src/gov/adapter.ts +103 -0
  427. package/src/gov/citations.ts +514 -0
  428. package/src/gov/consumed.ts +129 -0
  429. package/src/gov/install.ts +132 -0
  430. package/src/gov/list.ts +106 -0
  431. package/src/gov/payload.ts +39 -0
  432. package/src/gov/restated.ts +814 -0
  433. package/src/gov/stacks.ts +205 -0
  434. package/src/gov/superseded.ts +415 -0
  435. package/src/gov/test-order.ts +407 -0
  436. package/src/indexes/frontmatter.ts +46 -0
  437. package/src/indexes/regen.ts +84 -0
  438. package/src/indexes/render.ts +201 -0
  439. package/src/indexes/walk.ts +83 -0
  440. package/src/init/flags.ts +60 -0
  441. package/src/init/plan.ts +114 -0
  442. package/src/init/run.ts +46 -0
  443. package/src/init/steps.ts +77 -0
  444. package/src/intake/folder.ts +320 -0
  445. package/src/intake/items.ts +174 -0
  446. package/src/inventory/config.ts +117 -0
  447. package/src/inventory/group.ts +76 -0
  448. package/src/inventory/subjects.ts +114 -0
  449. package/src/inventory/walk.ts +129 -0
  450. package/src/labels/audit.ts +82 -0
  451. package/src/labels/coverage.ts +79 -0
  452. package/src/labels/map.ts +101 -0
  453. package/src/labels/phase.ts +95 -0
  454. package/src/markdown/bans.ts +94 -0
  455. package/src/markdown/files.ts +102 -0
  456. package/src/markdown/gate.ts +28 -0
  457. package/src/markdown/scan.ts +295 -0
  458. package/src/markdown/structure.ts +730 -0
  459. package/src/migrate/apply.ts +115 -0
  460. package/src/migrate/plan.ts +103 -0
  461. package/src/migrate/rename.ts +183 -0
  462. package/src/pr/bijection.ts +145 -0
  463. package/src/pr/paths.ts +335 -0
  464. package/src/process/harness.ts +167 -0
  465. package/src/project-root.ts +19 -0
  466. package/src/records/backup.ts +455 -0
  467. package/src/records/migrate.ts +78 -0
  468. package/src/records/size.ts +260 -0
  469. package/src/records/validate.ts +1162 -0
  470. package/src/sandbox/census.ts +228 -0
  471. package/src/sandbox/coverage.ts +115 -0
  472. package/src/sandbox/expect.ts +629 -0
  473. package/src/sandbox/tree.ts +47 -0
  474. package/src/secrets/marker.ts +30 -0
  475. package/src/secrets/patterns.ts +142 -0
  476. package/src/secrets/scan.ts +123 -0
  477. package/src/secrets/shipped.ts +111 -0
  478. package/src/seed-marker.ts +74 -0
  479. package/src/serve/static.ts +322 -0
  480. package/src/sessions/claim.ts +85 -0
  481. package/src/sessions/live.ts +79 -0
  482. package/src/sessions/registry.ts +137 -0
  483. package/src/sessions/resolve.ts +333 -0
  484. package/src/slides/layouts.ts +391 -0
  485. package/src/slides/open.ts +18 -0
  486. package/src/slides/parse.ts +84 -0
  487. package/src/slides/render.ts +88 -0
  488. package/src/slides/styles.ts +44 -0
  489. package/src/snippets/categories.ts +66 -0
  490. package/src/snippets/list.ts +32 -0
  491. package/src/snippets/presets.ts +50 -0
  492. package/src/standards/audit.ts +132 -0
  493. package/src/standards/read.ts +100 -0
  494. package/src/sync/check.ts +692 -0
  495. package/src/sync/engine.ts +576 -0
  496. package/src/sync/git.ts +225 -0
  497. package/src/sync/history.ts +123 -0
  498. package/src/sync/layout.ts +140 -0
  499. package/src/sync/reverse.ts +268 -0
  500. package/src/sync/seeds-report.ts +126 -0
  501. package/src/sync/stamp.ts +358 -0
  502. package/src/sync/target.ts +70 -0
  503. package/src/sync/workflow.ts +200 -0
  504. package/src/target.ts +43 -0
  505. package/src/targets/pulls.ts +250 -0
  506. package/src/targets/registry.ts +203 -0
  507. package/src/targets/resolve.ts +145 -0
  508. package/src/targets/sweep.ts +246 -0
  509. package/src/tasks/archive.ts +506 -0
  510. package/src/tasks/record.ts +311 -0
  511. package/src/tasks/trunk.ts +89 -0
  512. package/src/tasks/validate.ts +1001 -0
  513. package/src/teach/lesson.ts +180 -0
  514. package/src/teach/workspace.ts +842 -0
  515. package/src/tooling/gitignore.ts +122 -0
  516. package/src/tooling/inject.ts +193 -0
  517. package/src/tooling/list.ts +39 -0
  518. package/src/tooling/manifest.ts +176 -0
  519. package/src/tooling/package.ts +166 -0
  520. package/src/tooling/read.ts +65 -0
  521. package/src/tooling/scan.ts +147 -0
  522. package/src/tooling/stamp.ts +44 -0
  523. package/src/transcripts/fetch.ts +156 -0
  524. package/src/transcripts/metadata.ts +54 -0
  525. package/src/transcripts/vtt.ts +114 -0
  526. package/src/ui.ts +266 -0
  527. package/src/version/compare.ts +53 -0
  528. package/src/version/installed.ts +40 -0
  529. package/src/version/manager.ts +67 -0
  530. package/src/version/skew.ts +192 -0
  531. package/src/wiki/init.ts +85 -0
  532. package/src/worktree.ts +143 -0
  533. package/src/worktrees/reclaim.ts +306 -0
  534. package/standards/architecture.md +72 -0
  535. package/standards/branch.md +59 -0
  536. package/standards/commit.md +72 -0
  537. package/standards/context.md +151 -0
  538. package/standards/design.md +93 -0
  539. package/standards/diagrams.md +152 -0
  540. package/standards/glossary.md +75 -0
  541. package/standards/groundwork.md +211 -0
  542. package/standards/index.md +36 -0
  543. package/standards/intake.md +192 -0
  544. package/standards/issue.md +94 -0
  545. package/standards/markdown.md +137 -0
  546. package/standards/memory.md +144 -0
  547. package/standards/plan.md +172 -0
  548. package/standards/pr.md +139 -0
  549. package/standards/publish.md +51 -0
  550. package/standards/readme.md +208 -0
  551. package/standards/requirements.md +70 -0
  552. package/standards/rule.md +118 -0
  553. package/standards/session.md +109 -0
  554. package/standards/skill.md +300 -0
  555. package/standards/slug.md +39 -0
  556. package/standards/snippets.md +76 -0
  557. package/standards/standard.md +170 -0
  558. package/standards/tasks.md +254 -0
  559. package/standards/teach.md +153 -0
  560. package/standards/versioning.md +71 -0
  561. package/standards/wireframes.md +113 -0
  562. package/tooling/astro/configs/astro.config.mjs +31 -0
  563. package/tooling/astro/configs/eslint.config.js +79 -0
  564. package/tooling/astro/configs/playwright.config.ts +26 -0
  565. package/tooling/astro/configs/tsconfig.json +12 -0
  566. package/tooling/astro/configs/vitest.config.ts +22 -0
  567. package/tooling/astro/manifest.toml +34 -0
  568. package/tooling/astro/reference.md +60 -0
  569. package/tooling/base/configs/.editorconfig +5 -0
  570. package/tooling/base/configs/.github/pull_request_template.md +18 -0
  571. package/tooling/base/configs/.github/workflows/verify.yml +35 -0
  572. package/tooling/base/configs/.husky/commit-msg +1 -0
  573. package/tooling/base/configs/.husky/post-merge +61 -0
  574. package/tooling/base/configs/.husky/post-rewrite +21 -0
  575. package/tooling/base/configs/.husky/pre-commit +1 -0
  576. package/tooling/base/configs/.husky/pre-push +1 -0
  577. package/tooling/base/configs/.prettierrc +12 -0
  578. package/tooling/base/configs/.shellcheckrc +1 -0
  579. package/tooling/base/configs/.vscode/extensions.json +9 -0
  580. package/tooling/base/configs/.vscode/settings.json +3 -0
  581. package/tooling/base/configs/commitlint.config.js +11 -0
  582. package/tooling/base/configs/scripts/verify.sh +64 -0
  583. package/tooling/base/manifest.toml +30 -0
  584. package/tooling/base/reference.md +98 -0
  585. package/tooling/base/seeds/.claude/context/ci.md +33 -0
  586. package/tooling/base/seeds/.claude/context/development.md +37 -0
  587. package/tooling/base/seeds/.claude/context/index.md +11 -0
  588. package/tooling/base/seeds/.cspell/project-terms.txt +0 -0
  589. package/tooling/base/seeds/.cspell/tech-stack.txt +19 -0
  590. package/tooling/base/seeds/.lintstagedrc +8 -0
  591. package/tooling/base/seeds/.prettierignore +0 -0
  592. package/tooling/base/seeds/cspell.json +20 -0
  593. package/tooling/claude/manifest.toml +14 -0
  594. package/tooling/claude/reference.md +79 -0
  595. package/tooling/claude/seeds/.claude/ARCHITECTURE.md +13 -0
  596. package/tooling/claude/seeds/.claude/DESIGN.md +62 -0
  597. package/tooling/claude/seeds/.claude/REQUIREMENTS.md +18 -0
  598. package/tooling/claude/seeds/.claude/diagrams/index.md +8 -0
  599. package/tooling/claude/seeds/.claude/hooks/index-reminder.sh +50 -0
  600. package/tooling/claude/seeds/.claude/hooks/memory-index.sh +68 -0
  601. package/tooling/claude/seeds/.claude/hooks/path-form.sh +57 -0
  602. package/tooling/claude/seeds/.claude/hooks/scratch-guard.sh +52 -0
  603. package/tooling/claude/seeds/.claude/hooks/standards-audit.sh +86 -0
  604. package/tooling/claude/seeds/.claude/hooks/tasks-index.sh +71 -0
  605. package/tooling/claude/seeds/.claude/memory/index.md +8 -0
  606. package/tooling/claude/seeds/.claude/settings.json +47 -0
  607. package/tooling/claude/seeds/.claude/tasks/index.md +8 -0
  608. package/tooling/claude/seeds/.claude/wireframes/index.md +8 -0
  609. package/tooling/claude/seeds/CLAUDE.md +29 -0
  610. package/tooling/claude/user/settings.template.json +10 -0
  611. package/tooling/claude/user/statusline-command.sh +53 -0
  612. package/tooling/python/configs/.coveragerc +14 -0
  613. package/tooling/python/configs/.python-version +1 -0
  614. package/tooling/python/configs/mypy.ini +6 -0
  615. package/tooling/python/configs/pytest.ini +4 -0
  616. package/tooling/python/configs/ruff.toml +15 -0
  617. package/tooling/python/configs/scripts/verify.sh +77 -0
  618. package/tooling/python/manifest.toml +16 -0
  619. package/tooling/python/reference.md +66 -0
  620. package/tooling/python/seeds/.cspell/tech-stack.txt +19 -0
  621. package/tooling/python/seeds/tests/test_smoke.py +2 -0
  622. package/tooling/vite-react/configs/playwright.config.ts +26 -0
  623. package/tooling/vite-react/configs/tsconfig.json +35 -0
  624. package/tooling/vite-react/configs/vite.config.ts +24 -0
  625. package/tooling/vite-react/configs/vitest.config.ts +26 -0
  626. package/tooling/vite-react/manifest.toml +23 -0
  627. package/tooling/vite-react/reference.md +55 -0
  628. package/tooling/vite-react/seeds/.cspell/project-terms.txt +1 -0
  629. package/tooling/vite-react/seeds/.cspell/tech-stack.txt +1 -0
  630. package/tooling/web/configs/.github/workflows/verify.yml +134 -0
  631. package/tooling/web/configs/.vscode/extensions.json +13 -0
  632. package/tooling/web/configs/.vscode/settings.json +10 -0
  633. package/tooling/web/configs/e2e/home.spec.ts +6 -0
  634. package/tooling/web/configs/e2e/screenshot.ts +53 -0
  635. package/tooling/web/configs/eslint.config.js +82 -0
  636. package/tooling/web/configs/scripts/screenshot.sh +28 -0
  637. package/tooling/web/configs/scripts/verify.sh +80 -0
  638. package/tooling/web/configs/scripts/worktree-port.sh +74 -0
  639. package/tooling/web/configs/src/test/setup.ts +8 -0
  640. package/tooling/web/manifest.toml +58 -0
  641. package/tooling/web/reference.md +115 -0
  642. package/tooling/web/seeds/.cspell/tech-stack.txt +18 -0
  643. package/tsconfig.json +14 -0
package/src/cli.ts ADDED
@@ -0,0 +1,200 @@
1
+ #!/usr/bin/env bun
2
+
3
+ import { Command } from 'commander'
4
+ import { register as init } from '@/commands/init'
5
+ import { register as sandbox } from '@/commands/sandbox'
6
+ import { register as sync } from '@/commands/sync'
7
+ import { register as gov } from '@/commands/gov'
8
+ import { register as standards } from '@/commands/standards'
9
+ import { register as snippets } from '@/commands/snippets'
10
+ import { register as tooling } from '@/commands/tooling'
11
+ import { register as claude } from '@/commands/claude'
12
+ import { register as wiki } from '@/commands/wiki'
13
+ import { register as indexes } from '@/commands/indexes'
14
+ import { register as docs } from '@/commands/docs'
15
+ import { register as design } from '@/commands/design'
16
+ import { register as slides } from '@/commands/slides'
17
+ import { register as capture } from '@/commands/capture'
18
+ import { register as serve } from '@/commands/serve'
19
+ import { register as demo } from '@/commands/demo'
20
+ import { register as inventory } from '@/commands/inventory'
21
+ import { register as feedback } from '@/commands/feedback'
22
+ import { register as transcripts } from '@/commands/transcripts'
23
+ import { register as tasks } from '@/commands/tasks'
24
+ import { register as intake } from '@/commands/intake'
25
+ import { register as teach } from '@/commands/teach'
26
+ import { register as comments } from '@/commands/comments'
27
+ import { register as context } from '@/commands/context'
28
+ import { register as markdown } from '@/commands/markdown'
29
+ import { register as migrate } from '@/commands/migrate'
30
+ import { register as records } from '@/commands/records'
31
+ import { register as sessions } from '@/commands/sessions'
32
+ import { register as worktrees } from '@/commands/worktrees'
33
+ import { register as audits } from '@/commands/audits'
34
+ import { register as gate } from '@/commands/gate'
35
+ import { register as secrets } from '@/commands/secrets'
36
+ import { register as deps } from '@/commands/deps'
37
+ import { register as labels } from '@/commands/labels'
38
+ import { register as autoship } from '@/commands/autoship'
39
+ import { register as pr } from '@/commands/pr'
40
+ import { register as census } from '@/commands/census'
41
+ import { register as targets } from '@/commands/targets'
42
+ import { register as upgrade } from '@/commands/upgrade'
43
+ import { readInstalled, UNKNOWN_LABEL } from '@/version/installed'
44
+ import { palette } from '@/ui'
45
+
46
+ function showHelp(): void {
47
+ // The help text is the one framed surface written to stdout, so it asks
48
+ // about that stream rather than the stderr every other writer here uses.
49
+ const { GREY, NC, WHITE } = palette(process.stdout)
50
+ const lines = [
51
+ `${GREY}┌${NC}`,
52
+ `${GREY}├${NC} ${WHITE}Usage:${NC} canon [command]`,
53
+ `${GREY}│${NC}`,
54
+ `${GREY}│${NC} ${WHITE}Commands:${NC}`,
55
+ `${GREY}│${NC} init [path] ${GREY}# Bootstrap a project with toolkit domains${NC}`,
56
+ `${GREY}│${NC} sync [path] ${GREY}# Sync all installed domains in a project${NC}`,
57
+ `${GREY}│${NC} sandbox [cat:cmd] ${GREY}# Provision and run sandbox scenarios${NC}`,
58
+ `${GREY}│${NC} gov [command] ${GREY}# Governance commands (install, sync)${NC}`,
59
+ `${GREY}│${NC} standards [cmd] ${GREY}# Standards commands (install, sync, list, <name>)${NC}`,
60
+ `${GREY}│${NC} snippets [cmd] ${GREY}# Snippets commands (create, list)${NC}`,
61
+ `${GREY}│${NC} tooling [cmd] ${GREY}# Manage tooling stacks (sync, ref, create)${NC}`,
62
+ `${GREY}│${NC} claude [cmd] ${GREY}# Claude workflow (init, sync, setup)${NC}`,
63
+ `${GREY}│${NC} wiki [cmd] ${GREY}# Wiki commands (init)${NC}`,
64
+ `${GREY}│${NC} indexes [cmd] ${GREY}# Regenerate index.md files (regen)${NC}`,
65
+ `${GREY}│${NC} docs [cmd|topic] ${GREY}# Emit toolkit reference docs (list, <topic>)${NC}`,
66
+ `${GREY}│${NC} design [cmd] ${GREY}# Design system commands (render)${NC}`,
67
+ `${GREY}│${NC} slides [cmd] ${GREY}# Slide deck commands (render, list)${NC}`,
68
+ `${GREY}│${NC} capture [source] ${GREY}# Render HTML capture sources to PNG${NC}`,
69
+ `${GREY}│${NC} serve [dir] ${GREY}# Serve a directory over localhost and print the preview link${NC}`,
70
+ `${GREY}│${NC} demo [cmd] ${GREY}# Record a running app (compile, run)${NC}`,
71
+ `${GREY}│${NC} inventory [subj] ${GREY}# Report one computed property across every route${NC}`,
72
+ `${GREY}│${NC} feedback ${GREY}# Write toolkit feedback from stdin to .claude/review/feedback/${NC}`,
73
+ `${GREY}│${NC} transcripts <url> ${GREY}# Fetch a YouTube transcript with metadata frontmatter${NC}`,
74
+ `${GREY}│${NC} tasks [cmd] ${GREY}# Task board commands (archive)${NC}`,
75
+ `${GREY}│${NC} intake [cmd] ${GREY}# Intake folders under .claude/intake/ (list, answer)${NC}`,
76
+ `${GREY}│${NC} teach [cmd] ${GREY}# Learning workspaces under .claude/teach/ (list, open, resource, glossary)${NC}`,
77
+ `${GREY}│${NC} comments [cmd] ${GREY}# Measure comment density and trend (scan)${NC}`,
78
+ `${GREY}│${NC} context [cmd] ${GREY}# Report context folder health (audit)${NC}`,
79
+ `${GREY}│${NC} markdown [cmd] ${GREY}# Report markdown against the attribute standards (audit)${NC}`,
80
+ `${GREY}│${NC} records [cmd] ${GREY}# Session records under .claude/ (validate, size, push, pull)${NC}`,
81
+ `${GREY}│${NC} sessions [cmd] ${GREY}# Resolve live sessions to worktree and branch (list)${NC}`,
82
+ `${GREY}│${NC} targets [cmd] ${GREY}# Report the projects this toolkit installed into (list, pulls)${NC}`,
83
+ `${GREY}│${NC} worktrees [cmd] ${GREY}# Report which worktrees are reclaimable (list)${NC}`,
84
+ `${GREY}│${NC} secrets [cmd] ${GREY}# Read the shipped tree for credential-shaped values (scan)${NC}`,
85
+ `${GREY}│${NC} deps [cmd] ${GREY}# Read the resolved dependency set for advisories (audit)${NC}`,
86
+ `${GREY}│${NC} labels [cmd] ${GREY}# Read a changed set against the pull request label map (audit)${NC}`,
87
+ `${GREY}│${NC} autoship [cmd] ${GREY}# Decide whether a changed set needs the review pass (classify)${NC}`,
88
+ `${GREY}│${NC} pr [cmd] ${GREY}# Read a pull request body against its own diff (key-changes)${NC}`,
89
+ `${GREY}│${NC} census [path] ${GREY}# Report tracked file count, extension breakdown, and line totals${NC}`,
90
+ `${GREY}│${NC} audits [cmd] ${GREY}# Run every health check as one set (run, list)${NC}`,
91
+ `${GREY}│${NC} gate [cmd] ${GREY}# Run the merge gate stage by stage (run)${NC}`,
92
+ `${GREY}│${NC} upgrade ${GREY}# Reinstall the CLI globally with the manager that installed it${NC}`,
93
+ `${GREY}│${NC}`,
94
+ `${GREY}│${NC} ${WHITE}Sandbox:${NC}`,
95
+ `${GREY}│${NC} canon sandbox ${GREY}# Interactive scenario picker${NC}`,
96
+ `${GREY}│${NC} canon sandbox git:commit ${GREY}# Run specific scenario${NC}`,
97
+ `${GREY}│${NC} canon sandbox reset ${GREY}# Reset sandbox to baseline${NC}`,
98
+ `${GREY}│${NC} canon sandbox clean ${GREY}# Wipe the sandbox${NC}`,
99
+ `${GREY}│${NC}`,
100
+ `${GREY}│${NC} ${WHITE}Examples:${NC}`,
101
+ `${GREY}│${NC} canon sync ../my-app`,
102
+ `${GREY}│${NC} canon sandbox git:commit`,
103
+ `${GREY}│${NC} canon gov install react`,
104
+ `${GREY}│${NC} canon gov sync ../my-app`,
105
+ `${GREY}│${NC} canon gov restated --json`,
106
+ `${GREY}│${NC} canon standards markdown`,
107
+ `${GREY}│${NC} canon snippets list`,
108
+ `${GREY}│${NC} canon init ../my-app`,
109
+ `${GREY}│${NC} canon tooling sync base`,
110
+ `${GREY}│${NC} canon tooling create`,
111
+ `${GREY}│${NC} canon claude init`,
112
+ `${GREY}│${NC} canon indexes regen`,
113
+ `${GREY}│${NC} canon indexes regen --dry-run --json`,
114
+ `${GREY}│${NC} canon docs list --json`,
115
+ `${GREY}│${NC} canon docs agents`,
116
+ `${GREY}│${NC} canon design render`,
117
+ `${GREY}│${NC} canon slides render`,
118
+ `${GREY}│${NC} canon slides list --json`,
119
+ `${GREY}│${NC} canon capture assets/install.html`,
120
+ `${GREY}│${NC} canon serve .claude/teach`,
121
+ `${GREY}│${NC} canon inventory focus --json`,
122
+ `${GREY}│${NC} pbpaste | canon feedback`,
123
+ `${GREY}│${NC} canon transcripts https://youtu.be/VIDEO_ID`,
124
+ `${GREY}│${NC} canon tasks archive --pull-request 673 --json`,
125
+ `${GREY}│${NC} canon intake list toolkit-overview --unread --json`,
126
+ `${GREY}│${NC} canon teach list --json`,
127
+ `${GREY}│${NC} canon comments scan src --json`,
128
+ `${GREY}│${NC} canon context audit --json`,
129
+ `${GREY}│${NC} canon markdown audit .claude/rules --json`,
130
+ `${GREY}│${NC} canon records validate plans`,
131
+ `${GREY}│${NC} canon records size --json`,
132
+ `${GREY}│${NC} canon records push --json`,
133
+ `${GREY}│${NC} canon sessions list --json`,
134
+ `${GREY}│${NC} canon worktrees list --json`,
135
+ `${GREY}│${NC} canon secrets scan --json`,
136
+ `${GREY}│${NC} canon deps audit --json`,
137
+ `${GREY}│${NC} canon labels audit --json`,
138
+ `${GREY}│${NC} canon census --json`,
139
+ `${GREY}│${NC} canon audits run --json`,
140
+ `${GREY}│${NC} canon gate run --all --no-write`,
141
+ `${GREY}│${NC} canon upgrade --json`,
142
+ `${GREY}└${NC}`,
143
+ ]
144
+ console.log(lines.join('\n'))
145
+ }
146
+
147
+ const program = new Command()
148
+ program
149
+ .name('canon')
150
+ .version(readInstalled().version ?? UNKNOWN_LABEL)
151
+ .enablePositionalOptions()
152
+ .helpOption(false)
153
+ program.action(() => showHelp())
154
+ program.on('option:help', () => {
155
+ showHelp()
156
+ process.exit(0)
157
+ })
158
+ program.option('-h, --help', 'Show help')
159
+
160
+ init(program)
161
+ sandbox(program)
162
+ sync(program)
163
+ gov(program)
164
+ standards(program)
165
+ snippets(program)
166
+ tooling(program)
167
+ claude(program)
168
+ wiki(program)
169
+ indexes(program)
170
+ docs(program)
171
+ design(program)
172
+ slides(program)
173
+ capture(program)
174
+ serve(program)
175
+ demo(program)
176
+ inventory(program)
177
+ feedback(program)
178
+ transcripts(program)
179
+ tasks(program)
180
+ intake(program)
181
+ teach(program)
182
+ comments(program)
183
+ context(program)
184
+ markdown(program)
185
+ records(program)
186
+ migrate(program)
187
+ sessions(program)
188
+ targets(program)
189
+ worktrees(program)
190
+ secrets(program)
191
+ deps(program)
192
+ labels(program)
193
+ autoship(program)
194
+ pr(program)
195
+ census(program)
196
+ audits(program)
197
+ gate(program)
198
+ upgrade(program)
199
+
200
+ program.parse()
@@ -0,0 +1,350 @@
1
+ import { execa } from 'execa'
2
+ import type { Command } from 'commander'
3
+ import {
4
+ BASELINE_REL,
5
+ type Baseline,
6
+ baselineFrom,
7
+ compareBaseline,
8
+ type Delta,
9
+ readBaseline,
10
+ writeBaseline,
11
+ } from '@/audits/baseline'
12
+ import { AUDITS, type AuditResult } from '@/audits/catalog'
13
+ import {
14
+ exitCodeFor,
15
+ runAudits,
16
+ spawnAudit,
17
+ type Summary,
18
+ summarize,
19
+ } from '@/audits/run'
20
+ import { gitEnv } from '@/git-env'
21
+ import { intro, logError, logInfo, logStep, logWarn, outro, plural } from '@/ui'
22
+ import { currentWorktreeRoot } from '@/worktree'
23
+
24
+ interface RunCommandOptions {
25
+ readonly json?: boolean
26
+ readonly record?: boolean
27
+ readonly root?: string
28
+ }
29
+
30
+ interface ListCommandOptions {
31
+ readonly json?: boolean
32
+ }
33
+
34
+ export function register(program: Command): void {
35
+ const audits = program
36
+ .command('audits')
37
+ .description('Run every health check this repository owns as one set')
38
+ .helpOption('-h, --help', 'Show this help message')
39
+
40
+ audits
41
+ .command('run')
42
+ .description(
43
+ 'Run every audit, report per check under one verdict, and compare each count to the recorded baseline',
44
+ )
45
+ .helpOption('-h, --help', 'Show this help message')
46
+ .option('--json', 'Add a machine-readable record on stdout')
47
+ .option(
48
+ '--root <path>',
49
+ 'Tree to measure, defaulting to the current worktree',
50
+ )
51
+ .option(
52
+ '--record',
53
+ `Write this run's tracked counts to ${BASELINE_REL} as the new baseline`,
54
+ )
55
+ .addHelpText(
56
+ 'after',
57
+ [
58
+ '',
59
+ 'Exit codes:',
60
+ ' 0 every audit reported and none carried a finding that is a fact',
61
+ ' 1 refused, with the reason on stderr',
62
+ ' 2 an audit carries a finding that is a fact',
63
+ ' 3 an audit did not report, so the run measured less than the set',
64
+ '',
65
+ 'It gates on exactly what already gates a push and on nothing new:',
66
+ 'an unresolved context citation, a banned character, word, or spelling,',
67
+ 'and a skill folder carrying no REQUIREMENT.md. Every other measure is a',
68
+ 'judgment a reader settles, and failing a push on one teaches',
69
+ 'contributors to route around the stage.',
70
+ '',
71
+ 'Exit 3 is a defect in the run rather than in the tree. An aggregate that',
72
+ 'reports a pass over a set it did not finish measuring is the failure this',
73
+ 'command exists against, so a verb that did not report takes its own code.',
74
+ '',
75
+ `The baseline at ${BASELINE_REL} holds the counts from the last recorded`,
76
+ 'run, so a measure that reports rather than gates still costs something',
77
+ 'when it grows. Only a tracked corpus is retained: a gitignored record',
78
+ "folder holds one machine's scratch, and its counts answer nobody else.",
79
+ '',
80
+ 'Examples:',
81
+ ' canon audits run',
82
+ ' canon audits run --json',
83
+ ' canon audits run --record',
84
+ '',
85
+ ].join('\n'),
86
+ )
87
+ .action(async (opts: RunCommandOptions) => {
88
+ process.exitCode = await runAll(opts)
89
+ })
90
+
91
+ audits
92
+ .command('list')
93
+ .description(
94
+ 'List every audit this command runs and what each one gates on',
95
+ )
96
+ .helpOption('-h, --help', 'Show this help message')
97
+ .option('--json', 'Emit JSON with the id, invocation, corpus, and gate')
98
+ .addHelpText(
99
+ 'after',
100
+ [
101
+ '',
102
+ 'Exit codes:',
103
+ ' 0 the catalog was listed',
104
+ '',
105
+ 'Examples:',
106
+ ' canon audits list',
107
+ ' canon audits list --json',
108
+ '',
109
+ ].join('\n'),
110
+ )
111
+ .action((opts: ListCommandOptions) => {
112
+ process.exitCode = runList(opts)
113
+ })
114
+ }
115
+
116
+ function runList(opts: ListCommandOptions): number {
117
+ if (opts.json) {
118
+ process.stdout.write(
119
+ `${JSON.stringify({
120
+ audits: AUDITS.map((audit) => ({
121
+ id: audit.id,
122
+ label: audit.label,
123
+ command: `canon ${audit.argv.join(' ')}`,
124
+ corpus: audit.corpus,
125
+ gates: audit.gatingExits.length > 0,
126
+ })),
127
+ })}\n`,
128
+ )
129
+ return 0
130
+ }
131
+
132
+ intro('canon audits list')
133
+ for (const audit of AUDITS) {
134
+ logStep(audit.label)
135
+ logInfo(`canon ${audit.argv.join(' ')}`)
136
+ logInfo(
137
+ `${audit.corpus} corpus, ${audit.gatingExits.length > 0 ? 'gates on a fact' : 'reports only'}`,
138
+ )
139
+ }
140
+ outro()
141
+ return 0
142
+ }
143
+
144
+ /**
145
+ * The day a record is stamped with, as `YYYY-MM-DD`.
146
+ *
147
+ * Local rather than UTC, because the stamp is read beside a commit date in a
148
+ * context entry and a run taken in the evening should not record tomorrow.
149
+ */
150
+ function today(): string {
151
+ const now = new Date()
152
+ return [
153
+ now.getFullYear(),
154
+ String(now.getMonth() + 1).padStart(2, '0'),
155
+ String(now.getDate()).padStart(2, '0'),
156
+ ].join('-')
157
+ }
158
+
159
+ /**
160
+ * The commit the counts were read at, or `unknown` outside a repository.
161
+ *
162
+ * A target project can install this CLI without a git history behind it, and
163
+ * refusing there would withhold the whole report over a field that only makes
164
+ * the record reproducible.
165
+ */
166
+ async function headCommit(root: string): Promise<string> {
167
+ const result = await execa('git', ['-C', root, 'rev-parse', 'HEAD'], {
168
+ reject: false,
169
+ env: gitEnv(),
170
+ extendEnv: false,
171
+ })
172
+ return result.exitCode === 0 ? result.stdout.trim() : 'unknown'
173
+ }
174
+
175
+ async function runAll(opts: RunCommandOptions): Promise<number> {
176
+ const emitJson = opts.json ?? false
177
+ const root = opts.root ?? (await currentWorktreeRoot())
178
+
179
+ let baseline: Baseline | undefined
180
+ try {
181
+ baseline = await readBaseline(root)
182
+ } catch (error) {
183
+ const message = error instanceof Error ? error.message : String(error)
184
+ if (emitJson) {
185
+ process.stderr.write(`${message}\n`)
186
+ process.stdout.write(
187
+ `${JSON.stringify({ ok: false, reason: 'bad-baseline', message })}\n`,
188
+ )
189
+ return 1
190
+ }
191
+ intro('canon audits run')
192
+ logStep('Refused')
193
+ logError(message)
194
+ outro()
195
+ return 1
196
+ }
197
+
198
+ const results = await runAudits(AUDITS, spawnAudit(root))
199
+ const deltas = compareBaseline(baseline, results)
200
+ const summary = summarize(results, deltas)
201
+
202
+ let recorded: string | undefined
203
+ if (opts.record) {
204
+ const next = baselineFrom(results, {
205
+ recordedAt: today(),
206
+ commit: await headCommit(root),
207
+ })
208
+ recorded = await writeBaseline(root, next)
209
+ }
210
+
211
+ if (emitJson) {
212
+ process.stdout.write(
213
+ `${JSON.stringify({
214
+ ok: true,
215
+ root,
216
+ // Flat scalars, so a shell stage greps one out without a JSON parser.
217
+ // The nested arrays below carry the detail behind each number.
218
+ summary,
219
+ baseline: baseline
220
+ ? { recordedAt: baseline.recordedAt, commit: baseline.commit }
221
+ : undefined,
222
+ recorded,
223
+ audits: results,
224
+ deltas,
225
+ })}\n`,
226
+ )
227
+ } else {
228
+ report(results, deltas, baseline, recorded, summary)
229
+ }
230
+
231
+ return exitCodeFor(results)
232
+ }
233
+
234
+ /** The counts of one result, rendered as `key n` pairs a reader can scan. */
235
+ function countLine(counts: Record<string, number>): string {
236
+ return Object.entries(counts)
237
+ .map(([key, value]) => `${key} ${value}`)
238
+ .join(', ')
239
+ }
240
+
241
+ /**
242
+ * The delta line for one audit, or nothing when there is no comparison to
243
+ * report. A first run says so rather than showing a delta of zero, since zero
244
+ * against an absent baseline says the same as a corpus that did not move.
245
+ */
246
+ function deltaLine(delta: Delta): string | undefined {
247
+ if (
248
+ delta.kind === 'per-machine' ||
249
+ delta.kind === 'upstream' ||
250
+ delta.kind === 'unmeasured'
251
+ ) {
252
+ return undefined
253
+ }
254
+ if (delta.kind === 'unrecorded') return 'No recorded baseline to compare'
255
+
256
+ const parts = [
257
+ ...delta.moved.map(
258
+ ({ key, from, to, delta: moved }) =>
259
+ `${key} ${from} to ${to} (${moved > 0 ? '+' : ''}${moved})`,
260
+ ),
261
+ ...delta.added.map(({ key, to }) => `${key} ${to}, newly measured`),
262
+ ...delta.dropped.map(({ key, from }) => `${key} was ${from}, not measured`),
263
+ ]
264
+
265
+ return parts.length === 0 ? undefined : parts.join(', ')
266
+ }
267
+
268
+ function report(
269
+ results: readonly AuditResult[],
270
+ deltas: readonly Delta[],
271
+ baseline: Baseline | undefined,
272
+ recorded: string | undefined,
273
+ summary: Summary,
274
+ ): void {
275
+ const byId = new Map(deltas.map((delta) => [delta.id, delta]))
276
+
277
+ intro('canon audits run')
278
+
279
+ logStep('Baseline')
280
+ if (baseline === undefined) {
281
+ logWarn(`None recorded. Take one with canon audits run --record.`)
282
+ } else {
283
+ logInfo(`${baseline.recordedAt} at ${baseline.commit.slice(0, 8)}`)
284
+ }
285
+
286
+ for (const result of results) {
287
+ logStep(result.label)
288
+
289
+ if (result.status === 'absent') {
290
+ logInfo(`No corpus on this machine: ${result.reason ?? 'not found'}`)
291
+ continue
292
+ }
293
+
294
+ if (result.status === 'unmeasured') {
295
+ logWarn(`Did not report: ${result.reason ?? 'no reason given'}`)
296
+ continue
297
+ }
298
+
299
+ const counts = result.counts ?? {}
300
+ const line = countLine(counts)
301
+ if (result.status === 'finding') {
302
+ logError(line === '' ? 'A finding that is a fact' : line)
303
+ } else {
304
+ logInfo(line === '' ? 'Reported' : line)
305
+ }
306
+
307
+ if (!result.tracked) {
308
+ logInfo(
309
+ result.corpus === 'upstream'
310
+ ? 'Upstream index, so no baseline is kept and growth is not this tree'
311
+ : 'Per-machine corpus, so no baseline is kept',
312
+ )
313
+ continue
314
+ }
315
+
316
+ const moved = deltaLine(
317
+ byId.get(result.id) ?? { id: result.id, kind: 'unrecorded' },
318
+ )
319
+ if (moved !== undefined) logInfo(moved)
320
+ }
321
+
322
+ if (recorded !== undefined) {
323
+ logStep('Recorded')
324
+ logInfo(recorded)
325
+ }
326
+
327
+ logStep('Verdict')
328
+
329
+ if (summary.verdict === 'findings') {
330
+ logError(
331
+ `${plural(summary.facts, 'audit')} carrying a finding that is a fact. Fix what each names.`,
332
+ )
333
+ } else if (summary.verdict === 'incomplete') {
334
+ logError(
335
+ `${plural(summary.unmeasured, 'audit')} did not report, so this run measured less than the set.`,
336
+ )
337
+ } else if (summary.verdict === 'reported') {
338
+ logInfo('No fact. Every other finding is a judgment a reader settles.')
339
+ } else {
340
+ logInfo('Every audit reported and every count is zero.')
341
+ }
342
+
343
+ // Stated on every run, including a clean one. A count of what passed reads as
344
+ // a verdict on the whole set unless the run also says what it never reached.
345
+ logInfo(
346
+ `${summary.audited} of ${results.length} corpora measured, ${summary.absent} absent or unreachable from this machine`,
347
+ )
348
+
349
+ outro()
350
+ }
@@ -0,0 +1,129 @@
1
+ import type { Command } from 'commander'
2
+ import {
3
+ type ClassifyRefusal,
4
+ type FailedTest,
5
+ classifyChanges,
6
+ } from '@/autoship/classify'
7
+ import { intro, logInfo, logStep, logWarn, outro, plural } from '@/ui'
8
+
9
+ interface ClassifyOptions {
10
+ readonly json?: boolean
11
+ }
12
+
13
+ /** What a reader does about the one way the classification produced no reading. */
14
+ const REFUSALS: Record<ClassifyRefusal, string> = {
15
+ 'no-changes':
16
+ 'No changed files were supplied, so there is no set to classify. Pass the set the ship chain already computed.',
17
+ }
18
+
19
+ /** Why each failed test sends the branch to review, in the reader's terms. */
20
+ const TESTS: Record<FailedTest, string> = {
21
+ extension: 'is not prose, so this branch carries a change review reads',
22
+ 'behavior-path':
23
+ 'sits under a behavior path, so its prose states what an agent does',
24
+ }
25
+
26
+ export function register(program: Command): void {
27
+ const autoship = program
28
+ .command('autoship')
29
+ .description('Answer the decisions the ship chain used to make in prose')
30
+ .helpOption('-h, --help', 'Show this help message')
31
+
32
+ autoship
33
+ .command('classify')
34
+ .description('Decide whether a changed set needs the review pass')
35
+ .argument('[paths...]', 'Changed set to classify, as names')
36
+ .helpOption('-h, --help', 'Show this help message')
37
+ .option('--json', 'Add a machine-readable record on stdout')
38
+ .addHelpText(
39
+ 'after',
40
+ [
41
+ '',
42
+ 'Reads names only and never touches git, so the caller hands over the',
43
+ 'set it already computed rather than paying for a second baseline that',
44
+ 'can disagree with the first.',
45
+ '',
46
+ 'The skip needs both tests to pass. Every name reads as prose, and no',
47
+ 'name sits under a behavior path, which is where markdown states what',
48
+ 'an agent does. One behavior file sends the whole branch to review,',
49
+ 'since documentation shipped beside a behavior change does not cancel',
50
+ 'it.',
51
+ '',
52
+ 'An empty set refuses rather than skipping. Both tests are universally',
53
+ 'quantified, so an empty set satisfies them vacuously, and reading that',
54
+ 'as prose-only would route a branch past review for producing no output.',
55
+ '',
56
+ 'Exit codes:',
57
+ ' 0 prose-only, so the review pass can be skipped',
58
+ ' 1 refused, with the reason on stderr or in the JSON record',
59
+ ' 2 review is needed, with the file and the test it failed named',
60
+ '',
61
+ 'Examples:',
62
+ ' canon autoship classify docs/index.md README.md',
63
+ ' canon autoship classify --json .claude/skills/deploy-check/SKILL.md',
64
+ '',
65
+ ].join('\n'),
66
+ )
67
+ .action((paths: string[], opts: ClassifyOptions) => {
68
+ process.exitCode = runClassify(paths, opts)
69
+ })
70
+ }
71
+
72
+ function runClassify(paths: string[], opts: ClassifyOptions): number {
73
+ const emitJson = opts.json ?? false
74
+ const result = classifyChanges(paths)
75
+
76
+ intro('canon autoship classify')
77
+
78
+ // The frame renders on stderr in both modes and the record goes to stdout
79
+ // alone, so an operator reading the terminal sees the refusal rather than a
80
+ // command that appeared to do nothing.
81
+ if (result.kind === 'refused') {
82
+ logStep('Refused')
83
+ logWarn(REFUSALS[result.reason])
84
+ outro()
85
+
86
+ if (emitJson) {
87
+ process.stdout.write(
88
+ `${JSON.stringify({
89
+ decision: 'refused',
90
+ reason: result.reason,
91
+ message: REFUSALS[result.reason],
92
+ })}\n`,
93
+ )
94
+ }
95
+ return 1
96
+ }
97
+
98
+ logStep('Scope')
99
+ logInfo(`${plural(paths.length, 'path')} supplied by the caller`)
100
+
101
+ if (result.kind === 'skip') {
102
+ logStep('Prose only')
103
+ logInfo('every path reads as prose and none states agent behavior')
104
+ outro()
105
+
106
+ if (emitJson) {
107
+ process.stdout.write(
108
+ `${JSON.stringify({ decision: 'skip', changed: paths })}\n`,
109
+ )
110
+ }
111
+ return 0
112
+ }
113
+
114
+ logStep('Review')
115
+ logWarn(`${result.file} ${TESTS[result.test]}.`)
116
+ outro()
117
+
118
+ if (emitJson) {
119
+ process.stdout.write(
120
+ `${JSON.stringify({
121
+ decision: 'review',
122
+ test: result.test,
123
+ file: result.file,
124
+ changed: paths,
125
+ })}\n`,
126
+ )
127
+ }
128
+ return 2
129
+ }