@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
|
@@ -143,11 +143,11 @@ export const WORKFLOW_CASES: readonly SkillCase[] = [
|
|
|
143
143
|
{
|
|
144
144
|
prompt:
|
|
145
145
|
'Look over the interface and tell me what feels unfinished or confusing.',
|
|
146
|
-
expect: '
|
|
146
|
+
expect: 'ui-audit',
|
|
147
147
|
},
|
|
148
148
|
{
|
|
149
149
|
prompt: 'Tell me the paint and layout cost of this page right now.',
|
|
150
|
-
expect: '
|
|
150
|
+
expect: 'ui-measure',
|
|
151
151
|
},
|
|
152
152
|
{
|
|
153
153
|
prompt:
|
|
@@ -162,12 +162,12 @@ export const WORKFLOW_CASES: readonly SkillCase[] = [
|
|
|
162
162
|
{
|
|
163
163
|
prompt:
|
|
164
164
|
'I need real footage of the board import flow for the launch video. Film it from our app so HyperFrames can zoom in on the clicks.',
|
|
165
|
-
expect: 'ui-
|
|
165
|
+
expect: 'ui-film',
|
|
166
166
|
},
|
|
167
167
|
{
|
|
168
168
|
prompt:
|
|
169
169
|
'Shoot the takes for the storyboard we wrote, one clip per beat of the app doing its thing.',
|
|
170
|
-
expect: 'ui-
|
|
170
|
+
expect: 'ui-film',
|
|
171
171
|
},
|
|
172
172
|
{
|
|
173
173
|
prompt:
|
|
@@ -216,10 +216,10 @@ export const WORKFLOW_CASES: readonly SkillCase[] = [
|
|
|
216
216
|
},
|
|
217
217
|
{
|
|
218
218
|
prompt: 'Find the rough, unfinished-feeling spots in this interface.',
|
|
219
|
-
expect: '
|
|
219
|
+
expect: 'ui-audit',
|
|
220
220
|
},
|
|
221
221
|
{
|
|
222
222
|
prompt: 'Tell me the render cost of this page in the browser.',
|
|
223
|
-
expect: '
|
|
223
|
+
expect: 'ui-measure',
|
|
224
224
|
},
|
|
225
225
|
]
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Fake gh for src/commands/pr.test.ts. Reads FAKE_GH_FX, FAKE_GH_COMMENTS, and FAKE_GH_API_LOG.
|
|
3
|
+
set -o pipefail
|
|
4
|
+
fx="$FAKE_GH_FX"
|
|
5
|
+
f=.
|
|
6
|
+
p=
|
|
7
|
+
for a in "$@"; do
|
|
8
|
+
[ "$p" = --jq ] && f=$a
|
|
9
|
+
p=$a
|
|
10
|
+
done
|
|
11
|
+
case "$*" in
|
|
12
|
+
*graphql* | "pr "* | "repo view"*) exit 1 ;;
|
|
13
|
+
api*pulls/7/files*)
|
|
14
|
+
echo "$*" >>"$fx/files-calls.log"
|
|
15
|
+
[ -f "$fx/files-fail" ] && exit 1
|
|
16
|
+
{
|
|
17
|
+
if [ -f "$fx/files.tsv" ]; then
|
|
18
|
+
cat "$fx/files.tsv"
|
|
19
|
+
else
|
|
20
|
+
git diff --name-status --no-renames main...HEAD | sed -e 's/^A/added/' -e 's/^M/modified/' -e 's/^D/removed/'
|
|
21
|
+
fi
|
|
22
|
+
} | jq -Rn '[inputs | select(length > 0) | split("\t") | {status: .[0], filename: .[1]}]' | jq -r "$f"
|
|
23
|
+
;;
|
|
24
|
+
api*git/trees/*)
|
|
25
|
+
[ -f "$fx/base-tree.json" ] || exit 1
|
|
26
|
+
jq -r "$f" "$fx/base-tree.json"
|
|
27
|
+
;;
|
|
28
|
+
api*contents/*)
|
|
29
|
+
a="$*"
|
|
30
|
+
p=${a##*contents/}
|
|
31
|
+
p=${p%%\?*}
|
|
32
|
+
r=${a##*ref=}
|
|
33
|
+
[ -f "$fx/img/$r-$(basename "$p")" ] && cat "$fx/img/$r-$(basename "$p")" || exit 1
|
|
34
|
+
;;
|
|
35
|
+
api*compare/*)
|
|
36
|
+
if [ -f "$fx/merge-base" ]; then cat "$fx/merge-base"; else git merge-base main HEAD; fi
|
|
37
|
+
;;
|
|
38
|
+
"api -X PUT repos/{owner}/{repo}/pulls/7/reviews/"*)
|
|
39
|
+
id=${4##*/}
|
|
40
|
+
echo "$id" >>"$fx/review-puts.log"
|
|
41
|
+
[ -f "$fx/review-put-fail-$id" ] && exit 1
|
|
42
|
+
printf '%s\n' "${@: -1}" >>"$fx/review-bodies.log"
|
|
43
|
+
echo "{}"
|
|
44
|
+
;;
|
|
45
|
+
api*pulls/7/reviews*) [ -f "$fx/ui-reviews.json" ] && jq -r "$f" "$fx/ui-reviews.json" ;;
|
|
46
|
+
api*issues/7/comments*) jq '[.comments[] | {html_url: .url, body}]' "$FAKE_GH_COMMENTS" | jq -r "$f" ;;
|
|
47
|
+
"api -X PATCH repos/{owner}/{repo}/pulls/7 "*)
|
|
48
|
+
[ -f "$fx/body-fail" ] && exit 1
|
|
49
|
+
printf '%s' "${@: -1}" >"$fx/body-write.log"
|
|
50
|
+
echo "{}"
|
|
51
|
+
;;
|
|
52
|
+
"api repos/{owner}/{repo}/pulls/7")
|
|
53
|
+
if [ -f "$fx/head" ]; then h=$(cat "$fx/head"); else h=$(git rev-parse HEAD); fi
|
|
54
|
+
b=
|
|
55
|
+
[ -f "$fx/pr-body" ] && b=$(cat "$fx/pr-body")
|
|
56
|
+
jq -n --arg h "$h" --arg b "$b" '{number:7,head:{ref:"feat/x",sha:$h},base:{ref:"main"},mergeable_state:"clean",body:$b}'
|
|
57
|
+
;;
|
|
58
|
+
"api repos/{owner}/{repo}") echo "{\"full_name\":\"o/r\"}" ;;
|
|
59
|
+
api*)
|
|
60
|
+
printf '%s' "${@: -1}" >"$FAKE_GH_API_LOG"
|
|
61
|
+
echo "{}"
|
|
62
|
+
;;
|
|
63
|
+
*) exit 1 ;;
|
|
64
|
+
esac
|
package/src/commands/gov.ts
CHANGED
|
@@ -34,6 +34,7 @@ import {
|
|
|
34
34
|
} from '@/gov/restated'
|
|
35
35
|
import {
|
|
36
36
|
auditExit,
|
|
37
|
+
CORE_FOLDERS,
|
|
37
38
|
hasFinding,
|
|
38
39
|
PRACTICE_FOLDERS,
|
|
39
40
|
readRuleAudit,
|
|
@@ -62,6 +63,11 @@ import {
|
|
|
62
63
|
readTestOrder,
|
|
63
64
|
type TestOrderReport,
|
|
64
65
|
} from '@/gov/test-order'
|
|
66
|
+
import {
|
|
67
|
+
type ChangedSet,
|
|
68
|
+
collectChangedFiles,
|
|
69
|
+
commandRunner,
|
|
70
|
+
} from '@/gate/sequencer'
|
|
65
71
|
import { recordStamp, runDomainSync } from '@/sync/engine'
|
|
66
72
|
import { detectRules } from '@/gov/detect'
|
|
67
73
|
import { writeChainStamp } from '@/sync/stamp'
|
|
@@ -138,6 +144,7 @@ interface AuditOptions {
|
|
|
138
144
|
readonly root?: string
|
|
139
145
|
readonly json?: boolean
|
|
140
146
|
readonly gate?: boolean
|
|
147
|
+
readonly touched?: boolean
|
|
141
148
|
}
|
|
142
149
|
|
|
143
150
|
/** What a reader does about each way the sweep produced no reading. */
|
|
@@ -613,6 +620,10 @@ export function register(program: Command): void {
|
|
|
613
620
|
'--gate',
|
|
614
621
|
'Set 2 only for a finding in a gated folder, which the push stage reads',
|
|
615
622
|
)
|
|
623
|
+
.option(
|
|
624
|
+
'--touched',
|
|
625
|
+
'Owe a ledger for each core rule the branch changed against origin/main',
|
|
626
|
+
)
|
|
616
627
|
.addHelpText(
|
|
617
628
|
'after',
|
|
618
629
|
[
|
|
@@ -632,6 +643,9 @@ export function register(program: Command): void {
|
|
|
632
643
|
` asks a ledger of each rule under ${PRACTICE_FOLDERS.join(', ')}`,
|
|
633
644
|
' at governance/ledger/<folder>/<slug>.md, one table row per bullet',
|
|
634
645
|
' under a heading of the same name.',
|
|
646
|
+
` A rule under ${CORE_FOLDERS.join(', ')} has its ledger checked where`,
|
|
647
|
+
' one exists, and under --touched owes one once the branch changed it.',
|
|
648
|
+
' With no baseline against main, --touched reads no rule as touched.',
|
|
635
649
|
' Any other tree reads .claude/rules/project/ alone and asks no ledger.',
|
|
636
650
|
' .claude/rules/canon/ is fixed at the toolkit source and never read',
|
|
637
651
|
' unless named. A named path resolves against --root and must sit',
|
|
@@ -654,6 +668,7 @@ export function register(program: Command): void {
|
|
|
654
668
|
' canon gov audit',
|
|
655
669
|
' canon gov audit .claude/rules/project/api.md',
|
|
656
670
|
' canon gov audit --json',
|
|
671
|
+
' canon gov audit --gate --touched',
|
|
657
672
|
'',
|
|
658
673
|
].join('\n'),
|
|
659
674
|
)
|
|
@@ -672,7 +687,13 @@ async function runAudit(
|
|
|
672
687
|
opts: AuditOptions,
|
|
673
688
|
): Promise<number> {
|
|
674
689
|
const root = resolve(opts.root ?? process.cwd())
|
|
675
|
-
const
|
|
690
|
+
const changed = opts.touched
|
|
691
|
+
? await collectChangedFiles(commandRunner(root))
|
|
692
|
+
: undefined
|
|
693
|
+
// An unscoped set lists nothing, and reading it as every file would owe a
|
|
694
|
+
// ledger of every core rule on a branch that touched none of them.
|
|
695
|
+
const touched = changed?.scoped ? changed.files : []
|
|
696
|
+
const report = await readRuleAudit(root, paths, { touched })
|
|
676
697
|
const emitJson = opts.json ?? false
|
|
677
698
|
|
|
678
699
|
if (report.kind === 'unreadable') {
|
|
@@ -690,7 +711,7 @@ async function runAudit(
|
|
|
690
711
|
return 1
|
|
691
712
|
}
|
|
692
713
|
|
|
693
|
-
reportAudit(report, root, paths.length > 0)
|
|
714
|
+
reportAudit(report, root, paths.length > 0, changed)
|
|
694
715
|
|
|
695
716
|
if (emitJson) {
|
|
696
717
|
process.stdout.write(
|
|
@@ -700,6 +721,9 @@ async function runAudit(
|
|
|
700
721
|
limits: RULE_LIMITS,
|
|
701
722
|
gated: RULE_GATED_FOLDERS,
|
|
702
723
|
exempt: RULE_GATE_EXEMPT,
|
|
724
|
+
...(changed === undefined
|
|
725
|
+
? {}
|
|
726
|
+
: { touched: { scoped: changed.scoped } }),
|
|
703
727
|
...report,
|
|
704
728
|
})}\n`,
|
|
705
729
|
)
|
|
@@ -728,6 +752,7 @@ function reportAudit(
|
|
|
728
752
|
report: Extract<RuleAuditReport, { kind: 'measured' }>,
|
|
729
753
|
root: string,
|
|
730
754
|
named: boolean,
|
|
755
|
+
changed: ChangedSet | undefined,
|
|
731
756
|
): void {
|
|
732
757
|
intro('canon gov audit')
|
|
733
758
|
|
|
@@ -761,10 +786,15 @@ function reportAudit(
|
|
|
761
786
|
}
|
|
762
787
|
|
|
763
788
|
logStep('Ledgers')
|
|
789
|
+
if (changed !== undefined && !changed.scoped) {
|
|
790
|
+
logInfo(
|
|
791
|
+
'no baseline against main, so --touched reads no core rule as touched',
|
|
792
|
+
)
|
|
793
|
+
}
|
|
764
794
|
if (report.scope === 'target') {
|
|
765
795
|
logInfo('not read, since ledgers live in the toolkit and never ship')
|
|
766
796
|
} else if (ledgers.length === 0) {
|
|
767
|
-
logInfo('every
|
|
797
|
+
logInfo('every rule owing a ledger has one, with a row per bullet')
|
|
768
798
|
} else {
|
|
769
799
|
for (const line of ledgers) logWarn(line)
|
|
770
800
|
}
|
package/src/commands/migrate.ts
CHANGED
|
@@ -1309,6 +1309,13 @@ export function register(program: Command): void {
|
|
|
1309
1309
|
'any ordinal evidence/ already carries. The dry run labels every',
|
|
1310
1310
|
'derived destination, so check the split before passing --write.',
|
|
1311
1311
|
'',
|
|
1312
|
+
'Moves the design board to the folder Frameboard names:',
|
|
1313
|
+
' canvas/ -> board/',
|
|
1314
|
+
'',
|
|
1315
|
+
'Stop a frameboard serve on canvas/ before --write. A project holding',
|
|
1316
|
+
'both folders gets a collision, and a design.toml board key naming',
|
|
1317
|
+
'.canon/canvas is left for you to update.',
|
|
1318
|
+
'',
|
|
1312
1319
|
'A citation reaching into a moved folder or naming a moved file is',
|
|
1313
1320
|
'repointed, live or archived. A bare mention of an emptied folder, such',
|
|
1314
1321
|
'as review/evidence/ with no slug, matches no row and stays as written.',
|
|
@@ -1389,8 +1396,11 @@ export function register(program: Command): void {
|
|
|
1389
1396
|
`It also carries ${Object.keys(SKILL_CITATION_MAP).length} namespaced-only rows for a skill renamed from a single word.`,
|
|
1390
1397
|
'The seven draft- skills move onto verb-first names, such as',
|
|
1391
1398
|
// The old spellings below are the rename itself. canon-keep-retired
|
|
1392
|
-
'draft-doc to write-doc and draft-
|
|
1393
|
-
'pointer left under each old name is never moved.',
|
|
1399
|
+
'draft-doc to write-doc and draft-slides to make-deck, and a',
|
|
1400
|
+
'pointer left under each old name is never moved. Four skills then',
|
|
1401
|
+
'moved into the family their job belongs to, such as',
|
|
1402
|
+
// canon-keep-retired
|
|
1403
|
+
'ux-audit to ui-audit and pick-by-eye to design-pick.',
|
|
1394
1404
|
'It takes no scope. The skill folders it moves are authored in the',
|
|
1395
1405
|
'toolkit and no target holds a copy of that catalog, so in a target it',
|
|
1396
1406
|
'rewrites citations of a renamed skill and moves nothing.',
|