@erclx/canon 5.23.0 → 5.25.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/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/backlog-triage/REQUIREMENT.md +2 -2
- package/claude/skills/backlog-triage/SKILL.md +19 -6
- package/claude/skills/canon-operator/REQUIREMENT.md +1 -0
- package/claude/skills/canon-operator/SKILL.md +5 -1
- package/claude/skills/canvas/REQUIREMENT.md +49 -0
- package/claude/skills/canvas/SKILL.md +106 -0
- package/claude/skills/design-extract/REQUIREMENT.md +1 -1
- package/claude/skills/draft-doc/REQUIREMENT.md +2 -1
- package/claude/skills/draft-doc/references/readme/agent-facing.md +59 -0
- package/claude/skills/draft-doc/references/readme/application.md +66 -0
- package/claude/skills/draft-doc/references/readme/cli.md +64 -0
- package/claude/skills/draft-doc/references/readme/library.md +57 -0
- package/claude/skills/draft-doc/references/readme/plugin.md +66 -0
- package/claude/skills/draft-doc/references/readme.md +33 -4
- package/claude/skills/draft-figure/REQUIREMENT.md +14 -3
- package/claude/skills/draft-figure/SKILL.md +24 -51
- package/claude/skills/draft-figure/references/architecture-set.md +35 -0
- package/claude/skills/draft-figure/references/hand-drawn.md +31 -0
- package/claude/skills/draft-figure/references/mermaid.md +55 -0
- package/claude/skills/git-followup/SKILL.md +17 -6
- package/claude/skills/git-pr/references/evidence.md +4 -2
- package/claude/skills/git-split/SKILL.md +1 -1
- package/claude/skills/index-lookup/SKILL.md +2 -2
- package/claude/skills/review-address/SKILL.md +6 -13
- package/claude/skills/review-address/references/rest-reads.md +43 -0
- package/claude/skills/review-craft/references/ui.md +7 -1
- package/claude/skills/review-pr/REQUIREMENT.md +1 -0
- package/claude/skills/review-pr/SKILL.md +9 -3
- package/claude/skills/review-pr/references/close-out.md +2 -2
- package/claude/skills/review-pr/references/post.md +17 -5
- package/claude/skills/review-pr/references/scope.md +10 -8
- package/claude/skills/review-ui/SKILL.md +12 -4
- package/claude/skills/role-orchestrator/references/orchestrator-cloud-launch.md +30 -1
- package/claude/skills/role-orchestrator/references/orchestrator-launch.md +4 -0
- package/claude/skills/role-orchestrator/references/orchestrator-poll.md +4 -4
- package/claude/skills/role-orchestrator/references/orchestrator-review-dispatch.md +6 -0
- package/claude/skills/role-orchestrator/scripts/poll.ts +90 -27
- package/claude/skills/role-orchestrator/scripts/repo.ts +3 -5
- package/claude/skills/role-orchestrator/scripts/watch.ts +4 -7
- package/docs/agents/canvas.md +6 -2
- package/docs/agents/commands.md +45 -45
- package/docs/agents/context-audit-checks.md +2 -2
- package/docs/agents/index.md +0 -1
- package/docs/agents/key-changes.md +3 -3
- package/docs/agents/pr-evidence.md +11 -2
- package/docs/agents/pr-reads.md +5 -4
- package/docs/target/projects.md +4 -4
- package/docs/workflow/ai-workflow.md +0 -1
- package/docs/workflow/skill-map.md +3 -3
- package/docs/workflow/visual-design-workflow.md +2 -1
- package/governance/renames.toml +0 -4
- package/governance/rules/standards/markdown.md +1 -0
- package/package.json +1 -2
- package/scripts/core/install-check.sh +1 -1
- package/src/audits/catalog.ts +2 -2
- package/src/canvas/client/inspector/field.tsx +200 -0
- package/src/canvas/client/inspector/fields.css +151 -0
- package/src/canvas/client/inspector/section.tsx +27 -0
- package/src/canvas/client/inspector/values.ts +60 -0
- package/src/canvas/client/inspector.tsx +192 -111
- package/src/canvas/client/shell.css +0 -94
- package/src/canvas/tokens.ts +9 -1
- package/src/claude/cases/misc.ts +5 -0
- package/src/claude/cases/workflow.ts +1 -1
- package/src/claude/seeds.ts +0 -1
- package/src/commands/canvas.ts +29 -0
- package/src/commands/design.ts +2 -64
- package/src/commands/pr.ts +219 -202
- package/src/context/audit.ts +7 -6
- package/src/design/budget.ts +149 -0
- package/src/design/document.ts +22 -10
- package/src/design/render.ts +11 -1
- package/src/design/tokens.ts +40 -61
- package/src/gate/measures.ts +49 -0
- package/src/gate/stages.ts +5 -1
- package/src/help.ts +2 -2
- package/src/migrate/skill-names.ts +7 -1
- package/src/pr/evidence.ts +25 -5
- package/src/pr/rest.ts +137 -0
- package/standards/canvas.md +112 -0
- package/standards/context.md +2 -1
- package/standards/design.md +13 -3
- package/standards/figures.md +0 -1
- package/standards/index.md +1 -1
- package/standards/markdown.md +1 -0
- package/standards/mermaid.md +1 -7
- package/tooling/claude/reference.md +0 -5
- package/tooling/claude/seeds/.claude/hooks/scratch-guard.sh +1 -1
- package/claude/skills/draft-diagram/REQUIREMENT.md +0 -45
- package/claude/skills/draft-diagram/SKILL.md +0 -177
- package/docs/agents/design-board.md +0 -33
- package/governance/rules/standards/diagrams.md +0 -14
- package/governance/rules/standards/mermaid.md +0 -15
- package/scripts/core/check-gallery-exclusion.sh +0 -50
- package/src/design/board.ts +0 -576
- package/standards/diagrams.md +0 -132
- package/tooling/claude/seeds/.claude/diagrams/index.md +0 -8
|
@@ -320,29 +320,6 @@ code {
|
|
|
320
320
|
outline-offset: 6px;
|
|
321
321
|
}
|
|
322
322
|
|
|
323
|
-
.box {
|
|
324
|
-
display: grid;
|
|
325
|
-
grid-template-columns: 1fr 1fr;
|
|
326
|
-
gap: var(--space-xs) var(--space-md);
|
|
327
|
-
margin: var(--space-xs) 0 0;
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
.box-row {
|
|
331
|
-
display: flex;
|
|
332
|
-
justify-content: space-between;
|
|
333
|
-
gap: var(--space-sm);
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
.box dt {
|
|
337
|
-
color: var(--color-muted);
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
.box dd {
|
|
341
|
-
margin: 0;
|
|
342
|
-
color: var(--color-text);
|
|
343
|
-
font-variant-numeric: tabular-nums;
|
|
344
|
-
}
|
|
345
|
-
|
|
346
323
|
.toolbar {
|
|
347
324
|
position: absolute;
|
|
348
325
|
right: var(--space-md);
|
|
@@ -436,77 +413,6 @@ code {
|
|
|
436
413
|
white-space: nowrap;
|
|
437
414
|
}
|
|
438
415
|
|
|
439
|
-
/* One property a row, since a computed color or font stack outgrows a half. */
|
|
440
|
-
.styles {
|
|
441
|
-
grid-template-columns: 1fr;
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
.styles dd {
|
|
445
|
-
min-width: 0;
|
|
446
|
-
overflow: hidden;
|
|
447
|
-
text-overflow: ellipsis;
|
|
448
|
-
white-space: nowrap;
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
.styles .box-row {
|
|
452
|
-
align-items: center;
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
.styles dt {
|
|
456
|
-
flex: none;
|
|
457
|
-
width: 4.5rem;
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
.styles dd {
|
|
461
|
-
flex: 1;
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
.field-cell {
|
|
465
|
-
display: flex;
|
|
466
|
-
gap: var(--space-xs);
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
.field,
|
|
470
|
-
.token-picker {
|
|
471
|
-
min-width: 0;
|
|
472
|
-
min-height: 24px;
|
|
473
|
-
padding: 2px var(--space-xs);
|
|
474
|
-
border: 1px solid var(--color-border);
|
|
475
|
-
border-radius: var(--radius-action);
|
|
476
|
-
background: var(--color-surface);
|
|
477
|
-
color: var(--color-text);
|
|
478
|
-
font: inherit;
|
|
479
|
-
font-variant-numeric: tabular-nums;
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
.field {
|
|
483
|
-
flex: 1;
|
|
484
|
-
width: 100%;
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
.token-picker {
|
|
488
|
-
flex: none;
|
|
489
|
-
width: 4.5rem;
|
|
490
|
-
cursor: pointer;
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
.field:hover,
|
|
494
|
-
.token-picker:hover {
|
|
495
|
-
border-color: var(--color-muted);
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
.field:disabled,
|
|
499
|
-
.token-picker:disabled {
|
|
500
|
-
opacity: 0.5;
|
|
501
|
-
cursor: not-allowed;
|
|
502
|
-
}
|
|
503
|
-
|
|
504
|
-
.saved {
|
|
505
|
-
margin-left: var(--space-sm);
|
|
506
|
-
color: var(--color-success);
|
|
507
|
-
font-weight: 400;
|
|
508
|
-
}
|
|
509
|
-
|
|
510
416
|
.tabs {
|
|
511
417
|
display: flex;
|
|
512
418
|
gap: 2px;
|
package/src/canvas/tokens.ts
CHANGED
|
@@ -138,7 +138,15 @@ export function resolveFrameTokens(
|
|
|
138
138
|
options: TokenOptions = {},
|
|
139
139
|
): FrameTokens {
|
|
140
140
|
if (options.isOwnCheckout ?? isOwnCheckout(root)) {
|
|
141
|
-
|
|
141
|
+
/*
|
|
142
|
+
* Faces embedded, since the type tokens name `Geist Variable` and a
|
|
143
|
+
* machine with only static Geist installed renders every frame in the
|
|
144
|
+
* fallback. An installed base owns its fonts, so that branch gets none.
|
|
145
|
+
*/
|
|
146
|
+
return {
|
|
147
|
+
source: 'toolkit',
|
|
148
|
+
css: buildDesignCss(undefined, { embedFonts: true }),
|
|
149
|
+
}
|
|
142
150
|
}
|
|
143
151
|
|
|
144
152
|
const files = installedFiles(root)
|
package/src/claude/cases/misc.ts
CHANGED
|
@@ -27,6 +27,11 @@ export const MISC_CASES: readonly SkillCase[] = [
|
|
|
27
27
|
"I found two sites whose look I want us to draw from. Put them side by side and let's settle which one the design should follow before anyone writes a token.",
|
|
28
28
|
expect: 'sketch-design',
|
|
29
29
|
},
|
|
30
|
+
{
|
|
31
|
+
prompt:
|
|
32
|
+
'Draw the signup screen as a frame on the canvas, then restyle the element I just selected there.',
|
|
33
|
+
expect: 'canvas',
|
|
34
|
+
},
|
|
30
35
|
{
|
|
31
36
|
prompt: 'Fire up the dev server the way this project documents it.',
|
|
32
37
|
expect: 'project-commands',
|
package/src/claude/seeds.ts
CHANGED
package/src/commands/canvas.ts
CHANGED
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
STYLE_PROPERTIES,
|
|
21
21
|
} from '@/canvas/edit'
|
|
22
22
|
import { CANVAS_PORT, startCanvas } from '@/canvas/server'
|
|
23
|
+
import { PROJECT_ROOT } from '@/project-root'
|
|
23
24
|
import { resolveFrameTokens } from '@/canvas/tokens'
|
|
24
25
|
import { displayPath, parsePort, waitForInterrupt } from '@/serve/report'
|
|
25
26
|
import {
|
|
@@ -49,9 +50,35 @@ interface Refused {
|
|
|
49
50
|
| 'no-root'
|
|
50
51
|
| 'no-server'
|
|
51
52
|
| 'capture-failed'
|
|
53
|
+
| 'missing-client-deps'
|
|
52
54
|
readonly detail: string
|
|
53
55
|
}
|
|
54
56
|
|
|
57
|
+
const CLIENT_DEPS = ['preact', '@preact/signals'] as const
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Refuses when the shell's client packages do not resolve from `from`, since
|
|
61
|
+
* the bundler then answers `/` with an empty page rather than an error. The
|
|
62
|
+
* caller passes the package root the binary runs from, never the served
|
|
63
|
+
* project's, so a global install serving a target finds its own copies.
|
|
64
|
+
*/
|
|
65
|
+
export function missingClientDeps(from: string): Refused | undefined {
|
|
66
|
+
const missing = CLIENT_DEPS.filter((name) => {
|
|
67
|
+
try {
|
|
68
|
+
Bun.resolveSync(name, from)
|
|
69
|
+
return false
|
|
70
|
+
} catch {
|
|
71
|
+
return true
|
|
72
|
+
}
|
|
73
|
+
})
|
|
74
|
+
if (missing.length === 0) return undefined
|
|
75
|
+
return {
|
|
76
|
+
ok: false,
|
|
77
|
+
reason: 'missing-client-deps',
|
|
78
|
+
detail: `${missing.join(', ')} not installed in ${from}, so the canvas shell cannot load. Run bun install there`,
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
55
82
|
type RootOutcome = { readonly ok: true; readonly root: string } | Refused
|
|
56
83
|
|
|
57
84
|
/**
|
|
@@ -637,6 +664,8 @@ async function runServe(
|
|
|
637
664
|
return refuseServe(resolved.reason, resolved.detail, emitJson)
|
|
638
665
|
}
|
|
639
666
|
const { root } = resolved
|
|
667
|
+
const missing = missingClientDeps(PROJECT_ROOT)
|
|
668
|
+
if (missing) return refuseServe(missing.reason, missing.detail, emitJson)
|
|
640
669
|
/*
|
|
641
670
|
* Imported here rather than at the top, so a command module the test runner
|
|
642
671
|
* loads never asks it for an HTML module it cannot parse.
|
package/src/commands/design.ts
CHANGED
|
@@ -6,30 +6,22 @@ import {
|
|
|
6
6
|
DESIGN_INSTALL_DIR,
|
|
7
7
|
DESIGN_PROJECT_SUBDIR,
|
|
8
8
|
} from '@/design/adapter'
|
|
9
|
-
import { generateBoard } from '@/design/board'
|
|
10
9
|
import { buildDesignCss } from '@/design/css'
|
|
11
10
|
import { HAND_DRAWN_FONT_FACES } from '@/design/fonts'
|
|
12
11
|
import { renderDesignDoc } from '@/design/render'
|
|
13
12
|
import { DESIGN_BASE_CSS, DESIGN_DOCUMENT, regenDesign } from '@/design/regen'
|
|
14
|
-
import {
|
|
15
|
-
checkoutMismatchWarning,
|
|
16
|
-
isOwnCheckout,
|
|
17
|
-
PROJECT_ROOT,
|
|
18
|
-
} from '@/project-root'
|
|
13
|
+
import { checkoutMismatchWarning, PROJECT_ROOT } from '@/project-root'
|
|
19
14
|
import { creationRel, SCRATCH } from '@/record-root'
|
|
20
15
|
import { surfaceDir } from '@/surface-root'
|
|
21
16
|
import { recordStamp, runDomainSync } from '@/sync/engine'
|
|
22
17
|
import { resolveTarget } from '@/target'
|
|
23
18
|
import { intro, logAdd, logError, logInfo, logWarn, outro, palette } from '@/ui'
|
|
24
|
-
import { mainWorktreeRoot } from '@/worktree'
|
|
25
19
|
|
|
26
20
|
export function register(program: Command): void {
|
|
27
21
|
const design = program
|
|
28
22
|
.command('design')
|
|
29
23
|
.helpOption('-h, --help', 'Show this help message')
|
|
30
|
-
.description(
|
|
31
|
-
'Design system commands (regen, css, render, board, install, sync)',
|
|
32
|
-
)
|
|
24
|
+
.description('Design system commands (regen, css, render, install, sync)')
|
|
33
25
|
|
|
34
26
|
design
|
|
35
27
|
.command('regen')
|
|
@@ -145,60 +137,6 @@ export function register(program: Command): void {
|
|
|
145
137
|
)
|
|
146
138
|
})
|
|
147
139
|
|
|
148
|
-
design
|
|
149
|
-
.command('board')
|
|
150
|
-
.helpOption('-h, --help', 'Show this help message')
|
|
151
|
-
.description(
|
|
152
|
-
'Generate the design board, an index over a project’s design surfaces',
|
|
153
|
-
)
|
|
154
|
-
.option(
|
|
155
|
-
'-o, --out <path>',
|
|
156
|
-
'Output directory',
|
|
157
|
-
creationRel(process.cwd(), SCRATCH, 'render', 'board'),
|
|
158
|
-
)
|
|
159
|
-
.option('--root <path>', 'Project root, defaulting to the main worktree')
|
|
160
|
-
.addHelpText(
|
|
161
|
-
'after',
|
|
162
|
-
[
|
|
163
|
-
'',
|
|
164
|
-
'Reads its sources from --root, defaulting to the main worktree of',
|
|
165
|
-
'whatever project the caller stands in, and writes a static page',
|
|
166
|
-
'set, never installed or synced. The surfaces panel’s landing-page',
|
|
167
|
-
'half and the whole components panel render only when that root is',
|
|
168
|
-
'this toolkit’s own checkout. Open the result with canon serve <out>.',
|
|
169
|
-
'',
|
|
170
|
-
].join('\n'),
|
|
171
|
-
)
|
|
172
|
-
.action(async (opts: { out: string; root?: string }) => {
|
|
173
|
-
const outDir = resolve(process.cwd(), opts.out)
|
|
174
|
-
const root = opts.root
|
|
175
|
-
? resolve(process.cwd(), opts.root)
|
|
176
|
-
: await mainWorktreeRoot()
|
|
177
|
-
const isToolkitCheckout = isOwnCheckout(root)
|
|
178
|
-
const { GREEN, GREY, NC, RED, WHITE } = palette(process.stderr)
|
|
179
|
-
const mismatch = checkoutMismatchWarning(process.cwd())
|
|
180
|
-
process.stderr.write(
|
|
181
|
-
`${GREY}┌${NC}\n${GREY}│${NC} ${WHITE}Generate design board${NC}\n`,
|
|
182
|
-
)
|
|
183
|
-
if (mismatch !== undefined) logWarn(mismatch)
|
|
184
|
-
const result = generateBoard(
|
|
185
|
-
root,
|
|
186
|
-
outDir,
|
|
187
|
-
process.cwd(),
|
|
188
|
-
isToolkitCheckout,
|
|
189
|
-
)
|
|
190
|
-
if (!result.ok) {
|
|
191
|
-
process.stderr.write(
|
|
192
|
-
`${GREY}│${NC} ${RED}✗${NC} ${result.detail}\n${GREY}└${NC}\n`,
|
|
193
|
-
)
|
|
194
|
-
process.exitCode = 1
|
|
195
|
-
return
|
|
196
|
-
}
|
|
197
|
-
process.stderr.write(
|
|
198
|
-
`${GREY}│${NC} ${GREEN}✓${NC} ${relative(process.cwd(), result.indexPath)}\n${GREY}│${NC} Open with: canon serve ${relative(process.cwd(), result.outDir)}\n${GREY}└${NC}\n`,
|
|
199
|
-
)
|
|
200
|
-
})
|
|
201
|
-
|
|
202
140
|
design
|
|
203
141
|
.command('install')
|
|
204
142
|
.description('Install the base stylesheet into a project')
|