@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,158 @@
|
|
|
1
|
+
import type { SkillCase } from '@/claude/skills-rank'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The `claude-*` skill family: feature planning, review, and the session
|
|
5
|
+
* artifacts that coordinate work across sessions.
|
|
6
|
+
*
|
|
7
|
+
* Every positive is phrased away from its skill's own quoted trigger, since a
|
|
8
|
+
* verbatim trigger passes by construction and proves nothing about a prompt in
|
|
9
|
+
* someone's own words. Negatives target the pairs whose bodies already state
|
|
10
|
+
* an explicit `Do NOT` boundary against each other, since a boundary in a
|
|
11
|
+
* body does not reach the field a router reads.
|
|
12
|
+
*/
|
|
13
|
+
export const CLAUDE_WORKFLOW_CASES: readonly SkillCase[] = [
|
|
14
|
+
{
|
|
15
|
+
prompt: 'Go fix everything the reviewer flagged on my open PR.',
|
|
16
|
+
expect: 'claude-address-review',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
prompt:
|
|
20
|
+
'Run the whole implement, verify, review, and ship pipeline for the approved plan.',
|
|
21
|
+
expect: 'claude-autoship',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
prompt: "Pull together a design system from what's already in the app.",
|
|
25
|
+
expect: 'claude-design-extract',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
prompt: 'Draw me a diagram of how the pieces of this system connect.',
|
|
29
|
+
expect: 'claude-diagram',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
prompt:
|
|
33
|
+
'Bring the internal planning docs under .claude up to date with what we decided this session.',
|
|
34
|
+
expect: 'claude-docs',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
prompt:
|
|
38
|
+
'Sketch out a plan for adding this new capability before we touch any code.',
|
|
39
|
+
expect: 'claude-feature',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
prompt:
|
|
43
|
+
'We need to measure this properly before committing to an approach.',
|
|
44
|
+
expect: 'claude-groundwork',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
prompt: 'Take this pile of raw notes and turn it into filed items.',
|
|
48
|
+
expect: 'claude-intake',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
prompt: 'Walk me through the open intake items so I can decide on each.',
|
|
52
|
+
expect: 'claude-intake-answer',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
prompt:
|
|
56
|
+
"Draft a diff-based proposal for tightening this passage in the standard, don't just edit it.",
|
|
57
|
+
expect: 'claude-markdown-propose',
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
prompt: 'Pull the durable lessons out of this session before it ends.',
|
|
61
|
+
expect: 'claude-memory-capture',
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
prompt:
|
|
65
|
+
'Go through the memory folder and propose what to do with each entry.',
|
|
66
|
+
expect: 'claude-memory-review',
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
prompt:
|
|
70
|
+
'Take on the orchestrator role and coordinate the parallel feature builds.',
|
|
71
|
+
expect: 'claude-orchestrate',
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
prompt: 'Post a formal review with findings on that open pull request.',
|
|
75
|
+
expect: 'claude-pr-review',
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
prompt:
|
|
79
|
+
'Look over everything that changed on this branch for bugs and edge cases.',
|
|
80
|
+
expect: 'claude-review',
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
prompt: 'Draft me a script with beats for a screencast recording.',
|
|
84
|
+
expect: 'canon-screencast',
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
prompt:
|
|
88
|
+
"Check whether my installed Claude seed docs have drifted from the toolkit's.",
|
|
89
|
+
expect: 'claude-seed-sync',
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
prompt: 'Turn this topic into a slide deck I can render.',
|
|
93
|
+
expect: 'canon-slides-draft',
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
prompt:
|
|
97
|
+
'Check whether the markdown I changed violates any authoring standards.',
|
|
98
|
+
expect: 'claude-standards-audit',
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
prompt: 'Open a new entry on the task board for this piece of work.',
|
|
102
|
+
expect: 'claude-tasks',
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
prompt: 'Open a learning workspace so I can study this topic properly.',
|
|
106
|
+
expect: 'claude-teach',
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
prompt: 'Generate the Playwright tests I need after this UI change.',
|
|
110
|
+
expect: 'claude-ui-test',
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
prompt:
|
|
114
|
+
'Look over the interface and tell me what feels unfinished or confusing.',
|
|
115
|
+
expect: 'claude-ux-audit',
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
prompt: 'Tell me the paint and layout cost of this page right now.',
|
|
119
|
+
expect: 'claude-ux-measure',
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
prompt:
|
|
123
|
+
'I am building this branch for another session. What am I on the hook for, and what is off limits?',
|
|
124
|
+
expect: 'claude-worker',
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
prompt: 'Get me set up in a fresh Claude Code worktree for this branch.',
|
|
128
|
+
expect: 'claude-worktree',
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
// Negatives: pairs whose bodies already carry an explicit Do NOT boundary.
|
|
132
|
+
{
|
|
133
|
+
prompt:
|
|
134
|
+
'Refresh the stale sections of README and the docs folder based on what changed.',
|
|
135
|
+
expect: 'docs-sync',
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
prompt: 'Sort through this brain dump and write it up as findings.',
|
|
139
|
+
expect: 'claude-intake',
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
prompt:
|
|
143
|
+
"Go through what's still unanswered in the intake folder and decide.",
|
|
144
|
+
expect: 'claude-intake-answer',
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
prompt: 'Check this markdown against the house style rules.',
|
|
148
|
+
expect: 'claude-standards-audit',
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
prompt: 'Find the rough, unfinished-feeling spots in this interface.',
|
|
152
|
+
expect: 'claude-ux-audit',
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
prompt: 'Tell me the render cost of this page in the browser.',
|
|
156
|
+
expect: 'claude-ux-measure',
|
|
157
|
+
},
|
|
158
|
+
]
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { SkillCase } from '@/claude/skills-rank'
|
|
2
|
+
|
|
3
|
+
/** The `git-*` skill family: branch, commit, and pull-request mechanics. */
|
|
4
|
+
export const GIT_CASES: readonly SkillCase[] = [
|
|
5
|
+
{
|
|
6
|
+
prompt: 'Come up with a conventional name for this branch.',
|
|
7
|
+
expect: 'git-branch',
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
prompt: "Turn what's staged into one commit message.",
|
|
11
|
+
expect: 'git-commit',
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
prompt: "Push a quick follow-up fix onto the PR that's already open.",
|
|
15
|
+
expect: 'git-followup',
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
prompt: 'Turn this bug into a GitHub issue and file it.',
|
|
19
|
+
expect: 'git-issue',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
prompt: 'Write the title and body for this pull request.',
|
|
23
|
+
expect: 'git-pr',
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
prompt: 'Take this finished feature all the way through to an opened PR.',
|
|
27
|
+
expect: 'git-ship',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
prompt:
|
|
31
|
+
'This branch has unrelated commits mixed together, break it into separate branches.',
|
|
32
|
+
expect: 'git-split',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
prompt:
|
|
36
|
+
'These staged changes cover more than one concern, commit them separately.',
|
|
37
|
+
expect: 'git-stage',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
prompt:
|
|
41
|
+
'Show me the linked worktrees and clear out the ones already merged.',
|
|
42
|
+
expect: 'git-worktree',
|
|
43
|
+
},
|
|
44
|
+
]
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { SkillCase } from '@/claude/skills-rank'
|
|
2
|
+
|
|
3
|
+
/** Skills that share no prefix with any other domain file here. */
|
|
4
|
+
export const MISC_CASES: readonly SkillCase[] = [
|
|
5
|
+
{
|
|
6
|
+
prompt:
|
|
7
|
+
'Bundle up every open call that only I can make and ask me all at once.',
|
|
8
|
+
expect: 'decision-escalate',
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
prompt: 'Fire up the dev server the way this project documents it.',
|
|
12
|
+
expect: 'project-commands',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
prompt:
|
|
16
|
+
"We're about to hit the context limit, write the handoff before we lose state.",
|
|
17
|
+
expect: 'session-map',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
prompt: 'Catch me up on what was in progress before this session started.',
|
|
21
|
+
expect: 'session-resume',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
prompt: "This test just started failing and I don't know why yet.",
|
|
25
|
+
expect: 'systematic-debugging',
|
|
26
|
+
},
|
|
27
|
+
]
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { SkillCase } from '@/claude/skills-rank'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* `setup-*`, `migration-*`, `canon-*`, and `create-rule`: scaffolding,
|
|
5
|
+
* proposal-only migrations, and the toolkit's own reference and feedback
|
|
6
|
+
* surfaces.
|
|
7
|
+
*/
|
|
8
|
+
export const SETUP_CASES: readonly SkillCase[] = [
|
|
9
|
+
{
|
|
10
|
+
prompt:
|
|
11
|
+
'This project has no rules installed yet, get the right governance in place.',
|
|
12
|
+
expect: 'setup-gov',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
prompt:
|
|
16
|
+
"Get the index.md system bootstrapped across this project's folders.",
|
|
17
|
+
expect: 'setup-indexes',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
prompt:
|
|
21
|
+
'This is a brand-new project, get the toolkit bootstrapped in one shot.',
|
|
22
|
+
expect: 'setup-init',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
prompt: 'Get the usual Claude Code plugins provisioned on this machine.',
|
|
26
|
+
expect: 'setup-plugins',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
prompt:
|
|
30
|
+
"Run through the generated scaffold's scripts and confirm each one passes.",
|
|
31
|
+
expect: 'setup-verify',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
prompt:
|
|
35
|
+
'This CLAUDE.md file has grown huge, break it apart into the tiered context model.',
|
|
36
|
+
expect: 'migration-claude-md',
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
prompt:
|
|
40
|
+
'Move the agent-flavored docs out of the docs folder and into context.',
|
|
41
|
+
expect: 'migration-context',
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
prompt:
|
|
45
|
+
'This file was replaced by a folder, help me split its content into it.',
|
|
46
|
+
expect: 'migration-superseded',
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
prompt:
|
|
50
|
+
'This project still carries a copy of the standards folder, get rid of it and point everything at the CLI.',
|
|
51
|
+
expect: 'migration-standards-drop',
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
prompt:
|
|
55
|
+
"Before I run this sync, tell me exactly what it's going to overwrite.",
|
|
56
|
+
expect: 'canon-cli',
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
prompt:
|
|
60
|
+
'Something about the toolkit itself is broken, write it up and send it back to the maintainers.',
|
|
61
|
+
expect: 'canon-feedback-file',
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
prompt:
|
|
65
|
+
"I don't know which specific toolkit skill I need, just handle it for me.",
|
|
66
|
+
expect: 'canon-operator',
|
|
67
|
+
},
|
|
68
|
+
// The performing skill wins a phrase naming its operation over the front
|
|
69
|
+
// door's own routing framing, even though canon-operator's description
|
|
70
|
+
// quotes a phrase near this one. See .claude/context/cli/audits.md.
|
|
71
|
+
{
|
|
72
|
+
prompt:
|
|
73
|
+
"Whatever the right toolkit command is, get this project's rules installed.",
|
|
74
|
+
expect: 'setup-gov',
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
prompt:
|
|
78
|
+
'Work through the open feedback issues on the toolkit repo one by one.',
|
|
79
|
+
expect: 'canon-feedback-triage',
|
|
80
|
+
},
|
|
81
|
+
// The outbound direction is what separates this from the front door above.
|
|
82
|
+
// canon-operator runs inside one project the session already stands in, and
|
|
83
|
+
// this reaches every project the toolkit installed into from the toolkit.
|
|
84
|
+
{
|
|
85
|
+
prompt:
|
|
86
|
+
'Take this change out to every project that installed the toolkit and get each one to a pull request.',
|
|
87
|
+
expect: 'canon-rollout',
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
prompt:
|
|
91
|
+
"This project needs its own coding rule that the toolkit doesn't ship.",
|
|
92
|
+
expect: 'create-rule',
|
|
93
|
+
},
|
|
94
|
+
]
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs'
|
|
2
|
+
import { join } from 'node:path'
|
|
3
|
+
import { mergeSections } from '@/tooling/gitignore'
|
|
4
|
+
import { type Manifest, resolveChain } from '@/tooling/manifest'
|
|
5
|
+
|
|
6
|
+
export const CLAUDE_STACK = 'claude'
|
|
7
|
+
|
|
8
|
+
export interface GitignoreEntry {
|
|
9
|
+
readonly entry: string
|
|
10
|
+
readonly present: boolean
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function claudeChain(root: string): Manifest[] {
|
|
14
|
+
return resolveChain(root, CLAUDE_STACK)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Previews the gitignore merge without writing. The answer comes from
|
|
19
|
+
* `mergeSections`, the same function the apply step runs, so the preview can
|
|
20
|
+
* never disagree with what lands.
|
|
21
|
+
*
|
|
22
|
+
* The bash matched the manifest's `[gitignore]` table with a line regex that
|
|
23
|
+
* required the array to open and close on one line, and it re-parsed TOML that
|
|
24
|
+
* `loadManifest` already reads. Routing through the manifest loader drops both
|
|
25
|
+
* problems.
|
|
26
|
+
*/
|
|
27
|
+
export function planGitignore(
|
|
28
|
+
chain: readonly Manifest[],
|
|
29
|
+
target: string,
|
|
30
|
+
): GitignoreEntry[] {
|
|
31
|
+
const path = join(target, '.gitignore')
|
|
32
|
+
const content = existsSync(path) ? readFileSync(path, 'utf8') : ''
|
|
33
|
+
const entries: GitignoreEntry[] = []
|
|
34
|
+
|
|
35
|
+
for (const manifest of chain) {
|
|
36
|
+
const added = new Set(mergeSections(content, manifest.gitignore).added)
|
|
37
|
+
for (const section of manifest.gitignore) {
|
|
38
|
+
for (const entry of section.entries) {
|
|
39
|
+
entries.push({ entry, present: !added.has(entry) })
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return entries
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function pendingEntries(
|
|
48
|
+
entries: readonly GitignoreEntry[],
|
|
49
|
+
): GitignoreEntry[] {
|
|
50
|
+
return entries.filter((entry) => !entry.present)
|
|
51
|
+
}
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs'
|
|
2
|
+
import { join } from 'node:path'
|
|
3
|
+
|
|
4
|
+
const CLAUDE_MD = 'CLAUDE.md'
|
|
5
|
+
const RULES_DIR = join('.claude', 'rules')
|
|
6
|
+
|
|
7
|
+
/** A backticked token, which is how the always-loaded file spells a path. */
|
|
8
|
+
const TOKEN = /`([^`\s]+)`/g
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* A path a reader could open. Admits no `$`, `*`, or `=`, so an assignment
|
|
12
|
+
* (`CANON_NON_INTERACTIVE=1`) and a variable are both excluded.
|
|
13
|
+
*/
|
|
14
|
+
const PATH_TOKEN = /^[.A-Za-z0-9_][A-Za-z0-9._/-]*$/
|
|
15
|
+
|
|
16
|
+
/** A placeholder segment, which a shape carries and a real path does not. */
|
|
17
|
+
const SHAPE = /<[^>]*>/
|
|
18
|
+
|
|
19
|
+
/** An alphabetic extension, which separates `cspell.json` from `3.6.0`. */
|
|
20
|
+
const EXTENSION = /\.[a-z]{2,5}$/
|
|
21
|
+
|
|
22
|
+
/** Extensions a folder is probed with, so a glob narrowed by type still hits. */
|
|
23
|
+
const PROBES = ['probe.md', 'probe.ts', 'probe.tsx', 'probe.sh', 'probe.json']
|
|
24
|
+
|
|
25
|
+
export interface RuleGlobs {
|
|
26
|
+
/** Path under `.claude/rules/`, which is how a reader cites a rule. */
|
|
27
|
+
readonly rule: string
|
|
28
|
+
readonly globs: readonly string[]
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface Section {
|
|
32
|
+
/** `Behavior` for an H2, `Behavior / Scope` for the H3 beneath it. */
|
|
33
|
+
readonly heading: string
|
|
34
|
+
/** The top-level bullet lines the heading owns, in reading order. */
|
|
35
|
+
readonly lines: readonly string[]
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface SectionReport {
|
|
39
|
+
readonly heading: string
|
|
40
|
+
readonly bullets: number
|
|
41
|
+
/** Bullets naming at least one path, which is the reading this measures. */
|
|
42
|
+
readonly pathScoped: number
|
|
43
|
+
/** Path-scoped bullets whose named path some rule glob already reaches. */
|
|
44
|
+
readonly covered: number
|
|
45
|
+
/** Distinct named paths no rule glob reaches, in reading order. */
|
|
46
|
+
readonly uncovered: readonly string[]
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Why a scan produced no reading, which is never the same as a clean one. */
|
|
50
|
+
export type RoutingRefusal = 'no-claude-md' | 'no-rules'
|
|
51
|
+
|
|
52
|
+
export type RoutingReport =
|
|
53
|
+
| {
|
|
54
|
+
readonly kind: 'measured'
|
|
55
|
+
readonly rules: number
|
|
56
|
+
readonly sections: readonly SectionReport[]
|
|
57
|
+
}
|
|
58
|
+
| { readonly kind: 'refused'; readonly reason: RoutingRefusal }
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Every distinct path one bullet names, in reading order.
|
|
62
|
+
*
|
|
63
|
+
* Naming a path is what this measures, not firing only on it. A bullet can
|
|
64
|
+
* name a folder and still apply every session, and one can fire on a path it
|
|
65
|
+
* never spells, so the count is a reading a person still has to judge.
|
|
66
|
+
*/
|
|
67
|
+
export function namedPaths(line: string): string[] {
|
|
68
|
+
const paths: string[] = []
|
|
69
|
+
|
|
70
|
+
for (const match of line.matchAll(TOKEN)) {
|
|
71
|
+
const token = concretePrefix(match[1])
|
|
72
|
+
if (token === undefined) continue
|
|
73
|
+
if (!PATH_TOKEN.test(token)) continue
|
|
74
|
+
if (!token.includes('/') && !EXTENSION.test(token)) continue
|
|
75
|
+
if (!paths.includes(token)) paths.push(token)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return paths
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* The openable part of a token, which for a shape is the folder above the
|
|
83
|
+
* placeholder.
|
|
84
|
+
*
|
|
85
|
+
* `.claude/context/<domain>.md` names `.claude/context/` and nothing narrower,
|
|
86
|
+
* so dropping the whole token would report the section that carries it as
|
|
87
|
+
* naming no path at all. A token whose placeholder sits in the first segment
|
|
88
|
+
* has no openable prefix and is dropped.
|
|
89
|
+
*/
|
|
90
|
+
function concretePrefix(token: string): string | undefined {
|
|
91
|
+
if (!SHAPE.test(token)) return token
|
|
92
|
+
|
|
93
|
+
const prefix = token.slice(0, token.indexOf('<'))
|
|
94
|
+
return prefix.endsWith('/') ? prefix : undefined
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Splits the file into the sections a reader sees, counting top-level bullets.
|
|
99
|
+
*
|
|
100
|
+
* A nested bullet belongs to the one above it rather than to the section, and
|
|
101
|
+
* a fenced block holds example text rather than instruction, so neither is
|
|
102
|
+
* counted. A heading carrying no bullet is dropped, since the report answers
|
|
103
|
+
* how many bullets are path-scoped and a section with none answers nothing.
|
|
104
|
+
*/
|
|
105
|
+
export function splitSections(text: string): Section[] {
|
|
106
|
+
const sections: Section[] = []
|
|
107
|
+
let parent = ''
|
|
108
|
+
let heading: string | undefined
|
|
109
|
+
let lines: string[] = []
|
|
110
|
+
let fenced = false
|
|
111
|
+
|
|
112
|
+
const flush = (): void => {
|
|
113
|
+
if (heading !== undefined && lines.length > 0)
|
|
114
|
+
sections.push({ heading, lines })
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const open = (next: string): void => {
|
|
118
|
+
flush()
|
|
119
|
+
heading = next
|
|
120
|
+
lines = []
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
for (const line of text.split('\n')) {
|
|
124
|
+
if (line.startsWith('```')) {
|
|
125
|
+
fenced = !fenced
|
|
126
|
+
continue
|
|
127
|
+
}
|
|
128
|
+
if (fenced) continue
|
|
129
|
+
|
|
130
|
+
const h2 = line.match(/^## (.+)$/)
|
|
131
|
+
if (h2) {
|
|
132
|
+
parent = h2[1]
|
|
133
|
+
open(parent)
|
|
134
|
+
continue
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const h3 = line.match(/^### (.+)$/)
|
|
138
|
+
if (h3) {
|
|
139
|
+
open(parent === '' ? h3[1] : `${parent} / ${h3[1]}`)
|
|
140
|
+
continue
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (line.startsWith('- ')) lines.push(line)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
flush()
|
|
147
|
+
return sections
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Every path-scoped rule the tree installs, with the globs it declares.
|
|
152
|
+
*
|
|
153
|
+
* An always-on rule declares no `paths` and applies at the same priority as
|
|
154
|
+
* the always-loaded file, so it covers no path in particular and is skipped.
|
|
155
|
+
*/
|
|
156
|
+
export function readRuleGlobs(root: string): RuleGlobs[] {
|
|
157
|
+
const rulesRoot = join(root, RULES_DIR)
|
|
158
|
+
if (!existsSync(rulesRoot)) return []
|
|
159
|
+
|
|
160
|
+
const rules: RuleGlobs[] = []
|
|
161
|
+
const files = [
|
|
162
|
+
...new Bun.Glob('**/*.md').scanSync({ cwd: rulesRoot, onlyFiles: true }),
|
|
163
|
+
].sort()
|
|
164
|
+
|
|
165
|
+
for (const file of files) {
|
|
166
|
+
const text = readFileSync(join(rulesRoot, file), 'utf8')
|
|
167
|
+
const globs = [...frontmatter(text).matchAll(/^\s*-\s*'([^']+)'\s*$/gm)]
|
|
168
|
+
.map((match) => match[1])
|
|
169
|
+
.filter((glob) => glob.includes('*') || glob.includes('.'))
|
|
170
|
+
|
|
171
|
+
if (globs.length === 0) continue
|
|
172
|
+
rules.push({ rule: file.replaceAll('\\', '/'), globs })
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return rules
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* The block between the opening and closing `---`, or nothing for a rule
|
|
180
|
+
* carrying no frontmatter.
|
|
181
|
+
*
|
|
182
|
+
* Bounding the read is what keeps a body bullet out of the glob list. A rule
|
|
183
|
+
* quoting a path in prose would otherwise register it as a scope the rule
|
|
184
|
+
* never declared, and the resulting coverage would be wrong with nothing
|
|
185
|
+
* reporting it.
|
|
186
|
+
*/
|
|
187
|
+
function frontmatter(text: string): string {
|
|
188
|
+
if (!text.startsWith('---\n')) return ''
|
|
189
|
+
|
|
190
|
+
const end = text.indexOf('\n---', 3)
|
|
191
|
+
return end === -1 ? '' : text.slice(4, end)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Whether a glob scopes itself to a location rather than to a file type.
|
|
196
|
+
*
|
|
197
|
+
* A glob opening `**` reaches every folder in the tree, so it answers that a
|
|
198
|
+
* file type is governed and never that a named path is. Counting one would
|
|
199
|
+
* report every markdown path covered by `501-markdown` and leave the column
|
|
200
|
+
* saying nothing a reader could act on.
|
|
201
|
+
*/
|
|
202
|
+
function isAnchored(glob: string): boolean {
|
|
203
|
+
return !glob.startsWith('**/')
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* The first rule scoping itself to a named path, or undefined for none.
|
|
208
|
+
*
|
|
209
|
+
* A folder is probed with a handful of extensions rather than matched as a
|
|
210
|
+
* literal, because a glob narrowed by file type reaches under the folder
|
|
211
|
+
* without ever matching the folder's own name.
|
|
212
|
+
*/
|
|
213
|
+
export function coveringRule(
|
|
214
|
+
path: string,
|
|
215
|
+
rules: readonly RuleGlobs[],
|
|
216
|
+
): string | undefined {
|
|
217
|
+
const bare = path.replace(/\/+$/, '')
|
|
218
|
+
const candidates = [bare, ...PROBES.map((probe) => `${bare}/${probe}`)]
|
|
219
|
+
|
|
220
|
+
for (const { rule, globs } of rules) {
|
|
221
|
+
for (const glob of globs) {
|
|
222
|
+
if (!isAnchored(glob)) continue
|
|
223
|
+
const matcher = new Bun.Glob(glob)
|
|
224
|
+
if (candidates.some((candidate) => matcher.match(candidate))) return rule
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return undefined
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Reads the always-loaded file against the rules installed beside it.
|
|
233
|
+
*
|
|
234
|
+
* Measures the tree it is pointed at rather than the toolkit root, so a linked
|
|
235
|
+
* worktree reads its own branch and a target reads its own file.
|
|
236
|
+
*/
|
|
237
|
+
export function scanRouting(root: string): RoutingReport {
|
|
238
|
+
const file = join(root, CLAUDE_MD)
|
|
239
|
+
if (!existsSync(file)) return { kind: 'refused', reason: 'no-claude-md' }
|
|
240
|
+
|
|
241
|
+
const rules = readRuleGlobs(root)
|
|
242
|
+
if (rules.length === 0) return { kind: 'refused', reason: 'no-rules' }
|
|
243
|
+
|
|
244
|
+
const sections = splitSections(readFileSync(file, 'utf8')).map((section) =>
|
|
245
|
+
classify(section, rules),
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
return { kind: 'measured', rules: rules.length, sections }
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/** Counts one section's bullets against the rules installed beside the file. */
|
|
252
|
+
function classify(
|
|
253
|
+
section: Section,
|
|
254
|
+
rules: readonly RuleGlobs[],
|
|
255
|
+
): SectionReport {
|
|
256
|
+
let pathScoped = 0
|
|
257
|
+
let covered = 0
|
|
258
|
+
const uncovered: string[] = []
|
|
259
|
+
|
|
260
|
+
for (const line of section.lines) {
|
|
261
|
+
const paths = namedPaths(line)
|
|
262
|
+
if (paths.length === 0) continue
|
|
263
|
+
pathScoped += 1
|
|
264
|
+
|
|
265
|
+
const reached = paths.filter(
|
|
266
|
+
(path) => coveringRule(path, rules) !== undefined,
|
|
267
|
+
)
|
|
268
|
+
if (reached.length > 0) covered += 1
|
|
269
|
+
|
|
270
|
+
for (const path of paths) {
|
|
271
|
+
if (reached.includes(path) || uncovered.includes(path)) continue
|
|
272
|
+
uncovered.push(path)
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
return {
|
|
277
|
+
heading: section.heading,
|
|
278
|
+
bullets: section.lines.length,
|
|
279
|
+
pathScoped,
|
|
280
|
+
covered,
|
|
281
|
+
uncovered,
|
|
282
|
+
}
|
|
283
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises'
|
|
2
|
+
import { relative } from 'node:path'
|
|
3
|
+
import { planSeeds } from '@/claude/seeds'
|
|
4
|
+
|
|
5
|
+
export interface SeedListing {
|
|
6
|
+
readonly name: string
|
|
7
|
+
readonly source: string
|
|
8
|
+
readonly target: string
|
|
9
|
+
readonly src: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface SeedListingWithContent {
|
|
13
|
+
readonly name: string
|
|
14
|
+
readonly source: string
|
|
15
|
+
readonly target: string
|
|
16
|
+
readonly content: string
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Reads the same plan `canon claude init` applies. The bash re-globbed the seeds
|
|
21
|
+
* directory with its own hard-coded subdirectory list, which had drifted: it
|
|
22
|
+
* never listed `.claude/context/`, so a seed init installs went unreported.
|
|
23
|
+
*
|
|
24
|
+
* The target is irrelevant to a listing, so it resolves against the source
|
|
25
|
+
* root and only the source-side fields are read.
|
|
26
|
+
*/
|
|
27
|
+
export function listSeeds(root: string): SeedListing[] {
|
|
28
|
+
return planSeeds(root, root).map(({ seed }) => ({
|
|
29
|
+
name: seed.scanLabel,
|
|
30
|
+
source: relative(root, seed.src),
|
|
31
|
+
target: seed.applyLabel,
|
|
32
|
+
src: seed.src,
|
|
33
|
+
}))
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export async function readSeedContents(
|
|
37
|
+
listings: readonly SeedListing[],
|
|
38
|
+
): Promise<SeedListingWithContent[]> {
|
|
39
|
+
return Promise.all(
|
|
40
|
+
listings.map(async ({ name, source, target, src }) => ({
|
|
41
|
+
name,
|
|
42
|
+
source,
|
|
43
|
+
target,
|
|
44
|
+
content: await readFile(src, 'utf8'),
|
|
45
|
+
})),
|
|
46
|
+
)
|
|
47
|
+
}
|