@milehimikey/em 1.8.1 → 1.9.1
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 +40 -14
- 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 +115 -83
- package/.claude/skills/{event-modeling → event-modeling-shared}/reference/methodology.md +6 -5
- package/.claude/skills/event-modeling-shared/reference/operating-principles.md +150 -0
- package/.claude/skills/event-modeling-shared/reference/slice-doc-schema.md +381 -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 +57 -14
- 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 +6 -1
- package/dist/cli/coverage.js +28 -3
- 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 +503 -132
- package/dist/cli.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 +62 -8
- package/dist/emit/json.js +14 -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/templates.d.ts +1 -1
- package/dist/templates.js +2 -2
- 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,356 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// POC (MIL-159): generates a TypeSpec (https://typespec.io) contract surface — plain `model`/
|
|
3
|
+
// `interface`/`op` declarations, core scalars only, no imports — for a model's commands,
|
|
4
|
+
// public events, and public views. EXPERIMENTAL: see docs/cli.md's `em typespec` section for
|
|
5
|
+
// the scoping/type-mapping decisions this POC makes and what it deliberately leaves out.
|
|
6
|
+
//
|
|
7
|
+
// Reuses `buildExportDoc` (emit/json.ts) rather than re-deriving typeRef/tags/renamedFrom/
|
|
8
|
+
// assigned/public from the raw model a second time — same discipline `em export` itself
|
|
9
|
+
// follows: one resolution pass, one place field metadata is computed, every consumer reads
|
|
10
|
+
// the resolved shape. Deterministic and dependency-free: no LLM, no new runtime dependency —
|
|
11
|
+
// this emits TypeSpec *source text* directly rather than building an AST through
|
|
12
|
+
// `@typespec/compiler` (see test/typespec.test.ts for the optional, skip-if-absent
|
|
13
|
+
// compile-verification test that checks the text this module emits is actually valid
|
|
14
|
+
// TypeSpec, using `@typespec/compiler` as a devDependency only).
|
|
15
|
+
import { dedupe } from "../util/slug.js";
|
|
16
|
+
import { buildExportDoc } from "./json.js";
|
|
17
|
+
// 1.0 (MIL-159, POC): initial shape. Not part of the `em export` schema-versioning lineage —
|
|
18
|
+
// this is source text, not JSON, and the POC's own mapping/scoping decisions (see below) are
|
|
19
|
+
// expected to change if/when this graduates past POC, so it gets its own independent version.
|
|
20
|
+
export const TYPESPEC_SCHEMA_VERSION = "1.0";
|
|
21
|
+
// ---- Type mapping strategy ---------------------------------------------------------------
|
|
22
|
+
//
|
|
23
|
+
// em field types are free text with no semantic checking (docs/dsl.md, "Fields"). TypeSpec
|
|
24
|
+
// needs real scalar/model references, so this POC picks one explicit, documented strategy
|
|
25
|
+
// (per the ticket's "needs an explicit mapping strategy" — not assumed) rather than passing
|
|
26
|
+
// text through unchanged:
|
|
27
|
+
//
|
|
28
|
+
// 1. A field whose type names a declared `type` block (`FieldExport.typeRef`, already
|
|
29
|
+
// resolved by `buildExportDoc` — bare or `[]`-suffixed) references that type's generated
|
|
30
|
+
// `model` by name. This is the clean, low-risk case the ticket calls out — em already does
|
|
31
|
+
// all the resolution work.
|
|
32
|
+
// 2. Otherwise, the *bare* type name (after stripping a `[]` suffix or a `List<...>`/
|
|
33
|
+
// `Array<...>`/`Set<...>` generic wrapper) is looked up case-insensitively in
|
|
34
|
+
// SCALAR_TYPE_MAP below. A hit maps to that TypeSpec core scalar.
|
|
35
|
+
// 3. A field with no declared type at all (`type` was never written) maps to `unknown` —
|
|
36
|
+
// not a mapping failure, just an honest "this field's shape isn't declared here."
|
|
37
|
+
// 4. Anything else — a declared type string that's neither a known scalar nor a resolvable
|
|
38
|
+
// `type` reference (`Money`, a typo, a domain-specific string nobody's mapped) — also
|
|
39
|
+
// becomes `unknown`, but is recorded in `TypeSpecResult.unmappedTypes` so the gap is
|
|
40
|
+
// visible instead of silently swallowed. `List<X>` around an unresolved `X` (including a
|
|
41
|
+
// declared type referenced through the generic-wrapper spelling rather than `X[]` — see
|
|
42
|
+
// docs/dsl.md's Named types section on why only the bare/`[]` forms resolve) still maps to
|
|
43
|
+
// `unknown[]`, not `unknown`, so the arity survives even when the element type doesn't.
|
|
44
|
+
//
|
|
45
|
+
// This table is intentionally small and unopinionated (nothing domain-specific like `Money` ->
|
|
46
|
+
// a currency shape) — go/no-go note: a promoted, non-POC version would likely want this
|
|
47
|
+
// user-configurable (a mapping file) rather than hardcoded.
|
|
48
|
+
export const SCALAR_TYPE_MAP = Object.freeze({
|
|
49
|
+
string: "string",
|
|
50
|
+
str: "string",
|
|
51
|
+
text: "string",
|
|
52
|
+
uuid: "string",
|
|
53
|
+
guid: "string",
|
|
54
|
+
int: "int32",
|
|
55
|
+
integer: "int32",
|
|
56
|
+
int32: "int32",
|
|
57
|
+
int64: "int64",
|
|
58
|
+
long: "int64",
|
|
59
|
+
short: "int16",
|
|
60
|
+
int16: "int16",
|
|
61
|
+
byte: "int8",
|
|
62
|
+
int8: "int8",
|
|
63
|
+
uint: "uint32",
|
|
64
|
+
boolean: "boolean",
|
|
65
|
+
bool: "boolean",
|
|
66
|
+
float: "float32",
|
|
67
|
+
float32: "float32",
|
|
68
|
+
double: "float64",
|
|
69
|
+
float64: "float64",
|
|
70
|
+
decimal: "decimal",
|
|
71
|
+
money: "decimal",
|
|
72
|
+
currency: "decimal",
|
|
73
|
+
instant: "utcDateTime",
|
|
74
|
+
datetime: "utcDateTime",
|
|
75
|
+
timestamp: "utcDateTime",
|
|
76
|
+
utcdatetime: "utcDateTime",
|
|
77
|
+
date: "plainDate",
|
|
78
|
+
time: "plainTime",
|
|
79
|
+
duration: "duration",
|
|
80
|
+
url: "url",
|
|
81
|
+
uri: "url",
|
|
82
|
+
bytes: "bytes",
|
|
83
|
+
binary: "bytes",
|
|
84
|
+
object: "unknown",
|
|
85
|
+
any: "unknown",
|
|
86
|
+
void: "void",
|
|
87
|
+
});
|
|
88
|
+
function mapRawType(raw) {
|
|
89
|
+
let s = raw.trim();
|
|
90
|
+
let array = false;
|
|
91
|
+
const generic = s.match(/^(?:List|Array|Set)<(.+)>$/i);
|
|
92
|
+
if (generic) {
|
|
93
|
+
array = true;
|
|
94
|
+
s = generic[1].trim();
|
|
95
|
+
}
|
|
96
|
+
else if (s.endsWith("[]")) {
|
|
97
|
+
array = true;
|
|
98
|
+
s = s.slice(0, -2).trim();
|
|
99
|
+
}
|
|
100
|
+
const scalar = SCALAR_TYPE_MAP[s.toLowerCase()];
|
|
101
|
+
if (scalar)
|
|
102
|
+
return { tsType: array ? `${scalar}[]` : scalar, mapped: true };
|
|
103
|
+
return { tsType: array ? "unknown[]" : "unknown", mapped: false };
|
|
104
|
+
}
|
|
105
|
+
// ---- Identifier shaping -----------------------------------------------------------------
|
|
106
|
+
/** em element/type names are free text ("Place Order", "Order Placed"). TypeSpec model/
|
|
107
|
+
* operation names need a bare identifier — PascalCase, matching TypeSpec's own convention
|
|
108
|
+
* for `model`/`interface` names. */
|
|
109
|
+
function pascalCase(name) {
|
|
110
|
+
const words = name.match(/[A-Za-z0-9]+/g) ?? [];
|
|
111
|
+
const joined = words.map((w) => w[0].toUpperCase() + w.slice(1)).join("");
|
|
112
|
+
if (joined.length === 0)
|
|
113
|
+
return "Unnamed";
|
|
114
|
+
return /^[0-9]/.test(joined) ? `_${joined}` : joined;
|
|
115
|
+
}
|
|
116
|
+
function camelCase(pascal) {
|
|
117
|
+
return pascal.length > 0 ? pascal[0].toLowerCase() + pascal.slice(1) : pascal;
|
|
118
|
+
}
|
|
119
|
+
/** A field name that isn't a bare TypeSpec identifier (spaces, leading digit, ...) is quoted
|
|
120
|
+
* with backticks — the same escape TypeSpec itself uses for a non-identifier member name. em
|
|
121
|
+
* field names are conventionally already valid identifiers (see examples/*.em), so this is a
|
|
122
|
+
* defensive fallback, not the expected path. */
|
|
123
|
+
function fieldIdentifier(name) {
|
|
124
|
+
if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(name))
|
|
125
|
+
return name;
|
|
126
|
+
return "`" + name.replace(/\\/g, "\\\\").replace(/`/g, "\\`") + "`";
|
|
127
|
+
}
|
|
128
|
+
// ---- Doc-comment metadata -----------------------------------------------------------------
|
|
129
|
+
//
|
|
130
|
+
// `tag` (DCB), `renamed from`, and `assigned` are modeling/event-store concerns, not wire-
|
|
131
|
+
// contract shape — decided (per the ticket's open question) to carry them forward as plain
|
|
132
|
+
// `/** ... */` doc comments, never as decorators. A custom `@tag`/`@assigned`/`@renamedFrom`
|
|
133
|
+
// decorator would need its own TypeSpec extension library (`extern dec` + a JS implementation)
|
|
134
|
+
// to be anything but cosmetic, which is out of scope for a dependency-free POC; a doc comment
|
|
135
|
+
// keeps the information visible in the generated contract without inventing new TypeSpec
|
|
136
|
+
// vocabulary this POC can't back with real semantics.
|
|
137
|
+
function fieldDocComment(f) {
|
|
138
|
+
const notes = [];
|
|
139
|
+
if (f.tag)
|
|
140
|
+
notes.push("DCB identity tag");
|
|
141
|
+
if (f.renamedFrom && f.renamedFrom.length > 0) {
|
|
142
|
+
notes.push(`renamed from ${f.renamedFrom.map((n) => JSON.stringify(n)).join(", ")}`);
|
|
143
|
+
}
|
|
144
|
+
if (f.assigned)
|
|
145
|
+
notes.push("system-assigned — not supplied by the triggering command");
|
|
146
|
+
return notes.length > 0 ? notes.join("; ") : null;
|
|
147
|
+
}
|
|
148
|
+
function elementDocComment(el) {
|
|
149
|
+
const notes = [];
|
|
150
|
+
if (el.renamedFrom && el.renamedFrom.length > 0) {
|
|
151
|
+
notes.push(`renamed from ${el.renamedFrom.map((n) => JSON.stringify(n)).join(", ")}`);
|
|
152
|
+
}
|
|
153
|
+
if (el.tags) {
|
|
154
|
+
for (const t of el.tags) {
|
|
155
|
+
if (t.kind === "composite")
|
|
156
|
+
notes.push(`DCB composite tag \`${t.key}\` from ${(t.fields ?? []).join(", ")}`);
|
|
157
|
+
else if (t.kind === "external")
|
|
158
|
+
notes.push(`DCB external tag \`${t.key}\`: ${t.description}`);
|
|
159
|
+
// identity tags are already surfaced per-field (fieldDocComment) — not repeated here.
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return notes.length > 0 ? notes.join("; ") : null;
|
|
163
|
+
}
|
|
164
|
+
function indent(lines, depth) {
|
|
165
|
+
const pad = " ".repeat(depth);
|
|
166
|
+
return lines.map((l) => (l.length > 0 ? pad + l : l));
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Build the `em typespec <file>` document: TypeSpec source text for a model's contract
|
|
170
|
+
* surface. Mirrors `buildExport`'s parameter contract exactly (same four inputs, same
|
|
171
|
+
* "already-validated, error-free model" precondition — the caller, cli.ts, applies the same
|
|
172
|
+
* refuse-on-error gate `em export` uses before calling this).
|
|
173
|
+
*/
|
|
174
|
+
export function buildTypeSpec(model, refs, diagnostics, source, path) {
|
|
175
|
+
const { doc, diagnostics: allDiagnostics } = buildExportDoc(model, refs, diagnostics, source, path);
|
|
176
|
+
const unmappedNotes = [];
|
|
177
|
+
const recordUnmapped = (refLabel, field, rawType) => {
|
|
178
|
+
unmappedNotes.push(`${refLabel} field "${field}": type "${rawType}" has no scalar mapping — emitted as \`unknown\``);
|
|
179
|
+
};
|
|
180
|
+
const typesByRef = new Map(doc.model.types.map((t) => [t.ref, t]));
|
|
181
|
+
// ---- Scoping (per the ticket's own decision points) --------------------------------
|
|
182
|
+
//
|
|
183
|
+
// Events/views: exactly `public` (docs/dsl.md's Integration surface — the flag this
|
|
184
|
+
// generator was built for). Commands have no `public` flag of their own (dsl.md), so this
|
|
185
|
+
// POC's decision is: a command is included when its own slice declares at least one public
|
|
186
|
+
// event or view — the request contract for a slice that's already promoted its outcome
|
|
187
|
+
// (or its read model) to the integration surface belongs on the same contract. A slice with
|
|
188
|
+
// no public event/view contributes nothing, including its commands.
|
|
189
|
+
const slicePublic = new Map();
|
|
190
|
+
for (const slice of doc.model.slices) {
|
|
191
|
+
slicePublic.set(slice.key, slice.elements.some((el) => (el.kind === "event" || el.kind === "view") && el.public === true));
|
|
192
|
+
}
|
|
193
|
+
const publicEvents = [];
|
|
194
|
+
const publicViews = [];
|
|
195
|
+
const scopedCommands = [];
|
|
196
|
+
// A repeated view instance (`view X again`) shares one logical identity (docs/dsl.md,
|
|
197
|
+
// "view … again") — only the first instance is emitted as a `model`; later instances are
|
|
198
|
+
// folded into it rather than re-declared under the same name (which TypeSpec would reject
|
|
199
|
+
// as a duplicate). Left out of this POC: merging the *new* fields a later public instance
|
|
200
|
+
// adds — see buildTypeSpec's module comment / the PR's "left out of POC" notes.
|
|
201
|
+
const seenViewNames = new Set();
|
|
202
|
+
for (const slice of doc.model.slices) {
|
|
203
|
+
for (const el of slice.elements) {
|
|
204
|
+
if (el.kind === "event" && el.public)
|
|
205
|
+
publicEvents.push(el);
|
|
206
|
+
else if (el.kind === "view" && el.public) {
|
|
207
|
+
const key = el.name.trim().toLowerCase();
|
|
208
|
+
if (!seenViewNames.has(key)) {
|
|
209
|
+
seenViewNames.add(key);
|
|
210
|
+
publicViews.push(el);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
else if (el.kind === "command" && slicePublic.get(slice.key)) {
|
|
214
|
+
scopedCommands.push(el);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
// ---- Named types: only those reachable from an included element's fields, transitively
|
|
219
|
+
// (never every declared type — a type nobody in the public/command surface references
|
|
220
|
+
// would be dead weight in a *contract* artifact, unlike `em export`'s full-model dump). ----
|
|
221
|
+
const reachableTypeRefs = new Set();
|
|
222
|
+
const walkFields = (fields) => {
|
|
223
|
+
if (!fields)
|
|
224
|
+
return;
|
|
225
|
+
for (const f of fields) {
|
|
226
|
+
if (f.typeRef && !reachableTypeRefs.has(f.typeRef.ref)) {
|
|
227
|
+
reachableTypeRefs.add(f.typeRef.ref);
|
|
228
|
+
const t = typesByRef.get(f.typeRef.ref);
|
|
229
|
+
if (t)
|
|
230
|
+
walkFields(t.fields);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
for (const el of [...publicEvents, ...publicViews, ...scopedCommands])
|
|
235
|
+
walkFields(el.fields);
|
|
236
|
+
const usedNames = new Set();
|
|
237
|
+
const typeNameByRef = new Map();
|
|
238
|
+
const typeBlocks = [];
|
|
239
|
+
for (const t of doc.model.types) {
|
|
240
|
+
if (!reachableTypeRefs.has(t.ref))
|
|
241
|
+
continue;
|
|
242
|
+
const name = dedupe(pascalCase(t.name), usedNames, "_");
|
|
243
|
+
typeNameByRef.set(t.ref, name);
|
|
244
|
+
}
|
|
245
|
+
const resolveFieldType = (f, refLabel) => {
|
|
246
|
+
if (f.typeRef) {
|
|
247
|
+
const name = typeNameByRef.get(f.typeRef.ref) ?? pascalCase(f.typeRef.name);
|
|
248
|
+
return f.typeRef.array ? `${name}[]` : name;
|
|
249
|
+
}
|
|
250
|
+
if (f.type == null)
|
|
251
|
+
return "unknown";
|
|
252
|
+
const { tsType, mapped } = mapRawType(f.type);
|
|
253
|
+
if (!mapped)
|
|
254
|
+
recordUnmapped(refLabel, f.name, f.type);
|
|
255
|
+
return tsType;
|
|
256
|
+
};
|
|
257
|
+
const renderFieldLines = (fields, refLabel) => {
|
|
258
|
+
if (!fields || fields.length === 0)
|
|
259
|
+
return [];
|
|
260
|
+
const lines = [];
|
|
261
|
+
for (const f of fields) {
|
|
262
|
+
const fieldDoc = fieldDocComment(f);
|
|
263
|
+
if (fieldDoc)
|
|
264
|
+
lines.push(`/** ${fieldDoc} */`);
|
|
265
|
+
lines.push(`${fieldIdentifier(f.name)}: ${resolveFieldType(f, refLabel)};`);
|
|
266
|
+
}
|
|
267
|
+
return lines;
|
|
268
|
+
};
|
|
269
|
+
const renderModel = (name, fields, refLabel, docComment) => {
|
|
270
|
+
const lines = [];
|
|
271
|
+
if (docComment)
|
|
272
|
+
lines.push(`/** ${docComment} */`);
|
|
273
|
+
lines.push(`model ${name} {`);
|
|
274
|
+
lines.push(...indent(renderFieldLines(fields, refLabel), 1));
|
|
275
|
+
lines.push(`}`);
|
|
276
|
+
return lines.join("\n");
|
|
277
|
+
};
|
|
278
|
+
// Named types, in declaration order, filtered to what's reachable.
|
|
279
|
+
for (const t of doc.model.types) {
|
|
280
|
+
const name = typeNameByRef.get(t.ref);
|
|
281
|
+
if (!name)
|
|
282
|
+
continue;
|
|
283
|
+
typeBlocks.push(renderModel(name, t.fields, `types/${t.name}`));
|
|
284
|
+
}
|
|
285
|
+
// ---- Events (message payloads): plain `model` declarations, schema only ------------------
|
|
286
|
+
//
|
|
287
|
+
// Open question the ticket asks to research: how does TypeSpec represent an async/event
|
|
288
|
+
// contract, given core TypeSpec is HTTP/OpenAPI-shaped? This POC's answer is the option the
|
|
289
|
+
// ticket itself lists as viable without new tooling: a plain `model` for the payload shape,
|
|
290
|
+
// no protocol semantics attached. A promoted version could layer `@typespec/events` or an
|
|
291
|
+
// AsyncAPI emitter on top of these same models for channel/binding semantics — deliberately
|
|
292
|
+
// not attempted here (see "left out of POC", the PR description, and the go/no-go note in
|
|
293
|
+
// this module's header).
|
|
294
|
+
const eventNames = new Set(usedNames);
|
|
295
|
+
const eventBlocks = [];
|
|
296
|
+
for (const el of publicEvents) {
|
|
297
|
+
const name = dedupe(pascalCase(el.name), eventNames, "_");
|
|
298
|
+
eventBlocks.push(renderModel(name, el.fields, el.ref, elementDocComment(el)));
|
|
299
|
+
}
|
|
300
|
+
// ---- Views (read-model contracts): a `model` for the shape, plus a no-arg accessor `op` —
|
|
301
|
+
// covers both halves of the ticket's "Views -> TypeSpec models/operations". Deliberately no
|
|
302
|
+
// `@get`/`@route` (that's `@typespec/http` territory, a new dependency this POC doesn't
|
|
303
|
+
// need to prove the field-mapping question) — a bare, protocol-agnostic `op`. --------------
|
|
304
|
+
const viewNames = new Set(eventNames);
|
|
305
|
+
const viewBlocks = [];
|
|
306
|
+
const viewOps = [];
|
|
307
|
+
for (const el of publicViews) {
|
|
308
|
+
const name = dedupe(pascalCase(el.name), viewNames, "_");
|
|
309
|
+
viewBlocks.push(renderModel(name, el.fields, el.ref, elementDocComment(el)));
|
|
310
|
+
viewOps.push(`op get${name}(): ${name};`);
|
|
311
|
+
}
|
|
312
|
+
// ---- Commands (request contracts): an `op` per command, one parameter per field. ---------
|
|
313
|
+
const commandOpNames = new Set();
|
|
314
|
+
const commandOps = [];
|
|
315
|
+
for (const el of scopedCommands) {
|
|
316
|
+
const opName = dedupe(camelCase(pascalCase(el.name)), commandOpNames, "_");
|
|
317
|
+
const docComment = elementDocComment(el);
|
|
318
|
+
const params = (el.fields ?? []).map((f) => {
|
|
319
|
+
const fieldDoc = fieldDocComment(f);
|
|
320
|
+
const line = `${fieldIdentifier(f.name)}: ${resolveFieldType(f, el.ref)}`;
|
|
321
|
+
return fieldDoc ? `/** ${fieldDoc} */ ${line}` : line;
|
|
322
|
+
});
|
|
323
|
+
if (docComment)
|
|
324
|
+
commandOps.push(`/** ${docComment} */`);
|
|
325
|
+
commandOps.push(params.length > 0 ? `op ${opName}(${params.join(", ")}): void;` : `op ${opName}(): void;`);
|
|
326
|
+
}
|
|
327
|
+
// ---- Assemble ------------------------------------------------------------------------
|
|
328
|
+
const namespaceName = pascalCase(doc.model.name ?? "Model") || "Model";
|
|
329
|
+
const sections = [];
|
|
330
|
+
if (typeBlocks.length > 0)
|
|
331
|
+
sections.push(typeBlocks.join("\n\n"));
|
|
332
|
+
if (eventBlocks.length > 0)
|
|
333
|
+
sections.push(eventBlocks.join("\n\n"));
|
|
334
|
+
if (viewBlocks.length > 0) {
|
|
335
|
+
sections.push(viewBlocks.join("\n\n"));
|
|
336
|
+
sections.push(["interface Views {", ...indent(viewOps, 1), "}"].join("\n"));
|
|
337
|
+
}
|
|
338
|
+
if (commandOps.length > 0) {
|
|
339
|
+
sections.push(["interface Commands {", ...indent(commandOps, 1), "}"].join("\n"));
|
|
340
|
+
}
|
|
341
|
+
const header = [
|
|
342
|
+
`// GENERATED by \`em typespec\` (${TYPESPEC_SCHEMA_VERSION}) — EXPERIMENTAL / POC (MIL-159).`,
|
|
343
|
+
`// Source: ${doc.source.path} (sha256 ${doc.source.sha256})`,
|
|
344
|
+
`// Scope: \`public\` events/views (docs/dsl.md "Integration surface"), plus every command in`,
|
|
345
|
+
`// a slice that declares at least one of them. \`tag\`/\`renamed from\`/\`assigned\` are recorded`,
|
|
346
|
+
`// as doc comments only — see docs/cli.md's "em typespec" section for the full mapping.`,
|
|
347
|
+
`// Do not edit by hand — regenerate with \`em typespec ${doc.source.path}\`.`,
|
|
348
|
+
];
|
|
349
|
+
const body = sections.length > 0 ? indent(sections.join("\n\n").split("\n"), 1) : [];
|
|
350
|
+
const namespaceLines = body.length > 0
|
|
351
|
+
? [`namespace ${namespaceName} {`, ...body, `}`]
|
|
352
|
+
: [`namespace ${namespaceName} {}`];
|
|
353
|
+
const text = [...header, "", ...namespaceLines].join("\n");
|
|
354
|
+
return { text, diagnostics: allDiagnostics, unmappedTypes: unmappedNotes };
|
|
355
|
+
}
|
|
356
|
+
//# sourceMappingURL=typespec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typespec.js","sourceRoot":"","sources":["../../src/emit/typespec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// Builds the `em usage-report --json` document: a versioned envelope around `UsageReport` (see
|
|
3
|
+
// ../cli/usageLog.ts). Follows every other command's convention (statusJson.ts/coverageJson.ts):
|
|
4
|
+
// a schema field versioned independently of both the npm package and every other command's own
|
|
5
|
+
// schema. Pretty-printed, no trailing newline, no timestamps — byte-identical for the same
|
|
6
|
+
// input files.
|
|
7
|
+
import { GENERATOR_NAME, GENERATOR_VERSION } from "./json.js";
|
|
8
|
+
// 1.0 (MIL-161): initial shape.
|
|
9
|
+
export const USAGE_REPORT_SCHEMA_VERSION = "1.0";
|
|
10
|
+
export function buildUsageReportJson(report) {
|
|
11
|
+
const doc = {
|
|
12
|
+
usageReportSchemaVersion: USAGE_REPORT_SCHEMA_VERSION,
|
|
13
|
+
generator: { name: GENERATOR_NAME, version: GENERATOR_VERSION },
|
|
14
|
+
root: report.root,
|
|
15
|
+
files: report.files,
|
|
16
|
+
sessions: report.sessions,
|
|
17
|
+
phaseCounts: report.phaseCounts,
|
|
18
|
+
categoryCounts: report.categoryCounts,
|
|
19
|
+
unparseableLines: report.unparseableLines,
|
|
20
|
+
};
|
|
21
|
+
return JSON.stringify(doc, null, 2);
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=usageReportJson.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usageReportJson.js","sourceRoot":"","sources":["../../src/emit/usageReportJson.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,+FAA+F;AAC/F,iGAAiG;AACjG,+FAA+F;AAC/F,2FAA2F;AAC3F,eAAe;AAGf,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAE9D,gCAAgC;AAChC,MAAM,CAAC,MAAM,2BAA2B,GAAG,KAAK,CAAC;AAEjD,MAAM,UAAU,oBAAoB,CAAC,MAAmB;IACtD,MAAM,GAAG,GAAG;QACV,wBAAwB,EAAE,2BAA2B;QACrD,SAAS,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,iBAAiB,EAAE;QAC/D,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;KAC1C,CAAC;IACF,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACtC,CAAC"}
|
package/dist/mcp/server.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
4
4
|
* so `em --version`/`em export`'s `generator.version`/this server's version never drift apart. */
|
|
5
5
|
export declare const SERVER_NAME = "em";
|
|
6
6
|
export declare const SERVER_VERSION: string;
|
|
7
|
-
/** Registers all
|
|
7
|
+
/** Registers all thirteen MCP tools on a fresh McpServer instance and returns it, unconnected — the
|
|
8
8
|
* caller (src/mcp/main.ts's stdio entry, or a test harness using an in-memory transport)
|
|
9
9
|
* decides how to connect it. Building the server is a pure, side-effect-free function so tests
|
|
10
10
|
* can exercise it directly with the SDK's in-memory transport, no child process required. */
|