@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.
- package/LICENSE +21 -0
- package/README.md +129 -0
- package/claude/.claude-plugin/plugin.json +19 -0
- package/claude/skills/bash-cli-script/REQUIREMENT.md +42 -0
- package/claude/skills/bash-cli-script/SKILL.md +48 -0
- package/claude/skills/bash-cli-script/references/template.md +43 -0
- package/claude/skills/bash-script/REQUIREMENT.md +36 -0
- package/claude/skills/bash-script/SKILL.md +100 -0
- package/claude/skills/bash-script/references/patterns.md +349 -0
- package/claude/skills/canon-cli/REQUIREMENT.md +41 -0
- package/claude/skills/canon-cli/SKILL.md +103 -0
- package/claude/skills/canon-feedback-file/REQUIREMENT.md +40 -0
- package/claude/skills/canon-feedback-file/SKILL.md +80 -0
- package/claude/skills/canon-feedback-triage/REQUIREMENT.md +40 -0
- package/claude/skills/canon-feedback-triage/SKILL.md +63 -0
- package/claude/skills/canon-operator/REQUIREMENT.md +61 -0
- package/claude/skills/canon-operator/SKILL.md +108 -0
- package/claude/skills/canon-rollout/REQUIREMENT.md +59 -0
- package/claude/skills/canon-rollout/SKILL.md +147 -0
- package/claude/skills/canon-screencast/REQUIREMENT.md +39 -0
- package/claude/skills/canon-screencast/SKILL.md +167 -0
- package/claude/skills/canon-slides-draft/REQUIREMENT.md +39 -0
- package/claude/skills/canon-slides-draft/SKILL.md +62 -0
- package/claude/skills/ci-workflow/REQUIREMENT.md +40 -0
- package/claude/skills/ci-workflow/SKILL.md +65 -0
- package/claude/skills/ci-workflow/references/workflows.md +98 -0
- package/claude/skills/claude-address-review/REQUIREMENT.md +57 -0
- package/claude/skills/claude-address-review/SKILL.md +212 -0
- package/claude/skills/claude-address-review/references/rebase-conflicts.md +39 -0
- package/claude/skills/claude-autoship/REQUIREMENT.md +50 -0
- package/claude/skills/claude-autoship/SKILL.md +207 -0
- package/claude/skills/claude-design-extract/REQUIREMENT.md +42 -0
- package/claude/skills/claude-design-extract/SKILL.md +102 -0
- package/claude/skills/claude-diagram/REQUIREMENT.md +45 -0
- package/claude/skills/claude-diagram/SKILL.md +177 -0
- package/claude/skills/claude-docs/REQUIREMENT.md +60 -0
- package/claude/skills/claude-docs/SKILL.md +287 -0
- package/claude/skills/claude-docs/references/anchor-sweep.md +58 -0
- package/claude/skills/claude-docs/references/wireframe-sweep.md +45 -0
- package/claude/skills/claude-feature/REQUIREMENT.md +36 -0
- package/claude/skills/claude-feature/SKILL.md +115 -0
- package/claude/skills/claude-groundwork/REQUIREMENT.md +48 -0
- package/claude/skills/claude-groundwork/SKILL.md +142 -0
- package/claude/skills/claude-intake/REQUIREMENT.md +49 -0
- package/claude/skills/claude-intake/SKILL.md +114 -0
- package/claude/skills/claude-intake-answer/REQUIREMENT.md +48 -0
- package/claude/skills/claude-intake-answer/SKILL.md +90 -0
- package/claude/skills/claude-markdown-propose/REQUIREMENT.md +48 -0
- package/claude/skills/claude-markdown-propose/SKILL.md +118 -0
- package/claude/skills/claude-markdown-propose/references/format.md +107 -0
- package/claude/skills/claude-memory-capture/REQUIREMENT.md +50 -0
- package/claude/skills/claude-memory-capture/SKILL.md +101 -0
- package/claude/skills/claude-memory-review/REQUIREMENT.md +50 -0
- package/claude/skills/claude-memory-review/SKILL.md +210 -0
- package/claude/skills/claude-memory-review/references/receipt-format.md +48 -0
- package/claude/skills/claude-orchestrate/REQUIREMENT.md +121 -0
- package/claude/skills/claude-orchestrate/SKILL.md +241 -0
- package/claude/skills/claude-orchestrate/references/orchestrator-dispatch.md +132 -0
- package/claude/skills/claude-orchestrate/references/orchestrator-handoff.md +32 -0
- package/claude/skills/claude-orchestrate/references/orchestrator-parked.md +72 -0
- package/claude/skills/claude-orchestrate/references/orchestrator-poll.md +87 -0
- package/claude/skills/claude-orchestrate/references/orchestrator-resume.md +30 -0
- package/claude/skills/claude-orchestrate/references/orchestrator-sweep.md +21 -0
- package/claude/skills/claude-orchestrate/scripts/poll.sh +373 -0
- package/claude/skills/claude-orchestrate/scripts/watch.sh +181 -0
- package/claude/skills/claude-pr-review/REQUIREMENT.md +47 -0
- package/claude/skills/claude-pr-review/SKILL.md +295 -0
- package/claude/skills/claude-review/REQUIREMENT.md +39 -0
- package/claude/skills/claude-review/SKILL.md +142 -0
- package/claude/skills/claude-seed-sync/REQUIREMENT.md +45 -0
- package/claude/skills/claude-seed-sync/SKILL.md +156 -0
- package/claude/skills/claude-standards-audit/REQUIREMENT.md +33 -0
- package/claude/skills/claude-standards-audit/SKILL.md +99 -0
- package/claude/skills/claude-tasks/REQUIREMENT.md +43 -0
- package/claude/skills/claude-tasks/SKILL.md +161 -0
- package/claude/skills/claude-teach/REQUIREMENT.md +56 -0
- package/claude/skills/claude-teach/SKILL.md +196 -0
- package/claude/skills/claude-teach/references/lesson-craft.md +59 -0
- package/claude/skills/claude-teach/references/pedagogy.md +67 -0
- package/claude/skills/claude-teach/references/promotion.md +54 -0
- package/claude/skills/claude-ui-test/REQUIREMENT.md +40 -0
- package/claude/skills/claude-ui-test/SKILL.md +77 -0
- package/claude/skills/claude-ux-audit/REQUIREMENT.md +40 -0
- package/claude/skills/claude-ux-audit/SKILL.md +79 -0
- package/claude/skills/claude-ux-measure/REQUIREMENT.md +48 -0
- package/claude/skills/claude-ux-measure/SKILL.md +122 -0
- package/claude/skills/claude-worker/REQUIREMENT.md +54 -0
- package/claude/skills/claude-worker/SKILL.md +96 -0
- package/claude/skills/claude-worktree/REQUIREMENT.md +58 -0
- package/claude/skills/claude-worktree/SKILL.md +136 -0
- package/claude/skills/create-rule/REQUIREMENT.md +45 -0
- package/claude/skills/create-rule/SKILL.md +68 -0
- package/claude/skills/create-skill/REQUIREMENT.md +38 -0
- package/claude/skills/create-skill/SKILL.md +32 -0
- package/claude/skills/create-snippet/REQUIREMENT.md +39 -0
- package/claude/skills/create-snippet/SKILL.md +30 -0
- package/claude/skills/create-standard/REQUIREMENT.md +35 -0
- package/claude/skills/create-standard/SKILL.md +29 -0
- package/claude/skills/decision-escalate/REQUIREMENT.md +45 -0
- package/claude/skills/decision-escalate/SKILL.md +79 -0
- package/claude/skills/docs-sync/REQUIREMENT.md +41 -0
- package/claude/skills/docs-sync/SKILL.md +95 -0
- package/claude/skills/git-branch/REQUIREMENT.md +38 -0
- package/claude/skills/git-branch/SKILL.md +60 -0
- package/claude/skills/git-commit/REQUIREMENT.md +36 -0
- package/claude/skills/git-commit/SKILL.md +49 -0
- package/claude/skills/git-followup/REQUIREMENT.md +43 -0
- package/claude/skills/git-followup/SKILL.md +48 -0
- package/claude/skills/git-issue/REQUIREMENT.md +38 -0
- package/claude/skills/git-issue/SKILL.md +65 -0
- package/claude/skills/git-pr/REQUIREMENT.md +50 -0
- package/claude/skills/git-pr/SKILL.md +164 -0
- package/claude/skills/git-pr/references/labels.md +95 -0
- package/claude/skills/git-ship/REQUIREMENT.md +42 -0
- package/claude/skills/git-ship/SKILL.md +55 -0
- package/claude/skills/git-split/REQUIREMENT.md +39 -0
- package/claude/skills/git-split/SKILL.md +162 -0
- package/claude/skills/git-stage/REQUIREMENT.md +39 -0
- package/claude/skills/git-stage/SKILL.md +73 -0
- package/claude/skills/git-worktree/REQUIREMENT.md +38 -0
- package/claude/skills/git-worktree/SKILL.md +130 -0
- package/claude/skills/migration-claude-md/REQUIREMENT.md +40 -0
- package/claude/skills/migration-claude-md/SKILL.md +76 -0
- package/claude/skills/migration-context/REQUIREMENT.md +36 -0
- package/claude/skills/migration-context/SKILL.md +95 -0
- package/claude/skills/migration-standards-drop/REQUIREMENT.md +55 -0
- package/claude/skills/migration-standards-drop/SKILL.md +113 -0
- package/claude/skills/migration-superseded/REQUIREMENT.md +44 -0
- package/claude/skills/migration-superseded/SKILL.md +115 -0
- package/claude/skills/project-commands/REQUIREMENT.md +42 -0
- package/claude/skills/project-commands/SKILL.md +85 -0
- package/claude/skills/restate-plainly/REQUIREMENT.md +41 -0
- package/claude/skills/restate-plainly/SKILL.md +39 -0
- package/claude/skills/session-map/REQUIREMENT.md +57 -0
- package/claude/skills/session-map/SKILL.md +70 -0
- package/claude/skills/session-resume/REQUIREMENT.md +49 -0
- package/claude/skills/session-resume/SKILL.md +51 -0
- package/claude/skills/setup-gov/REQUIREMENT.md +37 -0
- package/claude/skills/setup-gov/SKILL.md +77 -0
- package/claude/skills/setup-indexes/REQUIREMENT.md +45 -0
- package/claude/skills/setup-indexes/SKILL.md +153 -0
- package/claude/skills/setup-init/REQUIREMENT.md +45 -0
- package/claude/skills/setup-init/SKILL.md +127 -0
- package/claude/skills/setup-plugins/REQUIREMENT.md +42 -0
- package/claude/skills/setup-plugins/SKILL.md +81 -0
- package/claude/skills/setup-plugins/references/plugin-catalog.md +53 -0
- package/claude/skills/setup-verify/REQUIREMENT.md +39 -0
- package/claude/skills/setup-verify/SKILL.md +51 -0
- package/claude/skills/systematic-debugging/REQUIREMENT.md +41 -0
- package/claude/skills/systematic-debugging/SKILL.md +70 -0
- package/claude/skills/write-human/REQUIREMENT.md +46 -0
- package/claude/skills/write-human/SKILL.md +68 -0
- package/claude/skills/write-human/references/density.md +38 -0
- package/claude/skills/write-human/references/machine-tells.md +107 -0
- package/claude/skills/write-human/references/source-material.md +37 -0
- package/claude/skills/youtube-transcripts/REQUIREMENT.md +38 -0
- package/claude/skills/youtube-transcripts/SKILL.md +34 -0
- package/docs/agents/audits.md +98 -0
- package/docs/agents/capture.md +37 -0
- package/docs/agents/census.md +23 -0
- package/docs/agents/commands.md +146 -0
- package/docs/agents/comments.md +34 -0
- package/docs/agents/context-audit-checks.md +120 -0
- package/docs/agents/context-audit.md +83 -0
- package/docs/agents/counts.md +76 -0
- package/docs/agents/demo.md +86 -0
- package/docs/agents/docs.md +17 -0
- package/docs/agents/gate.md +84 -0
- package/docs/agents/index.md +47 -0
- package/docs/agents/indexes.md +35 -0
- package/docs/agents/install-and-sync.md +385 -0
- package/docs/agents/intake.md +81 -0
- package/docs/agents/key-changes.md +103 -0
- package/docs/agents/label-coverage.md +73 -0
- package/docs/agents/markdown-audit.md +197 -0
- package/docs/agents/output-shape.md +70 -0
- package/docs/agents/overview.md +26 -0
- package/docs/agents/records.md +170 -0
- package/docs/agents/restated.md +81 -0
- package/docs/agents/review-classification.md +77 -0
- package/docs/agents/routing.md +61 -0
- package/docs/agents/rule-citations.md +98 -0
- package/docs/agents/sandbox.md +71 -0
- package/docs/agents/scripting.md +149 -0
- package/docs/agents/sessions.md +120 -0
- package/docs/agents/skills-audit.md +94 -0
- package/docs/agents/skills-reach.md +64 -0
- package/docs/agents/standards-audit.md +38 -0
- package/docs/agents/state-scoped-risk.md +105 -0
- package/docs/agents/superseded.md +85 -0
- package/docs/agents/targets.md +83 -0
- package/docs/agents/tasks.md +200 -0
- package/docs/agents/teach.md +158 -0
- package/docs/agents/test-order.md +56 -0
- package/docs/agents/worktrees.md +62 -0
- package/docs/ai-workflow.md +317 -0
- package/docs/index.md +23 -0
- package/docs/operating-model.md +223 -0
- package/docs/target-projects.md +258 -0
- package/docs/visual-design-workflow.md +151 -0
- package/docs/zshrc-aliases.md +65 -0
- package/governance/rules/ci/700-ci-workflow.md +44 -0
- package/governance/rules/claude/500-prose.md +15 -0
- package/governance/rules/claude/501-markdown.md +14 -0
- package/governance/rules/claude/510-context.md +28 -0
- package/governance/rules/claude/511-indexes.md +14 -0
- package/governance/rules/claude/520-wireframes.md +12 -0
- package/governance/rules/claude/530-requirements.md +11 -0
- package/governance/rules/claude/540-architecture.md +11 -0
- package/governance/rules/claude/550-design.md +11 -0
- package/governance/rules/claude/555-tasks.md +12 -0
- package/governance/rules/claude/556-groundwork.md +11 -0
- package/governance/rules/claude/557-intake.md +11 -0
- package/governance/rules/claude/558-plan.md +22 -0
- package/governance/rules/claude/559-memory.md +11 -0
- package/governance/rules/claude/560-diagrams.md +18 -0
- package/governance/rules/claude/561-teach.md +13 -0
- package/governance/rules/claude/562-session.md +15 -0
- package/governance/rules/claude/570-skill.md +24 -0
- package/governance/rules/claude/575-hooks.md +17 -0
- package/governance/rules/claude/576-settings.md +14 -0
- package/governance/rules/claude/580-readme.md +11 -0
- package/governance/rules/claude/590-rule-authoring.md +12 -0
- package/governance/rules/claude/591-standard-authoring.md +12 -0
- package/governance/rules/claude/592-claude-md.md +19 -0
- package/governance/rules/core/000-constitution.md +30 -0
- package/governance/rules/core/005-behavior.md +27 -0
- package/governance/rules/core/010-testing.md +35 -0
- package/governance/rules/core/015-output.md +20 -0
- package/governance/rules/core/020-concurrency.md +22 -0
- package/governance/rules/core/025-indexes.md +9 -0
- package/governance/rules/core/030-error-handling.md +31 -0
- package/governance/rules/core/035-tasks.md +13 -0
- package/governance/rules/core/040-performance.md +20 -0
- package/governance/rules/core/045-memory.md +12 -0
- package/governance/rules/core/050-logging.md +20 -0
- package/governance/rules/core/055-scratch.md +9 -0
- package/governance/rules/core/060-naming.md +19 -0
- package/governance/rules/core/065-spelling.md +19 -0
- package/governance/rules/core/070-planning.md +18 -0
- package/governance/rules/core/075-dependencies.md +25 -0
- package/governance/rules/core/080-config-comments.md +22 -0
- package/governance/rules/core/085-worktrees.md +17 -0
- package/governance/rules/core/087-git.md +11 -0
- package/governance/rules/core/090-code-comments.md +39 -0
- package/governance/rules/framework/200-react.md +51 -0
- package/governance/rules/framework/210-astro.md +41 -0
- package/governance/rules/framework/220-fastapi.md +43 -0
- package/governance/rules/framework/230-nextjs.md +48 -0
- package/governance/rules/framework/250-tailwind.md +32 -0
- package/governance/rules/framework/260-shadcn.md +34 -0
- package/governance/rules/lang/100-typescript.md +40 -0
- package/governance/rules/lang/110-python.md +42 -0
- package/governance/rules/lang/120-bash.md +19 -0
- package/governance/rules/lib/300-testing-ts.md +39 -0
- package/governance/rules/lib/305-e2e-reliability.md +34 -0
- package/governance/rules/lib/306-test-scope.md +25 -0
- package/governance/rules/lib/310-zod.md +25 -0
- package/governance/rules/lib/320-tanstack-query.md +32 -0
- package/governance/rules/lib/330-testing-py.md +44 -0
- package/governance/rules/lib/340-pydantic.md +38 -0
- package/governance/rules/lib/350-security-web.md +32 -0
- package/governance/rules/lib/360-security-server.md +39 -0
- package/governance/rules/lib/370-database.md +35 -0
- package/governance/rules/snippets/505-at-references.md +9 -0
- package/governance/rules/ui/400-ui.md +36 -0
- package/governance/rules/ui/410-a11y.md +48 -0
- package/governance/rules/ui/420-forms.md +36 -0
- package/governance/rules/ui/430-ux-completeness.md +65 -0
- package/governance/rules/ui/440-surface-capture.md +34 -0
- package/governance/rules/ui/450-link-behavior.md +19 -0
- package/governance/stacks/astro.toml +2 -0
- package/governance/stacks/base.toml +8 -0
- package/governance/stacks/node-server.toml +2 -0
- package/governance/stacks/node.toml +2 -0
- package/governance/stacks/python-fastapi.toml +2 -0
- package/governance/stacks/python.toml +2 -0
- package/governance/stacks/react.toml +2 -0
- package/package.json +69 -0
- package/scripts/config.sh +11 -0
- package/scripts/core/bootstrap.sh +81 -0
- package/scripts/core/check-color-source.sh +41 -0
- package/scripts/core/check-ignore-parity.sh +162 -0
- package/scripts/core/check-plugin-boundary.sh +45 -0
- package/scripts/core/check-seed-independence.sh +59 -0
- package/scripts/core/check-skill-paths.sh +24 -0
- package/scripts/core/clean.sh +36 -0
- package/scripts/core/install-check.sh +101 -0
- package/scripts/core/list-seed-roots.sh +18 -0
- package/scripts/core/regen-claude-copies.sh +10 -0
- package/scripts/core/regen-hero.sh +217 -0
- package/scripts/core/regen-indexes.sh +10 -0
- package/scripts/core/regen-tooling-paths.sh +61 -0
- package/scripts/core/repair-bare-flag.sh +19 -0
- package/scripts/core/snapshot.sh +134 -0
- package/scripts/core/update.sh +35 -0
- package/scripts/docs/list.sh +165 -0
- package/scripts/lib/frontmatter.sh +30 -0
- package/scripts/lib/gov.sh +14 -0
- package/scripts/lib/sandbox-fixtures.sh +191 -0
- package/scripts/lib/sandbox-git.sh +125 -0
- package/scripts/lib/sandbox-path.sh +206 -0
- package/scripts/lib/tooling.sh +35 -0
- package/scripts/lib/ui.sh +266 -0
- package/scripts/lib/worktree.sh +20 -0
- package/scripts/manage-sandbox.sh +466 -0
- package/scripts/snippets/create.sh +156 -0
- package/scripts/standards/list.sh +115 -0
- package/scripts/tooling/create.sh +109 -0
- package/scripts/tooling/verify.sh +179 -0
- package/snippets/align.md +12 -0
- package/snippets/claude/decision-memo.md +39 -0
- package/snippets/claude/feature-recap.md +19 -0
- package/snippets/claude/figma-steps.md +24 -0
- package/snippets/compact-summary.md +5 -0
- package/snippets/decision-help.md +6 -0
- package/snippets/meta-prompt.md +14 -0
- package/snippets/research-prompt.md +7 -0
- package/snippets/session-notes.md +11 -0
- package/snippets/snippets.toml +5 -0
- package/snippets/step-by-step.md +10 -0
- package/snippets/web-research.md +21 -0
- package/src/audits/baseline.ts +201 -0
- package/src/audits/catalog.ts +876 -0
- package/src/audits/run.ts +204 -0
- package/src/autoship/classify.ts +75 -0
- package/src/autoship/paths.ts +51 -0
- package/src/binary.ts +16 -0
- package/src/browser/engine.ts +40 -0
- package/src/census/count.ts +113 -0
- package/src/claude/cases/all.ts +24 -0
- package/src/claude/cases/authoring.ts +53 -0
- package/src/claude/cases/claude-workflow.ts +158 -0
- package/src/claude/cases/git.ts +44 -0
- package/src/claude/cases/misc.ts +27 -0
- package/src/claude/cases/setup.ts +94 -0
- package/src/claude/gitignore.ts +51 -0
- package/src/claude/routing.ts +283 -0
- package/src/claude/seeds-list.ts +47 -0
- package/src/claude/seeds.ts +150 -0
- package/src/claude/settings.ts +151 -0
- package/src/claude/skills-audit.ts +228 -0
- package/src/claude/skills-drift.ts +156 -0
- package/src/claude/skills-list.ts +99 -0
- package/src/claude/skills-rank.ts +320 -0
- package/src/claude/skills-reach.ts +227 -0
- package/src/cli-run.ts +43 -0
- package/src/cli.ts +200 -0
- package/src/commands/audits.ts +350 -0
- package/src/commands/autoship.ts +129 -0
- package/src/commands/capture.ts +133 -0
- package/src/commands/census.ts +105 -0
- package/src/commands/claude.ts +1286 -0
- package/src/commands/comments.ts +240 -0
- package/src/commands/context.ts +857 -0
- package/src/commands/demo.ts +389 -0
- package/src/commands/deps.ts +173 -0
- package/src/commands/design.ts +36 -0
- package/src/commands/docs.ts +60 -0
- package/src/commands/feedback-format.ts +23 -0
- package/src/commands/feedback.ts +112 -0
- package/src/commands/gate.ts +189 -0
- package/src/commands/gov.ts +1265 -0
- package/src/commands/indexes.ts +184 -0
- package/src/commands/init.ts +113 -0
- package/src/commands/intake.ts +406 -0
- package/src/commands/inventory.ts +256 -0
- package/src/commands/labels.ts +361 -0
- package/src/commands/markdown.ts +544 -0
- package/src/commands/migrate.ts +175 -0
- package/src/commands/pass-through.ts +39 -0
- package/src/commands/pr.ts +411 -0
- package/src/commands/records.ts +728 -0
- package/src/commands/sandbox.ts +468 -0
- package/src/commands/secrets.ts +132 -0
- package/src/commands/serve.ts +159 -0
- package/src/commands/sessions.ts +408 -0
- package/src/commands/slides.ts +126 -0
- package/src/commands/snippets.ts +84 -0
- package/src/commands/standards.ts +247 -0
- package/src/commands/sync.ts +428 -0
- package/src/commands/targets.ts +319 -0
- package/src/commands/tasks.ts +743 -0
- package/src/commands/teach.ts +786 -0
- package/src/commands/tooling.ts +573 -0
- package/src/commands/transcripts.ts +44 -0
- package/src/commands/upgrade.ts +231 -0
- package/src/commands/wiki.ts +100 -0
- package/src/commands/worktrees.ts +191 -0
- package/src/comments/scan.ts +338 -0
- package/src/comments/trend.ts +207 -0
- package/src/comments/vocabulary.ts +85 -0
- package/src/context/architecture.ts +364 -0
- package/src/context/audit.ts +790 -0
- package/src/context/citations.ts +196 -0
- package/src/context/folders.ts +186 -0
- package/src/context/gate.ts +57 -0
- package/src/context/index-drift.ts +64 -0
- package/src/context/narration.ts +99 -0
- package/src/copy.ts +30 -0
- package/src/counts/catalogs.ts +96 -0
- package/src/counts/numbers.ts +79 -0
- package/src/counts/scan.ts +314 -0
- package/src/demo/beats.ts +135 -0
- package/src/demo/compile.ts +326 -0
- package/src/demo/container.ts +63 -0
- package/src/demo/cursors.ts +55 -0
- package/src/demo/drive.ts +357 -0
- package/src/demo/pointer.ts +178 -0
- package/src/demo/theme.ts +112 -0
- package/src/deps/audit.ts +153 -0
- package/src/design/parse.ts +116 -0
- package/src/design/render.ts +249 -0
- package/src/docs/read.ts +77 -0
- package/src/exec.ts +16 -0
- package/src/exempt-marker.ts +43 -0
- package/src/frontmatter.ts +13 -0
- package/src/gate/measures.ts +682 -0
- package/src/gate/sequencer.ts +386 -0
- package/src/gate/stages.ts +412 -0
- package/src/git-env.ts +36 -0
- package/src/git-files.ts +105 -0
- package/src/git-ignore.ts +46 -0
- package/src/github-format.ts +13 -0
- package/src/github.ts +24 -0
- package/src/gov/adapter.ts +103 -0
- package/src/gov/citations.ts +514 -0
- package/src/gov/consumed.ts +129 -0
- package/src/gov/install.ts +132 -0
- package/src/gov/list.ts +106 -0
- package/src/gov/payload.ts +39 -0
- package/src/gov/restated.ts +814 -0
- package/src/gov/stacks.ts +205 -0
- package/src/gov/superseded.ts +415 -0
- package/src/gov/test-order.ts +407 -0
- package/src/indexes/frontmatter.ts +46 -0
- package/src/indexes/regen.ts +84 -0
- package/src/indexes/render.ts +201 -0
- package/src/indexes/walk.ts +83 -0
- package/src/init/flags.ts +60 -0
- package/src/init/plan.ts +114 -0
- package/src/init/run.ts +46 -0
- package/src/init/steps.ts +77 -0
- package/src/intake/folder.ts +320 -0
- package/src/intake/items.ts +174 -0
- package/src/inventory/config.ts +117 -0
- package/src/inventory/group.ts +76 -0
- package/src/inventory/subjects.ts +114 -0
- package/src/inventory/walk.ts +129 -0
- package/src/labels/audit.ts +82 -0
- package/src/labels/coverage.ts +79 -0
- package/src/labels/map.ts +101 -0
- package/src/labels/phase.ts +95 -0
- package/src/markdown/bans.ts +94 -0
- package/src/markdown/files.ts +102 -0
- package/src/markdown/gate.ts +28 -0
- package/src/markdown/scan.ts +295 -0
- package/src/markdown/structure.ts +730 -0
- package/src/migrate/apply.ts +115 -0
- package/src/migrate/plan.ts +103 -0
- package/src/migrate/rename.ts +183 -0
- package/src/pr/bijection.ts +145 -0
- package/src/pr/paths.ts +335 -0
- package/src/process/harness.ts +167 -0
- package/src/project-root.ts +19 -0
- package/src/records/backup.ts +455 -0
- package/src/records/migrate.ts +78 -0
- package/src/records/size.ts +260 -0
- package/src/records/validate.ts +1162 -0
- package/src/sandbox/census.ts +228 -0
- package/src/sandbox/coverage.ts +115 -0
- package/src/sandbox/expect.ts +629 -0
- package/src/sandbox/tree.ts +47 -0
- package/src/secrets/marker.ts +30 -0
- package/src/secrets/patterns.ts +142 -0
- package/src/secrets/scan.ts +123 -0
- package/src/secrets/shipped.ts +111 -0
- package/src/seed-marker.ts +74 -0
- package/src/serve/static.ts +322 -0
- package/src/sessions/claim.ts +85 -0
- package/src/sessions/live.ts +79 -0
- package/src/sessions/registry.ts +137 -0
- package/src/sessions/resolve.ts +333 -0
- package/src/slides/layouts.ts +391 -0
- package/src/slides/open.ts +18 -0
- package/src/slides/parse.ts +84 -0
- package/src/slides/render.ts +88 -0
- package/src/slides/styles.ts +44 -0
- package/src/snippets/categories.ts +66 -0
- package/src/snippets/list.ts +32 -0
- package/src/snippets/presets.ts +50 -0
- package/src/standards/audit.ts +132 -0
- package/src/standards/read.ts +100 -0
- package/src/sync/check.ts +692 -0
- package/src/sync/engine.ts +576 -0
- package/src/sync/git.ts +225 -0
- package/src/sync/history.ts +123 -0
- package/src/sync/layout.ts +140 -0
- package/src/sync/reverse.ts +268 -0
- package/src/sync/seeds-report.ts +126 -0
- package/src/sync/stamp.ts +358 -0
- package/src/sync/target.ts +70 -0
- package/src/sync/workflow.ts +200 -0
- package/src/target.ts +43 -0
- package/src/targets/pulls.ts +250 -0
- package/src/targets/registry.ts +203 -0
- package/src/targets/resolve.ts +145 -0
- package/src/targets/sweep.ts +246 -0
- package/src/tasks/archive.ts +506 -0
- package/src/tasks/record.ts +311 -0
- package/src/tasks/trunk.ts +89 -0
- package/src/tasks/validate.ts +1001 -0
- package/src/teach/lesson.ts +180 -0
- package/src/teach/workspace.ts +842 -0
- package/src/tooling/gitignore.ts +122 -0
- package/src/tooling/inject.ts +193 -0
- package/src/tooling/list.ts +39 -0
- package/src/tooling/manifest.ts +176 -0
- package/src/tooling/package.ts +166 -0
- package/src/tooling/read.ts +65 -0
- package/src/tooling/scan.ts +147 -0
- package/src/tooling/stamp.ts +44 -0
- package/src/transcripts/fetch.ts +156 -0
- package/src/transcripts/metadata.ts +54 -0
- package/src/transcripts/vtt.ts +114 -0
- package/src/ui.ts +266 -0
- package/src/version/compare.ts +53 -0
- package/src/version/installed.ts +40 -0
- package/src/version/manager.ts +67 -0
- package/src/version/skew.ts +192 -0
- package/src/wiki/init.ts +85 -0
- package/src/worktree.ts +143 -0
- package/src/worktrees/reclaim.ts +306 -0
- package/standards/architecture.md +72 -0
- package/standards/branch.md +59 -0
- package/standards/commit.md +72 -0
- package/standards/context.md +151 -0
- package/standards/design.md +93 -0
- package/standards/diagrams.md +152 -0
- package/standards/glossary.md +75 -0
- package/standards/groundwork.md +211 -0
- package/standards/index.md +36 -0
- package/standards/intake.md +192 -0
- package/standards/issue.md +94 -0
- package/standards/markdown.md +137 -0
- package/standards/memory.md +144 -0
- package/standards/plan.md +172 -0
- package/standards/pr.md +139 -0
- package/standards/publish.md +51 -0
- package/standards/readme.md +208 -0
- package/standards/requirements.md +70 -0
- package/standards/rule.md +118 -0
- package/standards/session.md +109 -0
- package/standards/skill.md +300 -0
- package/standards/slug.md +39 -0
- package/standards/snippets.md +76 -0
- package/standards/standard.md +170 -0
- package/standards/tasks.md +254 -0
- package/standards/teach.md +153 -0
- package/standards/versioning.md +71 -0
- package/standards/wireframes.md +113 -0
- package/tooling/astro/configs/astro.config.mjs +31 -0
- package/tooling/astro/configs/eslint.config.js +79 -0
- package/tooling/astro/configs/playwright.config.ts +26 -0
- package/tooling/astro/configs/tsconfig.json +12 -0
- package/tooling/astro/configs/vitest.config.ts +22 -0
- package/tooling/astro/manifest.toml +34 -0
- package/tooling/astro/reference.md +60 -0
- package/tooling/base/configs/.editorconfig +5 -0
- package/tooling/base/configs/.github/pull_request_template.md +18 -0
- package/tooling/base/configs/.github/workflows/verify.yml +35 -0
- package/tooling/base/configs/.husky/commit-msg +1 -0
- package/tooling/base/configs/.husky/post-merge +61 -0
- package/tooling/base/configs/.husky/post-rewrite +21 -0
- package/tooling/base/configs/.husky/pre-commit +1 -0
- package/tooling/base/configs/.husky/pre-push +1 -0
- package/tooling/base/configs/.prettierrc +12 -0
- package/tooling/base/configs/.shellcheckrc +1 -0
- package/tooling/base/configs/.vscode/extensions.json +9 -0
- package/tooling/base/configs/.vscode/settings.json +3 -0
- package/tooling/base/configs/commitlint.config.js +11 -0
- package/tooling/base/configs/scripts/verify.sh +64 -0
- package/tooling/base/manifest.toml +30 -0
- package/tooling/base/reference.md +98 -0
- package/tooling/base/seeds/.claude/context/ci.md +33 -0
- package/tooling/base/seeds/.claude/context/development.md +37 -0
- package/tooling/base/seeds/.claude/context/index.md +11 -0
- package/tooling/base/seeds/.cspell/project-terms.txt +0 -0
- package/tooling/base/seeds/.cspell/tech-stack.txt +19 -0
- package/tooling/base/seeds/.lintstagedrc +8 -0
- package/tooling/base/seeds/.prettierignore +0 -0
- package/tooling/base/seeds/cspell.json +20 -0
- package/tooling/claude/manifest.toml +14 -0
- package/tooling/claude/reference.md +79 -0
- package/tooling/claude/seeds/.claude/ARCHITECTURE.md +13 -0
- package/tooling/claude/seeds/.claude/DESIGN.md +62 -0
- package/tooling/claude/seeds/.claude/REQUIREMENTS.md +18 -0
- package/tooling/claude/seeds/.claude/diagrams/index.md +8 -0
- package/tooling/claude/seeds/.claude/hooks/index-reminder.sh +50 -0
- package/tooling/claude/seeds/.claude/hooks/memory-index.sh +68 -0
- package/tooling/claude/seeds/.claude/hooks/path-form.sh +57 -0
- package/tooling/claude/seeds/.claude/hooks/scratch-guard.sh +52 -0
- package/tooling/claude/seeds/.claude/hooks/standards-audit.sh +86 -0
- package/tooling/claude/seeds/.claude/hooks/tasks-index.sh +71 -0
- package/tooling/claude/seeds/.claude/memory/index.md +8 -0
- package/tooling/claude/seeds/.claude/settings.json +47 -0
- package/tooling/claude/seeds/.claude/tasks/index.md +8 -0
- package/tooling/claude/seeds/.claude/wireframes/index.md +8 -0
- package/tooling/claude/seeds/CLAUDE.md +29 -0
- package/tooling/claude/user/settings.template.json +10 -0
- package/tooling/claude/user/statusline-command.sh +53 -0
- package/tooling/python/configs/.coveragerc +14 -0
- package/tooling/python/configs/.python-version +1 -0
- package/tooling/python/configs/mypy.ini +6 -0
- package/tooling/python/configs/pytest.ini +4 -0
- package/tooling/python/configs/ruff.toml +15 -0
- package/tooling/python/configs/scripts/verify.sh +77 -0
- package/tooling/python/manifest.toml +16 -0
- package/tooling/python/reference.md +66 -0
- package/tooling/python/seeds/.cspell/tech-stack.txt +19 -0
- package/tooling/python/seeds/tests/test_smoke.py +2 -0
- package/tooling/vite-react/configs/playwright.config.ts +26 -0
- package/tooling/vite-react/configs/tsconfig.json +35 -0
- package/tooling/vite-react/configs/vite.config.ts +24 -0
- package/tooling/vite-react/configs/vitest.config.ts +26 -0
- package/tooling/vite-react/manifest.toml +23 -0
- package/tooling/vite-react/reference.md +55 -0
- package/tooling/vite-react/seeds/.cspell/project-terms.txt +1 -0
- package/tooling/vite-react/seeds/.cspell/tech-stack.txt +1 -0
- package/tooling/web/configs/.github/workflows/verify.yml +134 -0
- package/tooling/web/configs/.vscode/extensions.json +13 -0
- package/tooling/web/configs/.vscode/settings.json +10 -0
- package/tooling/web/configs/e2e/home.spec.ts +6 -0
- package/tooling/web/configs/e2e/screenshot.ts +53 -0
- package/tooling/web/configs/eslint.config.js +82 -0
- package/tooling/web/configs/scripts/screenshot.sh +28 -0
- package/tooling/web/configs/scripts/verify.sh +80 -0
- package/tooling/web/configs/scripts/worktree-port.sh +74 -0
- package/tooling/web/configs/src/test/setup.ts +8 -0
- package/tooling/web/manifest.toml +58 -0
- package/tooling/web/reference.md +115 -0
- package/tooling/web/seeds/.cspell/tech-stack.txt +18 -0
- package/tsconfig.json +14 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import type { Command } from 'commander'
|
|
2
|
+
import { execa } from 'execa'
|
|
3
|
+
import { PROJECT_ROOT } from '@/project-root'
|
|
4
|
+
import {
|
|
5
|
+
frameError,
|
|
6
|
+
intro,
|
|
7
|
+
logInfo,
|
|
8
|
+
logStep,
|
|
9
|
+
logWarn,
|
|
10
|
+
outro,
|
|
11
|
+
select,
|
|
12
|
+
} from '@/ui'
|
|
13
|
+
import { readInstalled, UNKNOWN_LABEL } from '@/version/installed'
|
|
14
|
+
import { detectManager, installCommand, type Manager } from '@/version/manager'
|
|
15
|
+
import {
|
|
16
|
+
describeSkew,
|
|
17
|
+
latestOf,
|
|
18
|
+
readSkew,
|
|
19
|
+
type SkewReport,
|
|
20
|
+
} from '@/version/skew'
|
|
21
|
+
|
|
22
|
+
interface UpgradeOptions {
|
|
23
|
+
readonly json?: boolean
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface UpgradeRecord {
|
|
27
|
+
readonly root: string
|
|
28
|
+
readonly manager?: string
|
|
29
|
+
readonly command?: string
|
|
30
|
+
readonly before: string
|
|
31
|
+
readonly after?: string
|
|
32
|
+
readonly latest?: string
|
|
33
|
+
readonly state: 'upgraded' | 'current' | 'cancelled' | 'refused'
|
|
34
|
+
readonly reason?: string
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function register(program: Command): void {
|
|
38
|
+
program
|
|
39
|
+
.command('upgrade')
|
|
40
|
+
.description(
|
|
41
|
+
'Reinstall the CLI globally with whichever package manager installed it',
|
|
42
|
+
)
|
|
43
|
+
.helpOption('-h, --help', 'Show this help message')
|
|
44
|
+
.option('--json', 'Add a machine-readable record on stdout')
|
|
45
|
+
.addHelpText(
|
|
46
|
+
'after',
|
|
47
|
+
[
|
|
48
|
+
'',
|
|
49
|
+
'Exit codes:',
|
|
50
|
+
' 0 the binary is current, the reinstall completed, or it was cancelled',
|
|
51
|
+
' 1 refused or the reinstall failed, with the reason on stderr',
|
|
52
|
+
'',
|
|
53
|
+
'The package manager is read off the install path rather than guessed',
|
|
54
|
+
'from PATH, and named before anything runs. A source checkout matches no',
|
|
55
|
+
'install tree and is refused rather than reinstalled over.',
|
|
56
|
+
'',
|
|
57
|
+
'Examples:',
|
|
58
|
+
' canon upgrade',
|
|
59
|
+
' canon upgrade --json',
|
|
60
|
+
'',
|
|
61
|
+
].join('\n'),
|
|
62
|
+
)
|
|
63
|
+
.action(async (opts: UpgradeOptions) => {
|
|
64
|
+
process.exitCode = await runUpgrade(opts)
|
|
65
|
+
})
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Detection runs before the registry lookup so the one case that cannot upgrade
|
|
70
|
+
* at all, a source checkout, refuses without waiting on a network call whose
|
|
71
|
+
* answer it would then discard.
|
|
72
|
+
*/
|
|
73
|
+
async function runUpgrade(opts: UpgradeOptions): Promise<number> {
|
|
74
|
+
const installed = readInstalled()
|
|
75
|
+
const before = installed.version ?? UNKNOWN_LABEL
|
|
76
|
+
|
|
77
|
+
intro('canon upgrade')
|
|
78
|
+
logStep('Installed')
|
|
79
|
+
logInfo(`${installed.name ?? UNKNOWN_LABEL} ${before}`)
|
|
80
|
+
logInfo(PROJECT_ROOT)
|
|
81
|
+
|
|
82
|
+
const manager = detectManager(PROJECT_ROOT)
|
|
83
|
+
if (manager === undefined) {
|
|
84
|
+
return refuse(
|
|
85
|
+
opts,
|
|
86
|
+
before,
|
|
87
|
+
`No package manager owns ${PROJECT_ROOT}. A source checkout is upgraded by pulling, not by reinstalling over it.`,
|
|
88
|
+
)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// A manifest that did not parse, or carried no `name`, would otherwise reach
|
|
92
|
+
// `installCommand` and produce a global install of whatever sits under that
|
|
93
|
+
// placeholder on the registry. The prompt below defaults to yes headlessly,
|
|
94
|
+
// so nothing downstream would stop it.
|
|
95
|
+
if (installed.name === undefined) {
|
|
96
|
+
return refuse(
|
|
97
|
+
opts,
|
|
98
|
+
before,
|
|
99
|
+
`No package name in ${PROJECT_ROOT}/package.json, so there is nothing safe to reinstall. Repair the manifest, or reinstall by name yourself.`,
|
|
100
|
+
manager,
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const command = installCommand(manager.id, installed.name)
|
|
105
|
+
logStep('Detected')
|
|
106
|
+
logInfo(`${manager.id}, from the \`${manager.evidence}\` path segment`)
|
|
107
|
+
logInfo(command.join(' '))
|
|
108
|
+
|
|
109
|
+
const skew = await readSkew({ installed })
|
|
110
|
+
logStep('Published')
|
|
111
|
+
logInfo(describeSkew(skew))
|
|
112
|
+
|
|
113
|
+
if (skew.state === 'current') {
|
|
114
|
+
outro()
|
|
115
|
+
emit(opts, {
|
|
116
|
+
...base(before, manager, command, skew),
|
|
117
|
+
after: before,
|
|
118
|
+
state: 'current',
|
|
119
|
+
})
|
|
120
|
+
return 0
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return await applyUpgrade(opts, before, skew, manager, command)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Runs the reinstall and reads the version back off disk rather than trusting
|
|
128
|
+
* the manager's own report, since each spells success differently and one of
|
|
129
|
+
* them exits zero on a no-op. The read is the same `package.json` the CLI names
|
|
130
|
+
* on `--version`, which the install has overwritten by this point.
|
|
131
|
+
*
|
|
132
|
+
* An `unknown` skew reaches here rather than stopping. The operator asked for
|
|
133
|
+
* the reinstall, and the manager reports its own network failure in terms the
|
|
134
|
+
* dist-tag endpoint cannot.
|
|
135
|
+
*/
|
|
136
|
+
async function applyUpgrade(
|
|
137
|
+
opts: UpgradeOptions,
|
|
138
|
+
before: string,
|
|
139
|
+
skew: SkewReport,
|
|
140
|
+
manager: Manager,
|
|
141
|
+
command: readonly string[],
|
|
142
|
+
): Promise<number> {
|
|
143
|
+
const proceed = await select({
|
|
144
|
+
message: `Run \`${command.join(' ')}\`?`,
|
|
145
|
+
options: [
|
|
146
|
+
{ value: true, label: 'Upgrade' },
|
|
147
|
+
{ value: false, label: 'Cancel' },
|
|
148
|
+
],
|
|
149
|
+
nonInteractiveDefault: true,
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
if (!proceed) {
|
|
153
|
+
logWarn('Cancelled')
|
|
154
|
+
outro()
|
|
155
|
+
emit(opts, { ...base(before, manager, command, skew), state: 'cancelled' })
|
|
156
|
+
return 0
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
logStep('Upgrading')
|
|
160
|
+
const [bin, ...args] = command
|
|
161
|
+
// The manager's own progress goes to stderr with the rest of the UI, leaving
|
|
162
|
+
// stdout carrying nothing but the record. Inheriting all three streams would
|
|
163
|
+
// put npm's output ahead of the JSON and break every wrapper parsing it.
|
|
164
|
+
const result = await execa(bin, args, {
|
|
165
|
+
reject: false,
|
|
166
|
+
stdin: 'inherit',
|
|
167
|
+
stdout: process.stderr,
|
|
168
|
+
stderr: 'inherit',
|
|
169
|
+
})
|
|
170
|
+
|
|
171
|
+
if (result.exitCode !== 0) {
|
|
172
|
+
return refuse(
|
|
173
|
+
opts,
|
|
174
|
+
before,
|
|
175
|
+
`\`${command.join(' ')}\` exited ${result.exitCode}. Run it yourself to read what it reported.`,
|
|
176
|
+
manager,
|
|
177
|
+
)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const after = readInstalled().version ?? UNKNOWN_LABEL
|
|
181
|
+
logStep('Installed')
|
|
182
|
+
logInfo(after === before ? `${after}, unchanged` : `${before} to ${after}`)
|
|
183
|
+
outro()
|
|
184
|
+
|
|
185
|
+
emit(opts, {
|
|
186
|
+
...base(before, manager, command, skew),
|
|
187
|
+
after,
|
|
188
|
+
state: 'upgraded',
|
|
189
|
+
})
|
|
190
|
+
return 0
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function base(
|
|
194
|
+
before: string,
|
|
195
|
+
manager: Manager,
|
|
196
|
+
command: readonly string[],
|
|
197
|
+
skew: SkewReport,
|
|
198
|
+
): Omit<UpgradeRecord, 'state'> {
|
|
199
|
+
const latest = latestOf(skew)
|
|
200
|
+
|
|
201
|
+
return {
|
|
202
|
+
root: PROJECT_ROOT,
|
|
203
|
+
manager: manager.id,
|
|
204
|
+
command: command.join(' '),
|
|
205
|
+
before,
|
|
206
|
+
...(latest === undefined ? {} : { latest }),
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function refuse(
|
|
211
|
+
opts: UpgradeOptions,
|
|
212
|
+
before: string,
|
|
213
|
+
reason: string,
|
|
214
|
+
manager?: Manager,
|
|
215
|
+
): number {
|
|
216
|
+
outro()
|
|
217
|
+
frameError(reason)
|
|
218
|
+
emit(opts, {
|
|
219
|
+
root: PROJECT_ROOT,
|
|
220
|
+
...(manager === undefined ? {} : { manager: manager.id }),
|
|
221
|
+
before,
|
|
222
|
+
state: 'refused',
|
|
223
|
+
reason,
|
|
224
|
+
})
|
|
225
|
+
return 1
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function emit(opts: UpgradeOptions, record: UpgradeRecord): void {
|
|
229
|
+
if (opts.json !== true) return
|
|
230
|
+
process.stdout.write(`${JSON.stringify(record)}\n`)
|
|
231
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { resolve } from 'node:path'
|
|
2
|
+
import type { Command } from 'commander'
|
|
3
|
+
import { PROJECT_ROOT } from '@/project-root'
|
|
4
|
+
import {
|
|
5
|
+
intro,
|
|
6
|
+
logAdd,
|
|
7
|
+
logError,
|
|
8
|
+
logInfo,
|
|
9
|
+
logStep,
|
|
10
|
+
logWarn,
|
|
11
|
+
outro,
|
|
12
|
+
palette,
|
|
13
|
+
select,
|
|
14
|
+
} from '@/ui'
|
|
15
|
+
import {
|
|
16
|
+
applyWikiInit,
|
|
17
|
+
isWikiTarget,
|
|
18
|
+
LEGACY_WIKI_DIR_REL,
|
|
19
|
+
planWikiInit,
|
|
20
|
+
WIKI_DIR_REL,
|
|
21
|
+
WIKI_INDEX_REL,
|
|
22
|
+
} from '@/wiki/init'
|
|
23
|
+
|
|
24
|
+
export function register(program: Command): void {
|
|
25
|
+
const wiki = program
|
|
26
|
+
.command('wiki')
|
|
27
|
+
.description('Wiki commands (init)')
|
|
28
|
+
.helpOption('-h, --help', 'Show this help message')
|
|
29
|
+
|
|
30
|
+
wiki
|
|
31
|
+
.command('init')
|
|
32
|
+
.description('Scaffold .claude/wiki/ with a stub index.md')
|
|
33
|
+
.argument('[target]', 'Target directory', '.')
|
|
34
|
+
.helpOption('-h, --help', 'Show this help message')
|
|
35
|
+
.action(async (target: string) => {
|
|
36
|
+
process.exitCode = await runInit(target)
|
|
37
|
+
})
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async function runInit(target: string): Promise<number> {
|
|
41
|
+
intro('canon wiki')
|
|
42
|
+
|
|
43
|
+
const resolved = resolve(target)
|
|
44
|
+
|
|
45
|
+
if (!isWikiTarget(resolved)) {
|
|
46
|
+
logError(`Target directory not found: ${target}`)
|
|
47
|
+
outro()
|
|
48
|
+
return 1
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (resolved === PROJECT_ROOT) {
|
|
52
|
+
logError(
|
|
53
|
+
'Cannot run against toolkit root. Files here are the source of truth.',
|
|
54
|
+
)
|
|
55
|
+
outro()
|
|
56
|
+
return 1
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const plan = planWikiInit(resolved)
|
|
60
|
+
const { GREEN, NC } = palette(process.stderr)
|
|
61
|
+
|
|
62
|
+
logStep(`Scanning ${WIKI_DIR_REL}`)
|
|
63
|
+
if (plan.changes.includes('dir')) logAdd(WIKI_DIR_REL)
|
|
64
|
+
if (plan.hasIndex) logInfo(WIKI_INDEX_REL)
|
|
65
|
+
else logAdd(WIKI_INDEX_REL)
|
|
66
|
+
|
|
67
|
+
if (plan.hasLegacyWiki) {
|
|
68
|
+
logWarn(`${LEGACY_WIKI_DIR_REL} found at the target root, not migrated`)
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const count = plan.changes.length
|
|
72
|
+
if (count === 0) {
|
|
73
|
+
outro()
|
|
74
|
+
process.stderr.write(`${GREEN}✓ Wiki already initialized${NC}\n`)
|
|
75
|
+
return 0
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const shouldApply = await select({
|
|
79
|
+
message: `Apply ${count} change(s)?`,
|
|
80
|
+
options: [
|
|
81
|
+
{ value: true, label: 'Apply all' },
|
|
82
|
+
{ value: false, label: 'Cancel' },
|
|
83
|
+
],
|
|
84
|
+
nonInteractiveDefault: true,
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
if (!shouldApply) {
|
|
88
|
+
logWarn('Cancelled')
|
|
89
|
+
outro()
|
|
90
|
+
return 0
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
logStep('Applying changes')
|
|
94
|
+
await applyWikiInit(resolved, plan)
|
|
95
|
+
if (plan.changes.includes('index')) logAdd(WIKI_INDEX_REL)
|
|
96
|
+
|
|
97
|
+
outro()
|
|
98
|
+
process.stderr.write(`${GREEN}✓ Wiki ready${NC}\n`)
|
|
99
|
+
return 0
|
|
100
|
+
}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import type { Command } from 'commander'
|
|
2
|
+
import {
|
|
3
|
+
intro,
|
|
4
|
+
logInfo,
|
|
5
|
+
logStep,
|
|
6
|
+
logWarn,
|
|
7
|
+
outro,
|
|
8
|
+
pipeOutput,
|
|
9
|
+
plural,
|
|
10
|
+
} from '@/ui'
|
|
11
|
+
import {
|
|
12
|
+
type Refusal,
|
|
13
|
+
reclaimReport,
|
|
14
|
+
type Unreadable,
|
|
15
|
+
type WorktreeVerdict,
|
|
16
|
+
} from '@/worktrees/reclaim'
|
|
17
|
+
|
|
18
|
+
interface ListCommandOptions {
|
|
19
|
+
readonly json?: boolean
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const REFUSALS: Record<Refusal, string> = {
|
|
23
|
+
'main-worktree': 'the main worktree, which is never reclaimable',
|
|
24
|
+
'detached-head': 'detached HEAD, so no branch names a pull request',
|
|
25
|
+
'no-merged-pull-request': 'no merged pull request for its branch',
|
|
26
|
+
'uncommitted-changes': 'uncommitted work no history stands behind',
|
|
27
|
+
'unreadable-worktree': 'the working tree could not be read',
|
|
28
|
+
'held-by-session': 'a live session still holds it',
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const UNREADABLE: Record<Unreadable, string> = {
|
|
32
|
+
'gh-missing':
|
|
33
|
+
'gh is not on the path, so the merge state could not be read. Install it and run this again.',
|
|
34
|
+
'gh-failed':
|
|
35
|
+
'The pull request read failed, so every worktree would report as unmerged whatever its real state. Authenticate gh and run this again.',
|
|
36
|
+
'sessions-unreadable':
|
|
37
|
+
'The session roster could not be read, so nothing was read about which worktrees are still held.',
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function register(program: Command): void {
|
|
41
|
+
const worktrees = program
|
|
42
|
+
.command('worktrees')
|
|
43
|
+
.description('Report which worktrees are reclaimable and which are not')
|
|
44
|
+
.helpOption('-h, --help', 'Show this help message')
|
|
45
|
+
|
|
46
|
+
worktrees
|
|
47
|
+
.command('list')
|
|
48
|
+
.description(
|
|
49
|
+
'Report every worktree with a reclaim verdict and the reason behind it',
|
|
50
|
+
)
|
|
51
|
+
.helpOption('-h, --help', 'Show this help message')
|
|
52
|
+
.option('--json', 'Add a machine-readable record on stdout')
|
|
53
|
+
.addHelpText(
|
|
54
|
+
'after',
|
|
55
|
+
[
|
|
56
|
+
'',
|
|
57
|
+
'Exit codes:',
|
|
58
|
+
' 0 every worktree was read',
|
|
59
|
+
' 1 refused, with the reason on stderr',
|
|
60
|
+
'',
|
|
61
|
+
'A worktree is reclaimable when all three hold: its branch has a merged',
|
|
62
|
+
'pull request, its working tree is clean, and no live session holds it.',
|
|
63
|
+
'Each alone has a case where removal loses something, so "refusals"',
|
|
64
|
+
'carries every failing condition rather than the first.',
|
|
65
|
+
'',
|
|
66
|
+
'The merged state comes from gh rather than from git ancestry. A',
|
|
67
|
+
'repository that squash merges never makes a merged branch an ancestor',
|
|
68
|
+
'of its trunk, so ancestry calls shipped work unmerged and calls an',
|
|
69
|
+
'abandoned branch sitting at a release commit merged.',
|
|
70
|
+
'',
|
|
71
|
+
'This reports and removes nothing. "route" names which removal shape',
|
|
72
|
+
'applies: "session" when a live session holds the directory, where',
|
|
73
|
+
'`claude rm <name>` takes the session and its worktree together, and',
|
|
74
|
+
'"worktree" when the session has ended, where `git worktree remove`',
|
|
75
|
+
'and a branch delete are the pair.',
|
|
76
|
+
'',
|
|
77
|
+
'An unreadable input refuses the whole reading rather than reporting',
|
|
78
|
+
'every worktree as not reclaimable, since an absent merge state and a',
|
|
79
|
+
'branch with no merged pull request produce the same empty answer.',
|
|
80
|
+
'',
|
|
81
|
+
'The merge read covers the most recent 200 merged pull requests. A',
|
|
82
|
+
'worktree older than that reads as having none and is refused, which',
|
|
83
|
+
'keeps a directory rather than removing one.',
|
|
84
|
+
'',
|
|
85
|
+
'Examples:',
|
|
86
|
+
' canon worktrees list',
|
|
87
|
+
' canon worktrees list --json',
|
|
88
|
+
'',
|
|
89
|
+
].join('\n'),
|
|
90
|
+
)
|
|
91
|
+
.action(async (opts: ListCommandOptions) => {
|
|
92
|
+
process.exitCode = await runList(opts)
|
|
93
|
+
})
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async function runList(opts: ListCommandOptions): Promise<number> {
|
|
97
|
+
const report = await reclaimReport({ cwd: process.cwd() })
|
|
98
|
+
|
|
99
|
+
intro('canon worktrees list')
|
|
100
|
+
|
|
101
|
+
if (report.kind === 'unreadable') {
|
|
102
|
+
logStep('Refused')
|
|
103
|
+
logWarn(UNREADABLE[report.reason])
|
|
104
|
+
logInfo(report.detail)
|
|
105
|
+
outro()
|
|
106
|
+
|
|
107
|
+
if (opts.json) {
|
|
108
|
+
process.stdout.write(
|
|
109
|
+
`${JSON.stringify({
|
|
110
|
+
reason: report.reason,
|
|
111
|
+
detail: report.detail,
|
|
112
|
+
worktrees: [],
|
|
113
|
+
})}\n`,
|
|
114
|
+
)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return 1
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
reportWorktrees(report.worktrees)
|
|
121
|
+
outro()
|
|
122
|
+
|
|
123
|
+
if (opts.json) {
|
|
124
|
+
process.stdout.write(
|
|
125
|
+
`${JSON.stringify({
|
|
126
|
+
reason: null,
|
|
127
|
+
detail: null,
|
|
128
|
+
worktrees: report.worktrees,
|
|
129
|
+
})}\n`,
|
|
130
|
+
)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return 0
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function reportWorktrees(worktrees: readonly WorktreeVerdict[]): void {
|
|
137
|
+
logStep('Worktrees')
|
|
138
|
+
|
|
139
|
+
if (worktrees.length === 0) {
|
|
140
|
+
logInfo('No worktree resolved here. Run this inside a repository.')
|
|
141
|
+
return
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
logInfo(plural(worktrees.length, 'worktree'))
|
|
145
|
+
pipeOutput(worktrees.map(describe).join('\n'))
|
|
146
|
+
|
|
147
|
+
const reclaimable = worktrees.filter((entry) => entry.reclaimable)
|
|
148
|
+
|
|
149
|
+
logStep('Reclaimable')
|
|
150
|
+
if (reclaimable.length === 0) {
|
|
151
|
+
logInfo('None. Every worktree fails at least one condition.')
|
|
152
|
+
return
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
logWarn(
|
|
156
|
+
`${plural(reclaimable.length, 'worktree')} can be reclaimed. This reports and removes nothing, so run the named command yourself.`,
|
|
157
|
+
)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Names the evidence beside the conclusion on every row.
|
|
162
|
+
*
|
|
163
|
+
* The reading has two consumers and they act on different halves. The sweep
|
|
164
|
+
* reads the verdict to decide what to offer, and a person reads it to decide
|
|
165
|
+
* what to remove, so a row phrased for the first alone leaves the second
|
|
166
|
+
* removing a directory on a conclusion it cannot check.
|
|
167
|
+
*/
|
|
168
|
+
function describe(verdict: WorktreeVerdict): string {
|
|
169
|
+
const held = verdict.branch ?? 'detached'
|
|
170
|
+
const head = `${verdict.path} ${held}`
|
|
171
|
+
|
|
172
|
+
if (!verdict.reclaimable) {
|
|
173
|
+
const reasons = verdict.refusals.map((refusal) => REFUSALS[refusal])
|
|
174
|
+
// A name is quoted because a session carries whatever string it was
|
|
175
|
+
// launched under, spaces included, and one command per name because a
|
|
176
|
+
// joined list reads as a single argument.
|
|
177
|
+
const routes =
|
|
178
|
+
verdict.route === 'session'
|
|
179
|
+
? verdict.sessions.map(
|
|
180
|
+
(name) => `\n Removal there goes through: claude rm '${name}'`,
|
|
181
|
+
)
|
|
182
|
+
: []
|
|
183
|
+
return `${head}\n Refused: ${reasons.join('; ')}.${routes.join('')}`
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
return [
|
|
187
|
+
head,
|
|
188
|
+
` Reclaimable. Pull request #${verdict.pullRequest} merged it, the tree is clean, and no session holds it.`,
|
|
189
|
+
` Remove with: git worktree remove ${verdict.path} && git branch -D ${held}`,
|
|
190
|
+
].join('\n')
|
|
191
|
+
}
|