@erclx/canon 5.24.0 → 5.26.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 (185) hide show
  1. package/README.md +2 -1
  2. package/claude/.claude-plugin/plugin.json +1 -1
  3. package/claude/skills/backlog-triage/REQUIREMENT.md +2 -2
  4. package/claude/skills/backlog-triage/SKILL.md +19 -6
  5. package/claude/skills/canvas/REQUIREMENT.md +49 -0
  6. package/claude/skills/canvas/SKILL.md +106 -0
  7. package/claude/skills/context-fold/REQUIREMENT.md +6 -2
  8. package/claude/skills/context-fold/SKILL.md +8 -6
  9. package/claude/skills/context-fold/references/anchor-sweep.md +2 -2
  10. package/claude/skills/design-extract/REQUIREMENT.md +1 -1
  11. package/claude/skills/design-taste/REQUIREMENT.md +1 -1
  12. package/claude/skills/design-taste/SKILL.md +4 -2
  13. package/claude/skills/design-taste/references/adopted.md +40 -0
  14. package/claude/skills/design-taste/references/kinds.md +1 -1
  15. package/claude/skills/design-taste/references/systems.md +1 -7
  16. package/claude/skills/design-taste/references/tells.md +2 -24
  17. package/claude/skills/docs-sync/REQUIREMENT.md +2 -1
  18. package/claude/skills/document-health/REQUIREMENT.md +2 -0
  19. package/claude/skills/document-health/SKILL.md +21 -0
  20. package/claude/skills/document-health/references/axes.md +12 -0
  21. package/claude/skills/draft-and-pick/SKILL.md +1 -1
  22. package/claude/skills/draft-doc/REQUIREMENT.md +1 -1
  23. package/claude/skills/draft-figure/REQUIREMENT.md +14 -3
  24. package/claude/skills/draft-figure/SKILL.md +24 -51
  25. package/claude/skills/draft-figure/references/architecture-set.md +35 -0
  26. package/claude/skills/draft-figure/references/hand-drawn.md +31 -0
  27. package/claude/skills/draft-figure/references/mermaid.md +55 -0
  28. package/claude/skills/draft-identity/SKILL.md +1 -1
  29. package/claude/skills/draft-screencast/SKILL.md +9 -7
  30. package/claude/skills/draft-slides/REQUIREMENT.md +17 -12
  31. package/claude/skills/draft-slides/SKILL.md +31 -20
  32. package/claude/skills/git-followup/SKILL.md +17 -6
  33. package/claude/skills/git-issue/references/issue.md +10 -0
  34. package/claude/skills/git-pr/references/evidence.md +12 -2
  35. package/claude/skills/git-pr/references/labels.md +12 -0
  36. package/claude/skills/git-split/SKILL.md +19 -8
  37. package/claude/skills/index-lookup/SKILL.md +2 -2
  38. package/claude/skills/markdown-propose/references/format.md +9 -0
  39. package/claude/skills/memory-review/references/later-phases.md +7 -0
  40. package/claude/skills/review-address/SKILL.md +6 -13
  41. package/claude/skills/review-address/references/rest-reads.md +43 -0
  42. package/claude/skills/review-craft/references/ui.md +7 -1
  43. package/claude/skills/review-pr/REQUIREMENT.md +1 -0
  44. package/claude/skills/review-pr/SKILL.md +9 -3
  45. package/claude/skills/review-pr/references/close-out.md +2 -2
  46. package/claude/skills/review-pr/references/post.md +17 -5
  47. package/claude/skills/review-pr/references/scope.md +10 -8
  48. package/claude/skills/review-ui/SKILL.md +12 -4
  49. package/claude/skills/review-ui/references/post.md +4 -2
  50. package/claude/skills/role-orchestrator/references/orchestrator-cloud-launch.md +38 -1
  51. package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +13 -0
  52. package/claude/skills/role-orchestrator/references/orchestrator-launch.md +4 -0
  53. package/claude/skills/role-orchestrator/references/orchestrator-poll.md +4 -4
  54. package/claude/skills/role-orchestrator/references/orchestrator-review-dispatch.md +6 -0
  55. package/claude/skills/role-orchestrator/scripts/poll.ts +90 -27
  56. package/claude/skills/role-orchestrator/scripts/repo.ts +3 -5
  57. package/claude/skills/role-orchestrator/scripts/watch.ts +4 -7
  58. package/claude/skills/search-craft/REQUIREMENT.md +1 -1
  59. package/claude/skills/search-craft/SKILL.md +3 -1
  60. package/claude/skills/search-craft/references/adopted.md +30 -0
  61. package/claude/skills/target-setup/references/detect.md +8 -0
  62. package/claude/skills/target-setup/references/indexes.md +13 -0
  63. package/claude/skills/target-setup/references/verify.md +8 -0
  64. package/claude/skills/test-first/SKILL.md +2 -0
  65. package/claude/skills/test-first/references/adopted.md +36 -0
  66. package/claude/skills/write-human/SKILL.md +1 -1
  67. package/claude/skills/write-human/references/machine-tells.md +13 -0
  68. package/docs/agents/canvas.md +4 -2
  69. package/docs/agents/capture.md +1 -1
  70. package/docs/agents/commands.md +47 -47
  71. package/docs/agents/context-audit-checks.md +2 -2
  72. package/docs/agents/index.md +2 -3
  73. package/docs/agents/key-changes.md +3 -3
  74. package/docs/agents/pr-evidence.md +11 -2
  75. package/docs/agents/pr-reads.md +5 -4
  76. package/docs/agents/records-stale.md +22 -9
  77. package/docs/agents/records.md +1 -1
  78. package/docs/agents/sandbox.md +1 -1
  79. package/docs/agents/skills-audit.md +10 -3
  80. package/docs/agents/slides.md +15 -3
  81. package/docs/target/projects.md +4 -4
  82. package/docs/workflow/ai-workflow.md +1 -2
  83. package/docs/workflow/index.md +1 -0
  84. package/docs/workflow/parallel-features.md +1 -1
  85. package/docs/workflow/skill-map-on-request.md +42 -0
  86. package/docs/workflow/skill-map.md +3 -36
  87. package/docs/workflow/visual-design-workflow.md +1 -0
  88. package/governance/renames.toml +0 -4
  89. package/governance/rules/standards/markdown.md +1 -0
  90. package/package.json +1 -2
  91. package/scripts/core/install-check.sh +1 -1
  92. package/scripts/lib/sandbox-dispatch.sh +1 -1
  93. package/scripts/lib/sandbox-git.sh +1 -9
  94. package/scripts/lib/sandbox-path.sh +1 -1
  95. package/scripts/sandbox-hook.sh +99 -0
  96. package/src/audits/catalog.ts +2 -2
  97. package/src/canvas/capture.ts +1 -9
  98. package/src/canvas/client/inspector/color-field.tsx +368 -0
  99. package/src/canvas/client/inspector/field.tsx +200 -0
  100. package/src/canvas/client/inspector/fields.css +292 -0
  101. package/src/canvas/client/inspector/section.tsx +27 -0
  102. package/src/canvas/client/inspector/values.ts +183 -0
  103. package/src/canvas/client/inspector.tsx +176 -160
  104. package/src/canvas/client/shell.css +0 -101
  105. package/src/capture/render.ts +45 -7
  106. package/src/capture/sources.ts +43 -0
  107. package/src/census/count.ts +1 -1
  108. package/src/claude/cases/misc.ts +5 -0
  109. package/src/claude/cases/workflow.ts +6 -1
  110. package/src/claude/seeds.ts +1 -2
  111. package/src/claude/skills-audit.ts +68 -14
  112. package/src/client-commands.ts +1 -1
  113. package/src/commands/claude.ts +27 -2
  114. package/src/commands/design.ts +2 -64
  115. package/src/commands/feedback.ts +3 -3
  116. package/src/commands/pr.ts +219 -202
  117. package/src/commands/records.ts +88 -6
  118. package/src/commands/sandbox.ts +50 -10
  119. package/src/commands/slides.ts +31 -77
  120. package/src/context/audit.ts +8 -7
  121. package/src/design/tokens.ts +2 -18
  122. package/src/docs/read.ts +1 -1
  123. package/src/{github.ts → feedback/github.ts} +1 -1
  124. package/src/gate/measures.ts +6 -4
  125. package/src/gov/citations.ts +1 -1
  126. package/src/gov/payload.ts +1 -1
  127. package/src/gov/superseded.ts +2 -2
  128. package/src/help.ts +2 -2
  129. package/src/markdown/ceiling.ts +1 -1
  130. package/src/migrate/skill-names.ts +7 -1
  131. package/src/pr/evidence.ts +25 -5
  132. package/src/pr/rest.ts +137 -0
  133. package/src/record-root.ts +1 -0
  134. package/src/records/backup.ts +1 -0
  135. package/src/records/push-guard.ts +1 -1
  136. package/src/records/stale-canonical.ts +146 -0
  137. package/src/records/stale.ts +1 -1
  138. package/src/sandbox/hooks.ts +128 -0
  139. package/src/sandbox/provision.ts +596 -0
  140. package/src/sandbox/tree.ts +103 -4
  141. package/src/secrets/marker.ts +2 -2
  142. package/src/secrets/scan.ts +1 -1
  143. package/src/shipped/references.ts +2 -2
  144. package/src/slides/convert/export.ts +2 -16
  145. package/src/slides/decks.ts +110 -0
  146. package/src/standards/read.ts +1 -1
  147. package/src/sync/seeds-report.ts +1 -1
  148. package/src/tasks/answers.ts +1 -1
  149. package/src/tasks/archive.ts +1 -1
  150. package/src/teach/nav.ts +1 -1
  151. package/src/tooling/inject.ts +1 -1
  152. package/src/web/readme-citations.ts +1 -1
  153. package/standards/architecture.md +1 -0
  154. package/standards/canvas.md +112 -0
  155. package/standards/context.md +2 -1
  156. package/standards/figures.md +0 -1
  157. package/standards/index.md +1 -1
  158. package/standards/markdown.md +1 -0
  159. package/standards/mermaid.md +1 -7
  160. package/standards/requirements.md +2 -0
  161. package/standards/skill-practice.md +2 -1
  162. package/standards/skill.md +1 -0
  163. package/tooling/claude/reference.md +0 -5
  164. package/claude/skills/draft-diagram/REQUIREMENT.md +0 -45
  165. package/claude/skills/draft-diagram/SKILL.md +0 -177
  166. package/docs/agents/design-board.md +0 -33
  167. package/governance/rules/standards/diagrams.md +0 -14
  168. package/governance/rules/standards/mermaid.md +0 -15
  169. package/scripts/core/check-gallery-exclusion.sh +0 -50
  170. package/scripts/manage-sandbox.sh +0 -472
  171. package/src/design/board.ts +0 -576
  172. package/src/slides/layouts.ts +0 -478
  173. package/src/slides/parse.ts +0 -84
  174. package/src/slides/render.ts +0 -110
  175. package/src/slides/styles.ts +0 -96
  176. package/standards/diagrams.md +0 -132
  177. package/tooling/claude/seeds/.claude/diagrams/index.md +0 -8
  178. /package/claude/skills/write-human/references/{source-material.md → adopted.md} +0 -0
  179. /package/src/{commands/feedback-format.ts → feedback/body.ts} +0 -0
  180. /package/src/{github-format.ts → feedback/github-format.ts} +0 -0
  181. /package/src/{frontmatter.ts → markdown/frontmatter.ts} +0 -0
  182. /package/src/{binary.ts → sweep/binary.ts} +0 -0
  183. /package/src/{exempt-marker.ts → sweep/exempt-marker.ts} +0 -0
  184. /package/src/{paths.ts → tasks/paths.ts} +0 -0
  185. /package/src/{seed-marker.ts → tooling/seed-marker.ts} +0 -0
