@erclx/canon 5.67.0 → 5.69.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/CHANGELOG.md +31 -0
- package/README.md +1 -1
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/app-drive/REQUIREMENT.md +5 -5
- package/claude/skills/app-drive/SKILL.md +14 -4
- package/claude/skills/app-drive/references/drive-record.md +12 -1
- package/claude/skills/canon-cli/SKILL.md +2 -2
- package/claude/skills/canon-feedback/REQUIREMENT.md +1 -1
- package/claude/skills/canon-feedback/SKILL.md +1 -1
- package/claude/skills/design-identity/REQUIREMENT.md +4 -4
- package/claude/skills/design-identity/SKILL.md +7 -7
- package/claude/skills/{pick-by-eye → design-pick}/REQUIREMENT.md +6 -6
- package/claude/skills/{pick-by-eye → design-pick}/SKILL.md +18 -10
- package/claude/skills/{pick-by-eye → design-pick}/references/board.md +17 -11
- package/claude/skills/design-pick/references/design-config.md +33 -0
- package/claude/skills/design-record/REQUIREMENT.md +2 -2
- package/claude/skills/design-record/SKILL.md +1 -1
- package/claude/skills/design-taste/REQUIREMENT.md +2 -2
- package/claude/skills/design-taste/SKILL.md +3 -3
- package/claude/skills/design-taste/references/preflight.md +1 -1
- package/claude/skills/git-issue/REQUIREMENT.md +1 -1
- package/claude/skills/git-issue/references/issue.md +1 -1
- package/claude/skills/plan-feature/SKILL.md +1 -1
- package/claude/skills/plan-feature/references/plan.md +21 -6
- package/claude/skills/plan-groundwork/SKILL.md +1 -1
- package/claude/skills/pr-evidence/REQUIREMENT.md +1 -1
- package/claude/skills/pr-evidence/SKILL.md +7 -1
- package/claude/skills/pr-evidence/references/evidence.md +33 -3
- package/claude/skills/review-craft/references/ui.md +30 -10
- package/claude/skills/role-orchestrator/references/orchestrator-launch.md +3 -3
- package/claude/skills/role-orchestrator/references/orchestrator-parked.md +1 -1
- package/claude/skills/role-orchestrator/references/orchestrator-planning-wait.md +24 -0
- package/claude/skills/role-planner/SKILL.md +4 -2
- package/claude/skills/role-worker/SKILL.md +5 -6
- package/claude/skills/task-board/references/tasks.md +1 -1
- package/claude/skills/task-complete/references/receipt-sweep.md +1 -1
- package/claude/skills/{ux-audit → ui-audit}/REQUIREMENT.md +3 -3
- package/claude/skills/{ux-audit → ui-audit}/SKILL.md +7 -7
- package/claude/skills/ui-checklist/REQUIREMENT.md +1 -1
- package/claude/skills/ui-craft/SKILL.md +1 -1
- package/claude/skills/{ui-record → ui-film}/REQUIREMENT.md +7 -5
- package/claude/skills/{ui-record → ui-film}/SKILL.md +23 -12
- package/claude/skills/{ui-record → ui-film}/references/config.md +3 -3
- package/claude/skills/{ui-record → ui-film}/references/handoff.md +28 -9
- package/claude/skills/ui-film/references/pr-clip.md +84 -0
- package/claude/skills/{ui-record → ui-film}/references/take-craft.md +8 -1
- package/claude/skills/{ux-measure → ui-measure}/REQUIREMENT.md +3 -3
- package/claude/skills/{ux-measure → ui-measure}/SKILL.md +6 -6
- package/docs/agents/audits.md +1 -1
- package/docs/agents/migrate.md +13 -13
- package/docs/agents/records.md +1 -0
- package/docs/target/migrations.md +12 -10
- package/docs/target/projects.md +1 -1
- package/docs/target/sync.md +1 -1
- package/docs/workflow/skill-map-on-request.md +1 -2
- package/docs/workflow/skill-map.md +9 -10
- package/docs/workflow/visual-design-workflow.md +6 -1
- package/governance/ledger/claude/background.md +26 -0
- package/governance/rules/claude/background.md +19 -0
- package/governance/stacks/base.toml +1 -0
- package/package.json +8 -5
- package/scripts/ci/install-playwright-deps.sh +52 -0
- package/src/claude/cases/authoring.ts +2 -2
- package/src/claude/cases/misc.ts +1 -1
- package/src/claude/cases/setup.ts +0 -5
- package/src/claude/cases/workflow.ts +6 -6
- package/src/commands/fixtures/gh.sh +64 -0
- package/src/commands/gov.ts +33 -3
- package/src/commands/migrate.ts +12 -2
- package/src/commands/pr.ts +237 -79
- package/src/commands/take.ts +44 -8
- package/src/commands/tasks.ts +183 -0
- package/src/gate/stages.ts +2 -2
- package/src/gov/audit.ts +48 -11
- package/src/gov/detect.ts +1 -1
- package/src/markdown/scope.ts +9 -14
- package/src/migrate/record-layout.ts +5 -3
- package/src/migrate/skill-names.ts +21 -4
- package/src/pr/evidence.ts +208 -78
- package/src/pr/frames.ts +42 -4
- package/src/pr/pixels.ts +44 -0
- package/src/records/backup.ts +28 -4
- package/src/records/validate.ts +1 -0
- package/src/sandbox/headless/dispatch-shim.sh +15 -0
- package/src/sandbox/headless/dispatch.ts +12 -14
- package/src/sandbox/stub-gh.sh +26 -0
- package/src/sandbox/stub-remote.ts +8 -29
- package/src/sync/engine.ts +1 -1
- package/src/take/camera.ts +2 -2
- package/src/take/encode.ts +38 -1
- package/src/take/film.ts +26 -3
- package/src/take/pointer.ts +169 -0
- package/src/take/reel.ts +215 -0
- package/src/take/screencast.ts +5 -2
- package/src/take/stepper.ts +23 -6
- package/src/take/zoom/NOTICE.md +1 -1
- package/src/tasks/launch-wait.ts +160 -0
- package/tooling/claude/reference.md +1 -1
- package/claude/skills/canon-feedback-triage/REQUIREMENT.md +0 -34
- package/claude/skills/canon-feedback-triage/SKILL.md +0 -98
- package/claude/skills/plan-ready/REQUIREMENT.md +0 -35
- package/claude/skills/plan-ready/SKILL.md +0 -136
- package/claude/skills/plan-ready/references/assembly.md +0 -75
- package/claude/skills/plan-ready/references/ready.md +0 -128
- /package/claude/skills/{pick-by-eye → design-pick}/references/live-arms.md +0 -0
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
---
|
|
2
|
-
title: UI
|
|
2
|
+
title: UI film handoff
|
|
3
3
|
description: What HyperFrames receives from a take, the shape of the click log and camera track, and how a composition applies the camera and draws the cursor
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# UI
|
|
6
|
+
# UI film handoff
|
|
7
7
|
|
|
8
|
-
Read at Step 5 of `ui-
|
|
8
|
+
Read at Step 5 of `ui-film`. Canon stops at the clip, and a HyperFrames composition does the rest. This file states what the composition receives and how it uses each part, so a session composing later needs nothing from the session that filmed.
|
|
9
9
|
|
|
10
10
|
## What the takes folder holds
|
|
11
11
|
|
|
12
|
-
`take.json` lists every beat in plan order, with the folder, the route that filmed it, and the frame count. Each beat's folder holds
|
|
12
|
+
`take.json` lists every beat in plan order, with the folder, the route that filmed it, and the frame count. Each beat's folder holds four files.
|
|
13
13
|
|
|
14
|
-
| File | Holds
|
|
15
|
-
| ------------- |
|
|
16
|
-
| `clip.mp4` | H.264 at 60 fps, 3840x2160 when frame stepped, 1920x1080 when screencast
|
|
17
|
-
| `log.json` | Every move, click, typing burst, and scroll, with each target's box
|
|
18
|
-
| `camera.json` | One camera per frame of the clip, with the cursor and the click ring
|
|
14
|
+
| File | Holds |
|
|
15
|
+
| ------------- | ---------------------------------------------------------------------------- |
|
|
16
|
+
| `clip.mp4` | H.264 at 60 fps, 3840x2160 when frame stepped, 1920x1080 when screencast |
|
|
17
|
+
| `log.json` | Every move, click, typing burst, and scroll, with each target's box |
|
|
18
|
+
| `camera.json` | One camera per frame of the clip, with the cursor and the click ring |
|
|
19
|
+
| `still.jpg` | The clip's closing frame, the check on each take, which no composition needs |
|
|
19
20
|
|
|
20
21
|
Every coordinate in the log and the track is in CSS pixels of a 1920x1080 page, whatever size the clip is. Every time is in milliseconds on the clip's own clock, so frame `n` sits at `n * 1000 / 60`.
|
|
21
22
|
|
|
@@ -30,6 +31,24 @@ Each frame carries `scale`, the view's top-left `x` and `y`, the `cursor`, and `
|
|
|
30
31
|
|
|
31
32
|
The track is final. It already carries the easing, the spring, and the hold, so a composition sets each frame's values and never tweens between them.
|
|
32
33
|
|
|
34
|
+
## Where the composition lives
|
|
35
|
+
|
|
36
|
+
The HyperFrames project sits in the same workspace as the takes, so one folder holds everything a video is made from.
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
bunx -y hyperframes init .canon/video/<slug>/composition
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
- Use `bunx` when bun is available, falling back to `npx -y hyperframes init ...` otherwise
|
|
43
|
+
- Prefix the path with the main worktree root when running from a linked worktree, as `ui-film`'s write scope states
|
|
44
|
+
- Read each clip from `../takes/<dir>/clip.mp4`, relative to the project, rather than copying it in
|
|
45
|
+
- Leave renders in the project's `renders/` folder, which `canon records push` skips along with `takes/`, `snapshots/`, `node_modules/`, and any video file
|
|
46
|
+
- An image the composition adds under `assets/`, such as a logo, is backed up with the project's source
|
|
47
|
+
|
|
48
|
+
Compose from a session started at the main worktree root. From a linked worktree or an isolated background session, `Write` and `Edit` refuse every file in `composition/` and redirect to a worktree copy no later session reads, so never take that redirect.
|
|
49
|
+
|
|
50
|
+
Where composing from the main root is not possible, write each file whole through the route `${CLAUDE_SKILL_DIR}/../session-worktree/references/main-root-writes.md` states.
|
|
51
|
+
|
|
33
52
|
## Applying it in a composition
|
|
34
53
|
|
|
35
54
|
Load `hyperframes-core` for placing the clip and `hyperframes-keyframes` for the wrapper's transform before writing the composition.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Pull request clip
|
|
3
|
+
description: Pull request mode of ui-film, run for pr-evidence with no operator present, covering the beat choice from the checklist, the length cap, the still check that stands in for approval, the reel flag, and the push to the frames branch
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Pull request clip
|
|
7
|
+
|
|
8
|
+
Read at the top of `ui-film` when the caller names pull request mode. `pr-evidence` is the only caller, passing the pull request number, the `url` its `canon pr local` read returned, and the checklist text.
|
|
9
|
+
|
|
10
|
+
This mode films a short reel of what the checklist asks a reviewer to try, hosts it on `canon/frames`, and hands back the link or the reason it skipped.
|
|
11
|
+
|
|
12
|
+
## Contents
|
|
13
|
+
|
|
14
|
+
- [What changes from an ordinary run](#what-changes-from-an-ordinary-run)
|
|
15
|
+
- [Choose the beats](#choose-the-beats)
|
|
16
|
+
- [Film the reel](#film-the-reel)
|
|
17
|
+
- [Check each still](#check-each-still)
|
|
18
|
+
- [Push the reel](#push-the-reel)
|
|
19
|
+
- [What goes back to the caller](#what-goes-back-to-the-caller)
|
|
20
|
+
|
|
21
|
+
## What changes from an ordinary run
|
|
22
|
+
|
|
23
|
+
The mode holds only while the caller names it. An ordinary run that finds a pull request in its context still stops at Step 2 for approval.
|
|
24
|
+
|
|
25
|
+
- Skip Step 1's throwaway copy. Film the address the caller passed, joined to the config's `access` value, and start no server.
|
|
26
|
+
- Skip Step 2's approval. The beats come from a checklist a reviewer already reads, and the still check below is the guard against posting a wrong take.
|
|
27
|
+
- Skip Step 5's handoff and its output block, since the reel is the product and HyperFrames composes nothing here
|
|
28
|
+
- Write inside `.canon/tmp/ui-film/pr-<number>/` at the current worktree's root in place of the video workspace, since a reel is thrown away once posted
|
|
29
|
+
- Ask nothing at any step. Every stop below is a skip with a reason, since the ship chain runs this with nobody to answer.
|
|
30
|
+
|
|
31
|
+
## Choose the beats
|
|
32
|
+
|
|
33
|
+
Take a beat from each checklist box that asks the reviewer to click, fill, or scroll something, in checklist order, up to three beats.
|
|
34
|
+
|
|
35
|
+
- Skip a box ending in `(taste)`, since no driver judges it
|
|
36
|
+
- Skip a box that asks only to look at a state the page opens on, since a screenshot already shows it
|
|
37
|
+
- Name each beat after its box's text, cut to the action
|
|
38
|
+
- Write the plan per `${CLAUDE_SKILL_DIR}/references/take-craft.md`, finding each target on the served page rather than guessing it
|
|
39
|
+
- With no box left, skip as `no-interactive-box` and film nothing
|
|
40
|
+
|
|
41
|
+
Keep the whole reel at or under 12 seconds. Each beat opens and closes on a 0.6 s hold, so give each action's `wait` only what its result needs to settle.
|
|
42
|
+
|
|
43
|
+
## Film the reel
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
canon take <url> .canon/tmp/ui-film/pr-<number>/plan.json --out .canon/tmp/ui-film/pr-<number>/takes --reel .canon/tmp/ui-film/pr-<number>/reel.webp --json
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Branch on the record's `reason`, never on the exit code.
|
|
50
|
+
|
|
51
|
+
| Record | Route |
|
|
52
|
+
| --------------- | ------------------------------------------------------------------ |
|
|
53
|
+
| No `reason` | Sum the beats' `seconds` and continue to the stills |
|
|
54
|
+
| `reel-failed` | Skip as `reel-failed` with the record's `message` |
|
|
55
|
+
| Any other value | Skip under that `reason`, such as `target-missing` with its `beat` |
|
|
56
|
+
|
|
57
|
+
When the beats sum past 12 seconds, drop the last beat from the plan and film once more. A second run past the cap skips as `over-cap`.
|
|
58
|
+
|
|
59
|
+
## Check each still
|
|
60
|
+
|
|
61
|
+
Open each beat's `still.jpg`, the closing frame the record names in its `still` field, and confirm it shows the state the beat's box describes. This check replaces the operator's approval, so it runs on every reel.
|
|
62
|
+
|
|
63
|
+
- A still showing the wrong state skips the reel as `wrong-state`, naming the beat and what the still shows
|
|
64
|
+
- A record whose beats carry no `still` field comes from a `canon` predating the still, so skip as `no-still` rather than posting a reel nothing checked
|
|
65
|
+
- Read `fallback` on each beat the way an ordinary run does. A beat filmed by screencast still joins the reel, since the reel shrinks every beat to one width.
|
|
66
|
+
|
|
67
|
+
## Push the reel
|
|
68
|
+
|
|
69
|
+
Stamp the pass in compact UTC and push the file:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
canon pr frames <number> --reel .canon/tmp/ui-film/pr-<number>/reel.webp --pass "$(date -u +%Y%m%dT%H%M%SZ)" --json
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
- `ok`: hold the record's `link`
|
|
76
|
+
- `reel-too-large`: skip as `reel-too-large`, since GitHub would not render it
|
|
77
|
+
- Any other `reason`: skip under it with the record's `message`
|
|
78
|
+
|
|
79
|
+
## What goes back to the caller
|
|
80
|
+
|
|
81
|
+
Hand `pr-evidence` one of two things and print nothing of your own:
|
|
82
|
+
|
|
83
|
+
- The `link` from the push, which it passes to `canon pr evidence --reel`
|
|
84
|
+
- A skip, as the reason and a one-line message, which its report names
|
|
@@ -5,7 +5,7 @@ description: The filming rules a take plan follows, the frame-stepping limits, a
|
|
|
5
5
|
|
|
6
6
|
# Take craft
|
|
7
7
|
|
|
8
|
-
Read at Step 3 of `ui-
|
|
8
|
+
Read at Step 3 of `ui-film`, before writing the first beat. `canon take --help` carries every step kind, the target forms, and each refusal code, so this file carries the judgment and leaves the vocabulary to the verb.
|
|
9
9
|
|
|
10
10
|
## Contents
|
|
11
11
|
|
|
@@ -57,6 +57,13 @@ A fallback films the beat again from a fresh load, replaying its setup and the s
|
|
|
57
57
|
|
|
58
58
|
A screencast beat films in real time at 1920x1080, which goes soft at the 1.8x zoom. Tell the operator which beats ran that way.
|
|
59
59
|
|
|
60
|
+
### Reading a take back
|
|
61
|
+
|
|
62
|
+
Two rules hold once a beat is filmed.
|
|
63
|
+
|
|
64
|
+
- A stepped still is 3840x2160 and opens at 2000 wide. Crop it for text too small to read there, with `ffmpeg -v error -y -i <dir>/still.jpg -vf crop=<w>:<h>:<x>:<y> <dir>/crop.png` on the still's own pixels.
|
|
65
|
+
- Read when something happened from `log.json` and `camera.json`, both on the clip's clock, never from a clock printed in the page, which starts before the first kept frame
|
|
66
|
+
|
|
60
67
|
## Targets
|
|
61
68
|
|
|
62
69
|
- Prefer a stable attribute, such as an `aria-label`, a `data-testid`, or an `id`, over a position like `:nth-child`
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
2
|
+
name: ui-measure
|
|
3
3
|
description: Why a rendering cost question is answered with a number against a published threshold, and why the runner is detected rather than prescribed
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# UI measure requirement
|
|
7
7
|
|
|
8
8
|
## Gap
|
|
9
9
|
|
|
@@ -29,7 +29,7 @@ A session that does start one picks a runner on the spot, takes one noisy load,
|
|
|
29
29
|
|
|
30
30
|
## Out of scope
|
|
31
31
|
|
|
32
|
-
- Judging the interface against stated intent, and contrast, which `
|
|
32
|
+
- Judging the interface against stated intent, and contrast, which `ui-audit` owns from the stylesheet's color values
|
|
33
33
|
- Writing behavioral tests against the interface, which `test-first` and `test-craft` own
|
|
34
34
|
- Network waterfall, bundle size, and accessibility, which no skill measures
|
|
35
35
|
- Fixing what the reading found, which a separate change owns
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
|
-
name:
|
|
3
|
-
description: Measures paint, processor, and layout cost against a running interface and reports numbers against published thresholds. Detects the project's existing browser harness rather than requiring one. Use when asked "how fast is this page", "measure the UI", "what does this cost to render", "check Core Web Vitals", or "profile the interface". Do NOT use to judge UI quality by reading source, which is `
|
|
2
|
+
name: ui-measure
|
|
3
|
+
description: Measures paint, processor, and layout cost against a running interface and reports numbers against published thresholds. Detects the project's existing browser harness rather than requiring one. Use when asked "how fast is this page", "measure the UI", "what does this cost to render", "check Core Web Vitals", or "profile the interface". Do NOT use to judge UI quality by reading source, which is `ui-audit`.
|
|
4
4
|
metadata:
|
|
5
5
|
family: check
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
#
|
|
8
|
+
# UI measure
|
|
9
9
|
|
|
10
10
|
Report numbers. A sentence about what the source looks like is what this exists to replace, so every finding is a reading beside the threshold it is measured against.
|
|
11
11
|
|
|
@@ -13,7 +13,7 @@ Report numbers. A sentence about what the source looks like is what this exists
|
|
|
13
13
|
|
|
14
14
|
- If the project names no command that serves an interface and the user names no URL, stop: `❌ Nothing to serve. Name a running URL or a command that starts one.`
|
|
15
15
|
- Test for a servable interface rather than source under a folder, since this measures what a browser receives and never reads the tree behind it
|
|
16
|
-
- If the request is about intent, consistency, missing states, or contrast, run nothing and name `
|
|
16
|
+
- If the request is about intent, consistency, missing states, or contrast, run nothing and name `ui-audit`. That skill reads source and this one runs the interface.
|
|
17
17
|
|
|
18
18
|
## Step 1: reach the interface
|
|
19
19
|
|
|
@@ -116,7 +116,7 @@ Report the reading and stop there. A remedy is a change with its own review, so
|
|
|
116
116
|
|
|
117
117
|
Derive `<slug>` per `${CLAUDE_SKILL_DIR}/../git-branch/references/slug.md`. Fall back to `latest` on an empty result.
|
|
118
118
|
|
|
119
|
-
- Write the full reading to `.canon/review/
|
|
119
|
+
- Write the full reading to `.canon/review/ui-measure-<slug>.md` at the main worktree root, resolved the way `session-worktree` does, creating the directory if needed and always overwriting
|
|
120
120
|
- The reading is a main-root write, so it goes out as a heredoc, routed the way `session-worktree` states
|
|
121
121
|
- `.canon/review/` is gitignored, so do not stage or commit the file
|
|
122
122
|
|
|
@@ -126,5 +126,5 @@ Output the summary line and the file path. Do not repeat the table in chat.
|
|
|
126
126
|
|
|
127
127
|
```plaintext
|
|
128
128
|
3 metrics measured against <url>. <n> past threshold.
|
|
129
|
-
📝 Wrote .canon/review/
|
|
129
|
+
📝 Wrote .canon/review/ui-measure-<slug>.md
|
|
130
130
|
```
|
package/docs/agents/audits.md
CHANGED
|
@@ -79,7 +79,7 @@ An audit that finds no corpus reports `absent`, which moves neither the verdict
|
|
|
79
79
|
| `secrets` | `canon secrets scan` | Credential-shaped values in the shipped tree | Gates |
|
|
80
80
|
| `labels` | `canon labels audit` | Changed paths no row of the label map reaches | Reports |
|
|
81
81
|
| `restated` | `canon gov restated` | Instructions `CLAUDE.md` states that a second surface states too | Reports |
|
|
82
|
-
| `rules` | `canon gov audit` | Rules past a shape limit, and here
|
|
82
|
+
| `rules` | `canon gov audit` | Rules past a shape limit, and here rules short of a ledger or out of step with one | Reports |
|
|
83
83
|
| `counts` | `canon gov counts` | Sentences stating a closed catalog's size that disagree with the tree | Reports |
|
|
84
84
|
| `census` | `canon census` | File count, extension breakdown, and line total | Reports |
|
|
85
85
|
| `deps` | `canon deps audit` | Advisories against the resolved dependencies | Reports |
|
package/docs/agents/migrate.md
CHANGED
|
@@ -8,22 +8,22 @@ kind: reference
|
|
|
8
8
|
|
|
9
9
|
`canon migrate <verb>` moves a project off a retired name or layout. Each verb reports its plan and writes nothing until `--write`, takes `--json`, and, except `rename`, takes `--root`. A second run rewrites nothing, which confirms the exclusions and markers fired.
|
|
10
10
|
|
|
11
|
-
| Verb | Moves
|
|
12
|
-
| ------------------ |
|
|
13
|
-
| `status` | Nothing. It lists every migration the project still needs, in run order.
|
|
14
|
-
| `rename` | The retired `aitk` name. `--scope target` rewrites toolkit-owned folders only.
|
|
15
|
-
| `skill-names` | Plugin skills off their `claude-` and `draft-` prefixes and other retired names, with every citation
|
|
16
|
-
| `records` | Session records from `.claude/` to `.canon/`, with every tracked citation
|
|
17
|
-
| `surface-roots` | Records such as `context/` and `REQUIREMENTS.md`, and the stamp folder, from `.claude/` to `canon/` by `git mv`
|
|
18
|
-
| `record-tree` | Citations inside the `.canon/` folders a session still follows, listed below the table
|
|
19
|
-
| `rule-layout` | A flat installed-rule layout onto the `canon/`-wrapped one
|
|
20
|
-
| `scratch-evidence` | A folder a durable record cites out of `.tmp/`, with its citations
|
|
21
|
-
| `record-layout` | Review receipts, memory archives, feedback, renders, picks, and
|
|
22
|
-
| `session-defaults` | The seeded session defaults into an existing `.claude/settings.json`, listed below the table
|
|
11
|
+
| Verb | Moves |
|
|
12
|
+
| ------------------ | --------------------------------------------------------------------------------------------------------------------- |
|
|
13
|
+
| `status` | Nothing. It lists every migration the project still needs, in run order. |
|
|
14
|
+
| `rename` | The retired `aitk` name. `--scope target` rewrites toolkit-owned folders only. |
|
|
15
|
+
| `skill-names` | Plugin skills off their `claude-` and `draft-` prefixes and other retired names, with every citation |
|
|
16
|
+
| `records` | Session records from `.claude/` to `.canon/`, with every tracked citation |
|
|
17
|
+
| `surface-roots` | Records such as `context/` and `REQUIREMENTS.md`, and the stamp folder, from `.claude/` to `canon/` by `git mv` |
|
|
18
|
+
| `record-tree` | Citations inside the `.canon/` folders a session still follows, listed below the table |
|
|
19
|
+
| `rule-layout` | A flat installed-rule layout onto the `canon/`-wrapped one |
|
|
20
|
+
| `scratch-evidence` | A folder a durable record cites out of `.tmp/`, with its citations |
|
|
21
|
+
| `record-layout` | Review receipts, memory archives, feedback, renders, picks, evidence, and the design board into their current folders |
|
|
22
|
+
| `session-defaults` | The seeded session defaults into an existing `.claude/settings.json`, listed below the table |
|
|
23
23
|
|
|
24
24
|
`record-tree` follows citations in `diagrams`, `memory`, `plans`, `proposals`, `review`, `tasks`, and `teach`. `session-defaults` denies `Agent`, `Task`, and both merge commands, and turns auto memory off. The bullets below add detail per verb.
|
|
25
25
|
|
|
26
|
-
- `skill-names` takes no `--scope`, and skips the changelog, eval transcripts, and the pointer each renamed `draft-` skill leaves at its old name
|
|
26
|
+
- `skill-names` takes no `--scope`, and skips the changelog, eval transcripts, replay fixtures, and the pointer each renamed `draft-` skill leaves at its old name
|
|
27
27
|
- `surface-roots` moves `context/`, `wireframes/`, `ARCHITECTURE.md`, `REQUIREMENTS.md`, `DESIGN.md`, and the stamp folder, and leaves `rules/`, `skills/`, `hooks/`, and `settings.json` in place
|
|
28
28
|
- `rule-layout` classifies each flat file against the stamp as clean, edited, or unclaimed. Clean and edited files move untouched, and an unclaimed name stays.
|
|
29
29
|
- `record-layout` labels each evidence folder `(pick)` or `(evidence)` in the dry run
|
package/docs/agents/records.md
CHANGED
|
@@ -28,6 +28,7 @@ printf '.canon/\n' >> .gitignore
|
|
|
28
28
|
```
|
|
29
29
|
|
|
30
30
|
- `push` commits every top-level folder under `.canon/` except `tmp`, `ordinal-locks`, and `.records.git`, then pushes. New folders list under `added`.
|
|
31
|
+
- `push` backs up a video workspace under `video/` without its media, skipping `takes/`, `renders/`, `snapshots/`, `node_modules/`, and any `.mp4`, `.webm`, or `.mov` file.
|
|
31
32
|
- `pull` restores the folders on a new machine after the setup above. It refuses rather than overwrite records the history lacks.
|
|
32
33
|
- `size` reports one row per folder, heaviest first, with file count, bytes, and growth over 7 and 30 days. After a `pull` every file reads as new.
|
|
33
34
|
- `prune-tmp` lists scratch untouched for 14 days and deletes it only with `--write`. It never offers `tmp/handoff/` or `tmp/pr/poll/`.
|
|
@@ -48,9 +48,7 @@ Run it once, ahead of `canon gov sync` or `canon gov install`.
|
|
|
48
48
|
|
|
49
49
|
## Rename the skill citations, once
|
|
50
50
|
|
|
51
|
-
Plugin skills dropped their `claude-` prefix, so `canon:claude-docs`
|
|
52
|
-
|
|
53
|
-
The seven `draft-` skills took verb-first names for what each makes. `canon migrate skill-names --write` carries a project across, and a pointer under each old name answers a typed invocation until it retires.
|
|
51
|
+
Plugin skills dropped their `claude-` prefix, so `canon:claude-docs` is now `canon:context-fold`. Five drafters merged into `write-doc`, seven `draft-` skills took verb-first names, and four joined their family. No old name keeps a pointer, and `canon migrate skill-names --write` moves a project. <!-- canon-keep-retired -->
|
|
54
52
|
|
|
55
53
|
| Old name | New name |
|
|
56
54
|
| ------------------ | ----------------------------------------------- |
|
|
@@ -58,17 +56,21 @@ The seven `draft-` skills took verb-first names for what each makes. `canon migr
|
|
|
58
56
|
| `draft-figure` | `draw-figure` <!-- canon-keep-retired --> |
|
|
59
57
|
| `draft-identity` | `design-identity` <!-- canon-keep-retired --> |
|
|
60
58
|
| `draft-slides` | `make-deck` <!-- canon-keep-retired --> |
|
|
61
|
-
| `draft-and-pick` | `pick
|
|
59
|
+
| `draft-and-pick` | `design-pick` <!-- canon-keep-retired --> |
|
|
62
60
|
| `draft-ready` | `plan-ready` <!-- canon-keep-retired --> |
|
|
63
61
|
| `draft-screencast` | `script-screencast` <!-- canon-keep-retired --> |
|
|
62
|
+
| `pick-by-eye` | `design-pick` <!-- canon-keep-retired --> |
|
|
63
|
+
| `ui-record` | `ui-film` <!-- canon-keep-retired --> |
|
|
64
|
+
| `ux-audit` | `ui-audit` <!-- canon-keep-retired --> |
|
|
65
|
+
| `ux-measure` | `ui-measure` <!-- canon-keep-retired --> |
|
|
64
66
|
|
|
65
67
|
Replace a citation of a skill with no successor by hand, or delete the sentence.
|
|
66
68
|
|
|
67
|
-
- `canvas` is now `canvas-board`. The sweep rewrites only `canon:canvas` and `skills/canvas`, so replace a bare
|
|
68
|
-
- `draft-ready` is rewritten only as `canon:draft-ready` and `skills/draft-ready`, since bare it also describes a pull request
|
|
69
|
+
- `canvas` is now `canvas-board`. The sweep rewrites only `canon:canvas` and `skills/canvas`, so replace a bare mention by hand. <!-- canon-keep-retired -->
|
|
70
|
+
- `draft-ready` is rewritten only as `canon:draft-ready` and `skills/draft-ready`, since bare it also describes a pull request, so replace a bare mention by hand. <!-- canon-keep-retired -->
|
|
69
71
|
- `design-extract` and `sketch-design` are replaced by `canon:canvas-board`. <!-- canon-keep-retired -->
|
|
70
|
-
- `review-branch`, `seed-sync`, `restate-plainly`, `bash-cli-script`, `canon-operator`, and `canon-
|
|
71
|
-
- `create-standard`, `markdown-propose`, `memory-review`, `project-commands`, `repo-metadata`,
|
|
72
|
+
- `review-branch`, `seed-sync`, `restate-plainly`, `bash-cli-script`, `canon-operator`, `canon-rollout`, and `canon-feedback-triage` have no successor <!-- canon-keep-retired -->
|
|
73
|
+
- `create-standard`, `markdown-propose`, `memory-review`, `project-commands`, `repo-metadata`, `ux-walkthrough`, and `plan-ready` have no successor <!-- canon-keep-retired -->
|
|
72
74
|
|
|
73
75
|
The `memory` record kind left `canon records`, so `canon records validate memory` refuses as an unknown kind and `canon records migrate` is gone.
|
|
74
76
|
|
|
@@ -134,7 +136,7 @@ From the registry the walk reports `historyUnavailable`, so check both paths by
|
|
|
134
136
|
| `plan-groundwork` | `groundwork`, `groundwork-spikes` |
|
|
135
137
|
| `plan-intake` | `intake` |
|
|
136
138
|
| `plan-feature` | `plan`, `plan-lifecycle` |
|
|
137
|
-
| `plan-ready` | `ready`
|
|
139
|
+
| `plan-ready` | `ready` <!-- canon-keep-retired --> |
|
|
138
140
|
| `write-doc` | `requirements`, `wiki` |
|
|
139
141
|
| `session-map` | `session` |
|
|
140
142
|
|
|
@@ -160,7 +162,7 @@ A reference to a retired skill takes a hand edit.
|
|
|
160
162
|
|
|
161
163
|
- Replace a `canon:teach-workspace` reference with `canon:teach-craft` by hand, since `canon migrate skill-names` does not rewrite it <!-- canon-keep-retired -->
|
|
162
164
|
- Delete a `canon:make-deck`, `canon:script-screencast`, `canon:record-screencast`, `canon:read-frames`, or `canon:video-craft` reference, since none has a successor <!-- canon-keep-retired -->
|
|
163
|
-
- Delete a `canon:canvas-board` reference too. Frameboard, which `canon:pick
|
|
165
|
+
- Delete a `canon:canvas-board` reference too. Frameboard, which `canon:design-pick` drives, reads each `.canon/canvas/` folder as a project, so move a kept page under one <!-- canon-keep-retired -->
|
|
164
166
|
|
|
165
167
|
## Move decisions out of a held architecture record, once
|
|
166
168
|
|
package/docs/target/projects.md
CHANGED
|
@@ -56,7 +56,7 @@ Keep the `## Scripts` table in `canon/context/development/local-loop.md` current
|
|
|
56
56
|
Before the first feature session:
|
|
57
57
|
|
|
58
58
|
1. Fill `canon/REQUIREMENTS.md` with the problem, goals, and non-goals. The seed's 600-word cap gates under `canon context audit`.
|
|
59
|
-
2. For a UI project, write `canon/DESIGN.md` from the seed and name the stylesheet in its lead, or work the direction out with `canon:pick
|
|
59
|
+
2. For a UI project, write `canon/DESIGN.md` from the seed and name the stylesheet in its lead, or work the direction out with `canon:design-pick`
|
|
60
60
|
3. Optionally invoke `canon:draw-figure` for an architecture view. The Mermaid CLI downloads on first use.
|
|
61
61
|
4. Start the feature loop in [AI workflow](../workflow/ai-workflow.md)
|
|
62
62
|
|
package/docs/target/sync.md
CHANGED
|
@@ -48,7 +48,7 @@ Add `--json` for a machine-readable report and `--exit-code` to fail CI when a t
|
|
|
48
48
|
- Tooling dependencies: a dependency on a later major than the stack pins reads as `ahead`, and sync leaves it
|
|
49
49
|
- Index regeneration: `canon indexes regen`
|
|
50
50
|
|
|
51
|
-
After `canon gov sync` applies, it lists each rule it copied with its globs and how many project files match. A `ui/` rule adds a pointer to `/canon:
|
|
51
|
+
After `canon gov sync` applies, it lists each rule it copied with its globs and how many project files match. A `ui/` rule adds a pointer to `/canon:ui-audit`. `--json` writes `{ "coverage": [{ "rule", "paths", "files", "ui" }] }` to stdout, empty when nothing was copied, with `files` null outside git. The report never changes the exit code.
|
|
52
52
|
|
|
53
53
|
Try a scenario from [sandbox](../../canon/context/development/sandbox.md) before syncing a real project.
|
|
54
54
|
|
|
@@ -15,11 +15,10 @@ These skills serve a request rather than a moment. With the [skill map](skill-ma
|
|
|
15
15
|
| `canon:create-rule` | A project rule the toolkit does not ship |
|
|
16
16
|
| `canon:create-skill` | A new `SKILL.md` |
|
|
17
17
|
| `canon:write-doc` | A new `docs/` page, context entry, or `README.md` |
|
|
18
|
-
| `canon:plan-ready` | Finished files a worker should copy |
|
|
19
18
|
| `canon:draw-figure` | A figure or architecture view inside a doc |
|
|
20
19
|
| `canon:ci-workflow` | A GitHub Actions workflow file |
|
|
21
20
|
| `canon:design-identity` | A logo mark and social card |
|
|
22
|
-
| `canon:ui-
|
|
21
|
+
| `canon:ui-film` | Real footage of the app for a video |
|
|
23
22
|
|
|
24
23
|
## Answer a question at any point
|
|
25
24
|
|
|
@@ -24,7 +24,7 @@ Groups run in the order a project meets them. Every name `canon claude skills li
|
|
|
24
24
|
| `canon:backlog-triage` | The backlog needs pruning |
|
|
25
25
|
| `canon:plan-groundwork` | The state is unmeasured and approaches compete |
|
|
26
26
|
| `canon:decision-escalate` | Open decisions turn on your preference |
|
|
27
|
-
| `canon:pick
|
|
27
|
+
| `canon:design-pick` | The call is taste, wanting candidates side by side |
|
|
28
28
|
| `canon:task-board` | A decided item needs a file on the board |
|
|
29
29
|
| `canon:plan-feature` | The approach is settled and needs a plan |
|
|
30
30
|
| `canon:codebase-layout` | A change adds a file and needs a folder |
|
|
@@ -53,8 +53,8 @@ Groups run in the order a project meets them. Every name `canon claude skills li
|
|
|
53
53
|
| Skill | When to use |
|
|
54
54
|
| ----------------------- | ---------------------------------------------- |
|
|
55
55
|
| `canon:document-health` | Documents must answer for length and staleness |
|
|
56
|
-
| `canon:
|
|
57
|
-
| `canon:
|
|
56
|
+
| `canon:ui-audit` | To read UI source for missing states |
|
|
57
|
+
| `canon:ui-measure` | To measure paint, processor, and layout cost |
|
|
58
58
|
| `canon:app-drive` | To drive a built app with the operator |
|
|
59
59
|
|
|
60
60
|
## Ship it
|
|
@@ -100,10 +100,9 @@ Groups run in the order a project meets them. Every name `canon claude skills li
|
|
|
100
100
|
|
|
101
101
|
## Keep the project current with the toolkit
|
|
102
102
|
|
|
103
|
-
| Skill
|
|
104
|
-
|
|
|
105
|
-
| `canon:target-check`
|
|
106
|
-
| `canon:target-update`
|
|
107
|
-
| `canon:document-repair`
|
|
108
|
-
| `canon:canon-feedback`
|
|
109
|
-
| `canon:canon-feedback-triage` | In the toolkit repo, to file feedback issues |
|
|
103
|
+
| Skill | When to use |
|
|
104
|
+
| ----------------------- | ------------------------------------------------------- |
|
|
105
|
+
| `canon:target-check` | In a target, to compare each domain with the toolkit |
|
|
106
|
+
| `canon:target-update` | After a release, to catch a target up to the toolkit |
|
|
107
|
+
| `canon:document-repair` | Rewrite a failing docs folder to the limits and gate it |
|
|
108
|
+
| `canon:canon-feedback` | The toolkit is broken, missing, or off |
|
|
@@ -72,7 +72,12 @@ A close posts as `## UI review closed`. The reviewers lift the draft mark on the
|
|
|
72
72
|
|
|
73
73
|
## Design authoring
|
|
74
74
|
|
|
75
|
-
Most projects author design in the loop above and need nothing more. Start with `canon:pick
|
|
75
|
+
Most projects author design in the loop above and need nothing more. Start with `canon:design-pick`, which drafts candidates as frames on a [Frameboard](https://www.npmjs.com/package/frameboard) board and takes your pick, then record the pick with `canon:design-record`. `canon:design-identity` drafts a logo mark and social card the same way.
|
|
76
|
+
|
|
77
|
+
A pick round drafts on `.canon/board/` unless the project names another board in `canon/config/design.toml`.
|
|
78
|
+
|
|
79
|
+
- Set `board` when your design sync reads another Frameboard board, so the picked frame lands without a redraw.
|
|
80
|
+
- Leave `project` unset to keep rounds in their own `picks` project on that board.
|
|
76
81
|
|
|
77
82
|
A graphical tool earns its place when design is the product, a designer owns it, and it changes more often than code. Then the tool is the source of truth, and `canon/DESIGN.md` carries a top note naming the upstream project.
|
|
78
83
|
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Background rule ledger
|
|
3
|
+
description: Decisions behind governance/rules/claude/background.md, one row per bullet
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Background rule ledger
|
|
7
|
+
|
|
8
|
+
The rule is a core rule, so every row is a house choice rather than a citation. Each names what goes wrong without its bullet and the option the bullet beat, with the date it was decided.
|
|
9
|
+
|
|
10
|
+
## Slow commands
|
|
11
|
+
|
|
12
|
+
| Bullet | Source | Read |
|
|
13
|
+
| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
14
|
+
| Background past about a minute | House choice: a foreground run holds the conversation, so the operator waits on a check they could have talked over. It beat a warning hook, which would only warn and still let the run block | 2026-10-26 |
|
|
15
|
+
| Name the slow kinds | House choice: a minute is a guess made before the run, and with no cases to match a session reads a full check as quick. It beat the threshold alone | 2026-10-26 |
|
|
16
|
+
| Keep a seconds command foreground | House choice: each wake costs a turn, so backgrounding a quick command spends two turns where one did. It beat backgrounding every command | 2026-10-26 |
|
|
17
|
+
| End the turn on one status line | House choice: a turn that stops silently leaves the operator unable to tell a wait from a stall. It beat ending on the tool call alone | 2026-10-26 |
|
|
18
|
+
| Keep working beside a server | House choice: a dev server or a watch never exits, so a session awaiting its wake waits forever. It beat treating every background command as awaited | 2026-10-26 |
|
|
19
|
+
|
|
20
|
+
## Waking
|
|
21
|
+
|
|
22
|
+
| Bullet | Source | Read |
|
|
23
|
+
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
|
|
24
|
+
| Act on the wake, never a guess | House choice: a session guessing a command is done reads a partial output as the result. It beat checking the output file on a hunch | 2026-10-26 |
|
|
25
|
+
| No sleep, poll, or scheduled wait | House choice: a foreground sleep or poll holds the conversation the rule freed, and a scheduled prompt spends a turn on every check. It beat all three as ways to wait on one command | 2026-10-26 |
|
|
26
|
+
| Keep a skill's own wait | House choice: a skill owns the verb and the timeout it waits on, such as a review-state wait, and one rule-wide wait would override it. It beat a single wait for every caller | 2026-10-26 |
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Run a command that may take more than about a minute in the background and resume on the harness wake, so the operator keeps the conversation
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Background standards
|
|
6
|
+
|
|
7
|
+
## Slow commands
|
|
8
|
+
|
|
9
|
+
- Start a command that may run past about a minute with `run_in_background: true`, since a foreground run holds the conversation. Revisit when a foreground Bash call stops blocking the turn.
|
|
10
|
+
- Treat a full check, a sandbox run, a capture or render, a build, and a wait on another session as slow.
|
|
11
|
+
- Keep a command expected to finish in seconds in the foreground, since each wake costs a turn.
|
|
12
|
+
- End the turn on one line naming what runs, when the next step needs that command's result.
|
|
13
|
+
- Keep working beside a server or a watch the session never waits on, since it never exits and its wake never comes.
|
|
14
|
+
|
|
15
|
+
## Waking
|
|
16
|
+
|
|
17
|
+
- Act on the wake the harness sends when an awaited command exits, never on a guess about when it is done. Revisit when a background Bash command stops waking the session at exit.
|
|
18
|
+
- Never wait with a foreground `sleep`, a foreground poll loop, or a scheduled prompt for one wait. The background run and its wake replace all three.
|
|
19
|
+
- Keep a skill's own wait as the skill states it, since the skill owns the verb and the timeout it waits on.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@erclx/canon",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "5.
|
|
4
|
+
"version": "5.69.0",
|
|
5
5
|
"description": "Runs your agent's work and keeps its code good, on one setup for every repo.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"bin": {
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
"access": "public"
|
|
26
26
|
},
|
|
27
27
|
"scripts": {
|
|
28
|
-
"format": "oxfmt . && prettier --write --log-level warn 'web/**/*.astro' && shfmt --write --indent 2 scripts/ tooling/ claude/",
|
|
29
|
-
"check:format": "oxfmt --check . && prettier --check --log-level warn 'web/**/*.astro' && shfmt --diff --indent 2 scripts/ tooling/ claude/",
|
|
30
|
-
"check:shell": "find scripts tooling claude .claude/hooks -name '*.sh' -exec shellcheck --severity=warning {} + && find .husky -maxdepth 1 -type f -exec shellcheck --severity=warning --shell=sh {} +",
|
|
28
|
+
"format": "oxfmt . && prettier --write --log-level warn 'web/**/*.astro' && shfmt --write --indent 2 scripts/ tooling/ claude/ src/",
|
|
29
|
+
"check:format": "oxfmt --check . && prettier --check --log-level warn 'web/**/*.astro' && shfmt --diff --indent 2 scripts/ tooling/ claude/ src/",
|
|
30
|
+
"check:shell": "find scripts tooling claude src .claude/hooks -name '*.sh' -exec shellcheck --severity=warning {} + && find .husky -maxdepth 1 -type f -exec shellcheck --severity=warning --shell=sh {} +",
|
|
31
31
|
"check:lint": "oxlint --disable-nested-config --max-warnings 0",
|
|
32
32
|
"check:types": "tsc --noEmit",
|
|
33
33
|
"check:install": "bun scripts/core/install-check.ts",
|
|
@@ -54,7 +54,9 @@
|
|
|
54
54
|
"axe-core": "4.14.0",
|
|
55
55
|
"commander": "^13.1.0",
|
|
56
56
|
"execa": "^9.5.2",
|
|
57
|
-
"
|
|
57
|
+
"pixelmatch": "8.0.0",
|
|
58
|
+
"playwright-core": "1.64.1",
|
|
59
|
+
"pngjs": "7.0.0"
|
|
58
60
|
},
|
|
59
61
|
"devDependencies": {
|
|
60
62
|
"@astrojs/check": "^0.9.8",
|
|
@@ -66,6 +68,7 @@
|
|
|
66
68
|
"@testing-library/jest-dom": "^6.9.1",
|
|
67
69
|
"@types/bun": "^1.2.10",
|
|
68
70
|
"@types/micromatch": "^4.0.10",
|
|
71
|
+
"@types/pngjs": "6.0.5",
|
|
69
72
|
"astro": "^6.1.9",
|
|
70
73
|
"husky": "^9.1.7",
|
|
71
74
|
"micromatch": "^4.0.8",
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Installs the Playwright system packages for the named browsers, killing an
|
|
3
|
+
# attempt that outlives its bound and retrying it. A degraded apt mirror hangs
|
|
4
|
+
# one connection rather than failing it, so a step timeout alone turns the
|
|
5
|
+
# hang into a red check and never recovers it, while a fresh attempt usually
|
|
6
|
+
# lands on a healthy backend.
|
|
7
|
+
#
|
|
8
|
+
# Usage: install-playwright-deps.sh [--package <spec>] <browser>...
|
|
9
|
+
# Exits 0 on the first success, 2 when no browser is named, and the last
|
|
10
|
+
# attempt's code when every attempt fails.
|
|
11
|
+
set -e
|
|
12
|
+
|
|
13
|
+
package=playwright
|
|
14
|
+
if [ "$1" = "--package" ]; then
|
|
15
|
+
package=$2
|
|
16
|
+
shift 2
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
if [ $# -eq 0 ]; then
|
|
20
|
+
echo "Usage: install-playwright-deps.sh [--package <spec>] <browser>..." >&2
|
|
21
|
+
exit 2
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
attempts=3
|
|
25
|
+
bound=${INSTALL_ATTEMPT_SECONDS:-150}
|
|
26
|
+
|
|
27
|
+
# The runner image sets these, yet a stalled log shows gaps of minutes, so
|
|
28
|
+
# print what apt actually reads to settle whether they took effect
|
|
29
|
+
apt-config dump | grep -E '^Acquire::(Retries|http::Timeout) ' || true
|
|
30
|
+
|
|
31
|
+
status=0
|
|
32
|
+
for attempt in $(seq 1 "$attempts"); do
|
|
33
|
+
if [ "$attempt" -gt 1 ]; then
|
|
34
|
+
# timeout runs as the runner user, and Linux drops its signal to the root
|
|
35
|
+
# apt-get playwright spawns through sudo. sudo relays it only to its own
|
|
36
|
+
# child shell, so a root apt-get or dpkg can outlive the kill and hold the
|
|
37
|
+
# lock the next attempt needs.
|
|
38
|
+
sudo pkill -KILL -x 'apt-get|dpkg' || true
|
|
39
|
+
# A kill during unpack leaves dpkg interrupted, which refuses the next
|
|
40
|
+
# install. Its own failure must not end the loop.
|
|
41
|
+
sudo dpkg --configure -a || echo "dpkg --configure -a failed before attempt ${attempt}" >&2
|
|
42
|
+
fi
|
|
43
|
+
|
|
44
|
+
status=0
|
|
45
|
+
timeout --kill-after=10 "$bound" bunx "$package" install-deps "$@" || status=$?
|
|
46
|
+
if [ "$status" -eq 0 ]; then
|
|
47
|
+
exit 0
|
|
48
|
+
fi
|
|
49
|
+
echo "attempt ${attempt}/${attempts} failed with exit ${status}" >&2
|
|
50
|
+
done
|
|
51
|
+
|
|
52
|
+
exit "$status"
|
|
@@ -26,8 +26,8 @@ export const AUTHORING_CASES: readonly SkillCase[] = [
|
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
28
|
prompt:
|
|
29
|
-
'I already wrote the finished
|
|
30
|
-
expect: 'plan-
|
|
29
|
+
'I already wrote the finished wording for a small new reference file, put it in a plan so a worker lands it exactly as written.',
|
|
30
|
+
expect: 'plan-feature',
|
|
31
31
|
},
|
|
32
32
|
{
|
|
33
33
|
prompt: 'This project has no README.md at all, write one from scratch.',
|
package/src/claude/cases/misc.ts
CHANGED
|
@@ -54,11 +54,6 @@ export const SETUP_CASES: readonly SkillCase[] = [
|
|
|
54
54
|
"Whatever the right toolkit command is, get this project's rules installed.",
|
|
55
55
|
expect: 'target-setup',
|
|
56
56
|
},
|
|
57
|
-
{
|
|
58
|
-
prompt:
|
|
59
|
-
'File the open feedback issues on the toolkit repo into an intake folder.',
|
|
60
|
-
expect: 'canon-feedback-triage',
|
|
61
|
-
},
|
|
62
57
|
// This answers one fixed question across a fixed domain list and repairs
|
|
63
58
|
// nothing, which is what separates it from the setup skill above.
|
|
64
59
|
{
|