@erclx/canon 4.73.0 → 4.75.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/create-skill/SKILL.md +0 -1
- package/claude/skills/docs-fold/SKILL.md +1 -1
- package/claude/skills/git-followup/SKILL.md +9 -5
- package/claude/skills/git-pr/SKILL.md +21 -0
- package/claude/skills/markdown-propose/REQUIREMENT.md +1 -1
- package/claude/skills/markdown-propose/SKILL.md +9 -7
- package/claude/skills/markdown-propose/references/format.md +5 -3
- package/claude/skills/plan-feature/SKILL.md +3 -3
- package/claude/skills/plan-groundwork/SKILL.md +6 -5
- package/claude/skills/plan-intake/SKILL.md +1 -1
- package/claude/skills/review-pr/SKILL.md +2 -2
- package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +1 -0
- package/claude/skills/role-orchestrator/references/orchestrator-parked.md +2 -1
- package/claude/skills/role-orchestrator/scripts/poll.sh +16 -10
- package/claude/skills/task-board/SKILL.md +37 -3
- package/claude/skills/teach-workspace/references/lesson-craft.md +1 -6
- package/docs/agents/commands.md +2 -0
- package/docs/agents/index.md +2 -1
- package/docs/agents/install-and-sync.md +7 -4
- package/docs/agents/pr-evidence.md +108 -0
- package/docs/agents/records.md +29 -9
- package/docs/agents/tasks.md +2 -0
- package/docs/target-projects.md +4 -0
- package/governance/rules/ui/440-surface-capture.md +1 -0
- package/package.json +1 -1
- package/src/commands/design.ts +10 -2
- package/src/commands/pr.ts +220 -0
- package/src/commands/records.ts +138 -0
- package/src/commands/transcripts.ts +20 -3
- package/src/design/base.css +59 -0
- package/src/design/components.ts +80 -50
- package/src/design/fonts.ts +21 -0
- package/src/init/plan.ts +8 -1
- package/src/init/steps.ts +17 -0
- package/src/intake/folder.ts +1 -1
- package/src/pr/evidence.ts +171 -0
- package/src/records/backup.ts +110 -38
- package/src/records/ordinal.ts +243 -0
- package/src/records/validate.ts +28 -0
- package/src/tasks/answers.ts +10 -1
- package/src/teach/fonts.ts +9 -11
- package/src/transcripts/fetch.ts +31 -1
- package/standards/architecture.md +1 -0
- package/standards/figures.md +51 -0
- package/standards/groundwork.md +2 -1
- package/standards/index.md +1 -0
- package/standards/intake.md +2 -1
- package/standards/plan.md +1 -0
- package/standards/skill.md +1 -1
- package/tooling/base/configs/.husky/post-merge +27 -0
- package/tooling/claude/seeds/.claude/hooks/tasks-index.sh +5 -4
package/src/records/validate.ts
CHANGED
|
@@ -73,6 +73,7 @@ export const FINDING_KINDS = [
|
|
|
73
73
|
'item-incomplete',
|
|
74
74
|
'category-mismatch',
|
|
75
75
|
'operator-call-phrasing',
|
|
76
|
+
'batch-unsplit',
|
|
76
77
|
] as const
|
|
77
78
|
|
|
78
79
|
export type FindingKind = (typeof FINDING_KINDS)[number]
|
|
@@ -235,6 +236,18 @@ async function listFolders(dir: string): Promise<string[]> {
|
|
|
235
236
|
|
|
236
237
|
const PLAN_NAME = /^feature-[a-z0-9]+(-[a-z0-9]+)*\.md$/
|
|
237
238
|
const PLAN_TITLE = /^#[ \t]+Feature:[ \t]+\S/
|
|
239
|
+
const BATCH_LABEL = /^\*\*Batch\s+\d+\b.*\*\*/i
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Reads the raw text rather than `splitPlanSections`'s output, since a
|
|
243
|
+
* colon-bearing `**Batch 1: ...**` line is itself a `MARKER_LINE` and is
|
|
244
|
+
* already dropped from the split `Files to touch` section before any check
|
|
245
|
+
* sees it.
|
|
246
|
+
*/
|
|
247
|
+
export function hasStagedBatches(text: string): boolean {
|
|
248
|
+
return linesOutsideFences(text).some((line) => BATCH_LABEL.test(line.trim()))
|
|
249
|
+
}
|
|
250
|
+
|
|
238
251
|
/**
|
|
239
252
|
* An entry names a file and says something about it. Both halves are tested as
|
|
240
253
|
* facts rather than as a syntax: a backticked span anywhere, and prose left over
|
|
@@ -463,6 +476,21 @@ export function checkPlan(name: string, text: string): Finding[] {
|
|
|
463
476
|
|
|
464
477
|
findings.push(...checkQuestionContract(name, sections.get('Questions') ?? []))
|
|
465
478
|
|
|
479
|
+
if (hasStagedBatches(text)) {
|
|
480
|
+
const staged = linesOutsideFences(text).find((line) =>
|
|
481
|
+
BATCH_LABEL.test(line.trim()),
|
|
482
|
+
)
|
|
483
|
+
|
|
484
|
+
findings.push(
|
|
485
|
+
finding(
|
|
486
|
+
'batch-unsplit',
|
|
487
|
+
name,
|
|
488
|
+
shorten((staged ?? '').trim()),
|
|
489
|
+
"stages a batch inside one file, so the batch sharing this plan's branch has nothing left to open a pull request against once an earlier one merges. Split it into one plan file per batch.",
|
|
490
|
+
),
|
|
491
|
+
)
|
|
492
|
+
}
|
|
493
|
+
|
|
466
494
|
return findings
|
|
467
495
|
}
|
|
468
496
|
|
package/src/tasks/answers.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { isAbsolute, relative, resolve } from 'node:path'
|
|
|
4
4
|
import { isUnder } from '@/paths'
|
|
5
5
|
import { recordDir, recordDirs } from '@/record-root'
|
|
6
6
|
import {
|
|
7
|
+
hasStagedBatches,
|
|
7
8
|
normalizeOperatorCall,
|
|
8
9
|
OPERATOR_CALL,
|
|
9
10
|
readQuestions,
|
|
@@ -219,9 +220,17 @@ export async function planAnswers(
|
|
|
219
220
|
const resolved = resolvePlanReference(root, reference)
|
|
220
221
|
if (!resolved.ok) return resolved
|
|
221
222
|
|
|
222
|
-
const
|
|
223
|
+
const text = await readFile(resolved.path, 'utf8')
|
|
224
|
+
const sections = splitPlanSections(text)
|
|
223
225
|
const open = openQuestions(sections.get('Questions') ?? [])
|
|
224
226
|
|
|
227
|
+
if (hasStagedBatches(text)) {
|
|
228
|
+
open.push({
|
|
229
|
+
label: 'Batch staging',
|
|
230
|
+
why: 'stages a batch inside one file and must split into one plan file per batch before it can dispatch.',
|
|
231
|
+
})
|
|
232
|
+
}
|
|
233
|
+
|
|
225
234
|
return {
|
|
226
235
|
ok: true,
|
|
227
236
|
plan: resolved.plan,
|