@erclx/canon 4.109.0 → 4.111.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 (33) hide show
  1. package/claude/.claude-plugin/plugin.json +1 -1
  2. package/claude/skills/{canon-feedback-file → canon-feedback}/REQUIREMENT.md +7 -6
  3. package/claude/skills/{canon-feedback-file → canon-feedback}/SKILL.md +9 -19
  4. package/claude/skills/canon-feedback-triage/REQUIREMENT.md +1 -1
  5. package/claude/skills/canon-feedback-triage/SKILL.md +1 -1
  6. package/claude/skills/canon-operator/REQUIREMENT.md +2 -2
  7. package/claude/skills/canon-operator/SKILL.md +3 -4
  8. package/claude/skills/draft-wiki/REQUIREMENT.md +42 -0
  9. package/claude/skills/draft-wiki/SKILL.md +83 -0
  10. package/claude/skills/git-issue/REQUIREMENT.md +1 -1
  11. package/claude/skills/git-issue/SKILL.md +1 -1
  12. package/claude/skills/target-check/references/domains.md +2 -2
  13. package/docs/agents/install-and-sync.md +4 -13
  14. package/docs/agents/teach.md +4 -2
  15. package/docs/target-projects.md +0 -2
  16. package/docs/workflow/ai-workflow.md +8 -11
  17. package/package.json +1 -1
  18. package/scripts/core/capture-home.sh +59 -0
  19. package/src/claude/cases/authoring.ts +5 -0
  20. package/src/claude/cases/setup.ts +3 -24
  21. package/src/commands/sync.ts +0 -16
  22. package/src/design/components.ts +459 -147
  23. package/src/shipped/references.ts +1 -2
  24. package/src/sync/reverse.ts +3 -74
  25. package/src/teach/nav.ts +410 -58
  26. package/claude/skills/migration-claude-md/REQUIREMENT.md +0 -40
  27. package/claude/skills/migration-claude-md/SKILL.md +0 -79
  28. package/claude/skills/migration-context/REQUIREMENT.md +0 -36
  29. package/claude/skills/migration-context/SKILL.md +0 -97
  30. package/claude/skills/migration-standards-drop/REQUIREMENT.md +0 -55
  31. package/claude/skills/migration-standards-drop/SKILL.md +0 -113
  32. package/claude/skills/migration-superseded/REQUIREMENT.md +0 -44
  33. package/claude/skills/migration-superseded/SKILL.md +0 -115
