@specverse/engines 6.33.0 → 6.34.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.
Files changed (57) hide show
  1. package/dist/libs/instance-factories/communication/rabbitmq-events.yaml +11 -0
  2. package/dist/libs/instance-factories/controllers/fastify.yaml +11 -0
  3. package/dist/libs/instance-factories/managed/stripe-rest-sdk.yaml +78 -0
  4. package/dist/libs/instance-factories/managed/templates/stripe/stripe-client-generator.js +8 -0
  5. package/dist/libs/instance-factories/orms/prisma.yaml +11 -0
  6. package/dist/realize/index.d.ts.map +1 -1
  7. package/dist/realize/index.js +261 -4
  8. package/dist/realize/index.js.map +1 -1
  9. package/dist/realize/library/loader.d.ts.map +1 -1
  10. package/dist/realize/library/loader.js +81 -1
  11. package/dist/realize/library/loader.js.map +1 -1
  12. package/dist/realize/per-action-emitter.d.ts +9 -0
  13. package/dist/realize/per-action-emitter.d.ts.map +1 -1
  14. package/dist/realize/per-action-emitter.js.map +1 -1
  15. package/dist/realize/per-action-llm-emit.d.ts.map +1 -1
  16. package/dist/realize/per-action-llm-emit.js +5 -1
  17. package/dist/realize/per-action-llm-emit.js.map +1 -1
  18. package/dist/realize/per-action-runner.d.ts +45 -0
  19. package/dist/realize/per-action-runner.d.ts.map +1 -1
  20. package/dist/realize/per-action-runner.js +132 -0
  21. package/dist/realize/per-action-runner.js.map +1 -1
  22. package/dist/realize/resolver/index.d.ts +157 -0
  23. package/dist/realize/resolver/index.d.ts.map +1 -0
  24. package/dist/realize/resolver/index.js +307 -0
  25. package/dist/realize/resolver/index.js.map +1 -0
  26. package/dist/realize/runtime-emitters/dispatcher.d.ts +176 -0
  27. package/dist/realize/runtime-emitters/dispatcher.d.ts.map +1 -0
  28. package/dist/realize/runtime-emitters/dispatcher.js +76 -0
  29. package/dist/realize/runtime-emitters/dispatcher.js.map +1 -0
  30. package/dist/realize/runtime-emitters/executable.d.ts +57 -0
  31. package/dist/realize/runtime-emitters/executable.d.ts.map +1 -0
  32. package/dist/realize/runtime-emitters/executable.js +316 -0
  33. package/dist/realize/runtime-emitters/executable.js.map +1 -0
  34. package/dist/realize/runtime-emitters/library.d.ts +52 -0
  35. package/dist/realize/runtime-emitters/library.d.ts.map +1 -0
  36. package/dist/realize/runtime-emitters/library.js +349 -0
  37. package/dist/realize/runtime-emitters/library.js.map +1 -0
  38. package/dist/realize/runtime-emitters/managed.d.ts +44 -0
  39. package/dist/realize/runtime-emitters/managed.d.ts.map +1 -0
  40. package/dist/realize/runtime-emitters/managed.js +283 -0
  41. package/dist/realize/runtime-emitters/managed.js.map +1 -0
  42. package/dist/realize/runtime-emitters/messaging.d.ts +77 -0
  43. package/dist/realize/runtime-emitters/messaging.d.ts.map +1 -0
  44. package/dist/realize/runtime-emitters/messaging.js +423 -0
  45. package/dist/realize/runtime-emitters/messaging.js.map +1 -0
  46. package/dist/realize/runtime-emitters/service.d.ts +42 -0
  47. package/dist/realize/runtime-emitters/service.d.ts.map +1 -0
  48. package/dist/realize/runtime-emitters/service.js +355 -0
  49. package/dist/realize/runtime-emitters/service.js.map +1 -0
  50. package/dist/realize/types/instance-factory.d.ts +1 -1
  51. package/dist/realize/types/instance-factory.d.ts.map +1 -1
  52. package/libs/instance-factories/communication/rabbitmq-events.yaml +11 -0
  53. package/libs/instance-factories/controllers/fastify.yaml +11 -0
  54. package/libs/instance-factories/managed/stripe-rest-sdk.yaml +78 -0
  55. package/libs/instance-factories/managed/templates/stripe/stripe-client-generator.ts +26 -0
  56. package/libs/instance-factories/orms/prisma.yaml +11 -0
  57. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/realize/resolver/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,176 @@
