@erclx/canon 5.35.0 → 5.37.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/README.md +11 -11
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/api-design/SKILL.md +6 -0
- package/claude/skills/backlog-triage/SKILL.md +7 -7
- package/claude/skills/build-in-slices/SKILL.md +6 -0
- package/claude/skills/build-in-slices/references/adopted.md +3 -0
- package/claude/skills/canon-cli/REQUIREMENT.md +2 -2
- package/claude/skills/canon-cli/SKILL.md +5 -1
- package/claude/skills/canon-feedback/SKILL.md +5 -0
- package/claude/skills/canon-feedback-triage/SKILL.md +3 -0
- package/claude/skills/canvas-board/REQUIREMENT.md +1 -1
- package/claude/skills/canvas-board/SKILL.md +5 -2
- package/claude/skills/canvas-board/references/canvas.md +12 -0
- package/claude/skills/canvas-board/references/design.md +53 -36
- package/claude/skills/ci-workflow/SKILL.md +5 -0
- package/claude/skills/code-craft/SKILL.md +6 -0
- package/claude/skills/codebase-layout/REQUIREMENT.md +1 -1
- package/claude/skills/codebase-layout/SKILL.md +2 -2
- package/claude/skills/context-fold/references/context.md +48 -34
- package/claude/skills/create-rule/REQUIREMENT.md +6 -8
- package/claude/skills/create-rule/SKILL.md +19 -17
- package/claude/skills/create-rule/references/rule.md +17 -23
- package/claude/skills/create-skill/SKILL.md +11 -2
- package/claude/skills/create-skill/references/skill-disclosure.md +26 -0
- package/claude/skills/create-skill/references/skill-paths.md +3 -0
- package/claude/skills/create-skill/references/skill-reference.md +12 -0
- package/claude/skills/create-skill/references/skill.md +26 -25
- package/claude/skills/deprecation-migration/SKILL.md +6 -0
- package/claude/skills/deprecation-migration/references/adopted.md +3 -0
- package/claude/skills/design-taste/REQUIREMENT.md +6 -6
- package/claude/skills/design-taste/SKILL.md +8 -2
- package/claude/skills/design-taste/references/craft.md +4 -1
- package/claude/skills/design-taste/references/preflight.md +18 -2
- package/claude/skills/design-taste/references/tells.md +1 -1
- package/claude/skills/docs-sync/references/docs.md +6 -0
- package/claude/skills/docs-sync/references/readme.md +15 -0
- package/claude/skills/draft-and-pick/SKILL.md +12 -0
- package/claude/skills/draft-doc/references/context.md +1 -1
- package/claude/skills/draft-doc/references/readme.md +3 -0
- package/claude/skills/draft-figure/references/mermaid.md +6 -0
- package/claude/skills/draft-identity/SKILL.md +3 -2
- package/claude/skills/draft-slides/SKILL.md +3 -0
- package/claude/skills/git-branch/references/branch.md +16 -11
- package/claude/skills/git-commit/references/commit.md +19 -11
- package/claude/skills/git-commit/references/versioning.md +9 -0
- package/claude/skills/git-issue/references/issue.md +12 -9
- package/claude/skills/git-pr/SKILL.md +5 -0
- package/claude/skills/git-pr/references/pr.md +24 -6
- package/claude/skills/git-ship/SKILL.md +3 -0
- package/claude/skills/git-split/SKILL.md +6 -0
- package/claude/skills/git-stage/SKILL.md +3 -0
- package/claude/skills/git-worktree/SKILL.md +6 -6
- package/claude/skills/markdown-craft/references/markdown.md +27 -8
- package/claude/skills/plan-feature/SKILL.md +10 -1
- package/claude/skills/plan-feature/references/plan.md +20 -8
- package/claude/skills/plan-groundwork/SKILL.md +6 -0
- package/claude/skills/plan-groundwork/references/groundwork.md +10 -7
- package/claude/skills/plan-intake/references/intake.md +6 -6
- package/claude/skills/read-frames/SKILL.md +3 -0
- package/claude/skills/review-craft/SKILL.md +3 -0
- package/claude/skills/review-craft/references/ui.md +1 -1
- package/claude/skills/review-ui/SKILL.md +6 -3
- package/claude/skills/role-orchestrator/SKILL.md +3 -0
- package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +7 -4
- package/claude/skills/role-orchestrator/references/orchestrator-refill.md +3 -0
- package/claude/skills/role-planner/SKILL.md +3 -0
- package/claude/skills/role-worker/SKILL.md +12 -0
- package/claude/skills/search-craft/SKILL.md +3 -0
- package/claude/skills/systematic-debugging/SKILL.md +6 -0
- package/claude/skills/target-check/references/domains.md +5 -0
- package/claude/skills/target-setup/SKILL.md +5 -0
- package/claude/skills/task-board/references/tasks.md +9 -6
- package/claude/skills/task-complete/references/archive.md +3 -0
- package/claude/skills/teach-workspace/SKILL.md +3 -0
- package/claude/skills/teach-workspace/references/glossary.md +3 -0
- package/claude/skills/teach-workspace/references/lesson-build.md +3 -0
- package/claude/skills/teach-workspace/references/lesson-craft.md +3 -0
- package/claude/skills/teach-workspace/references/teach.md +8 -8
- package/claude/skills/test-craft/SKILL.md +7 -2
- package/claude/skills/ux-audit/REQUIREMENT.md +1 -1
- package/claude/skills/ux-audit/SKILL.md +2 -2
- package/claude/skills/ux-measure/REQUIREMENT.md +1 -1
- package/claude/skills/video-craft/SKILL.md +6 -0
- package/claude/skills/write-human/SKILL.md +9 -0
- package/claude/skills/write-human/references/machine-tells.md +12 -0
- package/docs/agents/capture.md +2 -0
- package/docs/agents/commands.md +59 -56
- package/docs/agents/comments.md +1 -1
- package/docs/agents/context-audit-checks.md +6 -0
- package/docs/agents/context-audit.md +8 -8
- package/docs/agents/context-classify.md +2 -0
- package/docs/agents/drift-surfaces.md +5 -5
- package/docs/agents/gate.md +6 -7
- package/docs/agents/gov-detect.md +1 -1
- package/docs/agents/index.md +2 -2
- package/docs/agents/install-and-sync.md +6 -6
- package/docs/agents/markdown-audit-weight.md +11 -3
- package/docs/agents/markdown-audit.md +14 -2
- package/docs/agents/output-shape.md +1 -1
- package/docs/agents/overview.md +2 -2
- package/docs/agents/pr-frames.md +17 -3
- package/docs/agents/rule-citations.md +5 -10
- package/docs/agents/scripting.md +1 -1
- package/docs/agents/sessions-transfer.md +8 -6
- package/docs/agents/skills-audit.md +9 -1
- package/docs/target/projects.md +2 -2
- package/docs/target/scenarios.md +5 -5
- package/docs/target/standards-moved.md +20 -18
- package/docs/workflow/ai-workflow.md +4 -1
- package/docs/workflow/visual-design-workflow.md +8 -3
- package/governance/detect.toml +32 -32
- package/governance/renames.toml +44 -0
- package/governance/rules/lib/{305-e2e-reliability.md → e2e-reliability.md} +1 -1
- package/governance/rules/lib/{306-test-scope.md → test-scope.md} +2 -2
- package/governance/rules/ui/{410-a11y.md → a11y.md} +1 -1
- package/governance/rules/ui/{440-surface-capture.md → surface-capture.md} +3 -3
- package/governance/stacks/base.toml +6 -6
- package/governance/stacks/go.toml +1 -1
- package/governance/stacks/node.toml +1 -1
- package/governance/stacks/php.toml +1 -1
- package/governance/stacks/python.toml +1 -1
- package/package.json +2 -2
- package/scripts/core/install-check.sh +2 -7
- package/src/capture/frame-values.ts +3 -6
- package/src/cli/help-all.ts +96 -0
- package/src/cli/help.ts +28 -27
- package/src/cli.ts +8 -1
- package/src/commands/claude.ts +29 -0
- package/src/commands/context.ts +29 -4
- package/src/commands/design.ts +22 -1
- package/src/commands/gate.ts +1 -8
- package/src/commands/gov.ts +25 -3
- package/src/commands/init.ts +10 -1
- package/src/commands/markdown.ts +148 -3
- package/src/commands/pr.ts +17 -10
- package/src/commands/records.ts +1 -1
- package/src/commands/sync.ts +11 -0
- package/src/commands/tooling.ts +8 -0
- package/src/context/audit.ts +83 -0
- package/src/context/classify/prompts.ts +6 -1
- package/src/context/gate.ts +6 -3
- package/src/design/budget.ts +14 -10
- package/src/design/document.ts +5 -5
- package/src/design/parse.ts +21 -4
- package/src/design/render.ts +3 -3
- package/src/gate/measures.ts +187 -2
- package/src/gate/sequencer.ts +0 -4
- package/src/gate/stages.ts +32 -27
- package/src/git/files.ts +30 -0
- package/src/gov/adapter.ts +2 -2
- package/src/gov/citations.ts +10 -33
- package/src/gov/install.ts +2 -2
- package/src/gov/list.ts +1 -1
- package/src/gov/payload.ts +1 -1
- package/src/gov/stacks.ts +4 -4
- package/src/inventory/subjects.ts +1 -1
- package/src/markdown/ceiling.ts +6 -1
- package/src/markdown/colons.ts +86 -0
- package/src/markdown/gate.ts +25 -0
- package/src/markdown/growth.ts +43 -0
- package/src/markdown/heading-case.ts +74 -0
- package/src/markdown/stacks.ts +74 -0
- package/src/markdown/structure.ts +72 -4
- package/src/migrate/rule-layout.ts +12 -12
- package/src/pr/frames.ts +66 -1
- package/src/shipped/references.ts +14 -14
- package/src/sync/check.ts +23 -23
- package/src/sync/copy.ts +4 -5
- package/tooling/astro/configs/tsconfig.json +1 -1
- package/tooling/astro/manifest.toml +0 -1
- package/tooling/astro/reference.md +2 -10
- package/tooling/base/configs/scripts/verify.json +1 -1
- package/tooling/base/configs/scripts/verify.ts +23 -13
- package/tooling/base/manifest.toml +6 -5
- package/tooling/base/reference.md +15 -22
- package/tooling/base/seeds/.github/workflows/verify.yml +0 -6
- package/tooling/base/seeds/.lintstagedrc +1 -2
- package/tooling/base/seeds/canon/context/ci.md +7 -8
- package/tooling/base/seeds/canon/context/development.md +10 -10
- package/tooling/claude/seeds/.claude/hooks/scratch-guard.sh +9 -1
- package/tooling/claude/seeds/.claude/hooks/standards-audit.sh +27 -2
- package/tooling/claude/seeds/CLAUDE.md +1 -1
- package/tooling/claude/seeds/canon/DESIGN.md +24 -37
- package/tooling/shell/configs/.github/workflows/shell.yml +30 -0
- package/tooling/shell/manifest.toml +12 -0
- package/tooling/shell/reference.md +46 -0
- package/tooling/vite-react/configs/tsconfig.json +1 -1
- package/tooling/vite-react/configs/vitest.config.ts +1 -1
- package/tooling/vite-react/manifest.toml +0 -1
- package/tooling/vite-react/reference.md +2 -10
- package/tooling/web/configs/.github/workflows/readme-screenshot.yml +3 -5
- package/tooling/web/configs/.github/workflows/verify.yml +0 -6
- package/tooling/web/configs/src/test/setup.ts +1 -1
- package/tooling/web/manifest.toml +4 -4
- package/tooling/web/reference.md +4 -4
- package/tooling/base/configs/scripts/verify.sh +0 -2
- /package/governance/rules/canon/{606-git.md → git.md} +0 -0
- /package/governance/rules/canon/{611-indexes.md → indexes.md} +0 -0
- /package/governance/rules/canon/{604-scratch.md → scratch.md} +0 -0
- /package/governance/rules/canon/{602-tasks.md → task-scope.md} +0 -0
- /package/governance/rules/canon/{605-worktrees.md → worktrees.md} +0 -0
- /package/governance/rules/claude/{566-output.md → output.md} +0 -0
- /package/governance/rules/code/{000-code.md → routing.md} +0 -0
- /package/governance/rules/code/{010-testing.md → testing.md} +0 -0
- /package/governance/rules/framework/{210-astro.md → astro.md} +0 -0
- /package/governance/rules/framework/{220-fastapi.md → fastapi.md} +0 -0
- /package/governance/rules/framework/{230-nextjs.md → nextjs.md} +0 -0
- /package/governance/rules/framework/{200-react.md → react.md} +0 -0
- /package/governance/rules/framework/{260-shadcn.md → shadcn.md} +0 -0
- /package/governance/rules/framework/{250-tailwind.md → tailwind.md} +0 -0
- /package/governance/rules/lang/{130-go.md → go.md} +0 -0
- /package/governance/rules/lang/{140-php.md → php.md} +0 -0
- /package/governance/rules/lang/{110-python.md → python.md} +0 -0
- /package/governance/rules/lang/{100-typescript.md → typescript.md} +0 -0
- /package/governance/rules/lib/{370-database.md → database.md} +0 -0
- /package/governance/rules/lib/{340-pydantic.md → pydantic.md} +0 -0
- /package/governance/rules/lib/{360-security-server.md → security-server.md} +0 -0
- /package/governance/rules/lib/{350-security-web.md → security-web.md} +0 -0
- /package/governance/rules/lib/{320-tanstack-query.md → tanstack-query.md} +0 -0
- /package/governance/rules/lib/{335-testing-go.md → testing-go.md} +0 -0
- /package/governance/rules/lib/{336-testing-php.md → testing-php.md} +0 -0
- /package/governance/rules/lib/{330-testing-py.md → testing-py.md} +0 -0
- /package/governance/rules/lib/{300-testing-ts.md → testing-ts.md} +0 -0
- /package/governance/rules/lib/{310-zod.md → zod.md} +0 -0
- /package/governance/rules/tooling/{700-ci-workflow.md → ci-workflow.md} +0 -0
- /package/governance/rules/tooling/{790-code-comments.md → code-comments.md} +0 -0
- /package/governance/rules/tooling/{780-config-comments.md → config-comments.md} +0 -0
- /package/governance/rules/tooling/{775-dependencies.md → dependencies.md} +0 -0
- /package/governance/rules/ui/{480-canvas.md → canvas.md} +0 -0
- /package/governance/rules/ui/{400-ui.md → copy.md} +0 -0
- /package/governance/rules/ui/{460-design-taste.md → design-taste.md} +0 -0
- /package/governance/rules/ui/{420-forms.md → forms.md} +0 -0
- /package/governance/rules/ui/{465-interface-casing.md → interface-casing.md} +0 -0
- /package/governance/rules/ui/{450-link-behavior.md → link-behavior.md} +0 -0
- /package/governance/rules/ui/{470-motion.md → motion.md} +0 -0
- /package/governance/rules/ui/{430-ux-completeness.md → ux-completeness.md} +0 -0
- /package/tooling/{base → shell}/configs/.editorconfig +0 -0
- /package/tooling/{base → shell}/configs/.shellcheckrc +0 -0
|
@@ -1,57 +1,44 @@
|
|
|
1
1
|
# Design
|
|
2
2
|
|
|
3
|
-
Authoring guidance: the design standard.
|
|
3
|
+
Authoring guidance: the design standard. Values live in `<your stylesheet>`, such as `src/styles/tokens.css` or a Tailwind `@theme` block. A project with none writes them under `.claude/design/project/`, beside the installed base stylesheet.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Overview
|
|
6
6
|
|
|
7
7
|
One paragraph. Voice, tone, and the feeling a user should have. The same content a design intake form asks for.
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Colors
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Up to three rules a developer could get wrong.
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
| ---------- | ----------------------------- | ----- |
|
|
15
|
-
| background | page canvas | |
|
|
16
|
-
| surface | cards, panels, raised blocks | |
|
|
17
|
-
| text | primary body text | |
|
|
18
|
-
| muted | secondary text, captions | |
|
|
19
|
-
| accent | links, primary action | |
|
|
20
|
-
| success | confirmations, positive state | |
|
|
21
|
-
| warning | cautions, pending state | |
|
|
22
|
-
| error | failures, destructive action | |
|
|
13
|
+
One row per role, naming its custom property. Intent is a short phrase a human can picture.
|
|
23
14
|
|
|
24
|
-
|
|
15
|
+
| Role | Property | Intent |
|
|
16
|
+
| ---------- | -------------------- | ----------------------------- |
|
|
17
|
+
| background | `--color-background` | page canvas |
|
|
18
|
+
| surface | `--color-surface` | cards, panels, raised blocks |
|
|
19
|
+
| text | `--color-text` | primary body text |
|
|
20
|
+
| muted | `--color-muted` | secondary text, captions |
|
|
21
|
+
| accent | `--color-accent` | links, primary action |
|
|
22
|
+
| success | `--color-success` | confirmations, positive state |
|
|
23
|
+
| warning | `--color-warning` | cautions, pending state |
|
|
24
|
+
| error | `--color-error` | failures, destructive action |
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
## Typography
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
| ------- | ------ | ------ | ---- | ----------- |
|
|
30
|
-
| display | | | | |
|
|
31
|
-
| heading | | | | |
|
|
32
|
-
| body | | | | |
|
|
33
|
-
| label | | | | |
|
|
34
|
-
| code | | | | |
|
|
28
|
+
Up to three rules. How the roles divide between families, and any role that breaks the pattern.
|
|
35
29
|
|
|
36
30
|
## Spacing
|
|
37
31
|
|
|
38
|
-
|
|
32
|
+
One line. The base unit and how the scale steps.
|
|
39
33
|
|
|
40
|
-
|
|
41
|
-
| ---- | ---------- | ----- |
|
|
42
|
-
| xs | 0.5 | |
|
|
43
|
-
| sm | 1 | |
|
|
44
|
-
| md | 2 | |
|
|
45
|
-
| lg | 3 | |
|
|
46
|
-
| xl | 5 | |
|
|
34
|
+
## Shapes
|
|
47
35
|
|
|
48
|
-
|
|
36
|
+
One row per role, naming its radius property.
|
|
49
37
|
|
|
50
|
-
| Role |
|
|
51
|
-
| ------- |
|
|
52
|
-
| default |
|
|
53
|
-
| pill |
|
|
54
|
-
| none | 0 | 0 | edge-to-edge surfaces |
|
|
38
|
+
| Role | Property | When used |
|
|
39
|
+
| ------- | ------------------ | ------------------ |
|
|
40
|
+
| default | `--radius-default` | cards, inputs |
|
|
41
|
+
| pill | `--radius-pill` | tags, status chips |
|
|
55
42
|
|
|
56
43
|
## Motion
|
|
57
44
|
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
name: Shell
|
|
2
|
+
# canon-no-seed: an add-on stack's workflow with no root counterpart by design, since the toolkit checks its own shell inside verify.yml.
|
|
3
|
+
|
|
4
|
+
on:
|
|
5
|
+
pull_request:
|
|
6
|
+
branches:
|
|
7
|
+
- main
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
shell-checks:
|
|
12
|
+
name: 🐚 Shell Checks
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- name: Checkout
|
|
16
|
+
uses: actions/checkout@v4
|
|
17
|
+
|
|
18
|
+
- name: Setup Bun
|
|
19
|
+
uses: oven-sh/setup-bun@v2
|
|
20
|
+
with:
|
|
21
|
+
bun-version: latest
|
|
22
|
+
|
|
23
|
+
- name: Install Dependencies
|
|
24
|
+
run: bun install --frozen-lockfile
|
|
25
|
+
|
|
26
|
+
- name: Install Shell Tools
|
|
27
|
+
run: sudo apt-get install -y shfmt shellcheck
|
|
28
|
+
|
|
29
|
+
- name: Check Shell
|
|
30
|
+
run: bun run check:shell
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
[stack]
|
|
2
|
+
name = "shell"
|
|
3
|
+
extends = ""
|
|
4
|
+
runtime = "bun"
|
|
5
|
+
scaffold = ""
|
|
6
|
+
|
|
7
|
+
[sync]
|
|
8
|
+
source = "configs"
|
|
9
|
+
|
|
10
|
+
[scripts]
|
|
11
|
+
"check:shell" = "find scripts -name '*.sh' -exec shfmt --diff --indent 2 {} + && find scripts -name '*.sh' -exec shellcheck --severity=warning {} +"
|
|
12
|
+
"format:shell" = "find scripts -name '*.sh' -exec shfmt --write --indent 2 {} +"
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Tooling shell reference
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The shell stack is an add-on that formats and lints the shell scripts a project writes. It extends nothing and syncs beside any other stack at the same root with `canon tooling sync shell . --write`, so a project that writes no shell never installs shfmt or shellcheck.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
- Install `shfmt` and `shellcheck` by hand, through `sudo apt-get install shfmt shellcheck` or `brew install shfmt shellcheck`. Injection runs only `bun add -D`, and neither tool ships through the registry.
|
|
10
|
+
- `scripts/verify.ts` probes both before the `Shell` phase and names the install command when one is missing, rather than letting `find` report a missing executable.
|
|
11
|
+
|
|
12
|
+
## shfmt
|
|
13
|
+
|
|
14
|
+
- Indent with 2 spaces, set through `--indent 2` on every call.
|
|
15
|
+
- `.editorconfig` carries an `[*.sh]` block with `indent_style = space` and `indent_size = 2`, so the editor and shfmt agree. Dropping the block because shfmt already sets indentation produces spurious diffs.
|
|
16
|
+
|
|
17
|
+
## shellcheck
|
|
18
|
+
|
|
19
|
+
- Run at warning severity.
|
|
20
|
+
- `.shellcheckrc` sets `external-sources=true`, which shellcheck needs to follow `source` directives.
|
|
21
|
+
|
|
22
|
+
## Coverage
|
|
23
|
+
|
|
24
|
+
- Both tools take their files from `find scripts -name '*.sh'`, since `scripts/` can mix shell with TypeScript and shellcheck has no directory mode.
|
|
25
|
+
- A shell script with a shebang and no `.sh` extension is covered by neither, so give it the extension.
|
|
26
|
+
- Keep shell scripts in `scripts/`. A `.sh` file elsewhere, such as a seeded `.claude/hooks/` script, is left out on purpose.
|
|
27
|
+
|
|
28
|
+
## Verify
|
|
29
|
+
|
|
30
|
+
- `scripts/verify.ts` runs `check:shell` in its `Shell` phase wherever `package.json` declares it, between the format check and the unit tests. No stack's `scripts/verify.json` requires it, so a folder that never synced this stack skips the phase.
|
|
31
|
+
|
|
32
|
+
## lint-staged
|
|
33
|
+
|
|
34
|
+
- `.lintstagedrc` is a base seed this stack cannot reach once written. Add a `**/*.sh` entry by hand, running `shfmt --write --indent 2` then `shellcheck --severity=warning`, to run the checks on commit.
|
|
35
|
+
- Do NOT copy that glob into a `package.json` script. lint-staged expands its own globs and passes matched files as arguments, which a bare shell script does not.
|
|
36
|
+
|
|
37
|
+
## CI
|
|
38
|
+
|
|
39
|
+
- `.github/workflows/shell.yml` runs on pull requests targeting `main` and on `workflow_dispatch`: checkout, setup Bun, `bun install --frozen-lockfile`, install both tools through apt, then `check:shell`.
|
|
40
|
+
|
|
41
|
+
## CLI
|
|
42
|
+
|
|
43
|
+
| Script | What it does |
|
|
44
|
+
| ---------------------- | --------------------------------------------------------------- |
|
|
45
|
+
| `bun run check:shell` | Asserts shfmt formatting, then runs shellcheck at warning level |
|
|
46
|
+
| `bun run format:shell` | Writes shfmt formatting in place |
|
|
@@ -15,7 +15,6 @@ packages = [
|
|
|
15
15
|
"build" = "tsc --noEmit && vite build"
|
|
16
16
|
"preview" = "WORKTREE_PORT_OFFSET=$(bash scripts/worktree-port.sh) && export WORKTREE_PORT_OFFSET && vite preview"
|
|
17
17
|
"typecheck" = "tsc --noEmit"
|
|
18
|
-
"setup" = "./scripts/setup.sh"
|
|
19
18
|
|
|
20
19
|
[scripts.override]
|
|
21
20
|
"build" = "tsc --noEmit && vite build"
|
|
@@ -17,9 +17,9 @@ The vite-react stack covers Vite + React + TypeScript projects: web apps and Chr
|
|
|
17
17
|
## What ships as golden configs
|
|
18
18
|
|
|
19
19
|
- `vite.config.ts`: `@vitejs/plugin-react`, `@tailwindcss/vite`, `@` path alias to `./src`, `VITE_BASE_URL` env for base path. Dev port `5173` and preview port `4173`, each plus `WORKTREE_PORT_OFFSET`, both with `strictPort`.
|
|
20
|
-
- `vitest.config.ts`: merges from `vite.config.ts
|
|
20
|
+
- `vitest.config.ts`: merges from `vite.config.ts` (imported with its `.ts` extension, which Vite 8 requires), jsdom, globals, setup file, `passWithNoTests: true`, v8 coverage.
|
|
21
21
|
- `playwright.config.ts`: all browsers, `webServer` on `bun run dev` at port `5173` plus `WORKTREE_PORT_OFFSET`, `reuseExistingServer: false`, trace under `use`.
|
|
22
|
-
- `tsconfig.json`: unified, `noEmit: true`, `skipLibCheck: true`, `@/` paths, `vitest/globals` and `@testing-library/jest-dom` in types.
|
|
22
|
+
- `tsconfig.json`: unified, `noEmit: true`, `skipLibCheck: true`, `@/` paths, `vitest/globals` and `@testing-library/jest-dom/vitest` in types.
|
|
23
23
|
|
|
24
24
|
## Chrome extension variant
|
|
25
25
|
|
|
@@ -33,14 +33,6 @@ When scaffolding a Chrome extension, override the installed golden configs:
|
|
|
33
33
|
- `screenshot` script: `bun run build && bun e2e/screenshot.ts` (no preview server).
|
|
34
34
|
- Additional gitignore entries: `*.crx`, `*.pem`, `release/`.
|
|
35
35
|
|
|
36
|
-
## Setup script
|
|
37
|
-
|
|
38
|
-
- File: `scripts/setup.sh`. Destructive: deletes `.git` and self-removes after running. Run once immediately after scaffolding.
|
|
39
|
-
- Prompt for project name, normalize to kebab-case, derive title-cased display name.
|
|
40
|
-
- Update `package.json` name and version, inject verify/clean/update scripts, remove setup.
|
|
41
|
-
- Update `<title>` tags in HTML files.
|
|
42
|
-
- Wipe `.git`, re-init, make scripts executable, commit as `chore(root): initialize <name>`.
|
|
43
|
-
|
|
44
36
|
## Development docs (extend)
|
|
45
37
|
|
|
46
38
|
Append to the `## Scripts` table:
|
|
@@ -95,11 +95,9 @@ jobs:
|
|
|
95
95
|
# and stops here without pushing a second time.
|
|
96
96
|
if: steps.diff.outputs.changed == 'true'
|
|
97
97
|
# The hooks are off because this commit carries nothing they can read.
|
|
98
|
-
# `pre-push` runs the full verify,
|
|
99
|
-
#
|
|
100
|
-
#
|
|
101
|
-
# the source, and what this step pushes is PNG bytes a capture
|
|
102
|
-
# produced.
|
|
98
|
+
# `pre-push` runs the full verify, which reruns every check the jobs
|
|
99
|
+
# in verify.yml already ran against the source, and what this step
|
|
100
|
+
# pushes is PNG bytes a capture produced.
|
|
103
101
|
env:
|
|
104
102
|
HUSKY: 0
|
|
105
103
|
run: |
|
|
@@ -30,9 +30,6 @@ jobs:
|
|
|
30
30
|
- name: Install Dependencies
|
|
31
31
|
run: bun install --frozen-lockfile
|
|
32
32
|
|
|
33
|
-
- name: Install Shell Tools
|
|
34
|
-
run: sudo apt-get install -y shfmt shellcheck
|
|
35
|
-
|
|
36
33
|
- name: Typecheck
|
|
37
34
|
run: bun run typecheck
|
|
38
35
|
|
|
@@ -42,9 +39,6 @@ jobs:
|
|
|
42
39
|
- name: Check Formatting
|
|
43
40
|
run: bun run check:format
|
|
44
41
|
|
|
45
|
-
- name: Check Shell
|
|
46
|
-
run: bun run check:shell
|
|
47
|
-
|
|
48
42
|
unit-tests:
|
|
49
43
|
name: 🧪 Unit Tests
|
|
50
44
|
runs-on: ubuntu-latest
|
|
@@ -22,9 +22,9 @@ packages = [
|
|
|
22
22
|
"@types/react",
|
|
23
23
|
"@types/react-dom",
|
|
24
24
|
"@types/node",
|
|
25
|
-
"vitest@^
|
|
26
|
-
"@vitest/coverage-v8@^
|
|
27
|
-
"@vitest/ui@^
|
|
25
|
+
"vitest@^5",
|
|
26
|
+
"@vitest/coverage-v8@^5",
|
|
27
|
+
"@vitest/ui@^5",
|
|
28
28
|
"jsdom",
|
|
29
29
|
"@testing-library/react",
|
|
30
30
|
"@testing-library/jest-dom",
|
|
@@ -46,7 +46,7 @@ packages = [
|
|
|
46
46
|
"test:e2e:changed" = "WORKTREE_PORT_OFFSET=$(bash scripts/worktree-port.sh) && export WORKTREE_PORT_OFFSET && playwright test --only-changed"
|
|
47
47
|
"test:e2e:ui" = "WORKTREE_PORT_OFFSET=$(bash scripts/worktree-port.sh) && export WORKTREE_PORT_OFFSET && playwright test --ui"
|
|
48
48
|
"test:e2e:report" = "playwright show-report"
|
|
49
|
-
"check:full" = "
|
|
49
|
+
"check:full" = "bun scripts/verify.ts && bun run test:e2e"
|
|
50
50
|
"smoke:prod" = "bun e2e/screenshot.ts --check-console-clean --require-base-url"
|
|
51
51
|
|
|
52
52
|
[scripts.override]
|
package/tooling/web/reference.md
CHANGED
|
@@ -11,12 +11,12 @@ The web layer covers web-universal tooling shared across Vite + React, Astro, an
|
|
|
11
11
|
Golden config files live in `tooling/web/configs/` and are copied into the target on `canon tooling sync web . --write`, replacing whatever sits at those paths. They are the source of truth. The reference covers rationale and tradeoffs. Configs show the concrete setup.
|
|
12
12
|
|
|
13
13
|
- `eslint.config.js`: flat config with `@eslint/js`, `typescript-eslint`, React hooks, import sort, check-file, vitest rules scoped to test files, `eslint-config-prettier` last.
|
|
14
|
-
- `src/test/setup.ts`: `@testing-library/jest-dom` import, `cleanup` after each test.
|
|
14
|
+
- `src/test/setup.ts`: `@testing-library/jest-dom/vitest` import, `cleanup` after each test.
|
|
15
15
|
- `e2e/screenshot.ts`: capture template. A single `CASES` record at the top carries one entry per output file, each naming a section, a theme, and a route, and the loop below crosses every case with the `VIEWPORTS` array and writes `screenshots/<hostname>/<section>/<width>--<theme>.png`, keyed on `SCREENSHOT_BASE_URL`'s hostname so a local and a deployed run land in different folders. `VIEWPORTS` holds four breakpoint buckets named by width, 320, 768, 1280 and 1536, with 320 as the base a page has to hold without wrapping or clipping. A case flagged `evidence: true` additionally writes `evidence/<section>/<width>--<theme>.png`, with no hostname segment, at the viewports flagged `evidence` alone, which are 320 and 1280. Committing all four multiplies the tracked frames by the width count, so the flag is what keeps the tracked set at twice the sections rather than four times. A case may name `excludeViewports` to skip a width, for a route whose long-form prose reflows at 320 instead of breaking. `SCREENSHOT_FILTER` narrows a run to the cases whose label, `<section>/<width>--<theme>`, contains any comma-separated term, exits 1 when nothing matches and lists the labels that exist, and leaves the rest of the sweep alone. `--require-base-url` skips a flagged case entirely, so a production smoke run neither writes to the committed path nor counts an evidence route in its console-clean check, and exits 1 when that leaves zero cases run, so flagging every case cannot silence the production check without saying so. Per-project cases extend the one record. A route's widths and themes sit together under its section folder, so the filename carries both. A case may also name `sections`, one `{ name, selector }` per addressable part of the route, and each writes its own frame at `screenshots/<hostname>/<section>/<name>/<width>--<theme>.png` beside the whole-page one, plus `evidence/<section>/<name>/<width>--<theme>.png` where the case is flagged and the width carries `evidence`. The field is optional, so a case that names none captures the page alone as before, and a selector matching nothing is reported and skipped rather than raised, since `CASES` is a template a project rewrites and a target that syncs this file before editing its own list would otherwise capture nothing at all. Testing that every named section resolves belongs to the project that owns the selectors, beside its own page. A case may also name `mask`, a list of selectors whose boxes are painted over in every frame the case writes, whole-page and section alike, for a value that moves between runs with no code change, so a double capture still compares everything else. A mask selector matching nothing is reported and skipped the same way. Every case settles before anything is shot: the context is created with `reducedMotion: 'reduce'`, each named section is scrolled into view so an `IntersectionObserver` fires and a frame marked `loading="lazy"` loads, the page returns to the top, and fonts, images and same-origin frames are waited out on a bounded condition rather than on a second `networkidle`, which is a lifecycle event of the navigation and does not re-arm for a load a scroll started. A section frame drops the page's floating chrome, being whatever computes to `position: sticky` or `fixed`, because a section taller than the viewport is scrolled into view to be cut and a sticky bar otherwise rides that scroll into the middle of the frame. The whole-page frame is shot first and keeps its chrome. `--check-console-clean` collects `console`-level error messages per case and exits 1 with the list if any fired, turning the capture into a smoke check. `--require-base-url` exits 1 before launching a browser when `SCREENSHOT_BASE_URL` is unset, guarding a script meant to run against a real deployment from silently capturing `localhost`.
|
|
16
16
|
- `scripts/screenshot.sh`: sources `scripts/lib/preview-server.sh`, then runs the capture against the served preview.
|
|
17
17
|
- `scripts/lib/preview-server.sh`: sourced, never executed. Builds, serves on `PREVIEW_PORT`, blocks until the port answers, and traps the whole process group on exit, including the detached grandchild `lsof` finds. Both capture scripts source it so the startup lives once.
|
|
18
18
|
- `scripts/readme-screenshot.sh`: captures one case under `SCREENSHOT_FILTER` and copies its light and dark frames to `assets/evidence/readme/`. `README_FILTER` ships empty with `header/1280` as its example, and the script exits 1 until a project fills it, since a shipped default would capture the wrong part of the page in every project but one. Its copy reads from `screenshots/<hostname>/`, which is where the harness writes.
|
|
19
|
-
- `.github/workflows/readme-screenshot.yml`: refreshes that frame on a pull request and commits it back to the branch. The path list ships as `REPLACE_WITH_PROJECT_PATHS`, and the job's first step after checkout exits 1 while it stays, since a job that never fires leaves no run and no diff to notice. The workflow's own path is in the list so the installing pull request reaches that step. When a commit-back is right and when a report is, `governance/rules/tooling/
|
|
19
|
+
- `.github/workflows/readme-screenshot.yml`: refreshes that frame on a pull request and commits it back to the branch. The path list ships as `REPLACE_WITH_PROJECT_PATHS`, and the job's first step after checkout exits 1 while it stays, since a job that never fires leaves no run and no diff to notice. The workflow's own path is in the list so the installing pull request reaches that step. When a commit-back is right and when a report is, `governance/rules/tooling/ci-workflow.md` states the test.
|
|
20
20
|
- `.github/workflows/verify.yml`: `static-checks`, `unit-tests`, `build-verify`, and `e2e-tests` jobs.
|
|
21
21
|
- `scripts/verify.json`: the phases base's verify runner requires here, being typecheck, lint, unit tests, and build. `## Verify script` covers the order and the card exclusion stage.
|
|
22
22
|
- `scripts/worktree-port.sh`: prints a base port plus this working directory's offset. Called with no argument it prints the offset alone. It refuses a folder left under the worktrees directory after its worktree was removed, rather than printing a port for it.
|
|
@@ -113,7 +113,7 @@ Append rows:
|
|
|
113
113
|
|
|
114
114
|
`canon tooling verify <stack>` is the only automated caller of `bun run screenshot`, running it for any stack whose `package.json` declares the script and asserting that PNG files land under `screenshots/`. It counts them with a recursive find carrying no depth limit, so the section folders the seed writes satisfy the assertion without a change to it. Do not flatten the layout to protect that check. No ship chain captures a screenshot, so the output path the seed writes is a contract that one verifier reads rather than a default a ship step depends on.
|
|
115
115
|
|
|
116
|
-
`governance/rules/ui/
|
|
116
|
+
`governance/rules/ui/surface-capture.md` is what asks a session to run the capture after a surface changes. It now fires on every component file too, reversing the route-and-page-only scope this reference once described, after a shipped batch of components carried no capture and a defect went unseen. The rule body states its own exemption for a component the production build strips out, so a reader chasing that case reads it there rather than here.
|
|
117
117
|
|
|
118
118
|
The sweep under `screenshots/` is ignored again, and only a flagged case's `evidence/` output tracks in git, so the first capture a scaffolded target runs after this change is the baseline it commits there. A case naming sections commits a folder per section under that baseline rather than one file per theme, which is what lets a pull request comparison land on the part of the page that moved instead of on one image of the whole of it. The count is the section list times the themes, so a list is worth sizing against how many frames each later change has to regenerate and a reviewer has to read.
|
|
119
119
|
|
|
@@ -126,6 +126,6 @@ The sweep under `screenshots/` is ignored again, and only a flagged case's `evid
|
|
|
126
126
|
|
|
127
127
|
## Verify script
|
|
128
128
|
|
|
129
|
-
The web layer's `scripts/verify.json` requires `typecheck`, `lint`, `test:run`, and `build`, and base's `scripts/verify.ts` runs them in its fixed order: typecheck, lint, format, shell, unit tests, build, markdown bans, then the card exclusion check where one is installed. astro, vite-react, and nextjs inherit the list, since the nearest stack's copy wins. An adapter whose phases differ ships its own `verify.json` rather than a script.
|
|
129
|
+
The web layer's `scripts/verify.json` requires `typecheck`, `lint`, `test:run`, and `build`, and base's `scripts/verify.ts` runs them in its fixed order: typecheck, lint, format, shell where the `shell` stack declares it, unit tests, build, markdown bans, then the card exclusion check where one is installed. astro, vite-react, and nextjs inherit the list, since the nearest stack's copy wins. An adapter whose phases differ ships its own `verify.json` rather than a script.
|
|
130
130
|
|
|
131
131
|
The card stage runs `scripts/check-card-exclusion.sh` whenever that file is installed, which keeps the social card route's build exclusion on the default path rather than behind a flag. It tests for the script rather than the stack, so a project with no card route runs one less stage with no override, and the stack shipping a card route owns what the check reads, being the build the stage before it produced. The astro reference carries the route itself.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|