@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.
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/{canon-feedback-file → canon-feedback}/REQUIREMENT.md +7 -6
- package/claude/skills/{canon-feedback-file → canon-feedback}/SKILL.md +9 -19
- package/claude/skills/canon-feedback-triage/REQUIREMENT.md +1 -1
- package/claude/skills/canon-feedback-triage/SKILL.md +1 -1
- package/claude/skills/canon-operator/REQUIREMENT.md +2 -2
- package/claude/skills/canon-operator/SKILL.md +3 -4
- package/claude/skills/draft-wiki/REQUIREMENT.md +42 -0
- package/claude/skills/draft-wiki/SKILL.md +83 -0
- package/claude/skills/git-issue/REQUIREMENT.md +1 -1
- package/claude/skills/git-issue/SKILL.md +1 -1
- package/claude/skills/target-check/references/domains.md +2 -2
- package/docs/agents/install-and-sync.md +4 -13
- package/docs/agents/teach.md +4 -2
- package/docs/target-projects.md +0 -2
- package/docs/workflow/ai-workflow.md +8 -11
- package/package.json +1 -1
- package/scripts/core/capture-home.sh +59 -0
- package/src/claude/cases/authoring.ts +5 -0
- package/src/claude/cases/setup.ts +3 -24
- package/src/commands/sync.ts +0 -16
- package/src/design/components.ts +459 -147
- package/src/shipped/references.ts +1 -2
- package/src/sync/reverse.ts +3 -74
- package/src/teach/nav.ts +410 -58
- package/claude/skills/migration-claude-md/REQUIREMENT.md +0 -40
- package/claude/skills/migration-claude-md/SKILL.md +0 -79
- package/claude/skills/migration-context/REQUIREMENT.md +0 -36
- package/claude/skills/migration-context/SKILL.md +0 -97
- package/claude/skills/migration-standards-drop/REQUIREMENT.md +0 -55
- package/claude/skills/migration-standards-drop/SKILL.md +0 -113
- package/claude/skills/migration-superseded/REQUIREMENT.md +0 -44
- 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
|
|
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/`
|
package/src/sync/reverse.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { existsSync,
|
|
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: [],
|
|
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,
|
|
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.
|