1
+ /**
2
+ * Per-runtime emitter dispatcher — V2 Phase 3, Round 1.
3
+ *
4
+ * Proposal: 2026-05-08-COMPONENT-DEPENDENCIES-V2.md, "Realize bridge" section.
5
+ *
6
+ * The dispatcher is a small registry + lookup framework. The real work lives in
7
+ * each topology-specific emitter implementation (library.ts, and future
8
+ * service.ts / managed.ts / executable.ts / messaging.ts files).
9
+ *
10
+ * Round 1 ships: dispatcher framework + library topology emitter (this file +
11
+ * library.ts). The two cross-branch types — `ResolvedComponent` (Agent A) and
12
+ * `FactoryV2Metadata` / `InstanceFactory` (Agent B) — are imported from their
13
+ * canonical locations: Round 1d (this commit) reconciled the local stubs with
14
+ * the merged real types.
15
+ *
16
+ * Round 2 will add: service, managed, executable, messaging emitters + CLI wiring.
17
+ */
18
+ import type { ComponentSpec, SpecVerseAST, InstanceFactory, FactoryTopology } from '@specverse/types';
19
+ import type { ResolvedComponent } from '../resolver/index.js';
20
+ export type { ResolvedComponent } from '../resolver/index.js';
21
+ export type { FactoryTopology, InstanceFactory } from '@specverse/types';
22
+ /** Alias kept for back-compat with the Round-1 stub naming. */
23
+ export type FactoryMetadata = InstanceFactory;
24
+ /**
25
+ * A single entry in a component's `import:` block.
26
+ * Mirrors the V2 Phase 1 schema additions (commit bb4b99b):
27
+ * - from: provider name (resolved via 4-step lookup)
28
+ * - version?: semver range (optional, defaults to ^latest)
29
+ * - select: array of bare or dotted operation names
30
+ */
31
+ export interface ImportEntry {
32
+ from: string;
33
+ version?: string;
34
+ select: string[];
35
+ }
36
+ /**
37
+ * Context passed to every runtime emitter.
38
+ * Carries the consumer-side view (component + import entry) alongside
39
+ * the resolved provider (Agent A) and the factory metadata (Agent B).
40
+ */
41
+ export interface RuntimeEmitterContext {
42
+ /** The component that contains the `import:` block. */
43
+ consumerComponent: ComponentSpec;
44
+ /** The specific {from, version?, select} entry being emitted. */
45
+ importEntry: ImportEntry;
46
+ /**
47
+ * Resolver result for this import entry.
48
+ * Round 1 stub: callers construct this manually; Agent A's resolver will
49
+ * produce it automatically when integrated in Round 2.
50
+ */
51
+ resolved: ResolvedComponent;
52
+ /**
53
+ * Factory metadata from the manifest's capabilityMappings.
54
+ * Round 1 stub: callers construct this manually; Agent B's schema +
55
+ * the registry-aware manifest-emitter will produce it when integrated.
56
+ */
57
+ factory: FactoryMetadata;
58
+ /**
59
+ * Absolute path to the consumer component's realize output directory.
60
+ * Generated clients land at `<outputDir>/clients/<provider-name>.ts`.
61
+ */
62
+ outputDir: string;
63
+ /**
64
+ * The full parsed spec, for cross-component type lookups.
65
+ * Optional in Round 1 — the library emitter doesn't need cross-spec
66
+ * lookups yet; future emitters may need it for server-bind code.
67
+ */
68
+ spec?: SpecVerseAST;
69
+ }
70
+ /**
71
+ * Structured deployment-instance suggestion an emitter produces alongside
72
+ * its files/imports. The realize pipeline collects every emitter's
73
+ * suggestions into `<outputDir>/v2-deployment-suggestions.yaml` (V2 P3
74
+ * Round 3 follow-up), which the user merges into their deployment block
75
+ * manually. Auto-merge isn't safe — deployment shape is user-controlled
76
+ * (env-specific values, secrets, scaling parameters).
77
+ *
78
+ * Library-topology emitters do NOT produce suggestions (libraries are
79
+ * in-process imports, not deployment instances).
80
+ */
81
+ export interface DeploymentInstanceSuggestion {
82
+ /** Provider name (importEntry.from) — anchors the suggestion to its import. */
83
+ provider: string;
84
+ /** Component that declared the import — for cross-checking which
85
+ * deployment-instance scope the suggestion belongs to. */
86
+ consumerComponent?: string;
87
+ /**
88
+ * Which deployment-instance category this provider lands in. Mirrors
89
+ * the schema's InstancesSection keys (services, communications,
90
+ * infrastructure, …). Out-of-band categories should not be used.
91
+ */
92
+ category: 'services' | 'communications' | 'infrastructure' | 'storage' | 'security' | 'monitoring';
93
+ /** Instance key under the category (lower-camelCase client name). */
94
+ key: string;
95
+ /** Pre-built config block — placeholder values use `<...>` markers. */
96
+ config: Record<string, unknown>;
97
+ /** Factory name driving the choice (manifest.capabilityMappings). */
98
+ factory: string;
99
+ /** Topology that emitted this suggestion. */
100
+ topology: FactoryTopology;
101
+ /** Optional review-time hints (TODOs, OAuth flows, etc.). */
102
+ reviewNotes?: string[];
103
+ }
104
+ /**
105
+ * What a runtime emitter produces.
106
+ */
107
+ export interface RuntimeEmitterResult {
108
+ /**
109
+ * Files to write into the consumer's output directory.
110
+ * Paths are relative to `outputDir`.
111
+ */
112
+ files: Array<{
113
+ path: string;
114
+ content: string;
115
+ }>;
116
+ /**
117
+ * Import statements the consumer's main module (SalesReportController.ts)
118
+ * should add to wire up the generated client.
119
+ */
120
+ imports: Array<{
121
+ from: string;
122
+ specifier: string;
123
+ }>;
124
+ /**
125
+ * Optional realize-time hints or warnings.
126
+ */
127
+ notes?: string[];
128
+ /**
129
+ * V2 P3 R3 follow-up: structured deployment-instance suggestion. The
130
+ * free-text equivalent is in `notes` for human review; this field is
131
+ * the machine-readable version that the realize pipeline aggregates
132
+ * into v2-deployment-suggestions.yaml. Library-topology emissions
133
+ * omit this field.
134
+ */
135
+ deploymentSuggestion?: DeploymentInstanceSuggestion;
136
+ }
137
+ /**
138
+ * Contract every topology-specific emitter must satisfy.
139
+ */
140
+ export interface RuntimeEmitter {
141
+ /** The topology this emitter handles. Drives dispatch lookup. */
142
+ topology: FactoryTopology;
143
+ /** Emit files for one import entry. */
144
+ emit(ctx: RuntimeEmitterContext): Promise<RuntimeEmitterResult>;
145
+ }
146
+ /**
147
+ * Look up the correct emitter for the factory's topology.
148
+ *
149
+ * The emitters map is injected by the caller, making the dispatcher
150
+ * extensible without engine changes: register new emitters by adding
151
+ * entries to the map.
152
+ *
153
+ * @param factory - The resolved factory metadata (drives the topology lookup).
154
+ * @param emitters - Registry of topology → RuntimeEmitter. Typically built
155
+ * once per realize run by `buildDefaultEmitters()`.
156
+ * @returns The matching RuntimeEmitter.
157
+ * @throws Error if no emitter is registered for the factory's topology.
158
+ */
159
+ export declare function dispatchRuntimeEmitter(factory: FactoryMetadata, emitters: Map<string, RuntimeEmitter>): RuntimeEmitter;
160
+ /**
161
+ * Build the default emitter registry for a realize run.
162
+ *
163
+ * Round 1 shipped library; Round 2 added service / managed / executable /
164
+ * messaging. All 5 are registered here so the realize-side dispatcher can
165
+ * pick whichever the factory's v2metadata.topology selects.
166
+ *
167
+ * The 'external' topology is intentionally NOT registered — V2's design
168
+ * defines it as a passthrough requiring manual wiring (no auto-emission).
169
+ * Specs that bind a factory with topology: 'external' will trip a clear
170
+ * "No runtime emitter registered" error, which is the desired behavior.
171
+ *
172
+ * Imports are deferred to avoid circular deps — each emitter file imports
173
+ * only from dispatcher.ts, not vice versa.
174
+ */
175
+ export declare function buildDefaultEmitters(): Promise<Map<string, RuntimeEmitter>>;
176
+ //# sourceMappingURL=dispatcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatcher.d.ts","sourceRoot":"","sources":["../../../src/realize/runtime-emitters/dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACtG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAG9D,YAAY,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,YAAY,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEzE,+DAA+D;AAC/D,MAAM,MAAM,eAAe,GAAG,eAAe,CAAC;AAI9C;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAID;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC,uDAAuD;IACvD,iBAAiB,EAAE,aAAa,CAAC;IACjC,iEAAiE;IACjE,WAAW,EAAE,WAAW,CAAC;IACzB;;;;OAIG;IACH,QAAQ,EAAE,iBAAiB,CAAC;IAC5B;;;;OAIG;IACH,OAAO,EAAE,eAAe,CAAC;IACzB;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,IAAI,CAAC,EAAE,YAAY,CAAC;CACrB;AAED;;;;;;;;;;GAUG;AACH,MAAM,WAAW,4BAA4B;IAC3C,+EAA+E;IAC/E,QAAQ,EAAE,MAAM,CAAC;IACjB;+DAC2D;IAC3D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,EAAE,UAAU,GAAG,gBAAgB,GAAG,gBAAgB,GAAG,SAAS,GAAG,UAAU,GAAG,YAAY,CAAC;IACnG,qEAAqE;IACrE,GAAG,EAAE,MAAM,CAAC;IACZ,uEAAuE;IACvE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,QAAQ,EAAE,eAAe,CAAC;IAC1B,6DAA6D;IAC7D,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC;;;OAGG;IACH,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChD;;;OAGG;IACH,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpD;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB;;;;;;OAMG;IACH,oBAAoB,CAAC,EAAE,4BAA4B,CAAC;CACrD;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,iEAAiE;IACjE,QAAQ,EAAE,eAAe,CAAC;IAC1B,uCAAuC;IACvC,IAAI,CAAC,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;CACjE;AAID;;;;;;;;;;;;GAYG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,eAAe,EACxB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,GACpC,cAAc,CAchB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAsBjF"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Per-runtime emitter dispatcher — V2 Phase 3, Round 1.
3
+ *
4
+ * Proposal: 2026-05-08-COMPONENT-DEPENDENCIES-V2.md, "Realize bridge" section.
5
+ *
6
+ * The dispatcher is a small registry + lookup framework. The real work lives in
7
+ * each topology-specific emitter implementation (library.ts, and future
8
+ * service.ts / managed.ts / executable.ts / messaging.ts files).
9
+ *
10
+ * Round 1 ships: dispatcher framework + library topology emitter (this file +
11
+ * library.ts). The two cross-branch types — `ResolvedComponent` (Agent A) and
12
+ * `FactoryV2Metadata` / `InstanceFactory` (Agent B) — are imported from their
13
+ * canonical locations: Round 1d (this commit) reconciled the local stubs with
14
+ * the merged real types.
15
+ *
16
+ * Round 2 will add: service, managed, executable, messaging emitters + CLI wiring.
17
+ */
18
+ // ─── Dispatcher ───────────────────────────────────────────────────────────────
19
+ /**
20
+ * Look up the correct emitter for the factory's topology.
21
+ *
22
+ * The emitters map is injected by the caller, making the dispatcher
23
+ * extensible without engine changes: register new emitters by adding
24
+ * entries to the map.
25
+ *
26
+ * @param factory - The resolved factory metadata (drives the topology lookup).
27
+ * @param emitters - Registry of topology → RuntimeEmitter. Typically built
28
+ * once per realize run by `buildDefaultEmitters()`.
29
+ * @returns The matching RuntimeEmitter.
30
+ * @throws Error if no emitter is registered for the factory's topology.
31
+ */
32
+ export function dispatchRuntimeEmitter(factory, emitters) {
33
+ // V2 P3 R1d reconciliation: Agent B's loader populates factory.v2metadata
34
+ // (with topology defaulted from factory.category). Pre-V2 factories
35
+ // without v2metadata fall back to 'library' — the only emitter Round 1
36
+ // registers, so dispatch is deterministic.
37
+ const topology = factory.v2metadata?.topology ?? 'library';
38
+ const emitter = emitters.get(topology);
39
+ if (!emitter) {
40
+ const available = Array.from(emitters.keys()).sort().join(', ');
41
+ throw new Error(`No runtime emitter registered for topology '${topology}'. Available: ${available || '(none)'}`);
42
+ }
43
+ return emitter;
44
+ }
45
+ /**
46
+ * Build the default emitter registry for a realize run.
47
+ *
48
+ * Round 1 shipped library; Round 2 added service / managed / executable /
49
+ * messaging. All 5 are registered here so the realize-side dispatcher can
50
+ * pick whichever the factory's v2metadata.topology selects.
51
+ *
52
+ * The 'external' topology is intentionally NOT registered — V2's design
53
+ * defines it as a passthrough requiring manual wiring (no auto-emission).
54
+ * Specs that bind a factory with topology: 'external' will trip a clear
55
+ * "No runtime emitter registered" error, which is the desired behavior.
56
+ *
57
+ * Imports are deferred to avoid circular deps — each emitter file imports
58
+ * only from dispatcher.ts, not vice versa.
59
+ */
60
+ export async function buildDefaultEmitters() {
61
+ const [{ LibraryRuntimeEmitter }, { ServiceRuntimeEmitter }, { ManagedRuntimeEmitter }, { ExecutableRuntimeEmitter }, { MessagingRuntimeEmitter },] = await Promise.all([
62
+ import('./library.js'),
63
+ import('./service.js'),
64
+ import('./managed.js'),
65
+ import('./executable.js'),
66
+ import('./messaging.js'),
67
+ ]);
68
+ const map = new Map();
69
+ map.set('library', new LibraryRuntimeEmitter());
70
+ map.set('service', new ServiceRuntimeEmitter());
71
+ map.set('managed', new ManagedRuntimeEmitter());
72
+ map.set('executable', new ExecutableRuntimeEmitter());
73
+ map.set('messaging', new MessagingRuntimeEmitter());
74
+ return map;
75
+ }
76
+ //# sourceMappingURL=dispatcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dispatcher.js","sourceRoot":"","sources":["../../../src/realize/runtime-emitters/dispatcher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAyIH,iFAAiF;AAEjF;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,sBAAsB,CACpC,OAAwB,EACxB,QAAqC;IAErC,0EAA0E;IAC1E,oEAAoE;IACpE,uEAAuE;IACvE,2CAA2C;IAC3C,MAAM,QAAQ,GAAoB,OAAO,CAAC,UAAU,EAAE,QAAQ,IAAI,SAAS,CAAC;IAC5E,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChE,MAAM,IAAI,KAAK,CACb,+CAA+C,QAAQ,iBAAiB,SAAS,IAAI,QAAQ,EAAE,CAChG,CAAC;IACJ,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB;IACxC,MAAM,CACJ,EAAE,qBAAqB,EAAE,EACzB,EAAE,qBAAqB,EAAE,EACzB,EAAE,qBAAqB,EAAE,EACzB,EAAE,wBAAwB,EAAE,EAC5B,EAAE,uBAAuB,EAAE,EAC5B,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACpB,MAAM,CAAC,cAAc,CAAC;QACtB,MAAM,CAAC,cAAc,CAAC;QACtB,MAAM,CAAC,cAAc,CAAC;QACtB,MAAM,CAAC,iBAAiB,CAAC;QACzB,MAAM,CAAC,gBAAgB,CAAC;KACzB,CAAC,CAAC;IAEH,MAAM,GAAG,GAAG,IAAI,GAAG,EAA0B,CAAC;IAC9C,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,qBAAqB,EAAE,CAAC,CAAC;IAChD,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,qBAAqB,EAAE,CAAC,CAAC;IAChD,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,qBAAqB,EAAE,CAAC,CAAC;IAChD,GAAG,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,wBAAwB,EAAE,CAAC,CAAC;IACtD,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,IAAI,uBAAuB,EAAE,CAAC,CAAC;IACpD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Executable-runtime emitter — V2 Phase 3, Round 2.
3
+ *
4
+ * Handles `topology: 'executable'` factories: providers reached via
5
+ * `spawnSync` / `execSync` — local CLI binaries such as gitnexus, ffmpeg,
6
+ * or custom binaries.
7
+ *
8
+ * For each `import:` entry the consumer declares, this emitter produces:
9
+ * clients/<kebab-provider>.ts — spawnSync wrapper with typed interface
10
+ *
11
+ * The generated client module:
12
+ * - Emits an `assertBinaryAvailable()` function called at module load
13
+ * that runs `spawnSync('which', [binary])` (or `spawnSync(binary, ['--version'])`
14
+ * as fallback) to fail loud at boot if the binary isn't on PATH.
15
+ * - Exports a `<ProviderName>Client` TypeScript interface matching the
16
+ * selected operations from `import.select`.
17
+ * - Exports a `<providerName>Client` constant that implements the interface
18
+ * by dispatching to `spawnSync`:
19
+ * * Dotted op `Subcommand.action`: runs `spawnSync(binary, ['subcommand', 'action', ...args])`.
20
+ * * Bare entity: runs `spawnSync(binary, [entity.toLowerCase(), ...args])`.
21
+ * stdout is parsed as JSON; non-zero exit throws a clear Error.
22
+ *
23
+ * --- Binary name resolution ---
24
+ *
25
+ * The binary name is read from:
26
+ * 1. `factory.v2metadata.config?.binary` (explicit override)
27
+ * 2. `factory.name` lowercased (e.g. 'Gitnexus' → 'gitnexus')
28
+ *
29
+ * --- Select grammar ---
30
+ *
31
+ * Follows V2 D2 resolution (same as library.ts):
32
+ * - Dotted: `Subcommand.action` → dispatches `spawnSync(binary, ['subcommand', 'action', ...])`.
33
+ * - Bare: `EntityName` → dispatches `spawnSync(binary, [entityname, ...])`.
34
+ *
35
+ * --- No server file ---
36
+ *
37
+ * Subprocess providers don't have a server-bind file.
38
+ *
39
+ * --- Deployment instance hint ---
40
+ *
41
+ * Emitter notes include a hint to add the provider to
42
+ * `deployments.<env>.instances.infrastructure.<provider>` with
43
+ * `config: { binary: <name> }`.
44
+ */
45
+ import type { RuntimeEmitter, RuntimeEmitterContext, RuntimeEmitterResult } from './dispatcher.js';
46
+ /**
47
+ * Executable-runtime emitter implementation.
48
+ *
49
+ * One call to `emit()` processes a single `import:` entry and produces
50
+ * one client file under `clients/<provider-filename>.ts`.
51
+ * No server-bind file is emitted (subprocess providers have no server).
52
+ */
53
+ export declare class ExecutableRuntimeEmitter implements RuntimeEmitter {
54
+ readonly topology: "executable";
55
+ emit(ctx: RuntimeEmitterContext): Promise<RuntimeEmitterResult>;
56
+ }
57
+ //# sourceMappingURL=executable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executable.d.ts","sourceRoot":"","sources":["../../../src/realize/runtime-emitters/executable.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,oBAAoB,EACrB,MAAM,iBAAiB,CAAC;AAuOzB;;;;;;GAMG;AACH,qBAAa,wBAAyB,YAAW,cAAc;IAC7D,QAAQ,CAAC,QAAQ,EAAG,YAAY,CAAU;IAEpC,IAAI,CAAC,GAAG,EAAE,qBAAqB,GAAG,OAAO,CAAC,oBAAoB,CAAC;CAsFtE"}
@@ -0,0 +1,316 @@
1
+ /**
2
+ * Executable-runtime emitter — V2 Phase 3, Round 2.
3
+ *
4
+ * Handles `topology: 'executable'` factories: providers reached via
5
+ * `spawnSync` / `execSync` — local CLI binaries such as gitnexus, ffmpeg,
6
+ * or custom binaries.
7
+ *
8
+ * For each `import:` entry the consumer declares, this emitter produces:
9
+ * clients/<kebab-provider>.ts — spawnSync wrapper with typed interface
10
+ *
11
+ * The generated client module:
12
+ * - Emits an `assertBinaryAvailable()` function called at module load
13
+ * that runs `spawnSync('which', [binary])` (or `spawnSync(binary, ['--version'])`
14
+ * as fallback) to fail loud at boot if the binary isn't on PATH.
15
+ * - Exports a `<ProviderName>Client` TypeScript interface matching the
16
+ * selected operations from `import.select`.
17
+ * - Exports a `<providerName>Client` constant that implements the interface
18
+ * by dispatching to `spawnSync`:
19
+ * * Dotted op `Subcommand.action`: runs `spawnSync(binary, ['subcommand', 'action', ...args])`.
20
+ * * Bare entity: runs `spawnSync(binary, [entity.toLowerCase(), ...args])`.
21
+ * stdout is parsed as JSON; non-zero exit throws a clear Error.
22
+ *
23
+ * --- Binary name resolution ---
24
+ *
25
+ * The binary name is read from:
26
+ * 1. `factory.v2metadata.config?.binary` (explicit override)
27
+ * 2. `factory.name` lowercased (e.g. 'Gitnexus' → 'gitnexus')
28
+ *
29
+ * --- Select grammar ---
30
+ *
31
+ * Follows V2 D2 resolution (same as library.ts):
32
+ * - Dotted: `Subcommand.action` → dispatches `spawnSync(binary, ['subcommand', 'action', ...])`.
33
+ * - Bare: `EntityName` → dispatches `spawnSync(binary, [entityname, ...])`.
34
+ *
35
+ * --- No server file ---
36
+ *
37
+ * Subprocess providers don't have a server-bind file.
38
+ *
39
+ * --- Deployment instance hint ---
40
+ *
41
+ * Emitter notes include a hint to add the provider to
42
+ * `deployments.<env>.instances.infrastructure.<provider>` with
43
+ * `config: { binary: <name> }`.
44
+ */
45
+ // ─── Naming helpers (mirrors library.ts) ─────────────────────────────────────
46
+ /**
47
+ * Parse a select entry into head + optional tail.
48
+ * Dotted: `Subcommand.action` → { head: 'Subcommand', tail: 'action' }
49
+ * Bare: `EntityName` → { head: 'EntityName', tail: undefined }
50
+ */
51
+ function parseSelectEntry(entry) {
52
+ const dotIndex = entry.indexOf('.');
53
+ if (dotIndex === -1) {
54
+ return { head: entry, tail: undefined };
55
+ }
56
+ return {
57
+ head: entry.slice(0, dotIndex),
58
+ tail: entry.slice(dotIndex + 1),
59
+ };
60
+ }
61
+ /**
62
+ * Normalise a `from:` name into an array of words for identifier generation.
63
+ * Same implementation as library.ts — handles camelCase, scoped packages, hyphens.
64
+ */
65
+ function toWords(fromName) {
66
+ const normalised = fromName.replace(/^@/, '').replace(/\//g, '-');
67
+ return normalised
68
+ .replace(/([a-z])([A-Z])/g, '$1 $2')
69
+ .replace(/[^a-zA-Z0-9]+/g, ' ')
70
+ .trim()
71
+ .split(' ')
72
+ .filter(Boolean)
73
+ .map((w) => w.toLowerCase());
74
+ }
75
+ /**
76
+ * Convert a from-name to a lower-camelCase client constant name.
77
+ * 'Gitnexus' → 'gitnexus', 'GitNexus' → 'gitNexus', '@ffmpeg/core' → 'ffmpegCore'
78
+ */
79
+ function toClientName(fromName) {
80
+ const words = toWords(fromName);
81
+ if (words.length === 0)
82
+ return 'unknownClient';
83
+ return (words[0] +
84
+ words
85
+ .slice(1)
86
+ .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
87
+ .join(''));
88
+ }
89
+ /**
90
+ * Convert a from-name to a PascalCase interface name suffix.
91
+ * 'Gitnexus' → 'Gitnexus', 'GitNexus' → 'Gitnexus', '@ffmpeg/core' → 'FfmpegCore'
92
+ */
93
+ function toInterfaceName(fromName) {
94
+ const words = toWords(fromName);
95
+ return words.map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join('');
96
+ }
97
+ /**
98
+ * Convert a from-name to a filesystem-safe kebab-case filename.
99
+ * 'Gitnexus' → 'gitnexus', 'GitNexus' → 'git-nexus', '@ffmpeg/core' → 'ffmpeg-core'
100
+ */
101
+ function toFileName(fromName) {
102
+ return toWords(fromName).join('-');
103
+ }
104
+ // ─── Binary name resolution ───────────────────────────────────────────────────
105
+ /**
106
+ * Resolve the binary name for spawnSync.
107
+ *
108
+ * Priority:
109
+ * 1. `factory.v2metadata.config?.binary` (explicit override)
110
+ * 2. `factory.name` lowercased (e.g. 'Gitnexus' → 'gitnexus',
111
+ * 'SubprocessCLIAdapter' → 'subprocesscliadapter' — callers should
112
+ * prefer explicit `config.binary` for multi-word names)
113
+ */
114
+ function resolveBinaryName(factory) {
115
+ const configBinary = factory.v2metadata
116
+ ?.config?.binary;
117
+ if (configBinary && typeof configBinary === 'string' && configBinary.length > 0) {
118
+ return configBinary;
119
+ }
120
+ return factory.name.toLowerCase();
121
+ }
122
+ // ─── Code-generation helpers ──────────────────────────────────────────────────
123
+ /**
124
+ * Generate the `assertBinaryAvailable()` function that runs at module load.
125
+ *
126
+ * Uses `spawnSync('which', [binary])` as primary check (POSIX); on non-zero
127
+ * exit falls back to `spawnSync(binary, ['--version'])`. If both fail, throws
128
+ * a descriptive error pointing at the env-var escape hatch.
129
+ *
130
+ * The env-var name is SPECVERSE_<BINARY_UPPER>_PATH (e.g. SPECVERSE_PROFIT_CALC_PATH).
131
+ */
132
+ function generateBinaryAvailabilityCheck(binary) {
133
+ const envVar = `SPECVERSE_${binary.toUpperCase().replace(/[^A-Z0-9]/g, '_')}_PATH`;
134
+ const lines = [];
135
+ lines.push(`import { spawnSync } from 'child_process';`);
136
+ lines.push('');
137
+ lines.push(`const BINARY = '${binary}';`);
138
+ lines.push(`const ENV_OVERRIDE = process.env['${envVar}'];`);
139
+ lines.push(`const EFFECTIVE_BINARY = ENV_OVERRIDE ?? BINARY;`);
140
+ lines.push('');
141
+ lines.push(`/** Assert the required binary is available on PATH before any calls are made. */`);
142
+ lines.push(`function assertBinaryAvailable(): void {`);
143
+ lines.push(` const check = spawnSync('which', [EFFECTIVE_BINARY], { encoding: 'utf-8' });`);
144
+ lines.push(` if (check.status !== 0) {`);
145
+ lines.push(` // Fallback: try --version directly (useful when 'which' itself is absent)`);
146
+ lines.push(` const direct = spawnSync(EFFECTIVE_BINARY, ['--version'], { encoding: 'utf-8' });`);
147
+ lines.push(` if (direct.status !== 0 && direct.error) {`);
148
+ lines.push(` throw new Error(\`Required binary \${EFFECTIVE_BINARY} not found on PATH. ` +
149
+ `Install it or update ${envVar} env var.\`);`);
150
+ lines.push(` }`);
151
+ lines.push(` }`);
152
+ lines.push(`}`);
153
+ lines.push('');
154
+ lines.push(`// Run at module load — catches missing-binary errors at app boot.`);
155
+ lines.push(`assertBinaryAvailable();`);
156
+ return lines.join('\n');
157
+ }
158
+ /**
159
+ * Generate the TypeScript interface for the executable client type.
160
+ *
161
+ * Dotted entries (`Subcommand.action`) → typed `(...args: unknown[]) => unknown` method.
162
+ * Bare entries (`EntityName`) → typed `(...args: unknown[]) => unknown` method (passthrough).
163
+ *
164
+ * Unlike the library emitter, subprocess calls are synchronous (`spawnSync`), so
165
+ * the return type is `unknown` (not `Promise<unknown>`). Callers may wrap in a
166
+ * Promise if they need async composition; the underlying I/O is blocking.
167
+ */
168
+ function generateInterface(interfaceName, selectEntries) {
169
+ const lines = [];
170
+ lines.push(`export type ${interfaceName}Client = {`);
171
+ const seen = new Set();
172
+ for (const entry of selectEntries) {
173
+ if (seen.has(entry))
174
+ continue;
175
+ seen.add(entry);
176
+ const { head, tail } = parseSelectEntry(entry);
177
+ if (tail === undefined) {
178
+ // Bare entity — passthrough all args as JSON-encoded CLI arguments.
179
+ lines.push(` /** Invokes: spawnSync(binary, ['${head.toLowerCase()}', ...JSON-encoded args]) */`);
180
+ lines.push(` ${head}(...args: unknown[]): unknown;`);
181
+ }
182
+ else {
183
+ // Dotted operation — subcommand + action dispatch.
184
+ lines.push(` /** Invokes: spawnSync(binary, ['${head.toLowerCase()}', '${tail}', ...JSON-encoded args]) */`);
185
+ lines.push(` ${tail}(...args: unknown[]): unknown;`);
186
+ }
187
+ }
188
+ lines.push('};');
189
+ return lines.join('\n');
190
+ }
191
+ /**
192
+ * Generate the client constant — spawnSync-backed implementation.
193
+ *
194
+ * Each method:
195
+ * 1. JSON-encodes each argument via JSON.stringify.
196
+ * 2. Calls spawnSync with [subcommand, action, ...encodedArgs] (dotted) or
197
+ * [entityname, ...encodedArgs] (bare).
198
+ * 3. On non-zero exit, throws Error('<binary> <subcommand>: <stderr>').
199
+ * 4. Parses stdout as JSON and returns the result.
200
+ */
201
+ function generateClientConstant(clientName, interfaceName, selectEntries) {
202
+ const lines = [];
203
+ lines.push(`export const ${clientName}Client: ${interfaceName}Client = {`);
204
+ const seen = new Set();
205
+ for (const entry of selectEntries) {
206
+ if (seen.has(entry))
207
+ continue;
208
+ seen.add(entry);
209
+ const { head, tail } = parseSelectEntry(entry);
210
+ if (tail === undefined) {
211
+ // Bare entity passthrough — proxy all args as JSON-encoded CLI arguments.
212
+ const subcommand = head.toLowerCase();
213
+ lines.push(` ${head}(...args: unknown[]): unknown {`);
214
+ lines.push(` const encodedArgs = args.map((a) => JSON.stringify(a));`);
215
+ lines.push(` const result = spawnSync(EFFECTIVE_BINARY, ['${subcommand}', ...encodedArgs], { encoding: 'utf-8' });`);
216
+ lines.push(` if (result.status !== 0) {`);
217
+ lines.push(` throw new Error(\`\${EFFECTIVE_BINARY} ${subcommand}: \${result.stderr}\`);`);
218
+ lines.push(` }`);
219
+ lines.push(` return JSON.parse(result.stdout);`);
220
+ lines.push(` },`);
221
+ }
222
+ else {
223
+ // Dotted operation — subcommand (head) + action (tail) dispatch.
224
+ const subcommand = head.toLowerCase();
225
+ lines.push(` ${tail}(...args: unknown[]): unknown {`);
226
+ lines.push(` const encodedArgs = args.map((a) => JSON.stringify(a));`);
227
+ lines.push(` const result = spawnSync(EFFECTIVE_BINARY, ['${subcommand}', '${tail}', ...encodedArgs], { encoding: 'utf-8' });`);
228
+ lines.push(` if (result.status !== 0) {`);
229
+ lines.push(` throw new Error(\`\${EFFECTIVE_BINARY} ${subcommand}: \${result.stderr}\`);`);
230
+ lines.push(` }`);
231
+ lines.push(` return JSON.parse(result.stdout);`);
232
+ lines.push(` },`);
233
+ }
234
+ }
235
+ lines.push('};');
236
+ return lines.join('\n');
237
+ }
238
+ // ─── Executable emitter ───────────────────────────────────────────────────────
239
+ /**
240
+ * Executable-runtime emitter implementation.
241
+ *
242
+ * One call to `emit()` processes a single `import:` entry and produces
243
+ * one client file under `clients/<provider-filename>.ts`.
244
+ * No server-bind file is emitted (subprocess providers have no server).
245
+ */
246
+ export class ExecutableRuntimeEmitter {
247
+ topology = 'executable';
248
+ async emit(ctx) {
249
+ const { importEntry, resolved, factory } = ctx;
250
+ const selectEntries = importEntry.select ?? [];
251
+ // Resolve binary name: config?.binary → factory.name.toLowerCase()
252
+ const binary = resolveBinaryName(factory);
253
+ // Derive naming from the import's `from:` field.
254
+ const fileName = toFileName(importEntry.from);
255
+ const clientName = toClientName(importEntry.from);
256
+ const interfaceName = toInterfaceName(importEntry.from);
257
+ // File path relative to outputDir.
258
+ const relFilePath = `clients/${fileName}.ts`;
259
+ // Build file header.
260
+ const headerLines = [
261
+ '// FACTORY-EMITTED — DO NOT EDIT (R8)',
262
+ `// Generated by executable-runtime emitter — V2 Phase 3`,
263
+ `// Provider: ${importEntry.from} (${resolved.source}) via factory: ${factory.name}`,
264
+ `// Binary: ${binary}`,
265
+ '',
266
+ ];
267
+ // Build availability check block (includes `import { spawnSync }` and constant declaration).
268
+ const availabilityBlock = generateBinaryAvailabilityCheck(binary);
269
+ // Build interface.
270
+ const interfaceBlock = generateInterface(interfaceName, selectEntries);
271
+ // Build client constant.
272
+ const constantBlock = generateClientConstant(clientName, interfaceName, selectEntries);
273
+ // Assemble file.
274
+ const parts = [
275
+ ...headerLines,
276
+ availabilityBlock,
277
+ '',
278
+ interfaceBlock,
279
+ '',
280
+ constantBlock,
281
+ '',
282
+ ];
283
+ const content = parts.join('\n');
284
+ // Build the import entry for the consumer's controller file.
285
+ const consumerImport = {
286
+ from: `./clients/${fileName}`,
287
+ specifier: `${clientName}Client`,
288
+ };
289
+ // Notes: warnings + deployment instance hint.
290
+ const notes = [];
291
+ if (selectEntries.length === 0) {
292
+ notes.push(`Warning: import entry from '${importEntry.from}' has empty select: — no client members emitted.`);
293
+ }
294
+ // Deployment instance hint — provider lands in infrastructure category.
295
+ notes.push(`Deployment hint: add '${importEntry.from}' to deployments.<env>.instances.infrastructure` +
296
+ ` with config: { binary: '${binary}' }. No process lifecycle; just a binary path requirement.`);
297
+ const deploymentSuggestion = {
298
+ provider: importEntry.from,
299
+ consumerComponent: ctx.consumerComponent?.name,
300
+ category: 'infrastructure',
301
+ key: clientName,
302
+ config: {
303
+ binary,
304
+ },
305
+ factory: factory.name,
306
+ topology: 'executable',
307
+ };
308
+ return {
309
+ files: [{ path: relFilePath, content }],
310
+ imports: [consumerImport],
311
+ notes,
312
+ deploymentSuggestion,
313
+ };
314
+ }
315
+ }
316
+ //# sourceMappingURL=executable.js.map