@milehimikey/em 1.8.0 → 1.9.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/skills/event-modeling/SKILL.md +58 -404
- package/.claude/skills/event-modeling-conform/SKILL.md +77 -0
- package/.claude/skills/{event-modeling → event-modeling-conform}/reference/conform.md +39 -13
- package/.claude/skills/event-modeling-design/SKILL.md +139 -0
- package/.claude/skills/event-modeling-discover/SKILL.md +89 -0
- package/.claude/skills/{event-modeling → event-modeling-discover}/reference/extract.md +3 -2
- package/.claude/skills/event-modeling-implement/SKILL.md +40 -0
- package/.claude/skills/{event-modeling → event-modeling-implement}/reference/implement.md +3 -2
- package/.claude/skills/event-modeling-review/SKILL.md +58 -0
- package/.claude/skills/{event-modeling → event-modeling-shared}/reference/em-dsl.md +128 -84
- package/.claude/skills/{event-modeling → event-modeling-shared}/reference/methodology.md +6 -5
- package/.claude/skills/event-modeling-shared/reference/operating-principles.md +147 -0
- package/.claude/skills/{event-modeling → event-modeling-shared}/templates/model-readme.md +2 -2
- package/.claude/skills/{event-modeling → event-modeling-shared}/templates/slice.md +51 -8
- package/README.md +24 -4
- package/dist/catalog/build.js +9 -0
- package/dist/catalog/build.js.map +1 -1
- package/dist/catalog/docJoin.d.ts +15 -0
- package/dist/catalog/docJoin.js +8 -0
- package/dist/catalog/docJoin.js.map +1 -1
- package/dist/catalog/modelCollisionValidate.d.ts +22 -0
- package/dist/catalog/modelCollisionValidate.js +67 -0
- package/dist/catalog/modelCollisionValidate.js.map +1 -0
- package/dist/catalog/orphanedSliceDocValidate.d.ts +11 -0
- package/dist/catalog/orphanedSliceDocValidate.js +98 -0
- package/dist/catalog/orphanedSliceDocValidate.js.map +1 -0
- package/dist/catalog/sliceDoc.d.ts +15 -0
- package/dist/catalog/sliceDoc.js +18 -0
- package/dist/catalog/sliceDoc.js.map +1 -1
- package/dist/cli/changelogBuild.d.ts +12 -0
- package/dist/cli/changelogBuild.js +89 -0
- package/dist/cli/changelogBuild.js.map +1 -0
- package/dist/cli/ciInit.d.ts +42 -0
- package/dist/cli/ciInit.js +298 -0
- package/dist/cli/ciInit.js.map +1 -0
- package/dist/cli/conformSupersede.d.ts +32 -0
- package/dist/cli/conformSupersede.js +102 -0
- package/dist/cli/conformSupersede.js.map +1 -0
- package/dist/cli/coverage.d.ts +17 -10
- package/dist/cli/coverage.js +61 -16
- package/dist/cli/coverage.js.map +1 -1
- package/dist/cli/frontmatterSurgery.d.ts +28 -0
- package/dist/cli/frontmatterSurgery.js +66 -0
- package/dist/cli/frontmatterSurgery.js.map +1 -0
- package/dist/cli/markImplemented.js +6 -45
- package/dist/cli/markImplemented.js.map +1 -1
- package/dist/cli/ratify.d.ts +41 -0
- package/dist/cli/ratify.js +151 -0
- package/dist/cli/ratify.js.map +1 -0
- package/dist/cli/reratify.d.ts +33 -0
- package/dist/cli/reratify.js +137 -0
- package/dist/cli/reratify.js.map +1 -0
- package/dist/cli/skillCheck.d.ts +6 -0
- package/dist/cli/skillCheck.js +46 -0
- package/dist/cli/skillCheck.js.map +1 -1
- package/dist/cli/skillDirs.d.ts +15 -0
- package/dist/cli/skillDirs.js +34 -0
- package/dist/cli/skillDirs.js.map +1 -0
- package/dist/cli/skillSync.d.ts +10 -0
- package/dist/cli/skillSync.js +15 -0
- package/dist/cli/skillSync.js.map +1 -1
- package/dist/cli/sliceIndex.d.ts +3 -0
- package/dist/cli/sliceIndex.js +6 -2
- package/dist/cli/sliceIndex.js.map +1 -1
- package/dist/cli/sliceLink.d.ts +52 -0
- package/dist/cli/sliceLink.js +152 -0
- package/dist/cli/sliceLink.js.map +1 -0
- package/dist/cli/status.d.ts +261 -0
- package/dist/cli/status.js +536 -0
- package/dist/cli/status.js.map +1 -0
- package/dist/cli/usageLog.d.ts +75 -0
- package/dist/cli/usageLog.js +193 -0
- package/dist/cli/usageLog.js.map +1 -0
- package/dist/cli.js +501 -130
- package/dist/cli.js.map +1 -1
- package/dist/emit/diffJson.d.ts +9 -1
- package/dist/emit/diffJson.js +44 -1
- package/dist/emit/diffJson.js.map +1 -1
- package/dist/emit/freshnessJson.d.ts +6 -0
- package/dist/emit/freshnessJson.js +24 -0
- package/dist/emit/freshnessJson.js.map +1 -0
- package/dist/emit/json.d.ts +67 -8
- package/dist/emit/json.js +19 -3
- package/dist/emit/json.js.map +1 -1
- package/dist/emit/statusJson.d.ts +7 -0
- package/dist/emit/statusJson.js +39 -0
- package/dist/emit/statusJson.js.map +1 -0
- package/dist/emit/typespec.d.ts +26 -0
- package/dist/emit/typespec.js +356 -0
- package/dist/emit/typespec.js.map +1 -0
- package/dist/emit/usageReportJson.d.ts +3 -0
- package/dist/emit/usageReportJson.js +23 -0
- package/dist/emit/usageReportJson.js.map +1 -0
- package/dist/mcp/server.d.ts +1 -1
- package/dist/mcp/server.js +301 -11
- package/dist/mcp/server.js.map +1 -1
- package/dist/model/rules.d.ts +13 -0
- package/dist/model/rules.js +20 -0
- package/dist/model/rules.js.map +1 -1
- package/dist/model/validate.js +9 -1
- package/dist/model/validate.js.map +1 -1
- package/dist/parser/ast.d.ts +6 -0
- package/dist/parser/parser.js +20 -6
- package/dist/parser/parser.js.map +1 -1
- package/dist/render/drawNotes.d.ts +11 -1
- package/dist/render/drawNotes.js +20 -2
- package/dist/render/drawNotes.js.map +1 -1
- package/dist/render/render.js +31 -6
- package/dist/render/render.js.map +1 -1
- package/dist/render/serve.js +4 -0
- package/dist/render/serve.js.map +1 -1
- package/dist/render/sliceOverlay.d.ts +7 -2
- package/dist/render/sliceOverlay.js +19 -7
- package/dist/render/sliceOverlay.js.map +1 -1
- package/dist/render/sliceStatus.d.ts +7 -3
- package/dist/render/sliceStatus.js +21 -14
- package/dist/render/sliceStatus.js.map +1 -1
- package/dist/render/viewerHtml.js +1 -1
- package/dist/render/viewerHtml.js.map +1 -1
- package/dist/templates.d.ts +2 -2
- package/dist/templates.js +5 -5
- package/dist/util/markers.d.ts +16 -4
- package/dist/util/markers.js +23 -10
- package/dist/util/markers.js.map +1 -1
- package/package.json +2 -1
- /package/.claude/skills/{event-modeling → event-modeling-shared}/templates/conformance-report.md +0 -0
- /package/.claude/skills/{event-modeling → event-modeling-shared}/templates/state.md +0 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// `em slice reratify` (MIL-161 finding #4): the version-bump / status-flip mechanical edit
|
|
3
|
+
// SKILL.md's `slice` phase (step 0/2, re-ratification) has always described as "bump `version`
|
|
4
|
+
// and flip `status` back to `ready-to-implement` by hand" — the same shape `em slice
|
|
5
|
+
// mark-implemented` (MIL-103) already mechanized at the OTHER end of the lifecycle (the merge-
|
|
6
|
+
// time flip). Sets exactly two frontmatter fields on the doc resolved from the key via the SAME
|
|
7
|
+
// note-binding resolution `mark-implemented`/`ratify`/`--slice-ready`/`em export` use
|
|
8
|
+
// (catalog/docJoin.ts's resolveSliceDocJoin):
|
|
9
|
+
//
|
|
10
|
+
// version: <current + 1>
|
|
11
|
+
// status: ready-to-implement
|
|
12
|
+
//
|
|
13
|
+
// Only applies to a doc currently `status: implemented` — the precondition
|
|
14
|
+
// docs/slice-doc-schema.md#status-under-re-ratification describes ("a new version is ratified
|
|
15
|
+
// for a slice whose previous version already shipped"). Refuses (never guesses) otherwise: a
|
|
16
|
+
// `draft`/`reviewed` doc hasn't shipped yet, so there's no prior version to bump FROM, and a
|
|
17
|
+
// doc already `ready-to-implement` means either first-time authoring (never touch this doc with
|
|
18
|
+
// reratify at all — `em slice new` is what scaffolds those) or a reratify that already ran (a
|
|
19
|
+
// second bump would silently double-increment `version`, which this command deliberately never
|
|
20
|
+
// does — bumping isn't naturally idempotent the way ratify/mark-implemented's absolute-value
|
|
21
|
+
// writes are).
|
|
22
|
+
//
|
|
23
|
+
// Also clears `ratifiedBy:`/`ratifiedOn:` if either is present: those fields record who signed
|
|
24
|
+
// off the PRIOR version (`em slice ratify`, MIL-165) and describing the brand-new, not-yet-
|
|
25
|
+
// reviewed version as already ratified by the old signer would be actively misleading. Clearing
|
|
26
|
+
// them (rather than leaving them stale) is also what lets a subsequent `em slice ratify --by
|
|
27
|
+
// <name>` apply cleanly afterward — ratify's own idempotent-refusal guard would otherwise read
|
|
28
|
+
// the leftover prior ratifiedBy/ratifiedOn as "already ratified by someone else" and refuse.
|
|
29
|
+
//
|
|
30
|
+
// Write strategy: the same surgical index-math splicing markImplemented.ts/ratify.ts use, via
|
|
31
|
+
// the shared primitives in ./frontmatterSurgery.js — never a parse+re-serialize. Everything
|
|
32
|
+
// outside the edited value spans — the body, `implementedIn:`, the lineage/`covers` keys, and
|
|
33
|
+
// (best-effort) the file's own line-ending style — is copied through verbatim. The `## Delta`
|
|
34
|
+
// section (docs/slice-doc-schema.md#delta-section-grammar-and-lifecycle) recording WHAT changed
|
|
35
|
+
// stays entirely hand-authored — this command only ever touches the two lifecycle fields above.
|
|
36
|
+
import { readFileSync, writeFileSync } from "node:fs";
|
|
37
|
+
import { join } from "node:path";
|
|
38
|
+
import { resolveSliceDocJoin } from "../catalog/docJoin.js";
|
|
39
|
+
import { fieldLineRegex, fieldLineWithEolRegex, locateFrontmatterInner, normalizeFieldValue } from "./frontmatterSurgery.js";
|
|
40
|
+
/** The status a doc must already be in for `reratify` to apply — mirrors `RATIFIED_STATUS` in
|
|
41
|
+
* ratify.ts (the status this command flips TO), named separately since it's the precondition
|
|
42
|
+
* here, not the target. */
|
|
43
|
+
const IMPLEMENTED_STATUS = "implemented";
|
|
44
|
+
const TARGET_STATUS = "ready-to-implement";
|
|
45
|
+
/**
|
|
46
|
+
* Pure text transform: bumps `version:` by 1 and flips `status:` to `ready-to-implement` in
|
|
47
|
+
* `raw`'s frontmatter block, clearing any `ratifiedBy:`/`ratifiedOn:` lines found (see module
|
|
48
|
+
* header). Refuses (`ok: false`) unless the doc's CURRENT `status:` is exactly `implemented` —
|
|
49
|
+
* see module header for why this precondition (not idempotent-no-op) is the right refusal
|
|
50
|
+
* shape here. No fs access — the caller reads/writes; see `runReratify` below.
|
|
51
|
+
*/
|
|
52
|
+
export function applyReratifyFrontmatter(raw) {
|
|
53
|
+
const range = locateFrontmatterInner(raw);
|
|
54
|
+
if (!range)
|
|
55
|
+
return { ok: false, message: "no frontmatter block found" };
|
|
56
|
+
const inner = raw.slice(range.innerStart, range.innerEnd);
|
|
57
|
+
const statusMatch = fieldLineRegex("status").exec(inner);
|
|
58
|
+
if (!statusMatch)
|
|
59
|
+
return { ok: false, message: "no `status:` field found in frontmatter" };
|
|
60
|
+
const currentStatus = normalizeFieldValue(statusMatch[2])?.toLowerCase() ?? null;
|
|
61
|
+
if (currentStatus !== IMPLEMENTED_STATUS) {
|
|
62
|
+
return {
|
|
63
|
+
ok: false,
|
|
64
|
+
message: `doc is \`status: ${currentStatus ?? "(empty)"}\`, not \`implemented\` — reratify only applies to a ` +
|
|
65
|
+
"slice doc that has already shipped (see docs/slice-doc-schema.md#status-under-re-ratification); " +
|
|
66
|
+
"first-time authoring uses `em slice new`, and a doc already `ready-to-implement` may already " +
|
|
67
|
+
"have been reratified",
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
const versionMatch = fieldLineRegex("version").exec(inner);
|
|
71
|
+
if (!versionMatch)
|
|
72
|
+
return { ok: false, message: "no `version:` field found in frontmatter" };
|
|
73
|
+
const currentVersionRaw = normalizeFieldValue(versionMatch[2]);
|
|
74
|
+
const currentVersion = currentVersionRaw !== null ? Number(currentVersionRaw) : NaN;
|
|
75
|
+
if (!Number.isInteger(currentVersion) || currentVersion < 1) {
|
|
76
|
+
return {
|
|
77
|
+
ok: false,
|
|
78
|
+
message: `doc's \`version:\` value "${currentVersionRaw ?? ""}" isn't a positive integer — refusing to guess a bump`,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
const newVersion = currentVersion + 1;
|
|
82
|
+
// Apply from the highest index first so an earlier edit's index stays valid — same convention
|
|
83
|
+
// markImplemented.ts/ratify.ts use.
|
|
84
|
+
const edits = [
|
|
85
|
+
{ index: statusMatch.index, oldLen: statusMatch[0].length, next: `${statusMatch[1]}${TARGET_STATUS}` },
|
|
86
|
+
{ index: versionMatch.index, oldLen: versionMatch[0].length, next: `${versionMatch[1]}${newVersion}` },
|
|
87
|
+
].sort((a, b) => b.index - a.index);
|
|
88
|
+
let updatedInner = inner;
|
|
89
|
+
for (const edit of edits) {
|
|
90
|
+
updatedInner = updatedInner.slice(0, edit.index) + edit.next + updatedInner.slice(edit.index + edit.oldLen);
|
|
91
|
+
}
|
|
92
|
+
// Clear stale ratifiedBy:/ratifiedOn: — see module header. A plain `.replace()` (not
|
|
93
|
+
// index-spliced alongside the edits above) is safe here: these two keys are disjoint from
|
|
94
|
+
// `status:`/`version:` by construction (fieldLineRegex matches one key at a time), so removing
|
|
95
|
+
// them from the ALREADY-updated text can't disturb the edits just applied.
|
|
96
|
+
updatedInner = updatedInner.replace(fieldLineWithEolRegex("ratifiedBy"), "").replace(fieldLineWithEolRegex("ratifiedOn"), "");
|
|
97
|
+
const content = raw.slice(0, range.innerStart) + updatedInner + raw.slice(range.innerEnd);
|
|
98
|
+
return { ok: true, content, newVersion };
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Resolves `sliceKey` to its bound doc via the same note-binding join `mark-implemented`/
|
|
102
|
+
* `ratify`/`--slice-ready`/`em export` use (MIL-121 cross-binding included), then reads/applies/
|
|
103
|
+
* writes it. `baseDir` is the `.em` file's directory, same convention every doc/note path in
|
|
104
|
+
* `em` uses.
|
|
105
|
+
*/
|
|
106
|
+
export function runReratify(model, refs, baseDir, sliceKey) {
|
|
107
|
+
const sliceIndex = refs.sliceKeys.indexOf(sliceKey);
|
|
108
|
+
if (sliceIndex === -1) {
|
|
109
|
+
return { ok: false, message: `no slice with export key "${sliceKey}" in this model` };
|
|
110
|
+
}
|
|
111
|
+
const slice = model.slices[sliceIndex];
|
|
112
|
+
const { doc } = resolveSliceDocJoin(slice, sliceKey, baseDir, (id) => refs.refById.get(id));
|
|
113
|
+
if (doc.reason === "no-doc-bound") {
|
|
114
|
+
return {
|
|
115
|
+
ok: false,
|
|
116
|
+
message: `slice "${sliceKey}" has no doc bound via \`note "slices/${sliceKey}.md"\` — bind a slice doc before reratifying it`,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
if (doc.reason === "binding-missing-file") {
|
|
120
|
+
return { ok: false, message: `slice "${sliceKey}" notes "${doc.path}" but no such file exists` };
|
|
121
|
+
}
|
|
122
|
+
if (doc.reason === "frontmatter-invalid") {
|
|
123
|
+
return {
|
|
124
|
+
ok: false,
|
|
125
|
+
message: `slice doc "${doc.path}" has missing or invalid frontmatter — run \`em validate\` for details`,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
const absPath = join(baseDir, doc.path);
|
|
129
|
+
const raw = readFileSync(absPath, "utf8");
|
|
130
|
+
const result = applyReratifyFrontmatter(raw);
|
|
131
|
+
if (!result.ok) {
|
|
132
|
+
return { ok: false, message: `${doc.path}: ${result.message}` };
|
|
133
|
+
}
|
|
134
|
+
writeFileSync(absPath, result.content, "utf8");
|
|
135
|
+
return { ok: true, path: doc.path, newVersion: result.newVersion };
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=reratify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reratify.js","sourceRoot":"","sources":["../../src/cli/reratify.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/skillCheck.d.ts
CHANGED
|
@@ -16,3 +16,9 @@ export interface SkillCheckResult {
|
|
|
16
16
|
* em-version: stamp. No process.exit, no console.
|
|
17
17
|
*/
|
|
18
18
|
export declare function checkSkillSync(packagedDir: string, vendoredDir: string, installedVersion: string): SkillCheckResult;
|
|
19
|
+
/**
|
|
20
|
+
* Pure: checkSkillSync for every stamp-checked skill directory, plus content-drift-only
|
|
21
|
+
* (planSkillSync) for every shared directory. Same `SkillCheckResult` shape as checkSkillSync
|
|
22
|
+
* itself — a bundle check is just several single-directory checks with prefixed findings.
|
|
23
|
+
*/
|
|
24
|
+
export declare function checkSkillSyncBundle(packagedRoot: string, vendoredRoot: string, installedVersion: string, skillDirNames: readonly string[], sharedDirNames: readonly string[]): SkillCheckResult;
|
package/dist/cli/skillCheck.js
CHANGED
|
@@ -60,4 +60,50 @@ export function checkSkillSync(packagedDir, vendoredDir, installedVersion) {
|
|
|
60
60
|
}
|
|
61
61
|
return { findings, ok: findings.length === 0 };
|
|
62
62
|
}
|
|
63
|
+
// ---- Bundle variant (MIL-157) — the em skill ships as several sibling directories under
|
|
64
|
+
// `.claude/skills/` (see src/cli/skillDirs.ts): the stamp-checked skill directories (each with
|
|
65
|
+
// its own SKILL.md) and the shared, non-skill directories (reference/template material with no
|
|
66
|
+
// SKILL.md, so no stamp to check — content drift only). Findings from every directory are
|
|
67
|
+
// prefixed with `[<dirName>]` and their `driftedFiles` with `<dirName>/`, so a single aggregated
|
|
68
|
+
// report still tells you exactly which directory each finding concerns.
|
|
69
|
+
function prefixFinding(dirName, f) {
|
|
70
|
+
return {
|
|
71
|
+
...f,
|
|
72
|
+
message: `[${dirName}] ${f.message}`,
|
|
73
|
+
driftedFiles: f.driftedFiles?.map((p) => `${dirName}/${p}`),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Pure: checkSkillSync for every stamp-checked skill directory, plus content-drift-only
|
|
78
|
+
* (planSkillSync) for every shared directory. Same `SkillCheckResult` shape as checkSkillSync
|
|
79
|
+
* itself — a bundle check is just several single-directory checks with prefixed findings.
|
|
80
|
+
*/
|
|
81
|
+
export function checkSkillSyncBundle(packagedRoot, vendoredRoot, installedVersion, skillDirNames, sharedDirNames) {
|
|
82
|
+
const findings = [];
|
|
83
|
+
for (const name of skillDirNames) {
|
|
84
|
+
const result = checkSkillSync(join(packagedRoot, name), join(vendoredRoot, name), installedVersion);
|
|
85
|
+
for (const f of result.findings)
|
|
86
|
+
findings.push(prefixFinding(name, f));
|
|
87
|
+
}
|
|
88
|
+
for (const name of sharedDirNames) {
|
|
89
|
+
const vendoredDir = join(vendoredRoot, name);
|
|
90
|
+
if (!existsSync(vendoredDir)) {
|
|
91
|
+
findings.push(prefixFinding(name, {
|
|
92
|
+
code: "skill-check-not-installed",
|
|
93
|
+
message: `no vendored skill found at ${vendoredDir} — run \`em skill sync\` first`,
|
|
94
|
+
}));
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
const plan = planSkillSync(join(packagedRoot, name), vendoredDir);
|
|
98
|
+
if (plan.changes.length > 0) {
|
|
99
|
+
const driftedFiles = plan.changes.map((c) => c.relPath).sort();
|
|
100
|
+
findings.push(prefixFinding(name, {
|
|
101
|
+
code: "skill-check-content-drift",
|
|
102
|
+
message: `vendored skill differs from the packaged skill in ${driftedFiles.length} file(s) — run \`em skill sync\``,
|
|
103
|
+
driftedFiles,
|
|
104
|
+
}));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return { findings, ok: findings.length === 0 };
|
|
108
|
+
}
|
|
63
109
|
//# sourceMappingURL=skillCheck.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skillCheck.js","sourceRoot":"","sources":["../../src/cli/skillCheck.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,6FAA6F;AAC7F,0FAA0F;AAC1F,6FAA6F;AAC7F,6FAA6F;AAC7F,kFAAkF;AAClF,uDAAuD;AACvD,EAAE;AACF,+EAA+E;AAC/E,kFAAkF;AAClF,+FAA+F;AAC/F,0FAA0F;AAC1F,iEAAiE;AAEjE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAqB/C;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,WAAmB,EAAE,WAAmB,EAAE,gBAAwB;IAC/F,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,OAAO;YACL,EAAE,EAAE,KAAK;YACT,QAAQ,EAAE;gBACR;oBACE,IAAI,EAAE,2BAA2B;oBACjC,OAAO,EAAE,8BAA8B,WAAW,gCAAgC;iBACnF;aACF;SACF,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAwB,EAAE,CAAC;IAEzC,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,CAAC;IAClD,MAAM,aAAa,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAEhH,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;QAC3B,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,2BAA2B;YACjC,OAAO,EAAE,GAAG,WAAW,8EAA8E;SACtG,CAAC,CAAC;IACL,CAAC;SAAM,IAAI,aAAa,KAAK,gBAAgB,EAAE,CAAC;QAC9C,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,4BAA4B;YAClC,OAAO,EAAE,uCAAuC,aAAa,iCAAiC,gBAAgB,2BAA2B;YACzI,aAAa;YACb,gBAAgB;SACjB,CAAC,CAAC;IACL,CAAC;IAED,MAAM,IAAI,GAAG,aAAa,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IACrD,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/D,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,2BAA2B;YACjC,OAAO,EAAE,qDAAqD,YAAY,CAAC,MAAM,kCAAkC;YACnH,YAAY;SACb,CAAC,CAAC;IACL,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;AACjD,CAAC"}
|
|
1
|
+
{"version":3,"file":"skillCheck.js","sourceRoot":"","sources":["../../src/cli/skillCheck.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Directories with their own SKILL.md (a `name:`/`description:`/`em-version:` frontmatter and
|
|
2
|
+
* Claude Code entry point). Order is display order only, not load-bearing. */
|
|
3
|
+
export declare const EM_SKILL_DIR_NAMES: readonly string[];
|
|
4
|
+
/** Directories with no SKILL.md of their own — shared reference/template material every skill
|
|
5
|
+
* above points back to instead of duplicating. Still part of the sync/check bundle (content
|
|
6
|
+
* drift matters here too), just never stamp-checked for an `em-version:` frontmatter that
|
|
7
|
+
* doesn't exist. */
|
|
8
|
+
export declare const EM_SHARED_DIR_NAMES: readonly string[];
|
|
9
|
+
/** Every directory `em skill install`/`sync`/`check` treat as part of the one bundle. */
|
|
10
|
+
export declare const EM_ALL_SKILL_BUNDLE_DIRS: readonly string[];
|
|
11
|
+
/** The one directory whose presence/absence gates the bundle as a whole (used by `em skill
|
|
12
|
+
* install`'s already-installed check and `em ci init`'s generated CI gate) — the router skill,
|
|
13
|
+
* since it's the fixed entry point every consumer's `/event-modeling` resolves to regardless of
|
|
14
|
+
* which other skills in the bundle they've actually used. */
|
|
15
|
+
export declare const EM_SKILL_ANCHOR_DIR = "event-modeling";
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// The set of directories under `.claude/skills/` that together make up the em-bundled
|
|
3
|
+
// event-modeling skill (MIL-157): five focused, SDLC-stage skills plus the thin `event-modeling`
|
|
4
|
+
// router skill that preserves `/event-modeling` as a single resumable entry point, and one
|
|
5
|
+
// non-skill directory (`event-modeling-shared`, no SKILL.md) holding reference/template material
|
|
6
|
+
// every skill points back to instead of duplicating. `em skill install`/`sync`/`check` treat this
|
|
7
|
+
// whole set as one atomic bundle — installing/syncing/checking all of it in one command, exactly
|
|
8
|
+
// like before the split (MIL-93) — so a consumer repo's `.claude/skills/` never needs per-skill
|
|
9
|
+
// awareness, and unrelated skills already living in that directory (this em bundle isn't the only
|
|
10
|
+
// thing that can be there) are never touched: only these named directories are ever walked, never
|
|
11
|
+
// `.claude/skills/` wholesale.
|
|
12
|
+
/** Directories with their own SKILL.md (a `name:`/`description:`/`em-version:` frontmatter and
|
|
13
|
+
* Claude Code entry point). Order is display order only, not load-bearing. */
|
|
14
|
+
export const EM_SKILL_DIR_NAMES = [
|
|
15
|
+
"event-modeling",
|
|
16
|
+
"event-modeling-discover",
|
|
17
|
+
"event-modeling-design",
|
|
18
|
+
"event-modeling-implement",
|
|
19
|
+
"event-modeling-conform",
|
|
20
|
+
"event-modeling-review",
|
|
21
|
+
];
|
|
22
|
+
/** Directories with no SKILL.md of their own — shared reference/template material every skill
|
|
23
|
+
* above points back to instead of duplicating. Still part of the sync/check bundle (content
|
|
24
|
+
* drift matters here too), just never stamp-checked for an `em-version:` frontmatter that
|
|
25
|
+
* doesn't exist. */
|
|
26
|
+
export const EM_SHARED_DIR_NAMES = ["event-modeling-shared"];
|
|
27
|
+
/** Every directory `em skill install`/`sync`/`check` treat as part of the one bundle. */
|
|
28
|
+
export const EM_ALL_SKILL_BUNDLE_DIRS = [...EM_SKILL_DIR_NAMES, ...EM_SHARED_DIR_NAMES];
|
|
29
|
+
/** The one directory whose presence/absence gates the bundle as a whole (used by `em skill
|
|
30
|
+
* install`'s already-installed check and `em ci init`'s generated CI gate) — the router skill,
|
|
31
|
+
* since it's the fixed entry point every consumer's `/event-modeling` resolves to regardless of
|
|
32
|
+
* which other skills in the bundle they've actually used. */
|
|
33
|
+
export const EM_SKILL_ANCHOR_DIR = "event-modeling";
|
|
34
|
+
//# sourceMappingURL=skillDirs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skillDirs.js","sourceRoot":"","sources":["../../src/cli/skillDirs.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,sFAAsF;AACtF,iGAAiG;AACjG,2FAA2F;AAC3F,iGAAiG;AACjG,kGAAkG;AAClG,iGAAiG;AACjG,gGAAgG;AAChG,kGAAkG;AAClG,kGAAkG;AAClG,+BAA+B;AAE/B;+EAC+E;AAC/E,MAAM,CAAC,MAAM,kBAAkB,GAAsB;IACnD,gBAAgB;IAChB,yBAAyB;IACzB,uBAAuB;IACvB,0BAA0B;IAC1B,wBAAwB;IACxB,uBAAuB;CACxB,CAAC;AAEF;;;qBAGqB;AACrB,MAAM,CAAC,MAAM,mBAAmB,GAAsB,CAAC,uBAAuB,CAAC,CAAC;AAEhF,yFAAyF;AACzF,MAAM,CAAC,MAAM,wBAAwB,GAAsB,CAAC,GAAG,kBAAkB,EAAE,GAAG,mBAAmB,CAAC,CAAC;AAE3G;;;8DAG8D;AAC9D,MAAM,CAAC,MAAM,mBAAmB,GAAG,gBAAgB,CAAC"}
|
package/dist/cli/skillSync.d.ts
CHANGED
|
@@ -20,3 +20,13 @@ export declare function planSkillSync(packagedDir: string, vendoredDir: string):
|
|
|
20
20
|
* with no changes is a no-op. Creates vendoredDir (and any needed subdirectories) as needed.
|
|
21
21
|
*/
|
|
22
22
|
export declare function applySkillSync(plan: SkillSyncPlan, packagedDir: string, vendoredDir: string): void;
|
|
23
|
+
export interface SkillSyncBundleDirPlan {
|
|
24
|
+
dirName: string;
|
|
25
|
+
plan: SkillSyncPlan;
|
|
26
|
+
}
|
|
27
|
+
/** Pure: one planSkillSync call per named directory, paired with the directory name so the
|
|
28
|
+
* caller can report/apply per directory. No fs writes. */
|
|
29
|
+
export declare function planSkillSyncBundle(packagedRoot: string, vendoredRoot: string, dirNames: readonly string[]): SkillSyncBundleDirPlan[];
|
|
30
|
+
/** Shell: applies every directory's plan from planSkillSyncBundle. Same idempotency/no-merge
|
|
31
|
+
* contract as applySkillSync, just looped. */
|
|
32
|
+
export declare function applySkillSyncBundle(bundlePlan: SkillSyncBundleDirPlan[], packagedRoot: string, vendoredRoot: string): void;
|
package/dist/cli/skillSync.js
CHANGED
|
@@ -66,4 +66,19 @@ export function applySkillSync(plan, packagedDir, vendoredDir) {
|
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
|
+
/** Pure: one planSkillSync call per named directory, paired with the directory name so the
|
|
70
|
+
* caller can report/apply per directory. No fs writes. */
|
|
71
|
+
export function planSkillSyncBundle(packagedRoot, vendoredRoot, dirNames) {
|
|
72
|
+
return dirNames.map((dirName) => ({
|
|
73
|
+
dirName,
|
|
74
|
+
plan: planSkillSync(join(packagedRoot, dirName), join(vendoredRoot, dirName)),
|
|
75
|
+
}));
|
|
76
|
+
}
|
|
77
|
+
/** Shell: applies every directory's plan from planSkillSyncBundle. Same idempotency/no-merge
|
|
78
|
+
* contract as applySkillSync, just looped. */
|
|
79
|
+
export function applySkillSyncBundle(bundlePlan, packagedRoot, vendoredRoot) {
|
|
80
|
+
for (const { dirName, plan } of bundlePlan) {
|
|
81
|
+
applySkillSync(plan, join(packagedRoot, dirName), join(vendoredRoot, dirName));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
69
84
|
//# sourceMappingURL=skillSync.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"skillSync.js","sourceRoot":"","sources":["../../src/cli/skillSync.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"skillSync.js","sourceRoot":"","sources":["../../src/cli/skillSync.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/sliceIndex.d.ts
CHANGED
package/dist/cli/sliceIndex.js
CHANGED
|
@@ -16,8 +16,8 @@ import { applyMarker } from "../util/markers.js";
|
|
|
16
16
|
/** The marker name wrapping the Slices table: `<!-- GENERATED:slices:start -->` /
|
|
17
17
|
* `<!-- GENERATED:slices:end -->`, matching templates/model-readme.md. */
|
|
18
18
|
export const SLICE_INDEX_MARKER = "slices";
|
|
19
|
-
const TABLE_HEADER = "| # | Slice | Pattern | Status | Implemented in | Design doc |\n" +
|
|
20
|
-
"
|
|
19
|
+
const TABLE_HEADER = "| # | Slice | Pattern | Status | Ratified by | Owner | Tracking | Implemented in | Design doc |\n" +
|
|
20
|
+
"|---|-------|---------|--------|-------------|-------|----------|----------------|------------|";
|
|
21
21
|
/** Escape characters that would break a markdown table cell: `|` (the column separator) and
|
|
22
22
|
* newlines (a slice name is always one line, but a doc's freeform `implementedIn` text isn't
|
|
23
23
|
* guaranteed to be). */
|
|
@@ -53,11 +53,15 @@ export function buildSliceIndexTable(model, refs, baseDir) {
|
|
|
53
53
|
name: slice.name,
|
|
54
54
|
pattern: slicePatternLabel(pattern),
|
|
55
55
|
status: statusCell(doc),
|
|
56
|
+
ratifiedBy: doc.ratifiedBy ?? "—",
|
|
57
|
+
owner: doc.owner ?? "—",
|
|
58
|
+
tracking: doc.tracking ?? "—",
|
|
56
59
|
implementedIn: doc.implementedIn ?? "—",
|
|
57
60
|
docPath: doc.path,
|
|
58
61
|
};
|
|
59
62
|
});
|
|
60
63
|
const lines = rows.map((r) => `| ${r.index} | ${escapeCell(r.name)} | ${escapeCell(r.pattern)} | ${escapeCell(r.status)} | ` +
|
|
64
|
+
`${escapeCell(r.ratifiedBy)} | ${escapeCell(r.owner)} | ${escapeCell(r.tracking)} | ` +
|
|
61
65
|
`${escapeCell(r.implementedIn)} | [${r.docPath}](${r.docPath}) |`);
|
|
62
66
|
return { markdown: [TABLE_HEADER, ...lines].join("\n"), rows, diagnostics };
|
|
63
67
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sliceIndex.js","sourceRoot":"","sources":["../../src/cli/sliceIndex.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,6FAA6F;AAC7F,6FAA6F;AAC7F,sFAAsF;AACtF,iGAAiG;AACjG,EAAE;AACF,0FAA0F;AAC1F,uFAAuF;AACvF,+FAA+F;AAC/F,sDAAsD;AAEtD,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAI1C,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AACjF,OAAO,EAAE,mBAAmB,EAAkB,MAAM,uBAAuB,CAAC;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD;2EAC2E;AAC3E,MAAM,CAAC,MAAM,kBAAkB,GAAG,QAAQ,CAAC;AAE3C,MAAM,YAAY,GAChB,
|
|
1
|
+
{"version":3,"file":"sliceIndex.js","sourceRoot":"","sources":["../../src/cli/sliceIndex.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { NormalizedModel, Element } from "../model/model.js";
|
|
2
|
+
import { RefsResult } from "../model/refs.js";
|
|
3
|
+
import { SlicePattern } from "./sliceNew.js";
|
|
4
|
+
export type ResolvePrimaryElementResult = {
|
|
5
|
+
ok: true;
|
|
6
|
+
sliceIndex: number;
|
|
7
|
+
element: Element;
|
|
8
|
+
} | {
|
|
9
|
+
ok: false;
|
|
10
|
+
message: string;
|
|
11
|
+
};
|
|
12
|
+
/** Resolve `sliceKey`'s primary element for `pattern` — the export key must match a slice
|
|
13
|
+
* already declared in `model` (the ordinary case: the model phase already created the slice;
|
|
14
|
+
* `slice` phase authoring adds its doc afterward), and that slice must have EXACTLY one element
|
|
15
|
+
* of the pattern's primary kind(s) — zero or more than one is refused rather than guessed. */
|
|
16
|
+
export declare function resolvePrimaryElement(model: NormalizedModel, refs: RefsResult, sliceKey: string, pattern: SlicePattern): ResolvePrimaryElementResult;
|
|
17
|
+
export type InsertNoteResult = {
|
|
18
|
+
ok: true;
|
|
19
|
+
content: string;
|
|
20
|
+
} | {
|
|
21
|
+
ok: false;
|
|
22
|
+
message: string;
|
|
23
|
+
};
|
|
24
|
+
/** Insert `note "<notePath>"` into one raw source line — see module header for the placement
|
|
25
|
+
* rule. Pure string transform, no fs, no knowledge of the rest of the file. */
|
|
26
|
+
export declare function insertNoteClause(rawLine: string, notePath: string): InsertNoteResult;
|
|
27
|
+
/** Byte offsets of physical line `lineNo` (1-indexed) within `source`: `[start, end)` excludes
|
|
28
|
+
* the line's own terminator (a trailing `\r` before `\n` is excluded too, so a CRLF file's line
|
|
29
|
+
* content never carries a stray `\r`). Scans once, character by character, rather than
|
|
30
|
+
* `split(/\r?\n/)` — a split+rejoin would silently normalize every OTHER line's terminator
|
|
31
|
+
* style the moment the file is written back (the same pitfall markImplemented.ts/ratify.ts's
|
|
32
|
+
* module headers document for frontmatter surgery — this is the `.em`-source counterpart). */
|
|
33
|
+
export declare function findLineSpan(source: string, lineNo: number): {
|
|
34
|
+
start: number;
|
|
35
|
+
end: number;
|
|
36
|
+
} | null;
|
|
37
|
+
export type WireSliceNoteResult = {
|
|
38
|
+
ok: true;
|
|
39
|
+
content: string;
|
|
40
|
+
sliceName: string;
|
|
41
|
+
elementName: string;
|
|
42
|
+
} | {
|
|
43
|
+
ok: false;
|
|
44
|
+
message: string;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Full `--wire` operation: resolve `sliceKey`'s primary element for `pattern`, then insert
|
|
48
|
+
* `note "<notePath>"` on its exact header line in `source`. `source` MUST be the same text
|
|
49
|
+
* `model`/`refs` were compiled from — line numbers are meaningless against any other text.
|
|
50
|
+
* Every byte outside that one line's span is returned unchanged.
|
|
51
|
+
*/
|
|
52
|
+
export declare function wireSliceNote(source: string, model: NormalizedModel, refs: RefsResult, sliceKey: string, pattern: SlicePattern, notePath: string): WireSliceNoteResult;
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// `em slice new --wire` (MIL-161 finding #3): `em slice new` already computes the exact
|
|
3
|
+
// `note "slices/<key>.md"` line and knows which element is the slice's "primary" one for its
|
|
4
|
+
// pattern (SKILL.md's slice phase, step 4) — this module does the mechanical part that used to
|
|
5
|
+
// stop at printing that line: inserting it into the `.em` source directly, onto the right
|
|
6
|
+
// element's declaration line.
|
|
7
|
+
//
|
|
8
|
+
// Deliberately narrow, matching every other .em-source-editing decision in this codebase (there
|
|
9
|
+
// is no general .em serializer — see docModelConsistencyValidate.ts's header for why a
|
|
10
|
+
// parse+re-serialize is never on the table here either): this ONLY ever edits the ONE physical
|
|
11
|
+
// source line an element's declaration STARTS on (`Element.line`, 1-indexed, straight from the
|
|
12
|
+
// parser — parser.ts's `parseElement`/`lineNo`), and only ever INSERTS a `note "..."` clause
|
|
13
|
+
// into it. Every other line — including the rest of a multi-line field block and its closing
|
|
14
|
+
// `}` — is copied through byte-for-byte; multi-line field text on the SAME line as a note
|
|
15
|
+
// insertion (a block's opening line, e.g. `command Place Order { customerId`) is preserved
|
|
16
|
+
// verbatim too, since the insertion point is always relative to the unquoted `{`, never to
|
|
17
|
+
// anything after it.
|
|
18
|
+
//
|
|
19
|
+
// Placement follows the grammar exactly (parser.ts's `extractClauses`): `note`/`issue`/
|
|
20
|
+
// `divergence`/`tag`/`renamed from` are all extracted from an element's header line BEFORE
|
|
21
|
+
// `from`, and by locating the keyword anywhere in the line rather than requiring it in a fixed
|
|
22
|
+
// position — so a `note "..."` clause parses identically whether it comes before or after a
|
|
23
|
+
// `from "..."` clause, before or after a `@Tag`, immediately before an opening `{`, or right
|
|
24
|
+
// after a `}` that already closed inline. That's what makes one placement rule safe for every
|
|
25
|
+
// element shape:
|
|
26
|
+
//
|
|
27
|
+
// - the header line opens a field block on this SAME line (an unquoted `{`, MIL-122's
|
|
28
|
+
// quote-aware scan — a literal `{` inside a quoted clause like `issue "PUT /widgets/{id}"`
|
|
29
|
+
// is not a block opener): insert immediately BEFORE that `{`, matching every existing
|
|
30
|
+
// note-before-fields example in the DSL (`event X @Ctx note "..." { ... }`).
|
|
31
|
+
// - otherwise (no field block at all on this line, OR a fully inline `{ ... }` block that
|
|
32
|
+
// already closed on the same line): append at the very end of the code, before any trailing
|
|
33
|
+
// `# comment` — matching the grammar's "clauses may trail a closing `}` on the same line"
|
|
34
|
+
// rule, which already covers both shapes identically.
|
|
35
|
+
//
|
|
36
|
+
// Refuses (never overwrites/duplicates) when the header line already carries a `note` clause —
|
|
37
|
+
// the caller falls back to printing the line for a hand edit, same as when `--wire` isn't passed
|
|
38
|
+
// at all.
|
|
39
|
+
import { indexOfUnquoted, stripComment } from "../parser/lexer.js";
|
|
40
|
+
/** Which element kind(s) count as a slice's "primary" element per pattern — the one `note
|
|
41
|
+
* "slices/<key>.md"` binds to (SKILL.md's slice phase, step 4): the command for State Change,
|
|
42
|
+
* the view for State View, the reactor (processor/automation/saga) for Automation, the
|
|
43
|
+
* translation for Translation. Distinct from classify.ts's classifySlicePattern, which groups
|
|
44
|
+
* every kind a pattern's slice may contain (e.g. an Automation slice's command too) — this
|
|
45
|
+
* narrows to the single element the note actually binds to. */
|
|
46
|
+
const PRIMARY_KINDS = {
|
|
47
|
+
"state-change": ["command"],
|
|
48
|
+
"state-view": ["view"],
|
|
49
|
+
automation: ["processor", "automation", "saga"],
|
|
50
|
+
translation: ["translation"],
|
|
51
|
+
};
|
|
52
|
+
/** Resolve `sliceKey`'s primary element for `pattern` — the export key must match a slice
|
|
53
|
+
* already declared in `model` (the ordinary case: the model phase already created the slice;
|
|
54
|
+
* `slice` phase authoring adds its doc afterward), and that slice must have EXACTLY one element
|
|
55
|
+
* of the pattern's primary kind(s) — zero or more than one is refused rather than guessed. */
|
|
56
|
+
export function resolvePrimaryElement(model, refs, sliceKey, pattern) {
|
|
57
|
+
const sliceIndex = refs.sliceKeys.indexOf(sliceKey);
|
|
58
|
+
if (sliceIndex === -1) {
|
|
59
|
+
return { ok: false, message: `no slice with export key "${sliceKey}" in this model` };
|
|
60
|
+
}
|
|
61
|
+
const slice = model.slices[sliceIndex];
|
|
62
|
+
const kinds = PRIMARY_KINDS[pattern];
|
|
63
|
+
const candidates = slice.elements.filter((el) => kinds.includes(el.kind));
|
|
64
|
+
if (candidates.length === 0) {
|
|
65
|
+
return {
|
|
66
|
+
ok: false,
|
|
67
|
+
message: `slice "${slice.name}" has no ${kinds.join("/")} element to wire the note onto`,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
if (candidates.length > 1) {
|
|
71
|
+
return {
|
|
72
|
+
ok: false,
|
|
73
|
+
message: `slice "${slice.name}" has ${candidates.length} ${kinds.join("/")} elements — ambiguous, wire the note by hand`,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
return { ok: true, sliceIndex, element: candidates[0] };
|
|
77
|
+
}
|
|
78
|
+
/** Insert `note "<notePath>"` into one raw source line — see module header for the placement
|
|
79
|
+
* rule. Pure string transform, no fs, no knowledge of the rest of the file. */
|
|
80
|
+
export function insertNoteClause(rawLine, notePath) {
|
|
81
|
+
const code = stripComment(rawLine);
|
|
82
|
+
const comment = rawLine.slice(code.length); // '' or the (whitespace + '#...') tail stripComment dropped
|
|
83
|
+
const trimmedCode = code.replace(/[ \t]+$/, "");
|
|
84
|
+
// Conservative existing-clause check: a bare "note" immediately followed by a quote is
|
|
85
|
+
// EXACTLY how the parser itself recognizes the clause (lexer.ts's QUOTE_OPENER_KEYWORDS
|
|
86
|
+
// anchoring), regardless of where else it appears — a false positive here just means an
|
|
87
|
+
// avoidable refusal (falls back to a hand edit), never a corrupted line.
|
|
88
|
+
if (/\bnote\s*"/.test(trimmedCode)) {
|
|
89
|
+
return { ok: false, message: "this line already has a `note` clause — edit it by hand instead" };
|
|
90
|
+
}
|
|
91
|
+
const clause = `note "${notePath}"`;
|
|
92
|
+
const braceAt = indexOfUnquoted(trimmedCode, "{");
|
|
93
|
+
// A `{` on THIS line only means "insert before it" when the block actually stays open past
|
|
94
|
+
// this line (no matching unquoted `}` here too) — a fully inline `{ ... }` block that already
|
|
95
|
+
// closed on the same line is grammatically just like having no braces at all: the note clause
|
|
96
|
+
// trails it, same as the no-brace case below.
|
|
97
|
+
const closesInline = braceAt >= 0 && indexOfUnquoted(trimmedCode.slice(braceAt + 1), "}") >= 0;
|
|
98
|
+
const newCode = braceAt >= 0 && !closesInline
|
|
99
|
+
? `${trimmedCode.slice(0, braceAt).replace(/[ \t]+$/, "")} ${clause} ${trimmedCode.slice(braceAt)}`
|
|
100
|
+
: `${trimmedCode} ${clause}`;
|
|
101
|
+
return { ok: true, content: comment ? `${newCode} ${comment}` : newCode };
|
|
102
|
+
}
|
|
103
|
+
/** Byte offsets of physical line `lineNo` (1-indexed) within `source`: `[start, end)` excludes
|
|
104
|
+
* the line's own terminator (a trailing `\r` before `\n` is excluded too, so a CRLF file's line
|
|
105
|
+
* content never carries a stray `\r`). Scans once, character by character, rather than
|
|
106
|
+
* `split(/\r?\n/)` — a split+rejoin would silently normalize every OTHER line's terminator
|
|
107
|
+
* style the moment the file is written back (the same pitfall markImplemented.ts/ratify.ts's
|
|
108
|
+
* module headers document for frontmatter surgery — this is the `.em`-source counterpart). */
|
|
109
|
+
export function findLineSpan(source, lineNo) {
|
|
110
|
+
let line = 1;
|
|
111
|
+
let start = 0;
|
|
112
|
+
for (let i = 0; i <= source.length; i++) {
|
|
113
|
+
if (i === source.length || source[i] === "\n") {
|
|
114
|
+
let end = i;
|
|
115
|
+
if (end > start && source[end - 1] === "\r")
|
|
116
|
+
end--;
|
|
117
|
+
if (line === lineNo)
|
|
118
|
+
return { start, end };
|
|
119
|
+
line++;
|
|
120
|
+
start = i + 1;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Full `--wire` operation: resolve `sliceKey`'s primary element for `pattern`, then insert
|
|
127
|
+
* `note "<notePath>"` on its exact header line in `source`. `source` MUST be the same text
|
|
128
|
+
* `model`/`refs` were compiled from — line numbers are meaningless against any other text.
|
|
129
|
+
* Every byte outside that one line's span is returned unchanged.
|
|
130
|
+
*/
|
|
131
|
+
export function wireSliceNote(source, model, refs, sliceKey, pattern, notePath) {
|
|
132
|
+
const resolved = resolvePrimaryElement(model, refs, sliceKey, pattern);
|
|
133
|
+
if (!resolved.ok)
|
|
134
|
+
return resolved;
|
|
135
|
+
const span = findLineSpan(source, resolved.element.line);
|
|
136
|
+
if (!span) {
|
|
137
|
+
return {
|
|
138
|
+
ok: false,
|
|
139
|
+
message: `element "${resolved.element.name}"'s line ${resolved.element.line} not found in the given source — source doesn't match the compiled model`,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
const inserted = insertNoteClause(source.slice(span.start, span.end), notePath);
|
|
143
|
+
if (!inserted.ok)
|
|
144
|
+
return inserted;
|
|
145
|
+
return {
|
|
146
|
+
ok: true,
|
|
147
|
+
content: source.slice(0, span.start) + inserted.content + source.slice(span.end),
|
|
148
|
+
sliceName: model.slices[resolved.sliceIndex].name,
|
|
149
|
+
elementName: resolved.element.name,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=sliceLink.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sliceLink.js","sourceRoot":"","sources":["../../src/cli/sliceLink.ts"],"names":[],"mappings":"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"}
|