@erclx/canon 5.48.0 → 5.50.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/auto-ship/SKILL.md +1 -1
- package/claude/skills/canvas-board/REQUIREMENT.md +4 -3
- package/claude/skills/canvas-board/SKILL.md +8 -9
- package/claude/skills/context-fold/references/context.md +4 -3
- package/claude/skills/design-record/REQUIREMENT.md +33 -0
- package/claude/skills/design-record/SKILL.md +84 -0
- package/claude/skills/design-record/references/folder.md +69 -0
- package/claude/skills/design-taste/SKILL.md +1 -1
- package/claude/skills/markdown-craft/REQUIREMENT.md +1 -0
- package/claude/skills/markdown-craft/SKILL.md +6 -1
- package/claude/skills/markdown-craft/references/markdown.md +3 -3
- package/claude/skills/markdown-craft/references/tables.md +30 -0
- package/claude/skills/pick-by-eye/SKILL.md +10 -8
- package/claude/skills/plan-feature/SKILL.md +31 -16
- package/claude/skills/plan-feature/references/batches.md +5 -5
- package/claude/skills/plan-feature/references/plan.md +82 -33
- package/claude/skills/plan-groundwork/SKILL.md +8 -0
- package/claude/skills/plan-groundwork/references/groundwork.md +2 -1
- package/claude/skills/plan-intake/SKILL.md +8 -0
- package/claude/skills/plan-intake/references/intake.md +9 -1
- package/claude/skills/plan-ready/REQUIREMENT.md +3 -3
- package/claude/skills/plan-ready/SKILL.md +3 -3
- package/claude/skills/plan-ready/references/assembly.md +7 -7
- package/claude/skills/plan-ready/references/ready.md +8 -6
- package/claude/skills/review-ui/REQUIREMENT.md +1 -1
- package/claude/skills/review-ui/SKILL.md +4 -11
- package/claude/skills/review-ui/references/close-out.md +1 -1
- package/claude/skills/review-ui/references/drive-copy.md +38 -0
- package/claude/skills/review-ui/references/post.md +24 -3
- package/claude/skills/review-ui/references/verb-absent.md +18 -0
- package/claude/skills/role-orchestrator/SKILL.md +3 -2
- package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +1 -1
- package/claude/skills/role-orchestrator/references/orchestrator-hand-launch.md +60 -0
- package/claude/skills/role-orchestrator/references/orchestrator-launch.md +5 -0
- package/claude/skills/role-orchestrator/references/orchestrator-parked.md +1 -1
- package/claude/skills/role-orchestrator/references/orchestrator-reviewer-launch.md +1 -1
- package/claude/skills/role-planner/SKILL.md +1 -1
- package/claude/skills/role-worker/SKILL.md +4 -2
- package/claude/skills/session-compact/references/handoff-note.md +3 -1
- package/claude/skills/session-map/references/session.md +1 -1
- package/claude/skills/session-worktree/SKILL.md +1 -1
- package/claude/skills/task-board/references/board.md +2 -2
- package/claude/skills/task-board/references/tasks.md +1 -1
- package/docs/agents/index.md +1 -1
- package/docs/agents/markdown-audit.md +5 -2
- package/docs/agents/records.md +1 -1
- package/docs/target/migrations.md +7 -0
- package/docs/target/projects.md +1 -1
- package/docs/workflow/parallel-features.md +2 -2
- package/docs/workflow/skill-map.md +2 -1
- package/docs/workflow/visual-design-workflow.md +2 -1
- package/governance/ledger/ui/design-reference.md +1 -0
- package/governance/rules/ui/design-reference.md +1 -0
- package/package.json +1 -1
- package/src/claude/cases/misc.ts +5 -0
- package/src/commands/claude.ts +26 -1
- package/src/commands/gate.ts +57 -16
- package/src/commands/markdown.ts +98 -19
- package/src/commands/pr.ts +411 -23
- package/src/commands/records.ts +45 -8
- package/src/commands/tasks.ts +12 -0
- package/src/context/audit.ts +6 -5
- package/src/design/budget.ts +1 -1
- package/src/design/components.ts +1 -1
- package/src/design/document.ts +1 -1
- package/src/design/regen.ts +1 -1
- package/src/design/render.ts +1 -1
- package/src/gate/hand-suite.ts +52 -0
- package/src/gate/measures.ts +9 -2
- package/src/gate/sequencer.ts +17 -8
- package/src/hooks/post-merge.ts +11 -0
- package/src/markdown/gated.ts +5 -7
- package/src/markdown/scope.ts +60 -10
- package/src/markdown/structure.ts +1 -1
- package/src/markdown/tables.ts +150 -0
- package/src/pr/drive-copy.ts +218 -0
- package/src/pr/local.ts +26 -0
- package/src/pr/rest.ts +2 -0
- package/src/records/structure.ts +147 -0
- package/src/records/validate.ts +113 -12
- package/src/tasks/archive.ts +137 -4
- package/src/tasks/board.ts +68 -13
- package/src/tasks/validate.ts +54 -14
- package/tooling/base/configs/.github/workflows/pr-local-preview.yml +1 -1
- package/tooling/claude/reference.md +1 -0
- package/tooling/claude/seeds/.claude/hooks/standards-audit.sh +11 -1
- package/tooling/claude/seeds/CLAUDE.md +9 -0
- /package/claude/skills/{canvas-board → design-record}/references/design.md +0 -0
package/src/commands/markdown.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { BAN_SETS, emptyBanSets } from '@/markdown/bans'
|
|
|
6
6
|
import { isChangelog, lengthExemption } from '@/markdown/ceiling'
|
|
7
7
|
import { type ColonFinding, findColons } from '@/markdown/colons'
|
|
8
8
|
import { type MarkdownAuditRefusal, resolveMarkdown } from '@/markdown/files'
|
|
9
|
-
import {
|
|
9
|
+
import type { DensityKind } from '@/markdown/density'
|
|
10
10
|
import {
|
|
11
11
|
type GatedDensityFinding,
|
|
12
12
|
type GatedReferenceShapeFinding,
|
|
@@ -38,7 +38,19 @@ import {
|
|
|
38
38
|
readGatedConfig,
|
|
39
39
|
resolveGatedList,
|
|
40
40
|
} from '@/markdown/gated'
|
|
41
|
-
import {
|
|
41
|
+
import {
|
|
42
|
+
densityGates,
|
|
43
|
+
inDensityScope,
|
|
44
|
+
scopedDensityFindings,
|
|
45
|
+
} from '@/markdown/scope'
|
|
46
|
+
import {
|
|
47
|
+
TABLE_CELL,
|
|
48
|
+
TABLE_ROWS,
|
|
49
|
+
TABLE_TOKEN,
|
|
50
|
+
type TableFinding,
|
|
51
|
+
tableFindings,
|
|
52
|
+
type TableKind,
|
|
53
|
+
} from '@/markdown/tables'
|
|
42
54
|
import {
|
|
43
55
|
BASELINE,
|
|
44
56
|
CHECKPOINTS,
|
|
@@ -86,6 +98,8 @@ interface FileReport {
|
|
|
86
98
|
readonly headingCase: readonly HeadingCaseFinding[]
|
|
87
99
|
/** Empty on a path outside the density scope, so a plan never carries one. */
|
|
88
100
|
readonly density: readonly GatedDensityFinding[]
|
|
101
|
+
/** Empty outside the density scope, and never gating anywhere. */
|
|
102
|
+
readonly tables: readonly TableFinding[]
|
|
89
103
|
/** Empty on a page whose frontmatter does not carry `kind: reference`. */
|
|
90
104
|
readonly referenceShape: readonly GatedReferenceShapeFinding[]
|
|
91
105
|
readonly structure: StructureReport
|
|
@@ -131,13 +145,20 @@ export function register(program: Command): void {
|
|
|
131
145
|
'a row, a 200-character bullet, 5 plain bullets in a row, no H4, and a',
|
|
132
146
|
'paragraph or table opening every H3. Only context, docs, skills, tooling',
|
|
133
147
|
'seeds and references, the wiki, README.md, and CONTRIBUTING.md take a',
|
|
134
|
-
'finding.
|
|
135
|
-
'
|
|
136
|
-
'
|
|
137
|
-
'
|
|
138
|
-
'
|
|
148
|
+
'finding. CLAUDE.md and its seed take only the bullet run and the H3',
|
|
149
|
+
'opening, inside Key paths. In a canon checkout one gates under a',
|
|
150
|
+
'prefix in GATED_PATHS in src/markdown/scope.ts, and a bullet run gates',
|
|
151
|
+
'in context, docs, and skills from the start. Elsewhere one gates only',
|
|
152
|
+
'under a prefix canon/config/markdown.toml lists, which canon markdown',
|
|
153
|
+
'gated add writes, and with no such file every density finding reports',
|
|
154
|
+
'and none gates.',
|
|
139
155
|
'A config that does not parse refuses with its path named.',
|
|
140
156
|
'',
|
|
157
|
+
'Tables take four limits on the same paths, CLAUDE.md aside: a',
|
|
158
|
+
'120-character cell, 8 body rows, a list as the next block, and a code',
|
|
159
|
+
'span with a run past 30 characters. A table finding reports and never',
|
|
160
|
+
'fails a run.',
|
|
161
|
+
'',
|
|
141
162
|
'A page whose frontmatter carries kind: reference takes the reference',
|
|
142
163
|
'shape: no H2 beyond Output, Refusals, and See also, each at most once',
|
|
143
164
|
'and in that order, no H3, and no table whose first header cell names',
|
|
@@ -361,17 +382,16 @@ async function runAudit(
|
|
|
361
382
|
bans: scanBans(lines, bans),
|
|
362
383
|
colons: advisory ? findColons(lines) : [],
|
|
363
384
|
headingCase: advisory ? findHeadingCase(source) : [],
|
|
364
|
-
density:
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
: [],
|
|
385
|
+
density: scopedDensityFindings(rel, lines).map((finding) => ({
|
|
386
|
+
...finding,
|
|
387
|
+
gating: densityGates(
|
|
388
|
+
rel,
|
|
389
|
+
finding.kind,
|
|
390
|
+
gated.prefixes,
|
|
391
|
+
gated.alwaysGated,
|
|
392
|
+
),
|
|
393
|
+
})),
|
|
394
|
+
tables: inDensityScope(rel) ? tableFindings(lines) : [],
|
|
375
395
|
referenceShape: referenceShapeFindings(source).map((finding) => ({
|
|
376
396
|
...finding,
|
|
377
397
|
gating: referenceShapeGates(rel, gated.prefixes),
|
|
@@ -393,6 +413,7 @@ async function runAudit(
|
|
|
393
413
|
reportColons(reports)
|
|
394
414
|
reportHeadingCase(reports)
|
|
395
415
|
reportDensity(reports, gated, resolution.source)
|
|
416
|
+
reportTables(reports)
|
|
396
417
|
reportReferenceShape(reports, gated)
|
|
397
418
|
reportBullets(reports, checkpoints)
|
|
398
419
|
reportParagraphs(reports, checkpoints)
|
|
@@ -430,6 +451,7 @@ async function runAudit(
|
|
|
430
451
|
colons: report.colons,
|
|
431
452
|
headingCase: report.headingCase,
|
|
432
453
|
density: report.density,
|
|
454
|
+
tables: report.tables,
|
|
433
455
|
referenceShape: report.referenceShape,
|
|
434
456
|
longestRun: report.structure.longestRun,
|
|
435
457
|
longestRunLine: report.structure.longestRunLine,
|
|
@@ -643,7 +665,7 @@ function reportDensity(
|
|
|
643
665
|
`Paragraphs past ${CHECKPOINTS.paragraph} characters, more than 2 paragraphs in a row, bullets past ${CHECKPOINTS.bullet} characters, more than 5 plain bullets in a row, a heading past H3, and an H3 opening with neither a paragraph nor a table.`,
|
|
644
666
|
)
|
|
645
667
|
logInfo(
|
|
646
|
-
'Measured on context entries, docs, skill bodies, references, and requirements, tooling seeds and stack references, the wiki, README.md, and CONTRIBUTING.md. Every other path takes no density finding.',
|
|
668
|
+
'Measured on context entries, docs, skill bodies, references, and requirements, tooling seeds and stack references, the wiki, README.md, and CONTRIBUTING.md. CLAUDE.md and its seed take the bullet run and the H3 opening inside Key paths alone. Every other path takes no density finding.',
|
|
647
669
|
)
|
|
648
670
|
logInfo(densityGatingLine(gated, source))
|
|
649
671
|
|
|
@@ -695,6 +717,63 @@ function densityGatingLine(
|
|
|
695
717
|
: `A finding gates under a prefix ${GATED_CONFIG_REL} lists (${listed}). Every other finding reports.`
|
|
696
718
|
}
|
|
697
719
|
|
|
720
|
+
const TABLE_LABELS: Record<TableKind, string> = {
|
|
721
|
+
'table-cell': 'cell length',
|
|
722
|
+
'table-rows': 'rows',
|
|
723
|
+
'table-then-list': 'list after table',
|
|
724
|
+
'table-token': 'wide token',
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
function describeTable(finding: TableFinding): string {
|
|
728
|
+
const measured =
|
|
729
|
+
finding.kind === 'table-then-list'
|
|
730
|
+
? 'follows the table with no lead sentence'
|
|
731
|
+
: `${finding.value} past ${finding.limit}`
|
|
732
|
+
return ` :${finding.line} ${TABLE_LABELS[finding.kind]} ${measured}`
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
/**
|
|
736
|
+
* Lists every table finding on the density scope's paths. None gates yet,
|
|
737
|
+
* since a gate is decided per path rather than per kind, and a new density
|
|
738
|
+
* kind would fail every gated folder carrying a table hit at once.
|
|
739
|
+
*/
|
|
740
|
+
function reportTables(reports: readonly FileReport[]): void {
|
|
741
|
+
logStep('Tables')
|
|
742
|
+
logInfo(
|
|
743
|
+
`Cells past ${TABLE_CELL} characters, tables past ${TABLE_ROWS} body rows, a list directly after a table, and a code span in a cell holding a run past ${TABLE_TOKEN} characters.`,
|
|
744
|
+
)
|
|
745
|
+
logInfo(
|
|
746
|
+
'Measured on the paths density measures in full, so never on CLAUDE.md, outside fenced blocks. This never fails a run.',
|
|
747
|
+
)
|
|
748
|
+
|
|
749
|
+
const carrying = reports
|
|
750
|
+
.filter((report) => report.tables.length > 0)
|
|
751
|
+
.sort((a, b) => b.tables.length - a.tables.length)
|
|
752
|
+
|
|
753
|
+
if (carrying.length === 0) {
|
|
754
|
+
logInfo('No table finding.')
|
|
755
|
+
return
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
const total = carrying.reduce((sum, report) => sum + report.tables.length, 0)
|
|
759
|
+
logWarn(
|
|
760
|
+
`${plural(total, 'finding')} across ${plural(carrying.length, 'file')}`,
|
|
761
|
+
)
|
|
762
|
+
logInfo(
|
|
763
|
+
'Move a long cell into a bullet under the lead, split a long table into groups each under a lead sentence, give a trailing list its own lead, and move a wide token out of the table.',
|
|
764
|
+
)
|
|
765
|
+
pipeOutput(
|
|
766
|
+
carrying
|
|
767
|
+
.map(
|
|
768
|
+
(report) =>
|
|
769
|
+
`${report.rel} ${plural(report.tables.length, 'finding')}\n${report.tables
|
|
770
|
+
.map(describeTable)
|
|
771
|
+
.join('\n')}`,
|
|
772
|
+
)
|
|
773
|
+
.join('\n'),
|
|
774
|
+
)
|
|
775
|
+
}
|
|
776
|
+
|
|
698
777
|
const REFERENCE_SHAPE_LABELS: Record<ReferenceShapeKind, string> = {
|
|
699
778
|
'extra-section': 'section outside the shape',
|
|
700
779
|
'section-order': 'section out of order or repeated',
|