@milehimikey/em 1.7.1 → 1.8.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 +92 -65
- package/.claude/skills/event-modeling/reference/conform.md +45 -20
- package/.claude/skills/event-modeling/reference/em-dsl.md +120 -55
- package/.claude/skills/event-modeling/reference/extract.md +5 -4
- package/.claude/skills/event-modeling/reference/implement.md +34 -22
- package/.claude/skills/event-modeling/templates/model-readme.md +8 -5
- package/.claude/skills/event-modeling/templates/slice.md +19 -5
- package/README.md +6 -4
- package/dist/catalog/docJoin.d.ts +28 -3
- package/dist/catalog/docJoin.js +82 -13
- package/dist/catalog/docJoin.js.map +1 -1
- package/dist/catalog/docModelConsistencyValidate.d.ts +8 -0
- package/dist/catalog/docModelConsistencyValidate.js +335 -0
- package/dist/catalog/docModelConsistencyValidate.js.map +1 -0
- package/dist/catalog/noteBindingValidate.d.ts +8 -0
- package/dist/catalog/noteBindingValidate.js +133 -0
- package/dist/catalog/noteBindingValidate.js.map +1 -0
- package/dist/catalog/pages.js +3 -3
- package/dist/catalog/pages.js.map +1 -1
- package/dist/catalog/sliceDoc.d.ts +14 -0
- package/dist/catalog/sliceDoc.js +22 -0
- package/dist/catalog/sliceDoc.js.map +1 -1
- package/dist/catalog/sliceReadyValidate.d.ts +18 -0
- package/dist/catalog/sliceReadyValidate.js +25 -1
- package/dist/catalog/sliceReadyValidate.js.map +1 -1
- package/dist/cli/agentsMd.d.ts +15 -0
- package/dist/cli/agentsMd.js +72 -0
- package/dist/cli/agentsMd.js.map +1 -0
- package/dist/cli/conformScope.d.ts +86 -0
- package/dist/cli/conformScope.js +156 -0
- package/dist/cli/conformScope.js.map +1 -0
- package/dist/cli/contract.d.ts +7 -0
- package/dist/cli/contract.js +27 -0
- package/dist/cli/contract.js.map +1 -0
- package/dist/cli/coverage.d.ts +69 -0
- package/dist/cli/coverage.js +157 -0
- package/dist/cli/coverage.js.map +1 -0
- package/dist/cli/markImplemented.d.ts +34 -0
- package/dist/cli/markImplemented.js +180 -0
- package/dist/cli/markImplemented.js.map +1 -0
- package/dist/cli/migrateReactionShape.d.ts +62 -0
- package/dist/cli/migrateReactionShape.js +283 -0
- package/dist/cli/migrateReactionShape.js.map +1 -0
- package/dist/cli/sliceIndex.d.ts +49 -0
- package/dist/cli/sliceIndex.js +115 -0
- package/dist/cli/sliceIndex.js.map +1 -0
- package/dist/cli/sliceNew.d.ts +18 -0
- package/dist/cli/sliceNew.js +53 -0
- package/dist/cli/sliceNew.js.map +1 -0
- package/dist/cli/stateFile.d.ts +74 -0
- package/dist/cli/stateFile.js +191 -0
- package/dist/cli/stateFile.js.map +1 -0
- package/dist/cli.js +535 -43
- package/dist/cli.js.map +1 -1
- package/dist/emit/coverageJson.d.ts +8 -0
- package/dist/emit/coverageJson.js +30 -0
- package/dist/emit/coverageJson.js.map +1 -0
- package/dist/emit/dot.js +41 -10
- package/dist/emit/dot.js.map +1 -1
- package/dist/emit/json.d.ts +72 -4
- package/dist/emit/json.js +73 -4
- package/dist/emit/json.js.map +1 -1
- package/dist/emit/validateJson.d.ts +52 -0
- package/dist/emit/validateJson.js +120 -0
- package/dist/emit/validateJson.js.map +1 -0
- package/dist/mcp/main.d.ts +2 -0
- package/dist/mcp/main.js +20 -0
- package/dist/mcp/main.js.map +1 -0
- package/dist/mcp/server.d.ts +11 -0
- package/dist/mcp/server.js +260 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/model/model.d.ts +30 -1
- package/dist/model/model.js +26 -0
- package/dist/model/model.js.map +1 -1
- package/dist/model/rules.d.ts +114 -0
- package/dist/model/rules.js +116 -4
- package/dist/model/rules.js.map +1 -1
- package/dist/model/validate.js +83 -7
- package/dist/model/validate.js.map +1 -1
- package/dist/parser/ast.d.ts +41 -0
- package/dist/parser/lexer.d.ts +16 -0
- package/dist/parser/lexer.js +44 -2
- package/dist/parser/lexer.js.map +1 -1
- package/dist/parser/parser.js +340 -20
- package/dist/parser/parser.js.map +1 -1
- package/dist/render/drawNotes.js +8 -1
- package/dist/render/drawNotes.js.map +1 -1
- package/dist/render/render.js +85 -17
- package/dist/render/render.js.map +1 -1
- package/dist/render/serve.d.ts +4 -0
- package/dist/render/serve.js +23 -227
- package/dist/render/serve.js.map +1 -1
- package/dist/render/sliceStatus.d.ts +1 -1
- package/dist/render/sliceStatus.js +35 -6
- package/dist/render/sliceStatus.js.map +1 -1
- package/dist/render/viewerHtml.d.ts +1 -0
- package/dist/render/viewerHtml.js +5 -0
- package/dist/render/viewerHtml.js.map +1 -0
- package/dist/render/watch.d.ts +10 -0
- package/dist/render/watch.js +29 -0
- package/dist/render/watch.js.map +1 -1
- package/dist/templates.d.ts +19 -0
- package/dist/templates.js +169 -0
- package/dist/templates.js.map +1 -1
- package/dist/util/markers.d.ts +13 -0
- package/dist/util/markers.js +30 -0
- package/dist/util/markers.js.map +1 -0
- package/dist/util/walkDir.d.ts +10 -1
- package/dist/util/walkDir.js +11 -7
- package/dist/util/walkDir.js.map +1 -1
- package/package.json +12 -3
- package/.claude/skills/event-modeling/templates/live.html +0 -105
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// `em slice index` (MIL-98): rewrites the marker-delimited Slices table in a model's sibling
|
|
3
|
+
// README.md from the same facts `em export` derives for each slice — export key, AST-derived
|
|
4
|
+
// pattern, and the slice-doc frontmatter join — so the README's "ONE place slices are
|
|
5
|
+
// enumerated" (templates/model-readme.md) stops being hand-maintained, derived data that drifts.
|
|
6
|
+
//
|
|
7
|
+
// Deliberately no new parsing: buildSliceIndexTable below calls exactly the two functions
|
|
8
|
+
// `em export`'s own per-slice loop (src/emit/json.ts) calls — classifySlicePattern and
|
|
9
|
+
// resolveSliceDocJoin — so a slice's pattern/status/implementedIn here can never disagree with
|
|
10
|
+
// what `em export`/`em catalog` already say about it.
|
|
11
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
12
|
+
import { dirname, join } from "node:path";
|
|
13
|
+
import { classifySlicePattern, slicePatternLabel } from "../catalog/classify.js";
|
|
14
|
+
import { resolveSliceDocJoin } from "../catalog/docJoin.js";
|
|
15
|
+
import { applyMarker } from "../util/markers.js";
|
|
16
|
+
/** The marker name wrapping the Slices table: `<!-- GENERATED:slices:start -->` /
|
|
17
|
+
* `<!-- GENERATED:slices:end -->`, matching templates/model-readme.md. */
|
|
18
|
+
export const SLICE_INDEX_MARKER = "slices";
|
|
19
|
+
const TABLE_HEADER = "| # | Slice | Pattern | Status | Implemented in | Design doc |\n" +
|
|
20
|
+
"|---|-------|---------|--------|----------------|------------|";
|
|
21
|
+
/** Escape characters that would break a markdown table cell: `|` (the column separator) and
|
|
22
|
+
* newlines (a slice name is always one line, but a doc's freeform `implementedIn` text isn't
|
|
23
|
+
* guaranteed to be). */
|
|
24
|
+
function escapeCell(s) {
|
|
25
|
+
// Backslashes first: escaping `|` alone would let a pre-existing `\` in the source text
|
|
26
|
+
// combine with the newly-inserted `\` (e.g. a literal `\|`) and un-escape the pipe again
|
|
27
|
+
// once Markdown unescapes the backslash sequence (CodeQL "incomplete string escaping").
|
|
28
|
+
return s.replace(/\\/g, "\\\\").replace(/\|/g, "\\|").replace(/\r?\n/g, " ");
|
|
29
|
+
}
|
|
30
|
+
/** Status cell wording: mirrors `em catalog`'s own found/status split (catalog/pages.ts's
|
|
31
|
+
* statusLabel — "no doc" when nothing was found, the doc's own status otherwise, "unknown" for
|
|
32
|
+
* a found-but-unusable doc) with one deliberate difference: "no doc yet", matching the wording
|
|
33
|
+
* templates/model-readme.md and reference/extract.md already use for a slice that hasn't
|
|
34
|
+
* reached the `slice` phase. `doc.found` false covers both of docJoin's not-found reasons
|
|
35
|
+
* (no-doc-bound and binding-missing-file) — catalog doesn't distinguish them either, since a
|
|
36
|
+
* broken binding still means "there's no doc a human can currently read." */
|
|
37
|
+
function statusCell(doc) {
|
|
38
|
+
if (!doc.found)
|
|
39
|
+
return "no doc yet";
|
|
40
|
+
return doc.status ?? "unknown";
|
|
41
|
+
}
|
|
42
|
+
/** Build the Slices table body for `model`. `baseDir` is the `.em` file's directory — same
|
|
43
|
+
* doc-resolution convention `em export`/`em catalog` use for `slices/<key>.md`. */
|
|
44
|
+
export function buildSliceIndexTable(model, refs, baseDir) {
|
|
45
|
+
const diagnostics = [];
|
|
46
|
+
const rows = model.slices.map((slice, i) => {
|
|
47
|
+
const sliceKey = refs.sliceKeys[i];
|
|
48
|
+
const pattern = classifySlicePattern(slice);
|
|
49
|
+
const { doc, diagnostics: docDiags } = resolveSliceDocJoin(slice, sliceKey, baseDir, (id) => refs.refById.get(id));
|
|
50
|
+
diagnostics.push(...docDiags);
|
|
51
|
+
return {
|
|
52
|
+
index: i + 1,
|
|
53
|
+
name: slice.name,
|
|
54
|
+
pattern: slicePatternLabel(pattern),
|
|
55
|
+
status: statusCell(doc),
|
|
56
|
+
implementedIn: doc.implementedIn ?? "—",
|
|
57
|
+
docPath: doc.path,
|
|
58
|
+
};
|
|
59
|
+
});
|
|
60
|
+
const lines = rows.map((r) => `| ${r.index} | ${escapeCell(r.name)} | ${escapeCell(r.pattern)} | ${escapeCell(r.status)} | ` +
|
|
61
|
+
`${escapeCell(r.implementedIn)} | [${r.docPath}](${r.docPath}) |`);
|
|
62
|
+
return { markdown: [TABLE_HEADER, ...lines].join("\n"), rows, diagnostics };
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Rewrite (or, in `check` mode, verify) the GENERATED:slices block in `<dirname(emFilePath)>/
|
|
66
|
+
* README.md`. Never creates the README or the marker pair — both are user errors reported back
|
|
67
|
+
* via `ok: false`, not silently fixed: a missing README means the model wasn't scaffolded from
|
|
68
|
+
* templates/model-readme.md yet, and missing markers mean an older/hand-edited README that
|
|
69
|
+
* needs the marker pair added first (see the message text for exactly what to do).
|
|
70
|
+
*
|
|
71
|
+
* `check: true` never writes to disk; a stale table is reported as `kind: "stale"` instead
|
|
72
|
+
* (CI-ready — the caller exits non-zero without having touched the working tree).
|
|
73
|
+
*/
|
|
74
|
+
export function runSliceIndex(model, refs, emFilePath, check) {
|
|
75
|
+
const baseDir = dirname(emFilePath);
|
|
76
|
+
const readmePath = join(baseDir, "README.md");
|
|
77
|
+
const table = buildSliceIndexTable(model, refs, baseDir);
|
|
78
|
+
if (!existsSync(readmePath)) {
|
|
79
|
+
return {
|
|
80
|
+
ok: false,
|
|
81
|
+
kind: "missing-readme",
|
|
82
|
+
message: `em slice index: expected a README.md next to ${emFilePath} (looked for ${readmePath}) — ` +
|
|
83
|
+
"none found. Scaffold one from templates/model-readme.md first.",
|
|
84
|
+
table,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
const original = readFileSync(readmePath, "utf8");
|
|
88
|
+
const updated = applyMarker(original, SLICE_INDEX_MARKER, table.markdown);
|
|
89
|
+
if (updated === null) {
|
|
90
|
+
return {
|
|
91
|
+
ok: false,
|
|
92
|
+
kind: "missing-markers",
|
|
93
|
+
message: `em slice index: ${readmePath} has no <!-- GENERATED:${SLICE_INDEX_MARKER}:start --> / ` +
|
|
94
|
+
`<!-- GENERATED:${SLICE_INDEX_MARKER}:end --> markers around its Slices table — add them ` +
|
|
95
|
+
"(copy the ## Slices section from .claude/skills/event-modeling/templates/model-readme.md) " +
|
|
96
|
+
"before running this command.",
|
|
97
|
+
table,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
const changed = updated !== original;
|
|
101
|
+
if (!changed)
|
|
102
|
+
return { ok: true, readmePath, wrote: false, changed: false, table };
|
|
103
|
+
if (check) {
|
|
104
|
+
return {
|
|
105
|
+
ok: false,
|
|
106
|
+
kind: "stale",
|
|
107
|
+
message: `em slice index --check: ${readmePath}'s Slices table is stale — run ` +
|
|
108
|
+
`\`em slice index ${emFilePath}\` and commit the result.`,
|
|
109
|
+
table,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
writeFileSync(readmePath, updated, "utf8");
|
|
113
|
+
return { ok: true, readmePath, wrote: true, changed: true, table };
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=sliceIndex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sliceIndex.js","sourceRoot":"","sources":["../../src/cli/sliceIndex.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** `pattern`'s exact 4-value enum — docs/slice-doc-schema.md's "Canonical keys" table. */
|
|
2
|
+
export declare const SLICE_PATTERNS: readonly ["state-change", "state-view", "automation", "translation"];
|
|
3
|
+
export type SlicePattern = (typeof SLICE_PATTERNS)[number];
|
|
4
|
+
export declare function isSlicePattern(value: string): value is SlicePattern;
|
|
5
|
+
/** The filename stem a slice's display name maps to — `slices/<key>.md`, and the same key a
|
|
6
|
+
* `note "slices/<key>.md"` binding on the slice's primary element must match. Always derive
|
|
7
|
+
* it with this (kebabSlug, the same helper `em scaffold` uses) rather than letting a caller
|
|
8
|
+
* pass a pre-slugged key of their own, so the two can never drift apart. */
|
|
9
|
+
export declare function sliceDocKey(displayName: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Build the full contents of a fresh `slices/<key>.md`. Frontmatter: exactly the 5 keys
|
|
12
|
+
* required at `status: draft`, in the same order templates/slice.md's own frontmatter block
|
|
13
|
+
* uses. Body: the `# Slice: <name>` heading and the diagram-image stub the skill's `slice`
|
|
14
|
+
* phase step 3 fills the actual image in for (`em render ... --slice ... -o
|
|
15
|
+
* slices/<key>.svg`) — every judgment section (Intent, Command, Scenarios, Open Questions,
|
|
16
|
+
* ...) is deliberately left out, staying hand-authored per templates/slice.md.
|
|
17
|
+
*/
|
|
18
|
+
export declare function buildSliceDocContent(displayName: string, key: string, pattern: SlicePattern, swimlane: string): string;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// `em slice new` (MIL-97 item 3): scaffolds a fresh slices/<key>.md doc's mechanical
|
|
3
|
+
// frontmatter + heading — exactly the 5 keys docs/slice-doc-schema.md's required-vs-optional
|
|
4
|
+
// table requires at `status: draft` (schemaVersion/pattern/swimlane/status/version), nothing
|
|
5
|
+
// else — no `implementedIn` (only required once a slice has ever reached `implemented`), no
|
|
6
|
+
// lineage keys (`split-from`/`merged-from`/`superseded-by` only apply to a split/merge/rename
|
|
7
|
+
// doc), no commented-out guidance cruft. The skill's `slice` phase still writes every judgment
|
|
8
|
+
// section by hand (Intent, Command, Scenarios, Open Questions, ...) — this command only kills
|
|
9
|
+
// the copy-paste-the-template-and-fill-in-the-frontmatter step, the one purely mechanical part
|
|
10
|
+
// that was silently drifting when hand-typed (a placeholder left unedited, a key forgotten).
|
|
11
|
+
//
|
|
12
|
+
// Deliberately fs-free/pure — src/cli.ts owns the write, the existing-file/--force check, and
|
|
13
|
+
// the printed `note` reminder, same split as sliceIndex.ts (buildSliceIndexTable vs
|
|
14
|
+
// runSliceIndex/CLI wiring).
|
|
15
|
+
import { kebabSlug } from "../util/slug.js";
|
|
16
|
+
/** `pattern`'s exact 4-value enum — docs/slice-doc-schema.md's "Canonical keys" table. */
|
|
17
|
+
export const SLICE_PATTERNS = ["state-change", "state-view", "automation", "translation"];
|
|
18
|
+
export function isSlicePattern(value) {
|
|
19
|
+
return SLICE_PATTERNS.includes(value);
|
|
20
|
+
}
|
|
21
|
+
/** Current frontmatter dialect version (docs/slice-doc-schema.md, "schemaVersion vs version"):
|
|
22
|
+
* one value, the same across every doc using this dialect, bumped only by `em` maintainers
|
|
23
|
+
* when the dialect's canonical keys change — unrelated to any one slice's own `version`.
|
|
24
|
+
* Unchanged since MIL-86. */
|
|
25
|
+
const SCHEMA_VERSION = 1;
|
|
26
|
+
/** The filename stem a slice's display name maps to — `slices/<key>.md`, and the same key a
|
|
27
|
+
* `note "slices/<key>.md"` binding on the slice's primary element must match. Always derive
|
|
28
|
+
* it with this (kebabSlug, the same helper `em scaffold` uses) rather than letting a caller
|
|
29
|
+
* pass a pre-slugged key of their own, so the two can never drift apart. */
|
|
30
|
+
export function sliceDocKey(displayName) {
|
|
31
|
+
return kebabSlug(displayName);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Build the full contents of a fresh `slices/<key>.md`. Frontmatter: exactly the 5 keys
|
|
35
|
+
* required at `status: draft`, in the same order templates/slice.md's own frontmatter block
|
|
36
|
+
* uses. Body: the `# Slice: <name>` heading and the diagram-image stub the skill's `slice`
|
|
37
|
+
* phase step 3 fills the actual image in for (`em render ... --slice ... -o
|
|
38
|
+
* slices/<key>.svg`) — every judgment section (Intent, Command, Scenarios, Open Questions,
|
|
39
|
+
* ...) is deliberately left out, staying hand-authored per templates/slice.md.
|
|
40
|
+
*/
|
|
41
|
+
export function buildSliceDocContent(displayName, key, pattern, swimlane) {
|
|
42
|
+
return (`---\n` +
|
|
43
|
+
`schemaVersion: ${SCHEMA_VERSION}\n` +
|
|
44
|
+
`pattern: ${pattern}\n` +
|
|
45
|
+
`swimlane: ${swimlane}\n` +
|
|
46
|
+
`status: draft\n` +
|
|
47
|
+
`version: 1\n` +
|
|
48
|
+
`---\n` +
|
|
49
|
+
`# Slice: ${displayName}\n` +
|
|
50
|
+
`\n` +
|
|
51
|
+
`\n`);
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=sliceNew.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sliceNew.js","sourceRoot":"","sources":["../../src/cli/sliceNew.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,qFAAqF;AACrF,6FAA6F;AAC7F,6FAA6F;AAC7F,4FAA4F;AAC5F,8FAA8F;AAC9F,+FAA+F;AAC/F,8FAA8F;AAC9F,+FAA+F;AAC/F,6FAA6F;AAC7F,EAAE;AACF,8FAA8F;AAC9F,oFAAoF;AACpF,6BAA6B;AAE7B,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,0FAA0F;AAC1F,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,CAAU,CAAC;AAGnG,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,OAAQ,cAAoC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC/D,CAAC;AAED;;;8BAG8B;AAC9B,MAAM,cAAc,GAAG,CAAC,CAAC;AAEzB;;;6EAG6E;AAC7E,MAAM,UAAU,WAAW,CAAC,WAAmB;IAC7C,OAAO,SAAS,CAAC,WAAW,CAAC,CAAC;AAChC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAAC,WAAmB,EAAE,GAAW,EAAE,OAAqB,EAAE,QAAgB;IAC5G,OAAO,CACL,OAAO;QACP,kBAAkB,cAAc,IAAI;QACpC,YAAY,OAAO,IAAI;QACvB,aAAa,QAAQ,IAAI;QACzB,iBAAiB;QACjB,cAAc;QACd,OAAO;QACP,YAAY,WAAW,IAAI;QAC3B,IAAI;QACJ,gBAAgB,GAAG,SAAS,CAC7B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/** Filename the skill scaffolds/reads at `<model-dir>/.event-modeling.md`. */
|
|
2
|
+
export declare const STATE_FILE_NAME = ".event-modeling.md";
|
|
3
|
+
/** Canonical phase enum — the ONE list `em state set-phase` enforces. Mirrors
|
|
4
|
+
* templates/state.md's `Current phase:` placeholder list exactly (not SKILL.md's superset,
|
|
5
|
+
* which also lists `watch` — a live-viewing activity you pass through, never a phase you
|
|
6
|
+
* leave the model parked at, so it's deliberately not a valid `Current phase:` value). */
|
|
7
|
+
export declare const PHASES: readonly ["discover", "extract", "model", "slice", "implement", "conform", "review", "validate"];
|
|
8
|
+
export type Phase = (typeof PHASES)[number];
|
|
9
|
+
export declare function isPhase(value: string): value is Phase;
|
|
10
|
+
/** The state file's mechanical fields, decoded to plain data. `lastConformance`/`lastReview`
|
|
11
|
+
* are `null` for the template's `never` marker (never run yet). */
|
|
12
|
+
export interface ParsedState {
|
|
13
|
+
modelPath: string;
|
|
14
|
+
phase: string;
|
|
15
|
+
step: string;
|
|
16
|
+
lastUpdated: string;
|
|
17
|
+
lastConformance: {
|
|
18
|
+
date: string;
|
|
19
|
+
revision: string;
|
|
20
|
+
report: string;
|
|
21
|
+
} | null;
|
|
22
|
+
lastReview: string | null;
|
|
23
|
+
}
|
|
24
|
+
export type ParseStateResult = {
|
|
25
|
+
ok: true;
|
|
26
|
+
state: ParsedState;
|
|
27
|
+
} | {
|
|
28
|
+
ok: false;
|
|
29
|
+
message: string;
|
|
30
|
+
};
|
|
31
|
+
export type PatchResult = {
|
|
32
|
+
ok: true;
|
|
33
|
+
text: string;
|
|
34
|
+
} | {
|
|
35
|
+
ok: false;
|
|
36
|
+
message: string;
|
|
37
|
+
};
|
|
38
|
+
/** Resolve what `<dir>` means for every `em state` subcommand: a direct path to the state file
|
|
39
|
+
* itself (its basename is exactly `.event-modeling.md`) is used as-is; anything else is treated
|
|
40
|
+
* as the model directory containing it. Lets `em state read .` and
|
|
41
|
+
* `em state read path/to/.event-modeling.md` both work without a separate flag. */
|
|
42
|
+
export declare function resolveStateFilePath(dirOrFile: string): string;
|
|
43
|
+
export type LoadResult = {
|
|
44
|
+
ok: true;
|
|
45
|
+
path: string;
|
|
46
|
+
text: string;
|
|
47
|
+
} | {
|
|
48
|
+
ok: false;
|
|
49
|
+
message: string;
|
|
50
|
+
};
|
|
51
|
+
/** The one fs read every `em state` subcommand goes through. */
|
|
52
|
+
export declare function loadStateFile(dirOrFile: string): LoadResult;
|
|
53
|
+
/** Parse the six mechanical bullets out of a state file's raw text. `ok: false` when the file
|
|
54
|
+
* is missing one of the bullet lines entirely, or when `Last conformance:`/`Last stakeholder
|
|
55
|
+
* review:` holds neither `never` nor its documented format — both are the file failing to be
|
|
56
|
+
* the thing resume/conform scoping needs, so both are reported the same way. */
|
|
57
|
+
export declare function parseState(text: string): ParseStateResult;
|
|
58
|
+
/** `em state set-phase`: rewrite `Current phase:` (and `Current step:` when `step` is given)
|
|
59
|
+
* plus `Last updated:`. `phase` is trusted to already be a validated `Phase` — the CLI layer
|
|
60
|
+
* checks against `PHASES` before calling this so the enum has exactly one home. */
|
|
61
|
+
export declare function setPhase(text: string, phase: Phase, today: string, step?: string): PatchResult;
|
|
62
|
+
/** `em state set-conformance`: rewrite `Last conformance:` in the EXACT format
|
|
63
|
+
* reference/conform.md's "keep the format exact" instruction specifies — the next conform
|
|
64
|
+
* run's scoping (reference/conform.md step 1) parses this line back out — plus `Last
|
|
65
|
+
* updated:`. */
|
|
66
|
+
export declare function setConformance(text: string, revision: string, report: string, today: string): PatchResult;
|
|
67
|
+
/** `em state set-review`: rewrite `Last stakeholder review:` (per templates/state.md's format)
|
|
68
|
+
* plus `Last updated:`. `date` is trusted to already look like `YYYY-MM-DD` — the CLI layer
|
|
69
|
+
* validates before calling this. */
|
|
70
|
+
export declare function setReview(text: string, date: string, today: string): PatchResult;
|
|
71
|
+
/** Loose but real validation for a `YYYY-MM-DD` CLI argument: right shape, and month/day in
|
|
72
|
+
* range — not a full calendar (no leap-year/days-in-month check), which is more rigor than a
|
|
73
|
+
* state-file marker needs. */
|
|
74
|
+
export declare function isValidDateString(s: string): boolean;
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// Reads and writes the MECHANICAL fields of a model's resumable state file
|
|
3
|
+
// (`.event-modeling.md`, see .claude/skills/event-modeling/templates/state.md): `Model file:`,
|
|
4
|
+
// `Current phase:`, `Current step:`, `Last updated:`, `Last conformance:`, `Last stakeholder
|
|
5
|
+
// review:`. This is the ONE parser for those bullets — `em changelog` (src/emit/changelog.ts,
|
|
6
|
+
// parseDecisionsLog) parses a disjoint section of the same file (the `## Decisions log`) and
|
|
7
|
+
// stays a separate function for that reason, but shares STATE_FILE_NAME with this module rather
|
|
8
|
+
// than hard-coding the filename a second time.
|
|
9
|
+
//
|
|
10
|
+
// Deliberately narrow: judgment content (Session inputs, Participants, Decisions log, Usage
|
|
11
|
+
// log, Open questions, Slice inventory) is agent-authored prose and out of scope here — this
|
|
12
|
+
// module only ever touches the six mechanical bullets above, byte-for-byte leaving every other
|
|
13
|
+
// line alone.
|
|
14
|
+
//
|
|
15
|
+
// Pure text in, text/data out (parseState, setPhase, setConformance, setReview); `loadStateFile`
|
|
16
|
+
// is the one bit of fs I/O, kept here so both `em state` (src/cli.ts) and any future caller
|
|
17
|
+
// share the same file-location convention instead of re-deriving it.
|
|
18
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
19
|
+
import { basename, join } from "node:path";
|
|
20
|
+
/** Filename the skill scaffolds/reads at `<model-dir>/.event-modeling.md`. */
|
|
21
|
+
export const STATE_FILE_NAME = ".event-modeling.md";
|
|
22
|
+
/** Canonical phase enum — the ONE list `em state set-phase` enforces. Mirrors
|
|
23
|
+
* templates/state.md's `Current phase:` placeholder list exactly (not SKILL.md's superset,
|
|
24
|
+
* which also lists `watch` — a live-viewing activity you pass through, never a phase you
|
|
25
|
+
* leave the model parked at, so it's deliberately not a valid `Current phase:` value). */
|
|
26
|
+
export const PHASES = ["discover", "extract", "model", "slice", "implement", "conform", "review", "validate"];
|
|
27
|
+
export function isPhase(value) {
|
|
28
|
+
return PHASES.includes(value);
|
|
29
|
+
}
|
|
30
|
+
const LABELS = {
|
|
31
|
+
modelFile: "Model file",
|
|
32
|
+
currentPhase: "Current phase",
|
|
33
|
+
currentStep: "Current step",
|
|
34
|
+
lastUpdated: "Last updated",
|
|
35
|
+
lastConformance: "Last conformance",
|
|
36
|
+
lastStakeholderReview: "Last stakeholder review",
|
|
37
|
+
};
|
|
38
|
+
function escapeForRegex(s) {
|
|
39
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
40
|
+
}
|
|
41
|
+
function bulletLineRegex(label) {
|
|
42
|
+
// `m` (multiline) so `^`/`$` bound one line; `.` already excludes line terminators, so this
|
|
43
|
+
// never reaches across lines regardless of LF/CRLF.
|
|
44
|
+
return new RegExp(`^-\\s+\\*\\*${escapeForRegex(label)}:\\*\\*.*$`, "m");
|
|
45
|
+
}
|
|
46
|
+
function bulletValue(text, label) {
|
|
47
|
+
const re = new RegExp(`^-\\s+\\*\\*${escapeForRegex(label)}:\\*\\*\\s*(.*)$`, "m");
|
|
48
|
+
const m = re.exec(text);
|
|
49
|
+
return m ? m[1].trim() : null;
|
|
50
|
+
}
|
|
51
|
+
/** Resolve what `<dir>` means for every `em state` subcommand: a direct path to the state file
|
|
52
|
+
* itself (its basename is exactly `.event-modeling.md`) is used as-is; anything else is treated
|
|
53
|
+
* as the model directory containing it. Lets `em state read .` and
|
|
54
|
+
* `em state read path/to/.event-modeling.md` both work without a separate flag. */
|
|
55
|
+
export function resolveStateFilePath(dirOrFile) {
|
|
56
|
+
return basename(dirOrFile) === STATE_FILE_NAME ? dirOrFile : join(dirOrFile, STATE_FILE_NAME);
|
|
57
|
+
}
|
|
58
|
+
/** The one fs read every `em state` subcommand goes through. */
|
|
59
|
+
export function loadStateFile(dirOrFile) {
|
|
60
|
+
const path = resolveStateFilePath(dirOrFile);
|
|
61
|
+
if (!existsSync(path)) {
|
|
62
|
+
return { ok: false, message: `em state: no state file at ${path}` };
|
|
63
|
+
}
|
|
64
|
+
return { ok: true, path, text: readFileSync(path, "utf8") };
|
|
65
|
+
}
|
|
66
|
+
const LAST_CONFORMANCE_RE = /^(\d{4}-\d{2}-\d{2}) @ (.+?) — report: (.+)$/;
|
|
67
|
+
const LEADING_DATE_RE = /^(\d{4}-\d{2}-\d{2})\b/;
|
|
68
|
+
/** Parse the six mechanical bullets out of a state file's raw text. `ok: false` when the file
|
|
69
|
+
* is missing one of the bullet lines entirely, or when `Last conformance:`/`Last stakeholder
|
|
70
|
+
* review:` holds neither `never` nor its documented format — both are the file failing to be
|
|
71
|
+
* the thing resume/conform scoping needs, so both are reported the same way. */
|
|
72
|
+
export function parseState(text) {
|
|
73
|
+
const missing = [];
|
|
74
|
+
const raw = {};
|
|
75
|
+
for (const label of Object.values(LABELS)) {
|
|
76
|
+
const v = bulletValue(text, label);
|
|
77
|
+
if (v === null)
|
|
78
|
+
missing.push(label);
|
|
79
|
+
else
|
|
80
|
+
raw[label] = v;
|
|
81
|
+
}
|
|
82
|
+
if (missing.length > 0) {
|
|
83
|
+
return {
|
|
84
|
+
ok: false,
|
|
85
|
+
message: `missing bullet line(s): ${missing.map((l) => `"- **${l}:**"`).join(", ")}`,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
const modelPath = raw[LABELS.modelFile].replace(/^`|`$/g, "");
|
|
89
|
+
const lastConformanceRaw = raw[LABELS.lastConformance];
|
|
90
|
+
let lastConformance = null;
|
|
91
|
+
if (lastConformanceRaw !== "never") {
|
|
92
|
+
const m = LAST_CONFORMANCE_RE.exec(lastConformanceRaw);
|
|
93
|
+
if (!m) {
|
|
94
|
+
return {
|
|
95
|
+
ok: false,
|
|
96
|
+
message: `"- **Last conformance:**" doesn't match "YYYY-MM-DD @ <revision> — report: <path>" or "never": ${lastConformanceRaw}`,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
lastConformance = { date: m[1], revision: m[2], report: m[3] };
|
|
100
|
+
}
|
|
101
|
+
const lastReviewRaw = raw[LABELS.lastStakeholderReview];
|
|
102
|
+
let lastReview = null;
|
|
103
|
+
if (lastReviewRaw !== "never") {
|
|
104
|
+
const m = LEADING_DATE_RE.exec(lastReviewRaw);
|
|
105
|
+
if (!m) {
|
|
106
|
+
return {
|
|
107
|
+
ok: false,
|
|
108
|
+
message: `"- **Last stakeholder review:**" doesn't start with "YYYY-MM-DD" or "never": ${lastReviewRaw}`,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
lastReview = m[1];
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
ok: true,
|
|
115
|
+
state: {
|
|
116
|
+
modelPath,
|
|
117
|
+
phase: raw[LABELS.currentPhase],
|
|
118
|
+
step: raw[LABELS.currentStep],
|
|
119
|
+
lastUpdated: raw[LABELS.lastUpdated],
|
|
120
|
+
lastConformance,
|
|
121
|
+
lastReview,
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/** Replace one or more bullet lines in place, in the order given, failing (without writing
|
|
126
|
+
* anything) if any targeted bullet is missing. Every other byte of `text` — including every
|
|
127
|
+
* other bullet, and whatever line ending style the file already used — passes through the
|
|
128
|
+
* regex untouched. */
|
|
129
|
+
function applyBulletUpdates(text, updates) {
|
|
130
|
+
let result = text;
|
|
131
|
+
const missing = [];
|
|
132
|
+
for (const { label, value } of updates) {
|
|
133
|
+
const re = bulletLineRegex(label);
|
|
134
|
+
if (!re.test(result)) {
|
|
135
|
+
missing.push(label);
|
|
136
|
+
continue;
|
|
137
|
+
}
|
|
138
|
+
// Replacer function, not a string pattern — a string replacement would let `$&`/`$'`/`$$`
|
|
139
|
+
// etc. in a user-supplied value (revision, report path, step) expand against the matched
|
|
140
|
+
// line and corrupt the file. A function's return value is inserted literally.
|
|
141
|
+
result = result.replace(re, () => `- **${label}:** ${value}`);
|
|
142
|
+
}
|
|
143
|
+
if (missing.length > 0) {
|
|
144
|
+
return { ok: false, message: `missing bullet line(s): ${missing.map((l) => `"- **${l}:**"`).join(", ")}` };
|
|
145
|
+
}
|
|
146
|
+
return { ok: true, text: result };
|
|
147
|
+
}
|
|
148
|
+
/** `em state set-phase`: rewrite `Current phase:` (and `Current step:` when `step` is given)
|
|
149
|
+
* plus `Last updated:`. `phase` is trusted to already be a validated `Phase` — the CLI layer
|
|
150
|
+
* checks against `PHASES` before calling this so the enum has exactly one home. */
|
|
151
|
+
export function setPhase(text, phase, today, step) {
|
|
152
|
+
const updates = [{ label: LABELS.currentPhase, value: phase }];
|
|
153
|
+
if (step !== undefined)
|
|
154
|
+
updates.push({ label: LABELS.currentStep, value: step });
|
|
155
|
+
updates.push({ label: LABELS.lastUpdated, value: today });
|
|
156
|
+
return applyBulletUpdates(text, updates);
|
|
157
|
+
}
|
|
158
|
+
/** `em state set-conformance`: rewrite `Last conformance:` in the EXACT format
|
|
159
|
+
* reference/conform.md's "keep the format exact" instruction specifies — the next conform
|
|
160
|
+
* run's scoping (reference/conform.md step 1) parses this line back out — plus `Last
|
|
161
|
+
* updated:`. */
|
|
162
|
+
export function setConformance(text, revision, report, today) {
|
|
163
|
+
const value = `${today} @ ${revision} — report: ${report}`;
|
|
164
|
+
return applyBulletUpdates(text, [
|
|
165
|
+
{ label: LABELS.lastConformance, value },
|
|
166
|
+
{ label: LABELS.lastUpdated, value: today },
|
|
167
|
+
]);
|
|
168
|
+
}
|
|
169
|
+
/** `em state set-review`: rewrite `Last stakeholder review:` (per templates/state.md's format)
|
|
170
|
+
* plus `Last updated:`. `date` is trusted to already look like `YYYY-MM-DD` — the CLI layer
|
|
171
|
+
* validates before calling this. */
|
|
172
|
+
export function setReview(text, date, today) {
|
|
173
|
+
const value = `${date} — attendees: see Participants`;
|
|
174
|
+
return applyBulletUpdates(text, [
|
|
175
|
+
{ label: LABELS.lastStakeholderReview, value },
|
|
176
|
+
{ label: LABELS.lastUpdated, value: today },
|
|
177
|
+
]);
|
|
178
|
+
}
|
|
179
|
+
const DATE_RE = /^(\d{4})-(\d{2})-(\d{2})$/;
|
|
180
|
+
/** Loose but real validation for a `YYYY-MM-DD` CLI argument: right shape, and month/day in
|
|
181
|
+
* range — not a full calendar (no leap-year/days-in-month check), which is more rigor than a
|
|
182
|
+
* state-file marker needs. */
|
|
183
|
+
export function isValidDateString(s) {
|
|
184
|
+
const m = DATE_RE.exec(s);
|
|
185
|
+
if (!m)
|
|
186
|
+
return false;
|
|
187
|
+
const month = Number(m[2]);
|
|
188
|
+
const day = Number(m[3]);
|
|
189
|
+
return month >= 1 && month <= 12 && day >= 1 && day <= 31;
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=stateFile.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stateFile.js","sourceRoot":"","sources":["../../src/cli/stateFile.ts"],"names":[],"mappings":"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"}
|