@milehimikey/em 1.13.1 → 1.14.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/agents/em-critic.md +26 -0
- package/.claude/agents/em-implementer.md +34 -0
- package/.claude/agents/em-reviewer.md +31 -0
- package/.claude/agents/em-validator.md +27 -0
- package/.claude/skills/event-modeling/SKILL.md +50 -11
- package/.claude/skills/event-modeling-conform/SKILL.md +1 -1
- package/.claude/skills/event-modeling-design/SKILL.md +126 -18
- package/.claude/skills/event-modeling-discover/SKILL.md +1 -1
- package/.claude/skills/event-modeling-engagement/SKILL.md +192 -0
- package/.claude/skills/event-modeling-engagement/reference/engagement.md +143 -0
- package/.claude/skills/event-modeling-implement/SKILL.md +1 -1
- package/.claude/skills/event-modeling-implement/reference/implement.md +38 -11
- package/.claude/skills/event-modeling-review/SKILL.md +1 -1
- package/.claude/skills/event-modeling-shared/reference/em-dsl.md +274 -189
- package/.claude/skills/event-modeling-shared/reference/operating-principles.md +61 -0
- package/.claude/skills/event-modeling-shared/reference/slice-doc-schema.md +108 -5
- package/.claude/skills/event-modeling-shared/templates/constitution.md +18 -1
- package/.claude/skills/event-modeling-shared/templates/slice.md +64 -39
- package/.claude/skills/event-modeling-shared/templates/state.md +5 -1
- package/.claude-plugin/marketplace.json +14 -0
- package/README.md +25 -11
- package/dist/catalog/apiFirst.d.ts +28 -0
- package/dist/catalog/apiFirst.js +49 -0
- package/dist/catalog/apiFirst.js.map +1 -0
- package/dist/catalog/docJoin.d.ts +13 -0
- package/dist/catalog/docJoin.js +11 -0
- package/dist/catalog/docJoin.js.map +1 -1
- package/dist/catalog/docModelConsistencyValidate.js +44 -4
- package/dist/catalog/docModelConsistencyValidate.js.map +1 -1
- package/dist/catalog/invariantsValidate.d.ts +4 -0
- package/dist/catalog/invariantsValidate.js +102 -0
- package/dist/catalog/invariantsValidate.js.map +1 -0
- package/dist/catalog/scenarios.d.ts +15 -0
- package/dist/catalog/scenarios.js +97 -0
- package/dist/catalog/scenarios.js.map +1 -0
- package/dist/catalog/sliceDoc.d.ts +8 -0
- package/dist/catalog/sliceDoc.js +9 -0
- package/dist/catalog/sliceDoc.js.map +1 -1
- package/dist/catalog/sliceReadyValidate.d.ts +31 -4
- package/dist/catalog/sliceReadyValidate.js +66 -8
- package/dist/catalog/sliceReadyValidate.js.map +1 -1
- package/dist/catalog/sliceSections.d.ts +55 -0
- package/dist/catalog/sliceSections.js +317 -0
- package/dist/catalog/sliceSections.js.map +1 -0
- package/dist/cli/agentsMd.js +7 -1
- package/dist/cli/agentsMd.js.map +1 -1
- package/dist/cli/api.d.ts +90 -0
- package/dist/cli/api.js +318 -0
- package/dist/cli/api.js.map +1 -0
- package/dist/cli/ciInit.d.ts +82 -21
- package/dist/cli/ciInit.js +468 -64
- package/dist/cli/ciInit.js.map +1 -1
- package/dist/cli/conformScope.d.ts +28 -0
- package/dist/cli/conformScope.js +67 -0
- package/dist/cli/conformScope.js.map +1 -1
- package/dist/cli/coverage.d.ts +9 -0
- package/dist/cli/coverage.js +60 -8
- package/dist/cli/coverage.js.map +1 -1
- package/dist/cli/engagement.d.ts +210 -0
- package/dist/cli/engagement.js +444 -0
- package/dist/cli/engagement.js.map +1 -0
- package/dist/cli/engagementFile.d.ts +86 -0
- package/dist/cli/engagementFile.js +255 -0
- package/dist/cli/engagementFile.js.map +1 -0
- package/dist/cli/metrics.d.ts +10 -0
- package/dist/cli/metrics.js +49 -1
- package/dist/cli/metrics.js.map +1 -1
- package/dist/cli/pluginPin.d.ts +55 -0
- package/dist/cli/pluginPin.js +188 -0
- package/dist/cli/pluginPin.js.map +1 -0
- package/dist/cli/ratify.d.ts +27 -2
- package/dist/cli/ratify.js +112 -13
- package/dist/cli/ratify.js.map +1 -1
- package/dist/cli/reratify.d.ts +3 -2
- package/dist/cli/reratify.js +36 -14
- package/dist/cli/reratify.js.map +1 -1
- package/dist/cli/scopeInputs.d.ts +48 -0
- package/dist/cli/scopeInputs.js +176 -0
- package/dist/cli/scopeInputs.js.map +1 -0
- package/dist/cli/skillCheck.d.ts +15 -1
- package/dist/cli/skillCheck.js +22 -1
- package/dist/cli/skillCheck.js.map +1 -1
- package/dist/cli/skillDirs.d.ts +5 -0
- package/dist/cli/skillDirs.js +13 -1
- package/dist/cli/skillDirs.js.map +1 -1
- package/dist/cli/skillSync.d.ts +4 -0
- package/dist/cli/skillSync.js +23 -0
- package/dist/cli/skillSync.js.map +1 -1
- package/dist/cli/sliceNew.d.ts +11 -7
- package/dist/cli/sliceNew.js +91 -18
- package/dist/cli/sliceNew.js.map +1 -1
- package/dist/cli/sliceSync.d.ts +50 -0
- package/dist/cli/sliceSync.js +170 -0
- package/dist/cli/sliceSync.js.map +1 -0
- package/dist/cli/status.d.ts +24 -1
- package/dist/cli/status.js +20 -1
- package/dist/cli/status.js.map +1 -1
- package/dist/cli/systemInputs.d.ts +53 -10
- package/dist/cli/systemInputs.js +186 -11
- package/dist/cli/systemInputs.js.map +1 -1
- package/dist/cli/upgrade.d.ts +16 -3
- package/dist/cli/upgrade.js +366 -30
- package/dist/cli/upgrade.js.map +1 -1
- package/dist/cli/usageLog.d.ts +4 -2
- package/dist/cli/usageLog.js +4 -2
- package/dist/cli/usageLog.js.map +1 -1
- package/dist/cli.js +554 -94
- package/dist/cli.js.map +1 -1
- package/dist/emit/api.d.ts +29 -0
- package/dist/emit/api.js +220 -0
- package/dist/emit/api.js.map +1 -0
- package/dist/emit/apiCheckJson.d.ts +3 -0
- package/dist/emit/apiCheckJson.js +21 -0
- package/dist/emit/apiCheckJson.js.map +1 -0
- package/dist/emit/codeownersJson.d.ts +3 -0
- package/dist/emit/codeownersJson.js +19 -0
- package/dist/emit/codeownersJson.js.map +1 -0
- package/dist/emit/diffJson.d.ts +1 -1
- package/dist/emit/diffJson.js +8 -1
- package/dist/emit/diffJson.js.map +1 -1
- package/dist/emit/engagementJson.d.ts +8 -0
- package/dist/emit/engagementJson.js +46 -0
- package/dist/emit/engagementJson.js.map +1 -0
- package/dist/emit/glossaryJson.d.ts +1 -1
- package/dist/emit/glossaryJson.js +4 -1
- package/dist/emit/glossaryJson.js.map +1 -1
- package/dist/emit/json.d.ts +17 -1
- package/dist/emit/json.js +30 -1
- package/dist/emit/json.js.map +1 -1
- package/dist/emit/metricsJson.d.ts +1 -1
- package/dist/emit/metricsJson.js +4 -1
- package/dist/emit/metricsJson.js.map +1 -1
- package/dist/emit/queryJson.d.ts +1 -1
- package/dist/emit/queryJson.js +7 -1
- package/dist/emit/queryJson.js.map +1 -1
- package/dist/emit/scopeJson.d.ts +12 -0
- package/dist/emit/scopeJson.js +26 -0
- package/dist/emit/scopeJson.js.map +1 -0
- package/dist/emit/skillCheckJson.d.ts +3 -2
- package/dist/emit/skillCheckJson.js +10 -2
- package/dist/emit/skillCheckJson.js.map +1 -1
- package/dist/emit/statusJson.d.ts +1 -1
- package/dist/emit/statusJson.js +15 -1
- package/dist/emit/statusJson.js.map +1 -1
- package/dist/emit/systemJson.d.ts +15 -8
- package/dist/emit/systemJson.js +28 -13
- package/dist/emit/systemJson.js.map +1 -1
- package/dist/emit/validateJson.d.ts +3 -3
- package/dist/emit/validateJson.js +10 -4
- package/dist/emit/validateJson.js.map +1 -1
- package/dist/mcp/server.d.ts +1 -1
- package/dist/mcp/server.js +163 -31
- package/dist/mcp/server.js.map +1 -1
- package/dist/model/diff.d.ts +4 -1
- package/dist/model/diff.js +44 -8
- package/dist/model/diff.js.map +1 -1
- package/dist/model/glossary.d.ts +2 -0
- package/dist/model/glossary.js +1 -0
- package/dist/model/glossary.js.map +1 -1
- package/dist/model/model.d.ts +55 -2
- package/dist/model/model.js +57 -0
- package/dist/model/model.js.map +1 -1
- package/dist/model/qualifiedRef.d.ts +18 -0
- package/dist/model/qualifiedRef.js +26 -0
- package/dist/model/qualifiedRef.js.map +1 -1
- package/dist/model/queryIndex.d.ts +9 -1
- package/dist/model/queryIndex.js +18 -2
- package/dist/model/queryIndex.js.map +1 -1
- package/dist/model/rules.d.ts +143 -2
- package/dist/model/rules.js +162 -3
- package/dist/model/rules.js.map +1 -1
- package/dist/model/validate.d.ts +40 -0
- package/dist/model/validate.js +147 -1
- package/dist/model/validate.js.map +1 -1
- package/dist/parser/ast.d.ts +31 -3
- package/dist/parser/parser.js +148 -14
- package/dist/parser/parser.js.map +1 -1
- package/dist/query/format.js +1 -1
- package/dist/query/format.js.map +1 -1
- package/dist/query/verbs.d.ts +6 -0
- package/dist/query/verbs.js +6 -2
- package/dist/query/verbs.js.map +1 -1
- package/dist/system/adaptation.d.ts +14 -0
- package/dist/system/adaptation.js +49 -0
- package/dist/system/adaptation.js.map +1 -0
- package/dist/system/codeowners.d.ts +77 -0
- package/dist/system/codeowners.js +242 -0
- package/dist/system/codeowners.js.map +1 -0
- package/dist/system/manifest.d.ts +10 -5
- package/dist/system/manifest.js +54 -26
- package/dist/system/manifest.js.map +1 -1
- package/dist/system/migrateManifest.d.ts +28 -0
- package/dist/system/migrateManifest.js +155 -0
- package/dist/system/migrateManifest.js.map +1 -0
- package/dist/system/scope.d.ts +46 -0
- package/dist/system/scope.js +132 -0
- package/dist/system/scope.js.map +1 -0
- package/dist/system/verify.d.ts +50 -13
- package/dist/system/verify.js +179 -58
- package/dist/system/verify.js.map +1 -1
- package/dist/templates.d.ts +2 -2
- package/dist/templates.js +23 -2
- package/dist/templates.js.map +1 -1
- package/package.json +5 -2
- package/plugin/.claude-plugin/plugin.json +18 -0
- package/plugin/agents/em-critic.md +27 -0
- package/plugin/agents/em-implementer.md +35 -0
- package/plugin/agents/em-reviewer.md +32 -0
- package/plugin/agents/em-validator.md +28 -0
- package/plugin/shared/reference/em-dsl.md +866 -0
- package/plugin/shared/reference/methodology.md +329 -0
- package/plugin/shared/reference/operating-principles.md +222 -0
- package/plugin/shared/reference/slice-doc-schema.md +566 -0
- package/plugin/shared/templates/conformance-report.md +85 -0
- package/plugin/shared/templates/constitution.md +136 -0
- package/plugin/shared/templates/model-readme.md +46 -0
- package/plugin/shared/templates/slice.md +251 -0
- package/plugin/shared/templates/state.md +77 -0
- package/plugin/skills/conform/SKILL.md +93 -0
- package/plugin/skills/conform/reference/conform.md +428 -0
- package/plugin/skills/design/SKILL.md +297 -0
- package/plugin/skills/discover/SKILL.md +90 -0
- package/plugin/skills/discover/reference/extract.md +147 -0
- package/plugin/skills/engagement/SKILL.md +193 -0
- package/plugin/skills/engagement/reference/engagement.md +144 -0
- package/plugin/skills/event-modeling/SKILL.md +132 -0
- package/plugin/skills/implement/SKILL.md +61 -0
- package/plugin/skills/implement/reference/implement.md +439 -0
- package/plugin/skills/review/SKILL.md +74 -0
- package/dist/emit/typespec.d.ts +0 -26
- package/dist/emit/typespec.js +0 -356
- package/dist/emit/typespec.js.map +0 -1
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { Diagnostic } from "../model/validate.js";
|
|
2
|
+
import { compile } from "../pipeline.js";
|
|
3
|
+
import { ElementExport, FieldExport, TypeExport } from "../emit/json.js";
|
|
4
|
+
import { GitRunner } from "./diff-inputs.js";
|
|
5
|
+
/** `<modelDir>/contracts/<modelKey>.tsp` (R6), built from the model path as given. */
|
|
6
|
+
export declare function contractPathFor(modelFile: string, modelKey: string): string;
|
|
7
|
+
/** The `Source:` label: the model path relative to the contract file's directory, `/`-separated,
|
|
8
|
+
* so the generated text never depends on the cwd `em api generate` ran from. */
|
|
9
|
+
export declare function sourceLabelFor(modelFile: string, contractFile: string): string;
|
|
10
|
+
export interface GeneratedContract {
|
|
11
|
+
modelKey: string;
|
|
12
|
+
contractPath: string;
|
|
13
|
+
/** Full file text, trailing newline included. */
|
|
14
|
+
text: string;
|
|
15
|
+
diagnostics: Diagnostic[];
|
|
16
|
+
}
|
|
17
|
+
/** Compile result + generated contract text for an error-free model. */
|
|
18
|
+
export declare function generateContract(file: string, source: string, compiled: ReturnType<typeof compile>, outPath?: string): GeneratedContract;
|
|
19
|
+
export type ApiChangeKind = "additive" | "breaking";
|
|
20
|
+
export interface ApiCheckChange {
|
|
21
|
+
kind: ApiChangeKind;
|
|
22
|
+
/** `<kind>.<slug>` of the element (or `type.<slug>` for a declared type) — contract-level
|
|
23
|
+
* identity, no slice key (moving an element between slices does not change the contract). */
|
|
24
|
+
element: string;
|
|
25
|
+
/** The field the change concerns, or null for an element-level change. */
|
|
26
|
+
field: string | null;
|
|
27
|
+
what: string;
|
|
28
|
+
}
|
|
29
|
+
type Role = "input" | "output";
|
|
30
|
+
interface SurfaceEntry {
|
|
31
|
+
/** command | event | view | type */
|
|
32
|
+
kind: string;
|
|
33
|
+
name: string;
|
|
34
|
+
/** Normalized identity key: kind + normalizeName(name). */
|
|
35
|
+
key: string;
|
|
36
|
+
fields: FieldExport[];
|
|
37
|
+
renamedFrom: string[];
|
|
38
|
+
roles: Set<Role>;
|
|
39
|
+
/** Model-declared invariants (MIL-265), declaration order; `[]` for a type. */
|
|
40
|
+
invariants: {
|
|
41
|
+
id: string;
|
|
42
|
+
rule: string | null;
|
|
43
|
+
}[];
|
|
44
|
+
}
|
|
45
|
+
interface Surface {
|
|
46
|
+
entries: SurfaceEntry[];
|
|
47
|
+
/** Normalized `kind:name` of every element present in the model, public or not — tells
|
|
48
|
+
* "`public` dropped" apart from "removed". */
|
|
49
|
+
allElements: Set<string>;
|
|
50
|
+
}
|
|
51
|
+
/** Build the public surface of one compiled model: public commands (input), events and views
|
|
52
|
+
* (output), and every declared type reachable from them (carrying the roles that reach it). */
|
|
53
|
+
export declare function surfaceOf(slices: {
|
|
54
|
+
elements: ElementExport[];
|
|
55
|
+
}[], types: TypeExport[]): Surface;
|
|
56
|
+
/** A field's type as the contract sees it: a declared type's name or the raw string,
|
|
57
|
+
* normalized, with its array arity. */
|
|
58
|
+
export declare function typeLabel(f: Pick<FieldExport, "type" | "typeRef">): string;
|
|
59
|
+
export declare function typeIdentity(f: Pick<FieldExport, "type" | "typeRef">): string;
|
|
60
|
+
/** Diff two public surfaces. `base === null` means the model did not exist at the base
|
|
61
|
+
* revision: every HEAD element is an additive addition. */
|
|
62
|
+
export declare function diffSurfaces(base: Surface | null, head: Surface): ApiCheckChange[];
|
|
63
|
+
export interface ApiCheckReport {
|
|
64
|
+
file: string;
|
|
65
|
+
contractPath: string;
|
|
66
|
+
current: boolean;
|
|
67
|
+
/** True when the contract file does not exist at all (a special case of not current). */
|
|
68
|
+
missing: boolean;
|
|
69
|
+
base: string | null;
|
|
70
|
+
changes: ApiCheckChange[];
|
|
71
|
+
}
|
|
72
|
+
export type ApiCheckOutcome = {
|
|
73
|
+
ok: true;
|
|
74
|
+
report: ApiCheckReport;
|
|
75
|
+
diagnostics: Diagnostic[];
|
|
76
|
+
} | {
|
|
77
|
+
ok: false;
|
|
78
|
+
message: string;
|
|
79
|
+
diagnostics: Diagnostic[];
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Run `em api check <file> [--base <rev>]`. (a) "current" = regenerate from the working-tree
|
|
83
|
+
* model and compare to the committed contract file's text; (b) with `base`, compile the model
|
|
84
|
+
* at that revision (`resolveRevision`) and diff the public surfaces structurally. A model
|
|
85
|
+
* absent at `base` (new model) reports every public element as additive.
|
|
86
|
+
*/
|
|
87
|
+
export declare function runApiCheck(file: string, base: string | undefined, runGit?: GitRunner): ApiCheckOutcome;
|
|
88
|
+
/** The text report: one status line, then one `additive:`/`breaking:` line per change. */
|
|
89
|
+
export declare function formatApiCheckText(r: ApiCheckReport): string[];
|
|
90
|
+
export {};
|
package/dist/cli/api.js
ADDED
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
// `em api generate | check` (MIL-237): the contract path convention (briefing R6), the
|
|
3
|
+
// "is the committed contract current" text comparison, and the structural public-surface diff
|
|
4
|
+
// that annotates each change additive or breaking (briefing R8/R12). Pure where it can be —
|
|
5
|
+
// fs/git reads go through injectable readers so the diff and the classification are unit-
|
|
6
|
+
// testable without a repository; cli.ts and the MCP `api_check` tool share `runApiCheck`.
|
|
7
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
8
|
+
import { dirname, join, relative, resolve, sep } from "node:path";
|
|
9
|
+
import { normalizeName } from "../model/model.js";
|
|
10
|
+
import { computeModelKey } from "../model/qualifiedRef.js";
|
|
11
|
+
import { hasErrors } from "../model/validate.js";
|
|
12
|
+
import { compile } from "../pipeline.js";
|
|
13
|
+
import { ParseError } from "../parser/parser.js";
|
|
14
|
+
import { buildApiContract, publicSurfaceOf } from "../emit/api.js";
|
|
15
|
+
import { buildExportDoc } from "../emit/json.js";
|
|
16
|
+
import { kebabSlug } from "../util/slug.js";
|
|
17
|
+
import { realGit, resolveRevision } from "./diff-inputs.js";
|
|
18
|
+
/** `<modelDir>/contracts/<modelKey>.tsp` (R6), built from the model path as given. */
|
|
19
|
+
export function contractPathFor(modelFile, modelKey) {
|
|
20
|
+
return join(dirname(modelFile), "contracts", `${modelKey}.tsp`);
|
|
21
|
+
}
|
|
22
|
+
/** The `Source:` label: the model path relative to the contract file's directory, `/`-separated,
|
|
23
|
+
* so the generated text never depends on the cwd `em api generate` ran from. */
|
|
24
|
+
export function sourceLabelFor(modelFile, contractFile) {
|
|
25
|
+
return relative(dirname(resolve(contractFile)), resolve(modelFile)).split(sep).join("/");
|
|
26
|
+
}
|
|
27
|
+
/** Compile result + generated contract text for an error-free model. */
|
|
28
|
+
export function generateContract(file, source, compiled, outPath) {
|
|
29
|
+
const modelKey = computeModelKey(compiled.model, file);
|
|
30
|
+
const contractPath = outPath ?? contractPathFor(file, modelKey);
|
|
31
|
+
const result = buildApiContract(compiled.model, compiled.refs, compiled.diagnostics, source, file, sourceLabelFor(file, contractPath));
|
|
32
|
+
return { modelKey, contractPath, text: result.text + "\n", diagnostics: result.diagnostics };
|
|
33
|
+
}
|
|
34
|
+
const keyOf = (kind, name) => `${kind}:${normalizeName(name)}`;
|
|
35
|
+
/** Build the public surface of one compiled model: public commands (input), events and views
|
|
36
|
+
* (output), and every declared type reachable from them (carrying the roles that reach it). */
|
|
37
|
+
export function surfaceOf(slices, types) {
|
|
38
|
+
const s = publicSurfaceOf(slices);
|
|
39
|
+
const entries = [];
|
|
40
|
+
const typesByRef = new Map(types.map((t) => [t.ref, t]));
|
|
41
|
+
const typeRoles = new Map();
|
|
42
|
+
const reach = (fields, role) => {
|
|
43
|
+
for (const f of fields ?? []) {
|
|
44
|
+
if (!f.typeRef)
|
|
45
|
+
continue;
|
|
46
|
+
const roles = typeRoles.get(f.typeRef.ref) ?? new Set();
|
|
47
|
+
if (roles.has(role))
|
|
48
|
+
continue;
|
|
49
|
+
roles.add(role);
|
|
50
|
+
typeRoles.set(f.typeRef.ref, roles);
|
|
51
|
+
reach(typesByRef.get(f.typeRef.ref)?.fields ?? null, role);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
const push = (el, role) => {
|
|
55
|
+
entries.push({
|
|
56
|
+
kind: el.kind,
|
|
57
|
+
name: el.name,
|
|
58
|
+
key: keyOf(el.kind, el.name),
|
|
59
|
+
fields: el.fields ?? [],
|
|
60
|
+
renamedFrom: el.renamedFrom ?? [],
|
|
61
|
+
roles: new Set([role]),
|
|
62
|
+
invariants: el.invariants ?? [],
|
|
63
|
+
});
|
|
64
|
+
reach(el.fields, role);
|
|
65
|
+
};
|
|
66
|
+
for (const el of s.commands)
|
|
67
|
+
push(el, "input");
|
|
68
|
+
for (const el of s.events)
|
|
69
|
+
push(el, "output");
|
|
70
|
+
for (const el of s.views)
|
|
71
|
+
push(el, "output");
|
|
72
|
+
for (const t of types) {
|
|
73
|
+
const roles = typeRoles.get(t.ref);
|
|
74
|
+
if (!roles)
|
|
75
|
+
continue;
|
|
76
|
+
entries.push({ kind: "type", name: t.name, key: keyOf("type", t.name), fields: t.fields, renamedFrom: [], roles, invariants: [] });
|
|
77
|
+
}
|
|
78
|
+
const allElements = new Set();
|
|
79
|
+
for (const slice of slices)
|
|
80
|
+
for (const el of slice.elements)
|
|
81
|
+
allElements.add(keyOf(el.kind, el.name));
|
|
82
|
+
for (const t of types)
|
|
83
|
+
allElements.add(keyOf("type", t.name));
|
|
84
|
+
return { entries, allElements };
|
|
85
|
+
}
|
|
86
|
+
/** A field's type as the contract sees it: a declared type's name or the raw string,
|
|
87
|
+
* normalized, with its array arity. */
|
|
88
|
+
export function typeLabel(f) {
|
|
89
|
+
if (f.typeRef)
|
|
90
|
+
return `${f.typeRef.name}${f.typeRef.array ? "[]" : ""}`;
|
|
91
|
+
return f.type ?? "(none)";
|
|
92
|
+
}
|
|
93
|
+
export function typeIdentity(f) {
|
|
94
|
+
if (f.typeRef)
|
|
95
|
+
return `ref:${f.typeRef.ref}:${f.typeRef.array}`;
|
|
96
|
+
return `raw:${(f.type ?? "").replace(/\s+/g, "").toLowerCase()}`;
|
|
97
|
+
}
|
|
98
|
+
function diffFields(base, head, element, out) {
|
|
99
|
+
const roles = new Set([...base.roles, ...head.roles]);
|
|
100
|
+
const isInput = roles.has("input");
|
|
101
|
+
const isOutput = roles.has("output");
|
|
102
|
+
const headByName = new Map(head.fields.map((f) => [normalizeName(f.name), f]));
|
|
103
|
+
const baseByName = new Map(base.fields.map((f) => [normalizeName(f.name), f]));
|
|
104
|
+
// HEAD field -> base field it renames (a `renamed from` naming a base field that HEAD no
|
|
105
|
+
// longer carries under its old name).
|
|
106
|
+
const renamedTo = new Map();
|
|
107
|
+
for (const f of head.fields) {
|
|
108
|
+
if (baseByName.has(normalizeName(f.name)))
|
|
109
|
+
continue;
|
|
110
|
+
for (const old of f.renamedFrom ?? []) {
|
|
111
|
+
const k = normalizeName(old);
|
|
112
|
+
if (baseByName.has(k) && !headByName.has(k) && !renamedTo.has(k)) {
|
|
113
|
+
renamedTo.set(k, f);
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const compare = (b, h) => {
|
|
119
|
+
if (typeIdentity(b) !== typeIdentity(h)) {
|
|
120
|
+
out.push({ kind: "breaking", element, field: h.name, what: `type changed ${typeLabel(b)} → ${typeLabel(h)}` });
|
|
121
|
+
}
|
|
122
|
+
if (b.optional !== h.optional) {
|
|
123
|
+
if (h.optional) {
|
|
124
|
+
// required → optional: outputs may now omit it (breaking); inputs only loosen.
|
|
125
|
+
out.push({ kind: isOutput ? "breaking" : "additive", element, field: h.name, what: "changed required → optional" });
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
out.push({ kind: "breaking", element, field: h.name, what: "changed optional → required" });
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
// Base order first: removals, renames and changes to existing fields.
|
|
133
|
+
for (const b of base.fields) {
|
|
134
|
+
const k = normalizeName(b.name);
|
|
135
|
+
const h = headByName.get(k);
|
|
136
|
+
if (h) {
|
|
137
|
+
compare(b, h);
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
const renamed = renamedTo.get(k);
|
|
141
|
+
if (renamed) {
|
|
142
|
+
out.push({ kind: "breaking", element, field: renamed.name, what: `renamed from "${b.name}"` });
|
|
143
|
+
compare(b, renamed);
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
out.push({ kind: "breaking", element, field: b.name, what: "removed" });
|
|
147
|
+
}
|
|
148
|
+
// Then HEAD-only fields, HEAD order.
|
|
149
|
+
const renameTargets = new Set([...renamedTo.values()]);
|
|
150
|
+
for (const h of head.fields) {
|
|
151
|
+
if (baseByName.has(normalizeName(h.name)) || renameTargets.has(h))
|
|
152
|
+
continue;
|
|
153
|
+
const required = !h.optional;
|
|
154
|
+
// Adding a required input is breaking (existing callers do not send it); adding to an
|
|
155
|
+
// output is additive (consumers tolerate unknown fields).
|
|
156
|
+
const kind = isInput && required ? "breaking" : "additive";
|
|
157
|
+
out.push({ kind, element, field: h.name, what: `added (${required ? "required" : "optional"})` });
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/** MIL-265: a public element's invariants, base vs HEAD, matched by ID. Added or rule text
|
|
161
|
+
* changed = breaking (the contract got tighter); removed = additive (looser). HEAD order for
|
|
162
|
+
* additions/changes, then base order for removals. */
|
|
163
|
+
function diffInvariants(base, head, element, out) {
|
|
164
|
+
const baseById = new Map(base.invariants.map((i) => [i.id, i]));
|
|
165
|
+
const headIds = new Set(head.invariants.map((i) => i.id));
|
|
166
|
+
for (const h of head.invariants) {
|
|
167
|
+
const b = baseById.get(h.id);
|
|
168
|
+
if (!b)
|
|
169
|
+
out.push({ kind: "breaking", element, field: null, what: `invariant ${h.id} added` });
|
|
170
|
+
else if (b.rule !== h.rule)
|
|
171
|
+
out.push({ kind: "breaking", element, field: null, what: `invariant ${h.id} rule changed` });
|
|
172
|
+
}
|
|
173
|
+
for (const b of base.invariants) {
|
|
174
|
+
if (!headIds.has(b.id))
|
|
175
|
+
out.push({ kind: "additive", element, field: null, what: `invariant ${b.id} removed` });
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/** Diff two public surfaces. `base === null` means the model did not exist at the base
|
|
179
|
+
* revision: every HEAD element is an additive addition. */
|
|
180
|
+
export function diffSurfaces(base, head) {
|
|
181
|
+
const out = [];
|
|
182
|
+
const elementId = (e) => `${e.kind}.${kebabSlug(e.name)}`;
|
|
183
|
+
if (!base) {
|
|
184
|
+
for (const h of head.entries)
|
|
185
|
+
out.push({ kind: "additive", element: elementId(h), field: null, what: "added" });
|
|
186
|
+
return out;
|
|
187
|
+
}
|
|
188
|
+
const baseByKey = new Map(base.entries.map((e) => [e.key, e]));
|
|
189
|
+
const matchedBase = new Set();
|
|
190
|
+
for (const h of head.entries) {
|
|
191
|
+
const element = elementId(h);
|
|
192
|
+
const same = baseByKey.get(h.key);
|
|
193
|
+
if (same) {
|
|
194
|
+
matchedBase.add(same.key);
|
|
195
|
+
diffFields(same, h, element, out);
|
|
196
|
+
diffInvariants(same, h, element, out);
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
const renamedFrom = h.renamedFrom
|
|
200
|
+
.map((old) => baseByKey.get(keyOf(h.kind, old)))
|
|
201
|
+
.find((b) => b !== undefined && !matchedBase.has(b.key) && !head.entries.some((x) => x.key === b.key));
|
|
202
|
+
if (renamedFrom) {
|
|
203
|
+
matchedBase.add(renamedFrom.key);
|
|
204
|
+
out.push({ kind: "breaking", element, field: null, what: `renamed from "${renamedFrom.name}"` });
|
|
205
|
+
diffFields(renamedFrom, h, element, out);
|
|
206
|
+
diffInvariants(renamedFrom, h, element, out);
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
if (h.kind !== "type" && base.allElements.has(h.key)) {
|
|
210
|
+
out.push({ kind: "additive", element, field: null, what: "marked public" });
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
out.push({ kind: "additive", element, field: null, what: "added" });
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
for (const b of base.entries) {
|
|
217
|
+
if (matchedBase.has(b.key))
|
|
218
|
+
continue;
|
|
219
|
+
const element = elementId(b);
|
|
220
|
+
if (b.kind !== "type" && head.allElements.has(b.key)) {
|
|
221
|
+
out.push({ kind: "breaking", element, field: null, what: "`public` dropped" });
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
out.push({ kind: "breaking", element, field: null, what: "removed" });
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return out;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Run `em api check <file> [--base <rev>]`. (a) "current" = regenerate from the working-tree
|
|
231
|
+
* model and compare to the committed contract file's text; (b) with `base`, compile the model
|
|
232
|
+
* at that revision (`resolveRevision`) and diff the public surfaces structurally. A model
|
|
233
|
+
* absent at `base` (new model) reports every public element as additive.
|
|
234
|
+
*/
|
|
235
|
+
export function runApiCheck(file, base, runGit = realGit) {
|
|
236
|
+
let source;
|
|
237
|
+
try {
|
|
238
|
+
source = readFileSync(file, "utf8");
|
|
239
|
+
}
|
|
240
|
+
catch {
|
|
241
|
+
return { ok: false, message: `em api check: cannot read ${file}`, diagnostics: [] };
|
|
242
|
+
}
|
|
243
|
+
let head;
|
|
244
|
+
try {
|
|
245
|
+
head = compile(source);
|
|
246
|
+
}
|
|
247
|
+
catch (e) {
|
|
248
|
+
if (e instanceof ParseError)
|
|
249
|
+
return { ok: false, message: `em api check: parse error in ${file} ${e.message}`, diagnostics: [] };
|
|
250
|
+
throw e;
|
|
251
|
+
}
|
|
252
|
+
if (hasErrors(head.diagnostics)) {
|
|
253
|
+
return { ok: false, message: "em api check: not checking — fix the errors above", diagnostics: head.diagnostics };
|
|
254
|
+
}
|
|
255
|
+
const generated = generateContract(file, source, head);
|
|
256
|
+
const missing = !existsSync(generated.contractPath);
|
|
257
|
+
const current = !missing && readFileSync(generated.contractPath, "utf8") === generated.text;
|
|
258
|
+
let changes = [];
|
|
259
|
+
if (base !== undefined) {
|
|
260
|
+
const top = runGit(["-C", dirname(resolve(file)), "rev-parse", "--show-toplevel"]);
|
|
261
|
+
if (top.status !== 0) {
|
|
262
|
+
return { ok: false, message: `em api check: ${file} is not inside a git repository (needed for --base)`, diagnostics: head.diagnostics };
|
|
263
|
+
}
|
|
264
|
+
const verify = runGit(["-C", dirname(resolve(file)), "rev-parse", "--verify", "--quiet", `${base}^{commit}`]);
|
|
265
|
+
if (verify.status !== 0) {
|
|
266
|
+
return { ok: false, message: `em api check: unknown revision "${base}" (needed for --base)`, diagnostics: head.diagnostics };
|
|
267
|
+
}
|
|
268
|
+
const headDoc = buildExportDoc(head.model, head.refs, head.diagnostics, source, file).doc;
|
|
269
|
+
const headSurface = surfaceOf(headDoc.model.slices, headDoc.model.types);
|
|
270
|
+
const atBase = resolveRevision(file, base, runGit);
|
|
271
|
+
let baseSurface = null;
|
|
272
|
+
if (atBase.ok) {
|
|
273
|
+
let baseCompiled;
|
|
274
|
+
try {
|
|
275
|
+
baseCompiled = compile(atBase.content);
|
|
276
|
+
}
|
|
277
|
+
catch (e) {
|
|
278
|
+
if (e instanceof ParseError) {
|
|
279
|
+
return { ok: false, message: `em api check: parse error in ${file}@${base} ${e.message}`, diagnostics: head.diagnostics };
|
|
280
|
+
}
|
|
281
|
+
throw e;
|
|
282
|
+
}
|
|
283
|
+
// Base-side validate errors (e.g. a pre-1.14 free-text public type) do not block the
|
|
284
|
+
// structural diff — the diff reads shapes, not strictness.
|
|
285
|
+
const baseDoc = buildExportDoc(baseCompiled.model, baseCompiled.refs, baseCompiled.diagnostics, atBase.content, file).doc;
|
|
286
|
+
baseSurface = surfaceOf(baseDoc.model.slices, baseDoc.model.types);
|
|
287
|
+
}
|
|
288
|
+
else if (!/is not tracked by git/.test(atBase.message)) {
|
|
289
|
+
return { ok: false, message: atBase.message.replace(/^em diff:/, "em api check:"), diagnostics: head.diagnostics };
|
|
290
|
+
}
|
|
291
|
+
changes = diffSurfaces(baseSurface, headSurface);
|
|
292
|
+
}
|
|
293
|
+
return {
|
|
294
|
+
ok: true,
|
|
295
|
+
report: { file, contractPath: generated.contractPath, current, missing, base: base ?? null, changes },
|
|
296
|
+
diagnostics: generated.diagnostics,
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
/** The text report: one status line, then one `additive:`/`breaking:` line per change. */
|
|
300
|
+
export function formatApiCheckText(r) {
|
|
301
|
+
const lines = [];
|
|
302
|
+
const regen = `run: em api generate ${r.file}`;
|
|
303
|
+
if (r.current)
|
|
304
|
+
lines.push(`contract ${r.contractPath} is current`);
|
|
305
|
+
else if (r.missing)
|
|
306
|
+
lines.push(`contract ${r.contractPath} is missing — ${regen}`);
|
|
307
|
+
else
|
|
308
|
+
lines.push(`contract ${r.contractPath} is stale — ${regen}`);
|
|
309
|
+
if (r.base !== null) {
|
|
310
|
+
if (r.changes.length === 0)
|
|
311
|
+
lines.push(`no public-surface changes since ${r.base}`);
|
|
312
|
+
for (const c of r.changes) {
|
|
313
|
+
lines.push(`${c.kind}: ${c.element}${c.field !== null ? ` field "${c.field}"` : ""} ${c.what}`);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return lines;
|
|
317
|
+
}
|
|
318
|
+
//# sourceMappingURL=api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/cli/api.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/ciInit.d.ts
CHANGED
|
@@ -14,11 +14,35 @@ export declare function findUnsafeCiInitArg(value: string): string | null;
|
|
|
14
14
|
* by a pre-pin em shows stale the same way. */
|
|
15
15
|
export declare function ciManagedBody(model: string, testsDir: string, emVersion: string): string;
|
|
16
16
|
export declare function buildCiWorkflowFile(model: string, testsDir: string, emVersion: string): string;
|
|
17
|
+
/** One model of a system, as `em ci init <system.yaml>` hands it to the generators: its manifest
|
|
18
|
+
* key and its path relative to the repo root (the working directory the workflow runs from). */
|
|
19
|
+
export interface CiModel {
|
|
20
|
+
key: string;
|
|
21
|
+
path: string;
|
|
22
|
+
}
|
|
23
|
+
/** Deterministic, valid GitHub Actions job-id suffix per model key. Keys are kebab-case with an
|
|
24
|
+
* optional `~N` collision suffix (MIL-193), and `~` is not an Actions id character, so it
|
|
25
|
+
* becomes `-`; if two keys then collide (`a-2` and `a~2`), the later one in key order gets a
|
|
26
|
+
* numeric suffix until it is unique. Keys are processed in sorted order, so the mapping never
|
|
27
|
+
* depends on manifest order. */
|
|
28
|
+
export declare function ciJobIds(keys: string[]): Map<string, string>;
|
|
29
|
+
/** The directory a model's design artifacts live in (R6: `dirname(<model>.em)`). */
|
|
30
|
+
export declare function ciModelDir(modelPath: string): string;
|
|
31
|
+
/** The managed block for a whole system: per-model `validate-`/`slice-index-`/`coverage-`/
|
|
32
|
+
* `ledger-`/`upgrade-check-`/`status-badge-<id>` jobs, then ONE `skill-check` and ONE
|
|
33
|
+
* `glossary` (both repo-wide). Same version-pin discipline as `ciManagedBody`. */
|
|
34
|
+
export declare function ciManagedBodyMulti(models: CiModel[], testsDir: string, emVersion: string): string;
|
|
35
|
+
export declare function buildCiWorkflowFileMulti(arg: string, models: CiModel[], testsDir: string, emVersion: string): string;
|
|
17
36
|
/** The managed block only (no header/`on:`/`permissions:`/`jobs:` scaffolding) — what gets
|
|
18
37
|
* written between the marker pair, both for a fresh file and to patch an existing marked one
|
|
19
38
|
* in place. */
|
|
20
|
-
export declare function conformManagedBody(model: string, emVersion: string): string;
|
|
21
|
-
export declare function buildConformWorkflowFile(model: string, emVersion: string): string;
|
|
39
|
+
export declare function conformManagedBody(model: string, emVersion: string, usePlugin?: boolean): string;
|
|
40
|
+
export declare function buildConformWorkflowFile(model: string, emVersion: string, usePlugin?: boolean): string;
|
|
41
|
+
/** Conformance for a whole system: the same single `conform` job fanned out over a matrix of
|
|
42
|
+
* model directories (`MODEL_DIR: ${{ matrix.model }}`). Directories, not models: two models in
|
|
43
|
+
* one directory share a conformance folder, so the matrix lists each directory once. */
|
|
44
|
+
export declare function conformManagedBodyMulti(models: CiModel[], emVersion: string, usePlugin?: boolean): string;
|
|
45
|
+
export declare function buildConformWorkflowFileMulti(arg: string, models: CiModel[], emVersion: string, usePlugin?: boolean): string;
|
|
22
46
|
export type CiFileStatus = {
|
|
23
47
|
kind: "create";
|
|
24
48
|
content: string;
|
|
@@ -35,24 +59,42 @@ export type CiFileStatus = {
|
|
|
35
59
|
kind: "would-replace";
|
|
36
60
|
content: string;
|
|
37
61
|
} | {
|
|
38
|
-
kind: "other-
|
|
39
|
-
previous: string;
|
|
62
|
+
kind: "other-models";
|
|
63
|
+
previous: string[];
|
|
64
|
+
requested: string[];
|
|
65
|
+
narrowing: boolean;
|
|
40
66
|
} | {
|
|
41
|
-
kind: "replace-
|
|
67
|
+
kind: "replace-models";
|
|
42
68
|
content: string;
|
|
43
|
-
previous: string;
|
|
69
|
+
previous: string[];
|
|
70
|
+
requested: string[];
|
|
71
|
+
narrowing: boolean;
|
|
44
72
|
};
|
|
45
73
|
/**
|
|
46
|
-
*
|
|
47
|
-
* (MIL-256). Deliberately content-derived rather than a new marker
|
|
48
|
-
* 1.13.0 and earlier carry no machine-readable model, but every one
|
|
49
|
-
* the per-model `run:` lines
|
|
50
|
-
* `
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
74
|
+
* The model SET an existing managed block was generated for, read from the block's own content
|
|
75
|
+
* (MIL-256, widened to sets by MIL-233). Deliberately content-derived rather than a new marker
|
|
76
|
+
* line: blocks written by em 1.13.0 and earlier carry no machine-readable model, but every one
|
|
77
|
+
* of them bakes the model into the per-model `run:` lines. em-ci.yml: every
|
|
78
|
+
* `slice index "<model>" --check` line (one per model); em-conform.yml: every `matrix.model`
|
|
79
|
+
* entry of a multi-model block, else the single `MODEL_DIR: <dir>` line. None of these patterns
|
|
80
|
+
* includes the `npx @milehimikey/em@<ver>` pin, so a version difference can never read as a
|
|
81
|
+
* different model. Returns `[]` when the block was hand-edited past recognition - callers then
|
|
82
|
+
* treat it as covering the requested models (the conservative, pre-MIL-256 behavior) rather than
|
|
83
|
+
* refusing on a guess.
|
|
54
84
|
*/
|
|
55
|
-
export declare function
|
|
85
|
+
export declare function managedBlockModels(markerName: string, blockBody: string): string[];
|
|
86
|
+
/** The model set of an existing workflow file's managed block (`[]` when unmarked/unreadable). */
|
|
87
|
+
export declare function fileBlockModels(content: string, markerName: string): string[];
|
|
88
|
+
/** `--check`'s extra detail for a stale multi-model block: which models the manifest adds and
|
|
89
|
+
* which the workflow still names that the manifest no longer does. `null` when the sets agree. */
|
|
90
|
+
export declare function describeSetChange(previous: string[], requested: string[]): string | null;
|
|
91
|
+
/** The one-line explanation of an `other-models` refusal (also printed by `--check`), ending in
|
|
92
|
+
* what to do about it. Names both sets. */
|
|
93
|
+
export declare function describeOtherModels(path: string, status: {
|
|
94
|
+
previous: string[];
|
|
95
|
+
requested: string[];
|
|
96
|
+
narrowing: boolean;
|
|
97
|
+
}): string;
|
|
56
98
|
/**
|
|
57
99
|
* Decide what to do with one generated file: create it if missing, patch the managed block if
|
|
58
100
|
* the marker pair is present, or (without `force`) leave an existing unmarked file alone. Pure
|
|
@@ -63,11 +105,30 @@ export declare function managedBlockModel(markerName: string, blockBody: string)
|
|
|
63
105
|
* the text between the markers, reused to patch an existing marked file in place without
|
|
64
106
|
* touching whatever a repo added around it.
|
|
65
107
|
*
|
|
66
|
-
* MIL-256
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
108
|
+
* Block identity (MIL-256 #174, MIL-233): a block is identified by the SET of models it names
|
|
109
|
+
* (`managedBlockModels`). The requested set wins unless that would lose models by accident:
|
|
110
|
+
* - disjoint sets are `other-models` (refused without `force`, `replace-models` with it);
|
|
111
|
+
* - `multi` false (a single `<model.em>` argument) against a block naming several models is
|
|
112
|
+
* `other-models` too (`narrowing`) - the single-model form must never silently narrow it;
|
|
113
|
+
* - otherwise (same set, superset, subset or overlap, requested from the system manifest) the
|
|
114
|
+
* block is regenerated for the requested set - `stale` when anything differs, e.g. a version
|
|
115
|
+
* pin, an added model or a removed one.
|
|
116
|
+
* `em upgrade`'s ci-block step re-derives its arguments from the existing file (and, for a
|
|
117
|
+
* multi-model block, from the manifest), so it only ever plans the same set.
|
|
71
118
|
*/
|
|
72
|
-
export declare function planCiFile(path: string, generated: string, managedBody: string, markerName: string, force: boolean): CiFileStatus;
|
|
119
|
+
export declare function planCiFile(path: string, generated: string, managedBody: string, markerName: string, force: boolean, multi?: boolean): CiFileStatus;
|
|
73
120
|
export declare function applyCiFile(path: string, status: CiFileStatus): void;
|
|
121
|
+
export type CiModelsResult = {
|
|
122
|
+
ok: true;
|
|
123
|
+
models: CiModel[];
|
|
124
|
+
manifestPath: string;
|
|
125
|
+
} | {
|
|
126
|
+
ok: false;
|
|
127
|
+
message: string;
|
|
128
|
+
};
|
|
129
|
+
/** Read the system manifest at `target` (a file, or a directory holding `system.yaml`) and turn
|
|
130
|
+
* its `models:` into `CiModel`s whose paths are relative to `baseDir` - the repo root the
|
|
131
|
+
* workflows run from. Reuses MIL-235's `parseManifest`; compiling the models is not needed to
|
|
132
|
+
* write a workflow, so a model that does not compile does not block it. Every path goes through
|
|
133
|
+
* `findUnsafeCiInitArg`; a source must be a `.em` file inside `baseDir`. */
|
|
134
|
+
export declare function ciModelsFromManifest(target: string, baseDir: string): CiModelsResult;
|