@erclx/canon 5.14.1 → 5.16.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.
Files changed (77) hide show
  1. package/README.md +3 -2
  2. package/claude/.claude-plugin/plugin.json +1 -1
  3. package/claude/skills/draft-screencast/REQUIREMENT.md +2 -1
  4. package/claude/skills/draft-screencast/SKILL.md +14 -9
  5. package/claude/skills/draft-wiki/SKILL.md +1 -1
  6. package/claude/skills/plan-groundwork/SKILL.md +1 -1
  7. package/claude/skills/read-frames/SKILL.md +3 -2
  8. package/claude/skills/record-screencast/REQUIREMENT.md +3 -0
  9. package/claude/skills/record-screencast/SKILL.md +28 -5
  10. package/claude/skills/search-craft/REQUIREMENT.md +57 -0
  11. package/claude/skills/search-craft/SKILL.md +83 -0
  12. package/docs/agents/canvas.md +36 -0
  13. package/docs/agents/commands.md +3 -0
  14. package/docs/agents/demo.md +34 -7
  15. package/docs/agents/index.md +1 -0
  16. package/docs/agents/migrate.md +1 -1
  17. package/docs/agents/sandbox.md +25 -0
  18. package/docs/target/migrations.md +1 -1
  19. package/docs/workflow/ai-workflow.md +2 -3
  20. package/docs/workflow/skill-map.md +2 -1
  21. package/governance/renames.toml +7 -5
  22. package/governance/rules/canon/630-requirements.md +1 -1
  23. package/package.json +5 -2
  24. package/scripts/lib/sandbox-git.sh +2 -2
  25. package/src/canvas/address.ts +184 -0
  26. package/src/canvas/capture.ts +172 -0
  27. package/src/canvas/client/app.tsx +87 -0
  28. package/src/canvas/client/inspector.tsx +121 -0
  29. package/src/canvas/client/layers.tsx +118 -0
  30. package/src/canvas/client/main.tsx +62 -0
  31. package/src/canvas/client/pages-panel.tsx +157 -0
  32. package/src/canvas/client/shell.css +449 -0
  33. package/src/canvas/client/state.ts +372 -0
  34. package/src/canvas/client/surface.tsx +465 -0
  35. package/src/canvas/content.ts +617 -0
  36. package/src/canvas/index.html +14 -0
  37. package/src/canvas/server.ts +471 -0
  38. package/src/canvas/tokens.ts +71 -0
  39. package/src/claude/cases/misc.ts +5 -0
  40. package/src/claude/seeds.ts +0 -1
  41. package/src/cli.ts +2 -0
  42. package/src/commands/canvas.ts +522 -0
  43. package/src/commands/claude.ts +9 -14
  44. package/src/commands/demo.ts +6 -6
  45. package/src/commands/migrate.ts +1 -1
  46. package/src/commands/sandbox.ts +108 -0
  47. package/src/context/classify/prompts.ts +1 -1
  48. package/src/context/folders.ts +0 -1
  49. package/src/demo/compile.ts +8 -4
  50. package/src/demo/container.ts +1 -1
  51. package/src/gov/renames.ts +3 -2
  52. package/src/help.ts +1 -0
  53. package/src/migrate/rename.ts +5 -4
  54. package/src/record-root.ts +1 -0
  55. package/src/sandbox/equivalence.ts +847 -0
  56. package/src/serve/static.ts +25 -11
  57. package/src/surface-root.ts +0 -1
  58. package/src/teach/browser/compile.ts +44 -0
  59. package/src/teach/browser/dismiss.ts +76 -0
  60. package/src/teach/browser/focus-line.ts +19 -0
  61. package/src/teach/browser/glossary-filter.ts +44 -0
  62. package/src/teach/browser/head.ts +30 -0
  63. package/src/teach/browser/quiz.ts +19 -0
  64. package/src/teach/browser/sidebar.ts +233 -0
  65. package/src/teach/browser/theme.ts +18 -0
  66. package/src/teach/nav.ts +19 -374
  67. package/standards/architecture.md +1 -1
  68. package/standards/context.md +1 -1
  69. package/standards/design.md +1 -1
  70. package/standards/index.md +0 -1
  71. package/standards/requirements.md +4 -6
  72. package/standards/wireframes.md +2 -2
  73. package/tooling/claude/reference.md +0 -1
  74. package/tooling/claude/seeds/canon/REQUIREMENTS.md +0 -2
  75. package/governance/rules/canon/645-decisions.md +0 -12
  76. package/standards/decisions.md +0 -105
  77. package/tooling/claude/seeds/canon/decisions/index.md +0 -8