@@ -172,8 +172,7 @@ const DOCS_PATH = /(?<![\w./-])docs\/[^\s`)\]]*\.md\b/g
172
172
  * deliberate placeholder rather than a real citation. A body illustrating
173
173
  * the shape a project's own `standards/<name>.md` takes writes a bracketed
174
174
  * token this pattern also matches, such as `standards/<slug>.md` in
175
- * `create-standard/SKILL.md` or `standards/<name>.md` in
176
- * `migration-standards-drop/SKILL.md`, and neither names a real file. A bare,
175
+ * `create-standard/SKILL.md`, which names no real file. A bare,
177
176
  * non-bracketed match now reports whether or not the file exists, unlike
178
177
  * `DOCS_PATH`, which still gates on existence: a same-repository citation
179
178
  * under this corpus names no target project's own tree the way a `docs/`
@@ -1,4 +1,4 @@
1
- import { existsSync, readFileSync, statSync } from 'node:fs'
1
+ import { existsSync, statSync } from 'node:fs'
2
2
  import { join } from 'node:path'
3
3
  import { execaSync } from 'execa'
4
4
  import { gitEnv } from '@/git-env'
@@ -11,15 +11,6 @@ import {
11
11
 
12
12
  const CLAUDE_DIR = '.claude'
13
13
 
14
- /**
15
- * A `CLAUDE.md` past this many lines has more in it than the always-load tier
16
- * is for. The figure is the checkpoint `standards/context.md` sets for
17
- * a context entry, raised because `CLAUDE.md` legitimately carries more than
18
- * one domain. It gates a proposal rather than a failure, so being approximate
19
- * costs a line an operator can ignore.
20
- */
21
- const CLAUDE_MD_LINES = 250
22
-
23
14
  /**
24
15
  * Who put an unclaimed folder in the target. A dropped folder and one the
25
16
  * project wrote are the same bytes at the same path, so this is traced from the
@@ -45,26 +36,14 @@ export interface UnclaimedFolder {
45
36
  readonly since?: string
46
37
  }
47
38
 
48
- /**
49
- * A proposal-only skill with a live case in this target. The skills propose and
50
- * never execute, so the report names one rather than queueing a change.
51
- */
52
- export interface MigrationCandidate {
53
- readonly skill: string
54
- /** What was measured, so the proposal is checkable before it is run. */
55
- readonly reason: string
56
- }
57
-
58
39
  export interface ReverseReport {
59
40
  readonly unclaimed: readonly UnclaimedFolder[]
60
- readonly migrations: readonly MigrationCandidate[]
61
41
  /** Set when the walk needed history to run and this toolkit has none. */
62
42
  readonly historyUnavailable: boolean
63
43
  }
64
44
 
65
45
  const EMPTY_REVERSE: ReverseReport = {
66
46
  unclaimed: [],
67
- migrations: [],
68
47
  historyUnavailable: false,
69
48
  }
70
49
 
@@ -89,10 +68,9 @@ export function buildReverseReport(
89
68
  target: string,
90
69
  ): ReverseReport {
91
70
  const roots = readDroppedRoots(toolkitRoot)
92
- const migrations = detectMigrations(target)
93
71
 
94
72
  if (roots === undefined) {
95
- return { unclaimed: [], migrations, historyUnavailable: true }
73
+ return { unclaimed: [], historyUnavailable: true }
96
74
  }
97
75
 
98
76
  const unclaimed: UnclaimedFolder[] = []
@@ -106,7 +84,7 @@ export function buildReverseReport(
106
84
  }
107
85
  }
108
86
 
109
- return { unclaimed, migrations, historyUnavailable: false }
87
+ return { unclaimed, historyUnavailable: false }
110
88
  }
111
89
 
112
90
  export function emptyReverseReport(): ReverseReport {
@@ -206,55 +184,6 @@ function covers(index: HistoryIndex, sourceRel: string): boolean {
206
184
  return index.get(sourceRel) !== undefined
207
185
  }
208
186
 
209
- /**
210
- * Live cases for the two proposal-only skills no other report field names.
211
- * Without this, both are documented and unreachable.
212
- *
213
- * Both tests read what the skill itself acts on, so a proposal the report makes
214
- * is one the skill has work to do for. A context tier that already holds files
215
- * settles the `docs/` split, whether or not the toolkit is what made it.
216
- */
217
- export function detectMigrations(target: string): MigrationCandidate[] {
218
- const found: MigrationCandidate[] = []
219
- const claudeMd = join(target, 'CLAUDE.md')
220
-
221
- if (existsSync(claudeMd)) {
222
- const lines = countLines(readFileSync(claudeMd, 'utf8'))
223
- if (lines > CLAUDE_MD_LINES) {
224
- found.push({
225
- skill: 'migration-claude-md',
226
- reason: `CLAUDE.md carries ${lines} lines, past the ${CLAUDE_MD_LINES} the three-tier split is for`,
227
- })
228
- }
229
- }
230
-
231
- const docs = listFiles(join(target, 'docs')).filter(isMarkdown).length
232
- const context = listFiles(join(target, CLAUDE_DIR, 'context')).length
233
-
234
- if (docs > 0 && context === 0) {
235
- found.push({
236
- skill: 'migration-context',
237
- reason: `${docs} markdown files under docs/ with no canon/context/ tier`,
238
- })
239
- }
240
-
241
- return found
242
- }
243
-
244
- function isMarkdown(rel: string): boolean {
245
- return rel.endsWith('.md')
246
- }
247
-
248
- /**
249
- * Lines as `wc -l` counts them, so the figure in the reason matches what an
250
- * operator gets from the shell. Splitting alone overstates a file ending in a
251
- * newline by one, and the reason states a measurement rather than a rank.
252
- */
253
- function countLines(content: string): number {
254
- const parts = content.split('\n')
255
- return parts.at(-1) === '' ? parts.length - 1 : parts.length
256
- }
257
-
258
187
  /**
259
188
  * Every file under a directory, dotfiles included. A dropped root can hold any
260
189
  * extension, so this does not filter to markdown the way the domain walk does.