@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.
- package/README.md +2 -1
- 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/canvas/REQUIREMENT.md +49 -0
- package/claude/skills/canvas/SKILL.md +106 -0
- package/claude/skills/context-fold/REQUIREMENT.md +6 -2
- package/claude/skills/context-fold/SKILL.md +8 -6
- package/claude/skills/context-fold/references/anchor-sweep.md +2 -2
- package/claude/skills/design-extract/REQUIREMENT.md +1 -1
- package/claude/skills/design-taste/REQUIREMENT.md +1 -1
- package/claude/skills/design-taste/SKILL.md +4 -2
- package/claude/skills/design-taste/references/adopted.md +40 -0
- package/claude/skills/design-taste/references/kinds.md +1 -1
- package/claude/skills/design-taste/references/systems.md +1 -7
- package/claude/skills/design-taste/references/tells.md +2 -24
- package/claude/skills/docs-sync/REQUIREMENT.md +2 -1
- package/claude/skills/document-health/REQUIREMENT.md +2 -0
- package/claude/skills/document-health/SKILL.md +21 -0
- package/claude/skills/document-health/references/axes.md +12 -0
- package/claude/skills/draft-and-pick/SKILL.md +1 -1
- package/claude/skills/draft-doc/REQUIREMENT.md +1 -1
- 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/draft-identity/SKILL.md +1 -1
- package/claude/skills/draft-screencast/SKILL.md +9 -7
- package/claude/skills/draft-slides/REQUIREMENT.md +17 -12
- package/claude/skills/draft-slides/SKILL.md +31 -20
- package/claude/skills/git-followup/SKILL.md +17 -6
- package/claude/skills/git-issue/references/issue.md +10 -0
- package/claude/skills/git-pr/references/evidence.md +12 -2
- package/claude/skills/git-pr/references/labels.md +12 -0
- package/claude/skills/git-split/SKILL.md +19 -8
- package/claude/skills/index-lookup/SKILL.md +2 -2
- package/claude/skills/markdown-propose/references/format.md +9 -0
- package/claude/skills/memory-review/references/later-phases.md +7 -0
- 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/review-ui/references/post.md +4 -2
- package/claude/skills/role-orchestrator/references/orchestrator-cloud-launch.md +38 -1
- package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +13 -0
- 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/claude/skills/search-craft/REQUIREMENT.md +1 -1
- package/claude/skills/search-craft/SKILL.md +3 -1
- package/claude/skills/search-craft/references/adopted.md +30 -0
- package/claude/skills/target-setup/references/detect.md +8 -0
- package/claude/skills/target-setup/references/indexes.md +13 -0
- package/claude/skills/target-setup/references/verify.md +8 -0
- package/claude/skills/test-first/SKILL.md +2 -0
- package/claude/skills/test-first/references/adopted.md +36 -0
- package/claude/skills/write-human/SKILL.md +1 -1
- package/claude/skills/write-human/references/machine-tells.md +13 -0
- package/docs/agents/canvas.md +4 -2
- package/docs/agents/capture.md +1 -1
- package/docs/agents/commands.md +47 -47
- package/docs/agents/context-audit-checks.md +2 -2
- package/docs/agents/index.md +2 -3
- 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/agents/records-stale.md +22 -9
- package/docs/agents/records.md +1 -1
- package/docs/agents/sandbox.md +1 -1
- package/docs/agents/skills-audit.md +10 -3
- package/docs/agents/slides.md +15 -3
- package/docs/target/projects.md +4 -4
- package/docs/workflow/ai-workflow.md +1 -2
- package/docs/workflow/index.md +1 -0
- package/docs/workflow/parallel-features.md +1 -1
- package/docs/workflow/skill-map-on-request.md +42 -0
- package/docs/workflow/skill-map.md +3 -36
- package/docs/workflow/visual-design-workflow.md +1 -0
- 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/scripts/lib/sandbox-dispatch.sh +1 -1
- package/scripts/lib/sandbox-git.sh +1 -9
- package/scripts/lib/sandbox-path.sh +1 -1
- package/scripts/sandbox-hook.sh +99 -0
- package/src/audits/catalog.ts +2 -2
- package/src/canvas/capture.ts +1 -9
- package/src/canvas/client/inspector/color-field.tsx +368 -0
- package/src/canvas/client/inspector/field.tsx +200 -0
- package/src/canvas/client/inspector/fields.css +292 -0
- package/src/canvas/client/inspector/section.tsx +27 -0
- package/src/canvas/client/inspector/values.ts +183 -0
- package/src/canvas/client/inspector.tsx +176 -160
- package/src/canvas/client/shell.css +0 -101
- package/src/capture/render.ts +45 -7
- package/src/capture/sources.ts +43 -0
- package/src/census/count.ts +1 -1
- package/src/claude/cases/misc.ts +5 -0
- package/src/claude/cases/workflow.ts +6 -1
- package/src/claude/seeds.ts +1 -2
- package/src/claude/skills-audit.ts +68 -14
- package/src/client-commands.ts +1 -1
- package/src/commands/claude.ts +27 -2
- package/src/commands/design.ts +2 -64
- package/src/commands/feedback.ts +3 -3
- package/src/commands/pr.ts +219 -202
- package/src/commands/records.ts +88 -6
- package/src/commands/sandbox.ts +50 -10
- package/src/commands/slides.ts +31 -77
- package/src/context/audit.ts +8 -7
- package/src/design/tokens.ts +2 -18
- package/src/docs/read.ts +1 -1
- package/src/{github.ts → feedback/github.ts} +1 -1
- package/src/gate/measures.ts +6 -4
- package/src/gov/citations.ts +1 -1
- package/src/gov/payload.ts +1 -1
- package/src/gov/superseded.ts +2 -2
- package/src/help.ts +2 -2
- package/src/markdown/ceiling.ts +1 -1
- package/src/migrate/skill-names.ts +7 -1
- package/src/pr/evidence.ts +25 -5
- package/src/pr/rest.ts +137 -0
- package/src/record-root.ts +1 -0
- package/src/records/backup.ts +1 -0
- package/src/records/push-guard.ts +1 -1
- package/src/records/stale-canonical.ts +146 -0
- package/src/records/stale.ts +1 -1
- package/src/sandbox/hooks.ts +128 -0
- package/src/sandbox/provision.ts +596 -0
- package/src/sandbox/tree.ts +103 -4
- package/src/secrets/marker.ts +2 -2
- package/src/secrets/scan.ts +1 -1
- package/src/shipped/references.ts +2 -2
- package/src/slides/convert/export.ts +2 -16
- package/src/slides/decks.ts +110 -0
- package/src/standards/read.ts +1 -1
- package/src/sync/seeds-report.ts +1 -1
- package/src/tasks/answers.ts +1 -1
- package/src/tasks/archive.ts +1 -1
- package/src/teach/nav.ts +1 -1
- package/src/tooling/inject.ts +1 -1
- package/src/web/readme-citations.ts +1 -1
- package/standards/architecture.md +1 -0
- package/standards/canvas.md +112 -0
- package/standards/context.md +2 -1
- 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/standards/requirements.md +2 -0
- package/standards/skill-practice.md +2 -1
- package/standards/skill.md +1 -0
- package/tooling/claude/reference.md +0 -5
- 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/scripts/manage-sandbox.sh +0 -472
- package/src/design/board.ts +0 -576
- package/src/slides/layouts.ts +0 -478
- package/src/slides/parse.ts +0 -84
- package/src/slides/render.ts +0 -110
- package/src/slides/styles.ts +0 -96
- package/standards/diagrams.md +0 -132
- package/tooling/claude/seeds/.claude/diagrams/index.md +0 -8
- /package/claude/skills/write-human/references/{source-material.md → adopted.md} +0 -0
- /package/src/{commands/feedback-format.ts → feedback/body.ts} +0 -0
- /package/src/{github-format.ts → feedback/github-format.ts} +0 -0
- /package/src/{frontmatter.ts → markdown/frontmatter.ts} +0 -0
- /package/src/{binary.ts → sweep/binary.ts} +0 -0
- /package/src/{exempt-marker.ts → sweep/exempt-marker.ts} +0 -0
- /package/src/{paths.ts → tasks/paths.ts} +0 -0
- /package/src/{seed-marker.ts → tooling/seed-marker.ts} +0 -0
package/src/claude/seeds.ts
CHANGED
|
@@ -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:
|
|
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
|
|
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 (!
|
|
327
|
-
|
|
328
|
-
const
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
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.
|
package/src/client-commands.ts
CHANGED
package/src/commands/claude.ts
CHANGED
|
@@ -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
|
-
`
|
|
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
|
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')
|
package/src/commands/feedback.ts
CHANGED
|
@@ -7,11 +7,11 @@ import {
|
|
|
7
7
|
deriveTitle,
|
|
8
8
|
missingField,
|
|
9
9
|
missingFieldMessage,
|
|
10
|
-
} from '@/
|
|
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> {
|