@@ -0,0 +1,449 @@
1
+ /*
2
+ * The canvas chrome. Every value reads a custom property from this toolkit's
3
+ * own token module, served at /api/chrome.css, which maps dark onto :root and
4
+ * light onto [data-theme='light']. A frame reads the project's tokens inside
5
+ * its own iframe, so the two sets of names never meet.
6
+ */
7
+
8
+ * {
9
+ box-sizing: border-box;
10
+ }
11
+
12
+ html,
13
+ body {
14
+ height: 100%;
15
+ margin: 0;
16
+ }
17
+
18
+ body {
19
+ background: var(--color-background);
20
+ color: var(--color-text);
21
+ font-family: var(--type-body-family);
22
+ font-size: var(--type-label-size);
23
+ line-height: var(--type-label-lh);
24
+ }
25
+
26
+ #app {
27
+ height: 100%;
28
+ }
29
+
30
+ :focus-visible {
31
+ outline: 2px solid var(--color-accent);
32
+ outline-offset: 2px;
33
+ }
34
+
35
+ code {
36
+ font-family: var(--type-code-family);
37
+ font-size: var(--type-code-size);
38
+ }
39
+
40
+ .shell {
41
+ display: grid;
42
+ grid-template-columns: 15rem minmax(0, 1fr) 13rem;
43
+ height: 100%;
44
+ }
45
+
46
+ .panel {
47
+ overflow-y: auto;
48
+ padding: var(--space-md);
49
+ background: var(--color-chrome);
50
+ min-width: 0;
51
+ }
52
+
53
+ .panel-left {
54
+ border-right: 1px solid var(--color-border);
55
+ }
56
+
57
+ .panel-right {
58
+ border-left: 1px solid var(--color-border);
59
+ display: flex;
60
+ flex-direction: column;
61
+ gap: var(--space-lg);
62
+ }
63
+
64
+ .panel-head {
65
+ display: flex;
66
+ align-items: center;
67
+ justify-content: space-between;
68
+ margin-bottom: var(--space-md);
69
+ }
70
+
71
+ .brand {
72
+ font-weight: 600;
73
+ color: var(--color-text);
74
+ }
75
+
76
+ .section-label {
77
+ margin: var(--space-md) 0 var(--space-xs);
78
+ font-size: var(--type-label-size);
79
+ font-weight: 500;
80
+ color: var(--color-text-secondary);
81
+ }
82
+
83
+ .panel-right .section-label {
84
+ margin-top: 0;
85
+ }
86
+
87
+ .list {
88
+ list-style: none;
89
+ margin: 0;
90
+ padding: 2px;
91
+ display: flex;
92
+ flex-direction: column;
93
+ gap: 2px;
94
+ }
95
+
96
+ .row {
97
+ display: flex;
98
+ align-items: center;
99
+ justify-content: space-between;
100
+ gap: var(--space-sm);
101
+ width: 100%;
102
+ min-height: 28px;
103
+ padding: var(--space-xs) var(--space-sm);
104
+ border: 0;
105
+ border-radius: var(--radius-action);
106
+ background: transparent;
107
+ color: var(--color-text-body);
108
+ font: inherit;
109
+ text-align: left;
110
+ cursor: pointer;
111
+ }
112
+
113
+ .row:hover {
114
+ background: var(--color-surface);
115
+ color: var(--color-text);
116
+ }
117
+
118
+ .row:active {
119
+ background: var(--color-border);
120
+ }
121
+
122
+ .row[aria-current='page'],
123
+ .row[aria-current='true'] {
124
+ background: var(--color-surface);
125
+ color: var(--color-text);
126
+ box-shadow: inset 2px 0 0 var(--color-accent);
127
+ }
128
+
129
+ .row-label {
130
+ overflow: hidden;
131
+ text-overflow: ellipsis;
132
+ white-space: nowrap;
133
+ }
134
+
135
+ .row-meta {
136
+ flex-shrink: 0;
137
+ color: var(--color-muted);
138
+ font-variant-numeric: tabular-nums;
139
+ }
140
+
141
+ .empty,
142
+ .notice {
143
+ margin: var(--space-xs) 0;
144
+ color: var(--color-text-secondary);
145
+ }
146
+
147
+ .notice {
148
+ border-left: 2px solid var(--color-accent);
149
+ padding-left: var(--space-sm);
150
+ }
151
+
152
+ .detail {
153
+ margin: 0;
154
+ color: var(--color-text);
155
+ overflow: hidden;
156
+ text-overflow: ellipsis;
157
+ white-space: nowrap;
158
+ }
159
+
160
+ .detail-meta {
161
+ margin: 0;
162
+ color: var(--color-muted);
163
+ }
164
+
165
+ .files {
166
+ list-style: none;
167
+ margin: var(--space-xs) 0 0;
168
+ padding: 0;
169
+ }
170
+
171
+ .files li {
172
+ overflow: hidden;
173
+ text-overflow: ellipsis;
174
+ white-space: nowrap;
175
+ color: var(--color-text-body);
176
+ }
177
+
178
+ .icon-button,
179
+ .text-button {
180
+ min-width: 28px;
181
+ min-height: 28px;
182
+ padding: 0 var(--space-sm);
183
+ border: 1px solid var(--color-border);
184
+ border-radius: var(--radius-action);
185
+ background: var(--color-surface);
186
+ color: var(--color-text);
187
+ font: inherit;
188
+ cursor: pointer;
189
+ }
190
+
191
+ .icon-button:hover,
192
+ .text-button:hover {
193
+ border-color: var(--color-text-secondary);
194
+ }
195
+
196
+ .icon-button:active,
197
+ .text-button:active {
198
+ background: var(--color-border);
199
+ }
200
+
201
+ .surface {
202
+ position: relative;
203
+ min-width: 0;
204
+ overflow: hidden;
205
+ background: var(--color-background);
206
+ }
207
+
208
+ .viewport {
209
+ position: absolute;
210
+ inset: 0;
211
+ overflow: hidden;
212
+ cursor: grab;
213
+ touch-action: none;
214
+ }
215
+
216
+ .viewport:active {
217
+ cursor: grabbing;
218
+ }
219
+
220
+ .plane {
221
+ position: absolute;
222
+ top: 0;
223
+ left: 0;
224
+ transform-origin: 0 0;
225
+ }
226
+
227
+ .frame {
228
+ position: absolute;
229
+ margin: 0;
230
+ cursor: default;
231
+ }
232
+
233
+ .frame-label {
234
+ position: absolute;
235
+ bottom: 100%;
236
+ left: 0;
237
+ right: 0;
238
+ display: flex;
239
+ align-items: center;
240
+ gap: var(--space-sm);
241
+ padding-bottom: var(--space-sm);
242
+ font-size: 1.5rem;
243
+ color: var(--color-text-secondary);
244
+ white-space: nowrap;
245
+ }
246
+
247
+ .frame-name {
248
+ overflow: hidden;
249
+ text-overflow: ellipsis;
250
+ color: var(--color-text);
251
+ }
252
+
253
+ .frame-size {
254
+ color: var(--color-muted);
255
+ font-variant-numeric: tabular-nums;
256
+ }
257
+
258
+ .frame-theme {
259
+ margin-left: auto;
260
+ padding: 2px var(--space-sm);
261
+ border: 1px solid var(--color-border);
262
+ border-radius: var(--radius-pill);
263
+ background: var(--color-surface);
264
+ color: var(--color-text-secondary);
265
+ font: inherit;
266
+ cursor: pointer;
267
+ }
268
+
269
+ .frame-theme:hover {
270
+ color: var(--color-text);
271
+ }
272
+
273
+ .frame iframe {
274
+ display: block;
275
+ border: 1px solid var(--color-border);
276
+ border-radius: 2px;
277
+ }
278
+
279
+ /* The frame's handle, since a press inside the frame picks an element. */
280
+ .frame-label {
281
+ cursor: move;
282
+ touch-action: none;
283
+ }
284
+
285
+ .frame[data-dragging='true'] .frame-label {
286
+ cursor: grabbing;
287
+ }
288
+
289
+ .frame-body {
290
+ position: relative;
291
+ }
292
+
293
+ /* Inset by the iframe border, so a box lines up with the element it marks. */
294
+ .element-outline {
295
+ position: absolute;
296
+ translate: 1px 1px;
297
+ pointer-events: none;
298
+ }
299
+
300
+ .element-outline[data-outline='hover'] {
301
+ outline: calc(1px * var(--outline-scale, 1)) dashed var(--color-accent);
302
+ }
303
+
304
+ .element-outline[data-outline='selected'] {
305
+ outline: calc(2px * var(--outline-scale, 1)) solid var(--color-accent);
306
+ }
307
+
308
+ /* Above its neighbors, so a frame dragged over another stays whole. */
309
+ .frame[data-selected='true'] {
310
+ z-index: 1;
311
+ }
312
+
313
+ .frame[data-selected='true'] iframe {
314
+ outline: 2px solid var(--color-accent);
315
+ outline-offset: 2px;
316
+ }
317
+
318
+ .frame:focus-visible {
319
+ outline: 2px solid var(--color-accent);
320
+ outline-offset: 6px;
321
+ }
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
+ .toolbar {
347
+ position: absolute;
348
+ right: var(--space-md);
349
+ bottom: var(--space-md);
350
+ display: flex;
351
+ align-items: center;
352
+ gap: var(--space-xs);
353
+ padding: var(--space-xs);
354
+ border: 1px solid var(--color-border);
355
+ border-radius: var(--radius-panel);
356
+ background: var(--color-chrome);
357
+ }
358
+
359
+ .zoom {
360
+ min-width: 3.5rem;
361
+ text-align: center;
362
+ font-variant-numeric: tabular-nums;
363
+ color: var(--color-text-secondary);
364
+ }
365
+
366
+ @media (max-width: 900px) {
367
+ .shell {
368
+ grid-template-columns: 12rem minmax(0, 1fr);
369
+ }
370
+
371
+ .panel-right {
372
+ display: none;
373
+ }
374
+ }
375
+
376
+ @media (max-width: 600px) {
377
+ .shell {
378
+ grid-template-columns: minmax(0, 1fr);
379
+ grid-template-rows: auto minmax(0, 1fr);
380
+ }
381
+
382
+ .panel-left {
383
+ max-height: 40vh;
384
+ border-right: 0;
385
+ border-bottom: 1px solid var(--color-border);
386
+ }
387
+ }
388
+
389
+ .frame-row {
390
+ display: flex;
391
+ align-items: center;
392
+ }
393
+
394
+ .frame-row .row {
395
+ flex: 1;
396
+ min-width: 0;
397
+ }
398
+
399
+ .disclosure {
400
+ flex: none;
401
+ width: 24px;
402
+ height: 24px;
403
+ padding: 0;
404
+ border: 0;
405
+ border-radius: var(--radius-action);
406
+ background: none;
407
+ color: var(--color-muted);
408
+ font: inherit;
409
+ cursor: pointer;
410
+ }
411
+
412
+ .disclosure:hover {
413
+ background: var(--color-surface);
414
+ color: var(--color-text);
415
+ }
416
+
417
+ .layers {
418
+ margin: 0;
419
+ padding: 0 0 0 var(--space-sm);
420
+ list-style: none;
421
+ }
422
+
423
+ .layers-root {
424
+ padding-left: var(--space-lg);
425
+ }
426
+
427
+ .layer {
428
+ min-height: 24px;
429
+ }
430
+
431
+ .row-meta.layer-text {
432
+ flex-shrink: 1;
433
+ min-width: 0;
434
+ overflow: hidden;
435
+ text-overflow: ellipsis;
436
+ white-space: nowrap;
437
+ }
438
+
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
+ }