@specverse/engines 6.33.1 → 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 +246 -1
  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,157 @@
1
+ /**
2
+ * V2 Dependency Resolver — Phase 3 (Round 1)
3
+ *
4
+ * 4-step lookup chain for `import[].from` references:
5
+ * 1. Local component in same spec
6
+ * 2. Local npm package (node_modules/<name>/package.json)
7
+ * 3. Registry library (Library.type: component) — HTTP stubbed for Round 1
8
+ * 4. Registry factory (Library.type: factory) — HTTP stubbed for Round 1
9
+ *
10
+ * Decision points applied:
11
+ * D1: version defaults to ^latest (per-realize-run cache)
12
+ * Offline mode: skips steps 3 + 4, fails loudly if unresolvable
13
+ * Cache: <cacheDir>/registry-cache/ (default .specverse/registry-cache/)
14
+ * Fail-loud: throws DependencyResolutionError when nothing resolves
15
+ *
16
+ * @see docs/proposals/2026-05-08-COMPONENT-DEPENDENCIES-V2.md — "Realize bridge — Resolver"
17
+ */
18
+ import type { SpecVerseAST, ComponentSpec } from '@specverse/types';
19
+ /**
20
+ * A spec that has been resolved from a `from:` reference.
21
+ * For Round 1 registry paths, `spec` is a minimal stub generated from
22
+ * the registry Library record.
23
+ */
24
+ export interface ResolvedComponent {
25
+ /** The original `from:` value from the import entry that produced this. */
26
+ fromName: string;
27
+ /** Which step of the 4-step chain produced this result. */
28
+ source: 'local' | 'npm' | 'registry-component' | 'registry-factory';
29
+ /**
30
+ * The resolved SpecVerse spec. For local + npm sources this is the full
31
+ * parsed spec. For registry sources (stubs in Round 1) this is a minimal
32
+ * object bearing at least the component's `name` and `version`.
33
+ */
34
+ spec: PartialSpec;
35
+ /**
36
+ * The resolved provider name (component name for local, npm package name
37
+ * for npm, registry library/factory name for registry-*).
38
+ */
39
+ resolvedName: string;
40
+ /**
41
+ * Pinned version after ^latest expansion (or the version from the local
42
+ * spec / npm package.json). Optional because some local components may
43
+ * not declare a version field.
44
+ */
45
+ resolvedVersion?: string;
46
+ /**
47
+ * For source = 'npm' or 'registry-*': the package specifier to use in
48
+ * generated `import` statements (e.g. '@stripe/stripe-js' or 'profit-calc').
49
+ * For source = 'local': not populated; callers compute relative paths
50
+ * from outputDir + resolvedName.
51
+ */
52
+ packageSpecifier?: string;
53
+ /**
54
+ * For source = 'local': relative path from the consumer's outputDir to
55
+ * the provider's emitted module. Optional — when absent, callers fall
56
+ * back to `../{resolvedName}` or similar convention.
57
+ */
58
+ localRelativePath?: string;
59
+ /**
60
+ * Registry coordinates when source is 'registry-component' or 'registry-factory'.
61
+ */
62
+ registryRef?: {
63
+ name: string;
64
+ version: string;
65
+ };
66
+ }
67
+ /**
68
+ * A factory reference returned when the registry resolves a capability match
69
+ * (step 4).
70
+ */
71
+ export interface FactoryReference {
72
+ name: string;
73
+ version: string;
74
+ /** Factory metadata from registry — partial in Round 1 (HTTP is stubbed). */
75
+ metadata?: Record<string, unknown>;
76
+ }
77
+ /**
78
+ * Options passed to each `resolve()` call. The full spec + workspace context
79
+ * allow the local-component and npm-package steps to work without extra
80
+ * configuration.
81
+ */
82
+ export interface ResolveOptions {
83
+ /** The spec being realized — used for local-component lookup (step 1). */
84
+ spec: SpecVerseAST;
85
+ /**
86
+ * Absolute path to the workspace root. Used to locate node_modules for
87
+ * step 2. Defaults to `process.cwd()`.
88
+ */
89
+ workspaceRoot?: string;
90
+ /**
91
+ * When true, steps 3 and 4 (registry) are skipped. If a `from:` reference
92
+ * cannot be resolved via steps 1–2, throws `DependencyResolutionError`.
93
+ */
94
+ offline?: boolean;
95
+ /**
96
+ * Directory where registry responses are cached.
97
+ * Defaults to `.specverse/registry-cache/` inside `workspaceRoot`.
98
+ */
99
+ cacheDir?: string;
100
+ /**
101
+ * When true, treats the registry cache as stale and re-fetches even if a
102
+ * cached entry exists. Equivalent to the `--refresh-registry` flag.
103
+ * Can also be set via the `SPECVERSE_REFRESH_REGISTRY=1` environment variable.
104
+ */
105
+ refreshRegistry?: boolean;
106
+ }
107
+ export interface DependencyResolver {
108
+ /**
109
+ * Resolve a `from:` reference to a component spec.
110
+ *
111
+ * Steps (in order):
112
+ * 1. Local component in spec.components
113
+ * 2. node_modules/<from>/package.json
114
+ * 3. GET /api/libraries/<from> (Registry, Library.type: component) — STUBBED
115
+ * 4. GET /api/libraries?type=factory&capability=<from> — STUBBED
116
+ *
117
+ * @param from The `from:` value from the import entry.
118
+ * @param version Semver range or pin. Defaults to `^latest` (D1).
119
+ * @param options Resolve-time context.
120
+ * @returns ResolvedComponent or null when offline + not locally found.
121
+ * @throws DependencyResolutionError when nothing resolves (not offline) or
122
+ * when offline and no local resolution is possible.
123
+ */
124
+ resolve(from: string, version?: string, options?: ResolveOptions): Promise<ResolvedComponent | null>;
125
+ /**
126
+ * Resolve a capability tag to a factory reference.
127
+ * Used by realize emitters that need to find which factory covers a given
128
+ * capability string.
129
+ *
130
+ * Delegates to step 4 of the chain.
131
+ *
132
+ * @throws DependencyResolutionError when no factory matches and not offline.
133
+ */
134
+ resolveCapability(capability: string, options?: ResolveOptions): Promise<FactoryReference | null>;
135
+ }
136
+ export declare class DependencyResolutionError extends Error {
137
+ readonly from: string;
138
+ readonly triedSteps: string[];
139
+ constructor(message: string, from: string, triedSteps: string[]);
140
+ }
141
+ /** Minimal spec shape accepted from all resolution sources. */
142
+ export interface PartialSpec {
143
+ name?: string;
144
+ version?: string;
145
+ components?: ComponentSpec[];
146
+ [key: string]: unknown;
147
+ }
148
+ /**
149
+ * Create a `DependencyResolver` instance.
150
+ *
151
+ * The resolver is stateless between realize runs. A new instance should be
152
+ * created per-run (or per test) to avoid cross-run cache pollution in memory.
153
+ * On-disk cache in `<cacheDir>/registry-cache/` persists across runs and is
154
+ * shared across instances that use the same directory.
155
+ */
156
+ export declare function createDependencyResolver(): DependencyResolver;
157
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/realize/resolver/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAMpE;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,2EAA2E;IAC3E,QAAQ,EAAE,MAAM,CAAC;IACjB,2DAA2D;IAC3D,MAAM,EAAE,OAAO,GAAG,KAAK,GAAG,oBAAoB,GAAG,kBAAkB,CAAC;IACpE;;;;OAIG;IACH,IAAI,EAAE,WAAW,CAAC;IAClB;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B;;OAEG;IACH,WAAW,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CACjD;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,0EAA0E;IAC1E,IAAI,EAAE,YAAY,CAAC;IACnB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,MAAM,WAAW,kBAAkB;IACjC;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;IAErG;;;;;;;;OAQG;IACH,iBAAiB,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;CACnG;AAMD,qBAAa,yBAA0B,SAAQ,KAAK;aAGhC,IAAI,EAAE,MAAM;aACZ,UAAU,EAAE,MAAM,EAAE;gBAFpC,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAAE;CAKvC;AAMD,+DAA+D;AAC/D,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,aAAa,EAAE,CAAC;IAC7B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AA4TD;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,IAAI,kBAAkB,CAE7D"}
@@ -0,0 +1,307 @@
1
+ /**
2
+ * V2 Dependency Resolver — Phase 3 (Round 1)
3
+ *
4
+ * 4-step lookup chain for `import[].from` references:
5
+ * 1. Local component in same spec
6
+ * 2. Local npm package (node_modules/<name>/package.json)
7
+ * 3. Registry library (Library.type: component) — HTTP stubbed for Round 1
8
+ * 4. Registry factory (Library.type: factory) — HTTP stubbed for Round 1
9
+ *
10
+ * Decision points applied:
11
+ * D1: version defaults to ^latest (per-realize-run cache)
12
+ * Offline mode: skips steps 3 + 4, fails loudly if unresolvable
13
+ * Cache: <cacheDir>/registry-cache/ (default .specverse/registry-cache/)
14
+ * Fail-loud: throws DependencyResolutionError when nothing resolves
15
+ *
16
+ * @see docs/proposals/2026-05-08-COMPONENT-DEPENDENCIES-V2.md — "Realize bridge — Resolver"
17
+ */
18
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
19
+ import { join, resolve } from 'path';
20
+ // ============================================================================
21
+ // Error
22
+ // ============================================================================
23
+ export class DependencyResolutionError extends Error {
24
+ from;
25
+ triedSteps;
26
+ constructor(message, from, triedSteps) {
27
+ super(message);
28
+ this.from = from;
29
+ this.triedSteps = triedSteps;
30
+ this.name = 'DependencyResolutionError';
31
+ }
32
+ }
33
+ // ============================================================================
34
+ // Registry HTTP stub
35
+ // ============================================================================
36
+ /**
37
+ * Round-1 stub for registry component lookup.
38
+ *
39
+ * TODO: Replace with real HTTP fetch:
40
+ * GET <registryBase>/api/libraries/<name>
41
+ * Expected response shape (Library.type: component):
42
+ * { name, version, type: 'component', specContent: '<yaml>' }
43
+ *
44
+ * @returns null — no registry data in Round 1 (real HTTP not yet wired).
45
+ */
46
+ async function fetchRegistryComponent(name, _version) {
47
+ // TODO(v2-p3-round2): implement real HTTP fetch to specverse registry.
48
+ // Endpoint: GET /api/libraries/<name>
49
+ // Auth: anonymous reads; OAuth for publish
50
+ // Filtering: check Library.type === 'component'
51
+ void name;
52
+ return null;
53
+ }
54
+ /**
55
+ * Round-1 stub for registry factory lookup by capability.
56
+ *
57
+ * TODO: Replace with real HTTP fetch:
58
+ * GET <registryBase>/api/libraries?type=factory&capability=<capability>
59
+ * Expected response shape (array of Library.type: factory records):
60
+ * [{ name, version, type: 'factory', metadata: { topology, protocol, ... } }]
61
+ *
62
+ * @returns null — no registry data in Round 1.
63
+ */
64
+ async function fetchRegistryFactory(_capability) {
65
+ // TODO(v2-p3-round2): implement real HTTP fetch to specverse registry.
66
+ // Endpoint: GET /api/libraries?type=factory&capability=<capability>
67
+ // Auth: anonymous reads
68
+ // Selection: pick highest semver-matching version
69
+ void _capability;
70
+ return null;
71
+ }
72
+ // ============================================================================
73
+ // Resolver implementation
74
+ // ============================================================================
75
+ /**
76
+ * Default semver range when the spec author omits `version:` (D1).
77
+ */
78
+ const DEFAULT_VERSION = '^latest';
79
+ /**
80
+ * Resolve an effective cache directory from options + environment.
81
+ */
82
+ function resolveCacheDir(options) {
83
+ if (options.cacheDir)
84
+ return options.cacheDir;
85
+ const root = options.workspaceRoot ?? process.cwd();
86
+ return join(root, '.specverse', 'registry-cache');
87
+ }
88
+ /**
89
+ * Determine whether the registry cache should be refreshed.
90
+ * Checks:
91
+ * 1. `options.refreshRegistry` flag
92
+ * 2. `SPECVERSE_REFRESH_REGISTRY` environment variable
93
+ */
94
+ function shouldRefreshRegistry(options) {
95
+ if (options.refreshRegistry)
96
+ return true;
97
+ return process.env['SPECVERSE_REFRESH_REGISTRY'] === '1';
98
+ }
99
+ /**
100
+ * Read a cache entry if it exists (and we are not refreshing).
101
+ */
102
+ function readCache(cacheDir, key, refresh) {
103
+ if (refresh)
104
+ return null;
105
+ const filePath = join(cacheDir, `${key}.json`);
106
+ if (!existsSync(filePath))
107
+ return null;
108
+ try {
109
+ const raw = readFileSync(filePath, 'utf-8');
110
+ return JSON.parse(raw);
111
+ }
112
+ catch {
113
+ return null;
114
+ }
115
+ }
116
+ /**
117
+ * Write a cache entry. Creates the cache directory if it doesn't exist.
118
+ */
119
+ function writeCache(cacheDir, key, entry) {
120
+ try {
121
+ if (!existsSync(cacheDir)) {
122
+ mkdirSync(cacheDir, { recursive: true });
123
+ }
124
+ const filePath = join(cacheDir, `${key}.json`);
125
+ writeFileSync(filePath, JSON.stringify(entry, null, 2), 'utf-8');
126
+ }
127
+ catch {
128
+ // Cache write failure is non-fatal — resolution can continue without it.
129
+ }
130
+ }
131
+ /**
132
+ * Sanitise a `from:` value so it's safe as a filesystem key.
133
+ * Converts `@scope/pkg` → `scope__pkg`, slashes → `__`.
134
+ */
135
+ function cacheKey(from) {
136
+ return from.replace(/^@/, '').replace(/\//g, '__');
137
+ }
138
+ class DependencyResolverImpl {
139
+ async resolve(from, version, options = { spec: { components: [], deployments: [], manifests: [] } }) {
140
+ const effectiveVersion = version ?? DEFAULT_VERSION;
141
+ const triedSteps = [];
142
+ // ── Step 1: Local component in same spec ────────────────────────────────
143
+ triedSteps.push('local-component');
144
+ const localMatch = (options.spec?.components ?? []).find((c) => c.name === from);
145
+ if (localMatch) {
146
+ return {
147
+ fromName: from,
148
+ source: 'local',
149
+ spec: { name: localMatch.name, version: localMatch.version, components: [localMatch] },
150
+ resolvedName: localMatch.name,
151
+ resolvedVersion: localMatch.version,
152
+ };
153
+ }
154
+ // ── Step 2: Local npm package ────────────────────────────────────────────
155
+ triedSteps.push('npm-package');
156
+ const workspaceRoot = resolve(options.workspaceRoot ?? process.cwd());
157
+ const pkgJsonPath = join(workspaceRoot, 'node_modules', from, 'package.json');
158
+ if (existsSync(pkgJsonPath)) {
159
+ try {
160
+ const pkgJson = JSON.parse(readFileSync(pkgJsonPath, 'utf-8'));
161
+ const pkgName = pkgJson['name'] ?? from;
162
+ const pkgVersion = pkgJson['version'] ?? effectiveVersion;
163
+ return {
164
+ fromName: from,
165
+ source: 'npm',
166
+ spec: { name: pkgName, version: pkgVersion },
167
+ resolvedName: pkgName,
168
+ resolvedVersion: pkgVersion,
169
+ packageSpecifier: pkgName,
170
+ };
171
+ }
172
+ catch {
173
+ // Malformed package.json — fall through to registry steps.
174
+ }
175
+ }
176
+ // ── Offline fence ────────────────────────────────────────────────────────
177
+ if (options.offline) {
178
+ throw new DependencyResolutionError(`Cannot resolve "${from}": not found as a local component or npm package, ` +
179
+ `and offline mode prevents registry lookup.\n` +
180
+ ` Tried: ${triedSteps.join(', ')}`, from, triedSteps);
181
+ }
182
+ const cacheDir = resolveCacheDir(options);
183
+ const refresh = shouldRefreshRegistry(options);
184
+ const key = cacheKey(from);
185
+ // ── Step 3: Registry library (Library.type: component) ───────────────────
186
+ triedSteps.push('registry-component');
187
+ const cachedComponent = readCache(cacheDir, key, refresh);
188
+ if (cachedComponent && cachedComponent.source === 'registry-component') {
189
+ return {
190
+ fromName: from,
191
+ source: 'registry-component',
192
+ spec: { name: cachedComponent.name, version: cachedComponent.version },
193
+ resolvedName: cachedComponent.name,
194
+ resolvedVersion: cachedComponent.version,
195
+ packageSpecifier: cachedComponent.name,
196
+ registryRef: { name: cachedComponent.name, version: cachedComponent.version },
197
+ };
198
+ }
199
+ const registryComponentResult = await fetchRegistryComponent(from, effectiveVersion);
200
+ if (registryComponentResult) {
201
+ const entry = {
202
+ cachedAt: new Date().toISOString(),
203
+ source: 'registry-component',
204
+ name: registryComponentResult.name,
205
+ version: registryComponentResult.version,
206
+ data: registryComponentResult,
207
+ };
208
+ writeCache(cacheDir, key, entry);
209
+ return {
210
+ fromName: from,
211
+ source: 'registry-component',
212
+ spec: { name: registryComponentResult.name, version: registryComponentResult.version },
213
+ resolvedName: registryComponentResult.name,
214
+ resolvedVersion: registryComponentResult.version,
215
+ packageSpecifier: registryComponentResult.name,
216
+ registryRef: { name: registryComponentResult.name, version: registryComponentResult.version },
217
+ };
218
+ }
219
+ // ── Step 4: Registry factory (Library.type: factory) ─────────────────────
220
+ triedSteps.push('registry-factory');
221
+ const factoryKey = `factory__${key}`;
222
+ const cachedFactory = readCache(cacheDir, factoryKey, refresh);
223
+ if (cachedFactory && cachedFactory.source === 'registry-factory') {
224
+ return {
225
+ fromName: from,
226
+ source: 'registry-factory',
227
+ spec: { name: cachedFactory.name, version: cachedFactory.version },
228
+ resolvedName: cachedFactory.name,
229
+ resolvedVersion: cachedFactory.version,
230
+ packageSpecifier: cachedFactory.name,
231
+ registryRef: { name: cachedFactory.name, version: cachedFactory.version },
232
+ };
233
+ }
234
+ const registryFactoryResult = await fetchRegistryFactory(from);
235
+ if (registryFactoryResult) {
236
+ const entry = {
237
+ cachedAt: new Date().toISOString(),
238
+ source: 'registry-factory',
239
+ name: registryFactoryResult.name,
240
+ version: registryFactoryResult.version,
241
+ data: registryFactoryResult,
242
+ };
243
+ writeCache(cacheDir, factoryKey, entry);
244
+ return {
245
+ fromName: from,
246
+ source: 'registry-factory',
247
+ spec: { name: registryFactoryResult.name, version: registryFactoryResult.version },
248
+ resolvedName: registryFactoryResult.name,
249
+ resolvedVersion: registryFactoryResult.version,
250
+ packageSpecifier: registryFactoryResult.name,
251
+ registryRef: { name: registryFactoryResult.name, version: registryFactoryResult.version },
252
+ };
253
+ }
254
+ // ── Nothing resolved ─────────────────────────────────────────────────────
255
+ throw new DependencyResolutionError(`Cannot resolve "${from}" (version: "${effectiveVersion}"): ` +
256
+ `exhausted all 4 lookup steps with no match.\n` +
257
+ ` Tried: ${triedSteps.join(' → ')}\n` +
258
+ ` Hint: check the component name, npm package name, or registry entry for "${from}".`, from, triedSteps);
259
+ }
260
+ async resolveCapability(capability, options = { spec: { components: [], deployments: [], manifests: [] } }) {
261
+ if (options.offline) {
262
+ // In offline mode we cannot query the registry for capability matches.
263
+ return null;
264
+ }
265
+ const cacheDir = resolveCacheDir(options);
266
+ const refresh = shouldRefreshRegistry(options);
267
+ const key = `capability__${cacheKey(capability)}`;
268
+ // Check cache first.
269
+ const cached = readCache(cacheDir, key, refresh);
270
+ if (cached && cached.source === 'registry-factory') {
271
+ return {
272
+ name: cached.name,
273
+ version: cached.version,
274
+ metadata: cached.data,
275
+ };
276
+ }
277
+ // TODO(v2-p3-round2): real HTTP call stubbed below.
278
+ const result = await fetchRegistryFactory(capability);
279
+ if (result) {
280
+ const entry = {
281
+ cachedAt: new Date().toISOString(),
282
+ source: 'registry-factory',
283
+ name: result.name,
284
+ version: result.version,
285
+ data: result,
286
+ };
287
+ writeCache(cacheDir, key, entry);
288
+ return { name: result.name, version: result.version, metadata: result.metadata };
289
+ }
290
+ return null;
291
+ }
292
+ }
293
+ // ============================================================================
294
+ // Factory function (public API)
295
+ // ============================================================================
296
+ /**
297
+ * Create a `DependencyResolver` instance.
298
+ *
299
+ * The resolver is stateless between realize runs. A new instance should be
300
+ * created per-run (or per test) to avoid cross-run cache pollution in memory.
301
+ * On-disk cache in `<cacheDir>/registry-cache/` persists across runs and is
302
+ * shared across instances that use the same directory.
303
+ */
304
+ export function createDependencyResolver() {
305
+ return new DependencyResolverImpl();
306
+ }
307
+ //# sourceMappingURL=index.js.map
@@ -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"}