@@ -3,7 +3,7 @@ import { chmod, mkdir, readFile, writeFile } from 'node:fs/promises'
3
3
  import { dirname, join, relative } from 'node:path'
4
4
  import { copyPreservingMode } from '@/copy'
5
5
  import { creationRel, isRecordEntry } from '@/record-root'
6
- import { rewritesOnInstall, stripSeedMarker } from '@/seed-marker'
6
+ import { rewritesOnInstall, stripSeedMarker } from '@/tooling/seed-marker'
7
7
  import { SURFACE_ENTRIES, surfaceDir } from '@/surface-root'
8
8
 
9
9
  const SEEDS_DIR = join('tooling', 'claude', 'seeds')
@@ -20,7 +20,6 @@ const HOOKS = 'hooks'
20
20
  export const SUBDIRS: readonly string[] = [
21
21
  HOOKS,
22
22
  'context',
23
- 'diagrams',
24
23
  'memory',
25
24
  'tasks',
26
25
  'wireframes',
@@ -40,6 +40,21 @@ export const PRACTICE_SKILLS: readonly string[] = [
40
40
  join(SHIPPED_CORPUS, 'code-craft'),
41
41
  join(SHIPPED_CORPUS, 'build-in-slices'),
42
42
  join(SHIPPED_CORPUS, 'deprecation-migration'),
43
+ join(SHIPPED_CORPUS, 'search-craft'),
44
+ join(SHIPPED_CORPUS, 'video-craft'),
45
+ ]
46
+
47
+ /**
48
+ * Every skill carrying the source ledger, being the practice skills and the
49
+ * skills that teach a craft without the practice closing sections. Kept apart
50
+ * from `PRACTICE_SKILLS` so citing sources never forces those sections onto a
51
+ * skill whose body is not shaped around a practice a session cuts short.
52
+ */
53
+ export const LEDGER_SKILLS: readonly string[] = [
54
+ ...PRACTICE_SKILLS,
55
+ join(SHIPPED_CORPUS, 'design-taste'),
56
+ join(SHIPPED_CORPUS, 'write-human'),
57
+ join(SHIPPED_CORPUS, 'test-first'),
43
58
  ]
44
59
 
45
60
  /** The closing H2s a practice skill carries, matched exactly outside fences. */
@@ -52,6 +67,16 @@ export const PRACTICE_SECTIONS: readonly string[] = [
52
67
  /** The source ledger every practice skill carries beside its body. */
53
68
  export const PRACTICE_LEDGER = join('references', 'adopted.md')
54
69
 
70
+ /**
71
+ * The line count past which a reference opens with a contents list, from
72
+ * Anthropic's skill authoring guidance. Counted over the whole file the way
73
+ * `wc -l` counts it, so "over 100" holds at 101 and not at 100.
74
+ */
75
+ export const CONTENTS_THRESHOLD = 100
76
+
77
+ /** The H2 a long reference opens with, matched exactly outside fences. */
78
+ export const CONTENTS_SECTION = 'Contents'
79
+
55
80
  /**
56
81
  * The one reason this audit refuses. A project carrying neither corpus is the
57
82
  * ordinary state of a target that has not adopted either skills convention,
@@ -102,6 +127,7 @@ export interface SkillsAudit {
102
127
  readonly requirementSections: readonly SkillFinding[]
103
128
  readonly datedProvenance: readonly SkillFinding[]
104
129
  readonly practiceShape: readonly SkillFinding[]
130
+ readonly referenceContents: readonly SkillFinding[]
105
131
  }
106
132
 
107
133
  interface SkillSource {
@@ -126,6 +152,7 @@ interface SkillSource {
126
152
  interface SkillText {
127
153
  readonly rel: string
128
154
  readonly text: string
155
+ readonly isReference: boolean
129
156
  }
130
157
 
131
158
  /**
@@ -177,6 +204,9 @@ export async function auditSkills(root: string): Promise<SkillsAudit> {
177
204
  ),
178
205
  ...sources.flatMap(practiceFindings),
179
206
  ],
207
+ referenceContents: sources.flatMap((source) =>
208
+ source.bodies.flatMap(contentsFindings),
209
+ ),
180
210
  }
181
211
  }
182
212
 
@@ -233,16 +263,14 @@ async function readSkill(
233
263
  description: declared(readField(fields, 'description')),
234
264
  requirementHeadings:
235
265
  requirement === undefined ? undefined : headings(requirement),
236
- sections: bodyLines(body)
237
- .filter((line) => !line.fenced)
238
- .map((line) => SECTION.exec(line.text)?.[1])
239
- .filter((text): text is string => text !== undefined),
266
+ sections: sectionsOf(body),
240
267
  hasLedger: existsSync(join(skillDir, PRACTICE_LEDGER)),
241
268
  bodies: [
242
- { rel: join(skillRel, 'SKILL.md'), text: body },
269
+ { rel: join(skillRel, 'SKILL.md'), text: body, isReference: false },
243
270
  ...references.map((path, index) => ({
244
271
  rel: join(skillRel, path),
245
272
  text: referenceTexts[index] ?? '',
273
+ isReference: true,
246
274
  })),
247
275
  ],
248
276
  }
@@ -257,6 +285,14 @@ function declared(value: string | undefined): string | undefined {
257
285
  return trimmed === undefined || trimmed === '' ? undefined : trimmed
258
286
  }
259
287
 
288
+ /** Every H2 outside a fence, the one level both exact-section checks read. */
289
+ function sectionsOf(source: string): string[] {
290
+ return bodyLines(source)
291
+ .filter((line) => !line.fenced)
292
+ .map((line) => SECTION.exec(line.text)?.[1])
293
+ .filter((text): text is string => text !== undefined)
294
+ }
295
+
260
296
  function headings(source: string): string[] {
261
297
  return source
262
298
  .split('\n')
@@ -311,7 +347,7 @@ function missingPracticeSkills(
311
347
  ): SkillFinding[] {
312
348
  if (!hasShippedCorpus) return []
313
349
  const found = new Set(sources.map((source) => source.rel))
314
- return PRACTICE_SKILLS.filter((rel) => !found.has(rel)).map((rel) => ({
350
+ return LEDGER_SKILLS.filter((rel) => !found.has(rel)).map((rel) => ({
315
351
  rel,
316
352
  detail: 'missing skill: no folder under the shipped corpus',
317
353
  }))
@@ -323,14 +359,15 @@ function missingPracticeSkills(
323
359
  * standard never names.
324
360
  */
325
361
  function practiceFindings(source: SkillSource): SkillFinding[] {
326
- if (!PRACTICE_SKILLS.includes(source.rel)) return []
327
-
328
- const sections = PRACTICE_SECTIONS.filter(
329
- (section) => !source.sections.includes(section),
330
- ).map((section) => ({
331
- rel: source.rel,
332
- detail: `missing section: ${section}`,
333
- }))
362
+ if (!LEDGER_SKILLS.includes(source.rel)) return []
363
+
364
+ const isPractice = PRACTICE_SKILLS.includes(source.rel)
365
+ const sections = (isPractice ? PRACTICE_SECTIONS : [])
366
+ .filter((section) => !source.sections.includes(section))
367
+ .map((section) => ({
368
+ rel: source.rel,
369
+ detail: `missing section: ${section}`,
370
+ }))
334
371
  const ledger = source.hasLedger
335
372
  ? []
336
373
  : [{ rel: source.rel, detail: `missing ledger: ${PRACTICE_LEDGER}` }]
@@ -338,6 +375,23 @@ function practiceFindings(source: SkillSource): SkillFinding[] {
338
375
  return [...sections, ...ledger]
339
376
  }
340
377
 
378
+ /**
379
+ * Reads references alone, since `SKILL.md` carries its own length checkpoint
380
+ * and no contents rule. Frontmatter counts toward the length, so the count a
381
+ * finding names is the one `wc -l` prints beside it.
382
+ */
383
+ function contentsFindings(source: SkillText): SkillFinding[] {
384
+ if (!source.isReference) return []
385
+
386
+ const lines = source.text.replace(/\n$/, '').split('\n').length
387
+ if (lines <= CONTENTS_THRESHOLD) return []
388
+ if (sectionsOf(source.text).includes(CONTENTS_SECTION)) return []
389
+
390
+ return [
391
+ { rel: source.rel, detail: `${lines} lines, no ## ${CONTENTS_SECTION}` },
392
+ ]
393
+ }
394
+
341
395
  /**
342
396
  * A date inside a fence or a code span is example data a reader is shown, such
343
397
  * as a sample frontmatter block, so only prose outside both is read.
@@ -1,4 +1,4 @@
1
- import { escapeForPattern, isMarked } from '@/exempt-marker'
1
+ import { escapeForPattern, isMarked } from '@/sweep/exempt-marker'
2
2
 
3
3
  /**
4
4
  * A client command this repository quotes, with the argument spelling every
@@ -24,8 +24,11 @@ import { listSeeds, readSeedContents } from '@/claude/seeds-list'
24
24
  import {
25
25
  auditExitCode,
26
26
  auditSkills,
27
+ CONTENTS_SECTION,
28
+ CONTENTS_THRESHOLD,
27
29
  CORPORA,
28
30
  DESCRIPTION_LIMIT,
31
+ LEDGER_SKILLS,
29
32
  PRACTICE_LEDGER,
30
33
  PRACTICE_SECTIONS,
31
34
  PRACTICE_SKILLS,
@@ -1398,6 +1401,7 @@ async function runSkillsAudit(
1398
1401
  reportRequirementShape(report)
1399
1402
  reportProvenance(report)
1400
1403
  reportPracticeShape(report)
1404
+ reportReferenceContents(report)
1401
1405
  reportUnmeasured()
1402
1406
  outro()
1403
1407
  }
@@ -1421,13 +1425,16 @@ async function runSkillsAudit(
1421
1425
  requirementSections: report.requirementSections,
1422
1426
  datedProvenance: report.datedProvenance,
1423
1427
  practiceShape: report.practiceShape,
1428
+ referenceContents: report.referenceContents,
1424
1429
  },
1425
1430
  checkpoints: {
1426
1431
  descriptionLimit: DESCRIPTION_LIMIT,
1427
1432
  requirementSections: REQUIREMENT_SECTIONS,
1428
1433
  corpora: CORPORA,
1429
1434
  practiceSkills: PRACTICE_SKILLS,
1435
+ ledgerSkills: LEDGER_SKILLS,
1430
1436
  practiceSections: PRACTICE_SECTIONS,
1437
+ contentsThreshold: CONTENTS_THRESHOLD,
1431
1438
  },
1432
1439
  })}\n`,
1433
1440
  )
@@ -1626,10 +1633,10 @@ function reportProvenance(report: SkillsAudit): void {
1626
1633
  function reportPracticeShape(report: SkillsAudit): void {
1627
1634
  logStep('Practice shape')
1628
1635
  logInfo(
1629
- `A listed practice skill closes with ${PRACTICE_SECTIONS.map((section) => `## ${section}`).join(', ')}, and carries ${PRACTICE_LEDGER}.`,
1636
+ `A listed practice skill closes with ${PRACTICE_SECTIONS.map((section) => `## ${section}`).join(', ')}, and every skill on the wider ledger list carries ${PRACTICE_LEDGER}.`,
1630
1637
  )
1631
1638
  logInfo(
1632
- `The list is kept here and names ${plural(PRACTICE_SKILLS.length, 'shipped skill')}, so a skill outside ${SHIPPED_CORPUS} is never read.`,
1639
+ `Both lists are kept here and name ${plural(PRACTICE_SKILLS.length, 'practice skill')} and ${plural(LEDGER_SKILLS.length, 'ledger skill')}, so a skill outside ${SHIPPED_CORPUS} is never read.`,
1633
1640
  )
1634
1641
 
1635
1642
  if (report.practiceShape.length === 0) {
@@ -1643,6 +1650,24 @@ function reportPracticeShape(report: SkillsAudit): void {
1643
1650
  reportFindings(report.practiceShape)
1644
1651
  }
1645
1652
 
1653
+ /** Reports without failing the run, the same judgment the practice shape is. */
1654
+ function reportReferenceContents(report: SkillsAudit): void {
1655
+ logStep('Reference contents')
1656
+ logInfo(
1657
+ `A reference over ${CONTENTS_THRESHOLD} lines opens with a ## ${CONTENTS_SECTION} list, matched exactly outside fences.`,
1658
+ )
1659
+
1660
+ if (report.referenceContents.length === 0) {
1661
+ logInfo('Every long reference opens with a contents list.')
1662
+ return
1663
+ }
1664
+
1665
+ logWarn(
1666
+ `${plural(report.referenceContents.length, 'long reference')} with no contents list`,
1667
+ )
1668
+ reportFindings(report.referenceContents)
1669
+ }
1670
+
1646
1671
  /**
1647
1672
  * Stated on every run, including the run where everything above passed. A
1648
1673
  * report that lists only what it measured reads as a verdict on the standard
@@ -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')
@@ -7,11 +7,11 @@ import {
7
7
  deriveTitle,
8
8
  missingField,
9
9
  missingFieldMessage,
10
- } from '@/commands/feedback-format'
10
+ } from '@/feedback/body'
11
11
  import { checkoutMismatchWarning, PROJECT_ROOT } from '@/project-root'
12
12
  import { creationRel } from '@/record-root'
13
- import { createGithubIssue } from '@/github'
14
- import { issueFailureMessage } from '@/github-format'
13
+ import { createGithubIssue } from '@/feedback/github'
14
+ import { issueFailureMessage } from '@/feedback/github-format'
15
15
  import { frameError, frameSuccess, logWarn, palette } from '@/ui'
16
16
 
17
17
  function readStdin(): Promise<string> {