@pattern-stack/codegen 0.13.1 → 0.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/dist/{job-orchestrator.protocol-CHOEqBDk.d.ts → job-orchestrator.protocol-CARhMLCO.d.ts} +1 -1
  2. package/dist/runtime/subsystems/analytics/analytics.module.js +6 -2
  3. package/dist/runtime/subsystems/analytics/analytics.module.js.map +1 -1
  4. package/dist/runtime/subsystems/analytics/analytics.tokens.d.ts +0 -11
  5. package/dist/runtime/subsystems/analytics/analytics.tokens.js +6 -2
  6. package/dist/runtime/subsystems/analytics/analytics.tokens.js.map +1 -1
  7. package/dist/runtime/subsystems/analytics/cube-backend.js +6 -2
  8. package/dist/runtime/subsystems/analytics/cube-backend.js.map +1 -1
  9. package/dist/runtime/subsystems/analytics/index.js +6 -2
  10. package/dist/runtime/subsystems/analytics/index.js.map +1 -1
  11. package/dist/runtime/subsystems/auth/auth.module.js +12 -6
  12. package/dist/runtime/subsystems/auth/auth.module.js.map +1 -1
  13. package/dist/runtime/subsystems/auth/auth.tokens.d.ts +0 -28
  14. package/dist/runtime/subsystems/auth/auth.tokens.js +12 -8
  15. package/dist/runtime/subsystems/auth/auth.tokens.js.map +1 -1
  16. package/dist/runtime/subsystems/auth/controllers/auth.controller.js +12 -5
  17. package/dist/runtime/subsystems/auth/controllers/auth.controller.js.map +1 -1
  18. package/dist/runtime/subsystems/auth/index.js +12 -8
  19. package/dist/runtime/subsystems/auth/index.js.map +1 -1
  20. package/dist/runtime/subsystems/auth/middleware/requester-context.js +12 -1
  21. package/dist/runtime/subsystems/auth/middleware/requester-context.js.map +1 -1
  22. package/dist/runtime/subsystems/bridge/bridge-delivery-handler.d.ts +1 -1
  23. package/dist/runtime/subsystems/bridge/bridge-delivery-handler.js +10 -2
  24. package/dist/runtime/subsystems/bridge/bridge-delivery-handler.js.map +1 -1
  25. package/dist/runtime/subsystems/bridge/bridge-delivery.memory-backend.d.ts +1 -1
  26. package/dist/runtime/subsystems/bridge/bridge-delivery.memory-backend.js +2 -2
  27. package/dist/runtime/subsystems/bridge/bridge-delivery.memory-backend.js.map +1 -1
  28. package/dist/runtime/subsystems/bridge/bridge-outbox-drain-hook.js +10 -2
  29. package/dist/runtime/subsystems/bridge/bridge-outbox-drain-hook.js.map +1 -1
  30. package/dist/runtime/subsystems/bridge/bridge.module.d.ts +1 -1
  31. package/dist/runtime/subsystems/bridge/bridge.module.js +186 -168
  32. package/dist/runtime/subsystems/bridge/bridge.module.js.map +1 -1
  33. package/dist/runtime/subsystems/bridge/bridge.protocol.d.ts +1 -1
  34. package/dist/runtime/subsystems/bridge/event-flow.service.d.ts +1 -1
  35. package/dist/runtime/subsystems/bridge/event-flow.service.js +9 -1
  36. package/dist/runtime/subsystems/bridge/event-flow.service.js.map +1 -1
  37. package/dist/runtime/subsystems/bridge/index.d.ts +1 -1
  38. package/dist/runtime/subsystems/bridge/index.js +168 -150
  39. package/dist/runtime/subsystems/bridge/index.js.map +1 -1
  40. package/dist/runtime/subsystems/cache/cache.drizzle-backend.js +6 -1
  41. package/dist/runtime/subsystems/cache/cache.drizzle-backend.js.map +1 -1
  42. package/dist/runtime/subsystems/cache/cache.memory-backend.js +6 -1
  43. package/dist/runtime/subsystems/cache/cache.memory-backend.js.map +1 -1
  44. package/dist/runtime/subsystems/cache/cache.module.js +6 -2
  45. package/dist/runtime/subsystems/cache/cache.module.js.map +1 -1
  46. package/dist/runtime/subsystems/cache/cache.tokens.d.ts +0 -10
  47. package/dist/runtime/subsystems/cache/cache.tokens.js +6 -2
  48. package/dist/runtime/subsystems/cache/cache.tokens.js.map +1 -1
  49. package/dist/runtime/subsystems/cache/index.js +6 -2
  50. package/dist/runtime/subsystems/cache/index.js.map +1 -1
  51. package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js +5 -0
  52. package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js.map +1 -1
  53. package/dist/runtime/subsystems/events/event-bus.memory-backend.js +5 -0
  54. package/dist/runtime/subsystems/events/event-bus.memory-backend.js.map +1 -1
  55. package/dist/runtime/subsystems/events/event-bus.redis-backend.js +5 -1
  56. package/dist/runtime/subsystems/events/event-bus.redis-backend.js.map +1 -1
  57. package/dist/runtime/subsystems/events/events.module.js +5 -1
  58. package/dist/runtime/subsystems/events/events.module.js.map +1 -1
  59. package/dist/runtime/subsystems/events/events.tokens.d.ts +5 -11
  60. package/dist/runtime/subsystems/events/events.tokens.js +5 -1
  61. package/dist/runtime/subsystems/events/events.tokens.js.map +1 -1
  62. package/dist/runtime/subsystems/events/generated/bus.js +5 -0
  63. package/dist/runtime/subsystems/events/generated/bus.js.map +1 -1
  64. package/dist/runtime/subsystems/events/generated/index.js +5 -0
  65. package/dist/runtime/subsystems/events/generated/index.js.map +1 -1
  66. package/dist/runtime/subsystems/events/index.js +5 -1
  67. package/dist/runtime/subsystems/events/index.js.map +1 -1
  68. package/dist/runtime/subsystems/index.d.ts +2 -2
  69. package/dist/runtime/subsystems/index.js +186 -168
  70. package/dist/runtime/subsystems/index.js.map +1 -1
  71. package/dist/runtime/subsystems/jobs/bullmq.config.d.ts +0 -9
  72. package/dist/runtime/subsystems/jobs/bullmq.config.js +6 -2
  73. package/dist/runtime/subsystems/jobs/bullmq.config.js.map +1 -1
  74. package/dist/runtime/subsystems/jobs/index.d.ts +1 -1
  75. package/dist/runtime/subsystems/jobs/index.js +141 -124
  76. package/dist/runtime/subsystems/jobs/index.js.map +1 -1
  77. package/dist/runtime/subsystems/jobs/job-handler.base.d.ts +1 -1
  78. package/dist/runtime/subsystems/jobs/job-handler.base.js +5 -1
  79. package/dist/runtime/subsystems/jobs/job-handler.base.js.map +1 -1
  80. package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.d.ts +1 -1
  81. package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.js +10 -3
  82. package/dist/runtime/subsystems/jobs/job-orchestrator.bullmq-backend.js.map +1 -1
  83. package/dist/runtime/subsystems/jobs/job-orchestrator.drizzle-backend.d.ts +1 -1
  84. package/dist/runtime/subsystems/jobs/job-orchestrator.drizzle-backend.js +8 -1
  85. package/dist/runtime/subsystems/jobs/job-orchestrator.drizzle-backend.js.map +1 -1
  86. package/dist/runtime/subsystems/jobs/job-orchestrator.memory-backend.d.ts +1 -1
  87. package/dist/runtime/subsystems/jobs/job-orchestrator.memory-backend.js +137 -7
  88. package/dist/runtime/subsystems/jobs/job-orchestrator.memory-backend.js.map +1 -1
  89. package/dist/runtime/subsystems/jobs/job-orchestrator.protocol.d.ts +1 -1
  90. package/dist/runtime/subsystems/jobs/job-run-keyset-cursor.d.ts +1 -1
  91. package/dist/runtime/subsystems/jobs/job-run-service.drizzle-backend.d.ts +1 -1
  92. package/dist/runtime/subsystems/jobs/job-run-service.drizzle-backend.js +8 -2
  93. package/dist/runtime/subsystems/jobs/job-run-service.drizzle-backend.js.map +1 -1
  94. package/dist/runtime/subsystems/jobs/job-run-service.memory-backend.d.ts +1 -1
  95. package/dist/runtime/subsystems/jobs/job-run-service.memory-backend.js +25 -2
  96. package/dist/runtime/subsystems/jobs/job-run-service.memory-backend.js.map +1 -1
  97. package/dist/runtime/subsystems/jobs/job-run-service.protocol.d.ts +1 -1
  98. package/dist/runtime/subsystems/jobs/job-step-service.memory-backend.js +25 -2
  99. package/dist/runtime/subsystems/jobs/job-step-service.memory-backend.js.map +1 -1
  100. package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.d.ts +1 -1
  101. package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.js +5 -0
  102. package/dist/runtime/subsystems/jobs/job-worker.bullmq-backend.js.map +1 -1
  103. package/dist/runtime/subsystems/jobs/job-worker.d.ts +1 -1
  104. package/dist/runtime/subsystems/jobs/job-worker.js +10 -4
  105. package/dist/runtime/subsystems/jobs/job-worker.js.map +1 -1
  106. package/dist/runtime/subsystems/jobs/job-worker.module.d.ts +31 -3
  107. package/dist/runtime/subsystems/jobs/job-worker.module.js +163 -145
  108. package/dist/runtime/subsystems/jobs/job-worker.module.js.map +1 -1
  109. package/dist/runtime/subsystems/jobs/jobs-domain.module.js +144 -130
  110. package/dist/runtime/subsystems/jobs/jobs-domain.module.js.map +1 -1
  111. package/dist/runtime/subsystems/jobs/jobs-domain.tokens.d.ts +0 -11
  112. package/dist/runtime/subsystems/jobs/jobs-domain.tokens.js +8 -4
  113. package/dist/runtime/subsystems/jobs/jobs-domain.tokens.js.map +1 -1
  114. package/dist/runtime/subsystems/jobs/jobs-errors.d.ts +1 -1
  115. package/dist/runtime/subsystems/observability/index.d.ts +1 -1
  116. package/dist/runtime/subsystems/observability/index.js +9 -1
  117. package/dist/runtime/subsystems/observability/index.js.map +1 -1
  118. package/dist/runtime/subsystems/observability/observability.module.js +9 -1
  119. package/dist/runtime/subsystems/observability/observability.module.js.map +1 -1
  120. package/dist/runtime/subsystems/observability/observability.protocol.d.ts +1 -1
  121. package/dist/runtime/subsystems/observability/observability.service.d.ts +1 -1
  122. package/dist/runtime/subsystems/observability/observability.service.js +9 -1
  123. package/dist/runtime/subsystems/observability/observability.service.js.map +1 -1
  124. package/dist/runtime/subsystems/observability/reporters/bridge-metrics.reporter.d.ts +1 -1
  125. package/dist/runtime/subsystems/observability/reporters/index.d.ts +1 -1
  126. package/dist/runtime/subsystems/storage/index.js +5 -1
  127. package/dist/runtime/subsystems/storage/index.js.map +1 -1
  128. package/dist/runtime/subsystems/storage/storage.module.js +5 -1
  129. package/dist/runtime/subsystems/storage/storage.module.js.map +1 -1
  130. package/dist/runtime/subsystems/storage/storage.tokens.d.ts +0 -8
  131. package/dist/runtime/subsystems/storage/storage.tokens.js +5 -1
  132. package/dist/runtime/subsystems/storage/storage.tokens.js.map +1 -1
  133. package/dist/runtime/subsystems/token-key.d.ts +7 -0
  134. package/dist/runtime/subsystems/token-key.js +8 -0
  135. package/dist/runtime/subsystems/token-key.js.map +1 -0
  136. package/dist/src/cli/index.js +1160 -694
  137. package/dist/src/cli/index.js.map +1 -1
  138. package/package.json +5 -1
  139. package/runtime/subsystems/analytics/analytics.tokens.ts +6 -2
  140. package/runtime/subsystems/auth/auth.tokens.ts +15 -8
  141. package/runtime/subsystems/bridge/bridge-delivery.memory-backend.ts +8 -1
  142. package/runtime/subsystems/cache/cache.tokens.ts +7 -2
  143. package/runtime/subsystems/events/events.tokens.ts +8 -1
  144. package/runtime/subsystems/index.ts +5 -1
  145. package/runtime/subsystems/jobs/bullmq.config.ts +5 -2
  146. package/runtime/subsystems/jobs/job-handler.base.ts +6 -1
  147. package/runtime/subsystems/jobs/job-orchestrator.memory-backend.ts +8 -3
  148. package/runtime/subsystems/jobs/job-run-service.memory-backend.ts +4 -1
  149. package/runtime/subsystems/jobs/job-step-service.memory-backend.ts +7 -2
  150. package/runtime/subsystems/jobs/job-worker.module.ts +18 -2
  151. package/runtime/subsystems/jobs/job-worker.ts +4 -1
  152. package/runtime/subsystems/jobs/jobs-domain.tokens.ts +10 -7
  153. package/runtime/subsystems/storage/storage.tokens.ts +6 -1
  154. package/runtime/subsystems/token-key.ts +7 -0
  155. package/src/config/runtime-mode.mjs +82 -0
  156. package/templates/entity/new/backend/modules/core/integration-source.ejs.t +3 -2
  157. package/templates/entity/new/clean-lite-ps/controller.ejs.t +1 -1
  158. package/templates/entity/new/clean-lite-ps/module.ejs.t +1 -1
  159. package/templates/entity/new/clean-lite-ps/prompt-extension.js +8 -2
  160. package/templates/entity/new/clean-lite-ps/repository.ejs.t +4 -4
  161. package/templates/entity/new/clean-lite-ps/service.ejs.t +4 -4
  162. package/templates/entity/new/prompt.js +49 -10
@@ -1073,8 +1073,8 @@ var icons = {
1073
1073
  };
1074
1074
 
1075
1075
  // src/cli/commands/entity.ts
1076
- import fs9 from "fs";
1077
- import path13 from "path";
1076
+ import fs10 from "fs";
1077
+ import path14 from "path";
1078
1078
  import { Command as Command2, Option as Option2 } from "clipanion";
1079
1079
 
1080
1080
  // src/utils/yaml-loader.ts
@@ -3082,8 +3082,8 @@ function loadEntityFromYaml(filePath) {
3082
3082
  }
3083
3083
  function formatZodErrors(error) {
3084
3084
  return error.errors.map((err) => {
3085
- const path34 = err.path.join(".");
3086
- const location = path34 ? `at '${path34}'` : "at root";
3085
+ const path36 = err.path.join(".");
3086
+ const location = path36 ? `at '${path36}'` : "at root";
3087
3087
  return `${err.message} ${location}`;
3088
3088
  });
3089
3089
  }
@@ -3684,8 +3684,8 @@ function collectEntitySurfaces(entities) {
3684
3684
  return surfaces;
3685
3685
  }
3686
3686
  function resolveImportRef(ref, opts) {
3687
- const { path: path34, exportName } = parseImportRef(ref);
3688
- const file = resolveModuleFile(path34, opts);
3687
+ const { path: path36, exportName } = parseImportRef(ref);
3688
+ const file = resolveModuleFile(path36, opts);
3689
3689
  if (!file) {
3690
3690
  return { status: "module-not-found", resolvedFrom: opts.sourceRoot };
3691
3691
  }
@@ -3905,19 +3905,19 @@ function findCircularDependencies(graph) {
3905
3905
  const cycles = [];
3906
3906
  const visited = /* @__PURE__ */ new Set();
3907
3907
  const recursionStack = /* @__PURE__ */ new Set();
3908
- function dfs(node, path34) {
3908
+ function dfs(node, path36) {
3909
3909
  visited.add(node);
3910
3910
  recursionStack.add(node);
3911
3911
  const outgoingEdges = graph.edges.filter((e) => e.from === node);
3912
3912
  for (const edge of outgoingEdges) {
3913
3913
  if (!visited.has(edge.to)) {
3914
- dfs(edge.to, [...path34, edge.to]);
3914
+ dfs(edge.to, [...path36, edge.to]);
3915
3915
  } else if (recursionStack.has(edge.to)) {
3916
- const cycleStart = path34.indexOf(edge.to);
3916
+ const cycleStart = path36.indexOf(edge.to);
3917
3917
  if (cycleStart !== -1) {
3918
- cycles.push([...path34.slice(cycleStart), edge.to]);
3918
+ cycles.push([...path36.slice(cycleStart), edge.to]);
3919
3919
  } else {
3920
- cycles.push([...path34, edge.to]);
3920
+ cycles.push([...path36, edge.to]);
3921
3921
  }
3922
3922
  }
3923
3923
  }
@@ -4514,8 +4514,8 @@ function suggestTransitiveRelationships(graph, options) {
4514
4514
  for (const [entityName, entity] of graph.entities) {
4515
4515
  if (shouldExcludeEntity(entityName, opts)) continue;
4516
4516
  const paths = findTransitivePaths(graph, entityName, opts);
4517
- for (const path34 of paths) {
4518
- suggestions.push(createSuggestion(path34));
4517
+ for (const path36 of paths) {
4518
+ suggestions.push(createSuggestion(path36));
4519
4519
  }
4520
4520
  }
4521
4521
  return suggestions;
@@ -4546,7 +4546,7 @@ function findTransitivePaths(graph, sourceEntity, opts) {
4546
4546
  while (queue.length > 0) {
4547
4547
  const current = queue.shift();
4548
4548
  if (!current) continue;
4549
- const { entity, depth, path: path34, visited } = current;
4549
+ const { entity, depth, path: path36, visited } = current;
4550
4550
  if (depth >= opts.maxDepth) continue;
4551
4551
  const currentEntity = graph.entities.get(entity);
4552
4552
  if (!currentEntity) continue;
@@ -4557,7 +4557,7 @@ function findTransitivePaths(graph, sourceEntity, opts) {
4557
4557
  if (shouldExcludeEntity(target, opts)) continue;
4558
4558
  if (visited.has(target)) continue;
4559
4559
  const newPath = [
4560
- ...path34,
4560
+ ...path36,
4561
4561
  {
4562
4562
  via: entity,
4563
4563
  relationship: relName,
@@ -4625,15 +4625,15 @@ function generateYamlSnippet(name, target, throughPath) {
4625
4625
  target: ${target}
4626
4626
  through: "${throughPath}"`;
4627
4627
  }
4628
- function createSuggestion(path34) {
4629
- const pathDescription = [path34.source, ...path34.hops.map((h) => h.via), path34.target].join(" -> ");
4628
+ function createSuggestion(path36) {
4629
+ const pathDescription = [path36.source, ...path36.hops.map((h) => h.via), path36.target].join(" -> ");
4630
4630
  return {
4631
4631
  severity: "info",
4632
4632
  type: "transitive_suggestion",
4633
- entity: path34.source,
4633
+ entity: path36.source,
4634
4634
  message: `Potential transitive relationship: ${pathDescription}`,
4635
- suggestion: `Add "${path34.suggestedName}" relationship via "${path34.throughPath}"`,
4636
- path: path34
4635
+ suggestion: `Add "${path36.suggestedName}" relationship via "${path36.throughPath}"`,
4636
+ path: path36
4637
4637
  };
4638
4638
  }
4639
4639
 
@@ -6279,6 +6279,24 @@ import path8 from "path";
6279
6279
  // src/cli/shared/subsystem-detect.ts
6280
6280
  import fs4 from "fs";
6281
6281
  import path6 from "path";
6282
+
6283
+ // src/cli/shared/runtime-import.ts
6284
+ var PACKAGE = "@pattern-stack/codegen";
6285
+ function resolveRuntimeMode(config) {
6286
+ return config?.runtime === "vendored" ? "vendored" : "package";
6287
+ }
6288
+ function subsystemsImport(mode, subsystem) {
6289
+ if (mode === "vendored") {
6290
+ return subsystem ? `@shared/subsystems/${subsystem}` : "@shared/subsystems";
6291
+ }
6292
+ return `${PACKAGE}/subsystems`;
6293
+ }
6294
+ function runtimeImport(mode, relpath) {
6295
+ const clean = relpath.replace(/^\/+/, "");
6296
+ return mode === "vendored" ? `@shared/${clean}` : `${PACKAGE}/runtime/${clean}`;
6297
+ }
6298
+
6299
+ // src/cli/shared/subsystem-detect.ts
6282
6300
  var SUBSYSTEMS = [
6283
6301
  {
6284
6302
  name: "events",
@@ -6475,6 +6493,36 @@ async function detectInstalledSubsystems(ctx) {
6475
6493
  const states = await detectSubsystemStatesImpl(ctx);
6476
6494
  return states.filter((s) => s.status === "installed");
6477
6495
  }
6496
+ function configuredSubsystemNames(config) {
6497
+ const subsystems = config?.subsystems;
6498
+ const raw = subsystems?.install;
6499
+ if (!Array.isArray(raw)) return [];
6500
+ const known = new Set(KNOWN_NAMES);
6501
+ const seen = /* @__PURE__ */ new Set();
6502
+ const out = [];
6503
+ for (const entry of raw) {
6504
+ if (typeof entry !== "string") continue;
6505
+ if (!known.has(entry)) continue;
6506
+ const name = entry;
6507
+ if (seen.has(name)) continue;
6508
+ seen.add(name);
6509
+ out.push(name);
6510
+ }
6511
+ return out;
6512
+ }
6513
+ function configuredInstalledSubsystems(config) {
6514
+ return configuredSubsystemNames(config).map((name) => {
6515
+ const desc3 = SUBSYSTEMS.find((s) => s.name === name);
6516
+ const cfg = config?.[name];
6517
+ const backend = typeof cfg?.backend === "string" ? cfg.backend : desc3?.defaultBackend ?? "drizzle";
6518
+ return {
6519
+ name,
6520
+ path: `@pattern-stack/codegen/subsystems#${name}`,
6521
+ backend,
6522
+ status: "installed"
6523
+ };
6524
+ });
6525
+ }
6478
6526
 
6479
6527
  // src/cli/shared/subsystems-path.ts
6480
6528
  import path7 from "path";
@@ -6523,55 +6571,55 @@ function quoteBullmqDomainOpts(input) {
6523
6571
  return `{ ${parts.join(", ")} }`;
6524
6572
  }
6525
6573
  var COMPOSERS = {
6526
- events: ({ subsystemsRel, cfg }) => {
6574
+ events: ({ moduleImport, cfg }) => {
6527
6575
  const backend = cfg?.backend ?? "drizzle";
6528
6576
  const multiTenant = Boolean(cfg?.multi_tenant);
6529
6577
  return {
6530
6578
  imports: [
6531
- `import { EventsModule } from '${subsystemsRel}/events/events.module';`
6579
+ `import { EventsModule } from '${moduleImport("events", "events.module")}';`
6532
6580
  ],
6533
6581
  calls: [
6534
6582
  ` EventsModule.forRoot(${quoteOpts({ backend, multiTenant })}),`
6535
6583
  ]
6536
6584
  };
6537
6585
  },
6538
- jobs: ({ subsystemsRel, cfg }) => {
6586
+ jobs: ({ moduleImport, cfg }) => {
6539
6587
  const backend = cfg?.backend ?? "drizzle";
6540
6588
  const multiTenant = Boolean(cfg?.multi_tenant);
6541
6589
  const workerMode = (cfg?.worker_mode ?? "standalone").trim();
6542
6590
  const imports = [
6543
- `import { JobsDomainModule } from '${subsystemsRel}/jobs/jobs-domain.module';`
6591
+ `import { JobsDomainModule } from '${moduleImport("jobs", "jobs-domain.module")}';`
6544
6592
  ];
6545
6593
  const bullExt = backend === "bullmq" ? cfg?.extensions?.bullmq : void 0;
6546
6594
  const domainOpts = quoteBullmqDomainOpts({ backend, multiTenant, bullExt });
6547
6595
  const calls = [` JobsDomainModule.forRoot(${domainOpts}),`];
6548
6596
  if (workerMode === "embedded") {
6549
6597
  imports.push(
6550
- `import { JobWorkerModule } from '${subsystemsRel}/jobs/job-worker.module';`
6598
+ `import { JobWorkerModule } from '${moduleImport("jobs", "job-worker.module")}';`
6551
6599
  );
6552
6600
  const workerOpts = backend === "bullmq" ? `{ mode: 'embedded', backend: 'bullmq'${bullExt ? `, domainModuleExtensions: { bullmq: ${jsonToTs(bullExt)} }` : ""} }` : `{ mode: 'embedded' }`;
6553
6601
  calls.push(` JobWorkerModule.forRoot(${workerOpts}),`);
6554
6602
  }
6555
6603
  return { imports, calls };
6556
6604
  },
6557
- bridge: ({ subsystemsRel, cfg }) => {
6605
+ bridge: ({ moduleImport, cfg }) => {
6558
6606
  const backend = cfg?.backend ?? "drizzle";
6559
6607
  const multiTenant = Boolean(cfg?.multi_tenant);
6560
6608
  return {
6561
6609
  imports: [
6562
- `import { BridgeModule } from '${subsystemsRel}/bridge/bridge.module';`
6610
+ `import { BridgeModule } from '${moduleImport("bridge", "bridge.module")}';`
6563
6611
  ],
6564
6612
  calls: [
6565
6613
  ` BridgeModule.forRoot(${quoteOpts({ backend, multiTenant })}),`
6566
6614
  ]
6567
6615
  };
6568
6616
  },
6569
- integration: ({ subsystemsRel, cfg }) => {
6617
+ integration: ({ moduleImport, cfg }) => {
6570
6618
  const backend = cfg?.backend ?? "drizzle";
6571
6619
  const multiTenant = Boolean(cfg?.multi_tenant);
6572
6620
  return {
6573
6621
  imports: [
6574
- `import { IntegrationModule } from '${subsystemsRel}/integration/integration.module';`
6622
+ `import { IntegrationModule } from '${moduleImport("integration", "integration.module")}';`
6575
6623
  ],
6576
6624
  calls: [
6577
6625
  ` IntegrationModule.forRoot(${quoteOpts({ backend, multiTenant })}),`
@@ -6579,6 +6627,13 @@ var COMPOSERS = {
6579
6627
  };
6580
6628
  }
6581
6629
  };
6630
+ var PACKAGE2 = "@pattern-stack/codegen";
6631
+ function makeModuleImport(mode, subsystemsRel) {
6632
+ if (mode === "vendored") {
6633
+ return (subsystem, moduleBasename) => `${subsystemsRel}/${subsystem}/${moduleBasename}`;
6634
+ }
6635
+ return (subsystem) => subsystem === "events" ? `${PACKAGE2}/subsystems` : `${PACKAGE2}/runtime/subsystems/${subsystem}/index`;
6636
+ }
6582
6637
  var COMPOSABLE_ORDER = ["events", "jobs", "bridge", "integration"];
6583
6638
  var HEADER3 = `// AUTO-GENERATED by @pattern-stack/codegen. DO NOT EDIT.
6584
6639
  // Subsystem composition barrel \u2014 reflects \`subsystems.install\` in
@@ -6593,7 +6648,8 @@ var HEADER3 = `// AUTO-GENERATED by @pattern-stack/codegen. DO NOT EDIT.
6593
6648
  // Regenerated by every \`codegen entity new\` / \`codegen subsystem install\`.
6594
6649
 
6595
6650
  `;
6596
- function buildSubsystemBarrel(installed, config, subsystemsRel) {
6651
+ function buildSubsystemBarrel(installed, config, subsystemsRel, mode = "vendored") {
6652
+ const moduleImport = makeModuleImport(mode, subsystemsRel);
6597
6653
  const actable = installed.filter((i) => i.status !== "incomplete");
6598
6654
  const installedNames = new Set(actable.map((i) => i.name));
6599
6655
  const emitted = [];
@@ -6608,7 +6664,7 @@ function buildSubsystemBarrel(installed, config, subsystemsRel) {
6608
6664
  continue;
6609
6665
  }
6610
6666
  const cfg = config?.[name] ?? void 0;
6611
- const out = composer({ subsystemsRel, cfg });
6667
+ const out = composer({ moduleImport, cfg });
6612
6668
  allImports.push(...out.imports);
6613
6669
  allCalls.push(...out.calls);
6614
6670
  emitted.push(name);
@@ -6629,7 +6685,10 @@ ${allCalls.join("\n")}
6629
6685
  async function regenerateSubsystemBarrel(opts) {
6630
6686
  const { ctx, dryRun = false } = opts;
6631
6687
  const generatedDir = opts.generatedDir ?? resolveGeneratedDir(ctx);
6632
- const installed = await detectInstalledSubsystems(ctx);
6688
+ const mode = resolveRuntimeMode(ctx.config);
6689
+ const installed = mode === "package" ? configuredInstalledSubsystems(
6690
+ ctx.config
6691
+ ) : await detectInstalledSubsystems(ctx);
6633
6692
  const subsystemsAbs = resolveSubsystemsRoot(ctx);
6634
6693
  const barrelAbs = path8.resolve(generatedDir, "subsystems.ts");
6635
6694
  let subsystemsRel = path8.relative(path8.dirname(barrelAbs), subsystemsAbs).split(path8.sep).join("/");
@@ -6637,7 +6696,8 @@ async function regenerateSubsystemBarrel(opts) {
6637
6696
  const { content, emitted, skipped } = buildSubsystemBarrel(
6638
6697
  installed,
6639
6698
  ctx.config,
6640
- subsystemsRel
6699
+ subsystemsRel,
6700
+ mode
6641
6701
  );
6642
6702
  let written = false;
6643
6703
  if (!dryRun) {
@@ -6654,11 +6714,101 @@ async function regenerateSubsystemBarrel(opts) {
6654
6714
  };
6655
6715
  }
6656
6716
 
6657
- // src/cli/shared/bridge-registry-generator.ts
6717
+ // src/cli/shared/subsystem-schema-generator.ts
6658
6718
  import fs6 from "fs";
6659
6719
  import path9 from "path";
6660
- import ts2 from "typescript";
6720
+ var PACKAGE3 = "@pattern-stack/codegen";
6721
+ var SCHEMA_SYMBOLS = {
6722
+ events: ["domainEvents"],
6723
+ jobs: [
6724
+ "jobs",
6725
+ "jobRuns",
6726
+ "jobSteps",
6727
+ "jobRunStatusEnum",
6728
+ "jobStepKindEnum",
6729
+ "jobStepStatusEnum",
6730
+ "collisionModeEnum",
6731
+ "replayFromEnum",
6732
+ "parentClosePolicyEnum",
6733
+ "waitKindEnum",
6734
+ "triggerSourceEnum"
6735
+ ],
6736
+ bridge: ["bridgeDelivery", "bridgeDeliveryStatusEnum"],
6737
+ integration: [
6738
+ "integrationSubscriptions",
6739
+ "integrationRuns",
6740
+ "integrationRunItems",
6741
+ "integrationRunDirectionEnum",
6742
+ "integrationRunActionEnum",
6743
+ "integrationRunStatusEnum",
6744
+ "integrationRunItemOperationEnum",
6745
+ "integrationRunItemStatusEnum"
6746
+ ]
6747
+ };
6748
+ var SCHEMA_ORDER = ["events", "jobs", "bridge", "integration"];
6661
6749
  var HEADER4 = `// AUTO-GENERATED by @pattern-stack/codegen. Do not edit.
6750
+ // Subsystem Drizzle schema barrel \u2014 re-exports the tables + pgEnums of every
6751
+ // installed subsystem so drizzle-kit emits their CREATE TABLE / CREATE TYPE.
6752
+ //
6753
+ // Fold into your drizzle-kit schema entrypoint once, alongside the entity
6754
+ // schema barrel:
6755
+ //
6756
+ // // src/schema.ts
6757
+ // export * from './generated/schema'; // entity tables
6758
+ // export * from './generated/subsystems-schema'; // subsystem tables + enums
6759
+ //
6760
+ // Regenerated by every \`codegen entity new\` / \`codegen subsystem install\`.
6761
+
6762
+ `;
6763
+ function schemaImportFor(mode, subsystem, subsystemsRel) {
6764
+ return mode === "vendored" ? `${subsystemsRel}/${subsystem}` : `${PACKAGE3}/runtime/subsystems/${subsystem}/index`;
6765
+ }
6766
+ function buildSubsystemSchemaBarrel(installed, subsystemsRel, mode) {
6767
+ const actable = installed.filter((i) => i.status !== "incomplete");
6768
+ const installedNames = new Set(actable.map((i) => i.name));
6769
+ const emitted = [];
6770
+ const lines = [];
6771
+ for (const name of SCHEMA_ORDER) {
6772
+ if (!installedNames.has(name)) continue;
6773
+ const symbols = SCHEMA_SYMBOLS[name];
6774
+ if (!symbols || symbols.length === 0) continue;
6775
+ const importSpec = schemaImportFor(mode, name, subsystemsRel);
6776
+ lines.push(`export { ${symbols.join(", ")} } from '${importSpec}';`);
6777
+ emitted.push(name);
6778
+ }
6779
+ const body = lines.length === 0 ? "export {};\n" : lines.join("\n") + "\n";
6780
+ return { content: HEADER4 + body, emitted };
6781
+ }
6782
+ async function regenerateSubsystemSchemaBarrel(opts) {
6783
+ const { ctx, dryRun = false } = opts;
6784
+ const generatedDir = opts.generatedDir ?? resolveGeneratedDir(ctx);
6785
+ const mode = resolveRuntimeMode(ctx.config);
6786
+ const installed = mode === "package" ? configuredInstalledSubsystems(
6787
+ ctx.config
6788
+ ) : await detectInstalledSubsystems(ctx);
6789
+ const subsystemsAbs = resolveSubsystemsRoot(ctx);
6790
+ const barrelAbs = path9.resolve(generatedDir, "subsystems-schema.ts");
6791
+ let subsystemsRel = path9.relative(path9.dirname(barrelAbs), subsystemsAbs).split(path9.sep).join("/");
6792
+ if (!subsystemsRel.startsWith(".")) subsystemsRel = "./" + subsystemsRel;
6793
+ const { content, emitted } = buildSubsystemSchemaBarrel(
6794
+ installed,
6795
+ subsystemsRel,
6796
+ mode
6797
+ );
6798
+ let written = false;
6799
+ if (!dryRun) {
6800
+ fs6.mkdirSync(path9.dirname(barrelAbs), { recursive: true });
6801
+ fs6.writeFileSync(barrelAbs, content);
6802
+ written = true;
6803
+ }
6804
+ return { schemaBarrel: barrelAbs, emitted, content, written };
6805
+ }
6806
+
6807
+ // src/cli/shared/bridge-registry-generator.ts
6808
+ import fs7 from "fs";
6809
+ import path10 from "path";
6810
+ import ts2 from "typescript";
6811
+ var HEADER5 = `// AUTO-GENERATED by @pattern-stack/codegen. Do not edit.
6662
6812
  // Run \`codegen entity new --all\` to refresh.
6663
6813
  `;
6664
6814
  var DuplicateTriggerError = class extends Error {
@@ -6716,12 +6866,12 @@ var UnknownTriggerEventError = class extends Error {
6716
6866
  name = "UnknownTriggerEventError";
6717
6867
  };
6718
6868
  function findHandlerFiles(dir) {
6719
- if (!fs6.existsSync(dir)) return [];
6869
+ if (!fs7.existsSync(dir)) return [];
6720
6870
  const out = [];
6721
- for (const entry of fs6.readdirSync(dir, { withFileTypes: true })) {
6871
+ for (const entry of fs7.readdirSync(dir, { withFileTypes: true })) {
6722
6872
  if (entry.name.startsWith(".")) continue;
6723
6873
  if (entry.name === "node_modules" || entry.name === "generated") continue;
6724
- const full = path9.join(dir, entry.name);
6874
+ const full = path10.join(dir, entry.name);
6725
6875
  if (entry.isDirectory()) {
6726
6876
  out.push(...findHandlerFiles(full));
6727
6877
  } else if (entry.isFile() && entry.name.endsWith(".ts") && !entry.name.endsWith(".d.ts")) {
@@ -6784,7 +6934,7 @@ function scanHandlerFiles(handlersDir) {
6784
6934
  const files = findHandlerFiles(handlersDir);
6785
6935
  const out = [];
6786
6936
  for (const filePath of files) {
6787
- const text2 = fs6.readFileSync(filePath, "utf8");
6937
+ const text2 = fs7.readFileSync(filePath, "utf8");
6788
6938
  const sourceFile = ts2.createSourceFile(
6789
6939
  filePath,
6790
6940
  text2,
@@ -6799,9 +6949,9 @@ function scanHandlerFiles(handlersDir) {
6799
6949
  }
6800
6950
  function readKnownEventTypes(eventsGeneratedDir) {
6801
6951
  if (!eventsGeneratedDir) return [];
6802
- const registryPath = path9.join(eventsGeneratedDir, "registry.ts");
6803
- if (!fs6.existsSync(registryPath)) return [];
6804
- const text2 = fs6.readFileSync(registryPath, "utf8");
6952
+ const registryPath = path10.join(eventsGeneratedDir, "registry.ts");
6953
+ if (!fs7.existsSync(registryPath)) return [];
6954
+ const text2 = fs7.readFileSync(registryPath, "utf8");
6805
6955
  const out = /* @__PURE__ */ new Set();
6806
6956
  const re = /^\s*'([a-zA-Z0-9_.-]+)':\s*\{/gm;
6807
6957
  let m;
@@ -6813,9 +6963,9 @@ function readKnownEventTypes(eventsGeneratedDir) {
6813
6963
  function readEventTiers(eventsGeneratedDir) {
6814
6964
  const out = /* @__PURE__ */ new Map();
6815
6965
  if (!eventsGeneratedDir) return out;
6816
- const registryPath = path9.join(eventsGeneratedDir, "registry.ts");
6817
- if (!fs6.existsSync(registryPath)) return out;
6818
- const text2 = fs6.readFileSync(registryPath, "utf8");
6966
+ const registryPath = path10.join(eventsGeneratedDir, "registry.ts");
6967
+ if (!fs7.existsSync(registryPath)) return out;
6968
+ const text2 = fs7.readFileSync(registryPath, "utf8");
6819
6969
  const re = /'([a-zA-Z0-9_.-]+)':\s*\{[^}]*?tier:\s*'(domain|audit)'/g;
6820
6970
  let m;
6821
6971
  while ((m = re.exec(text2)) !== null) {
@@ -6872,7 +7022,7 @@ function validateAgainstEventRegistry(triggers, knownEventTypes) {
6872
7022
  }
6873
7023
  function buildBridgeRegistryContent(triggers) {
6874
7024
  const chunks = [];
6875
- chunks.push(HEADER4);
7025
+ chunks.push(HEADER5);
6876
7026
  chunks.push("");
6877
7027
  chunks.push(`import type { BridgeRegistry } from '../bridge.protocol';`);
6878
7028
  chunks.push("");
@@ -6910,11 +7060,11 @@ function buildBridgeRegistryContent(triggers) {
6910
7060
  var OUTPUT_FILE_NAME = "registry.ts";
6911
7061
  async function generateBridgeRegistry(opts) {
6912
7062
  const { handlersDir, eventsGeneratedDir, outputDir, dryRun = false } = opts;
6913
- const bridgeProtocolPath = path9.resolve(outputDir, "..", "bridge.protocol.ts");
6914
- if (!fs6.existsSync(bridgeProtocolPath)) {
6915
- const strayPath = path9.join(outputDir, OUTPUT_FILE_NAME);
6916
- if (!dryRun && fs6.existsSync(strayPath)) {
6917
- fs6.rmSync(strayPath);
7063
+ const bridgeProtocolPath = path10.resolve(outputDir, "..", "bridge.protocol.ts");
7064
+ if (!fs7.existsSync(bridgeProtocolPath)) {
7065
+ const strayPath = path10.join(outputDir, OUTPUT_FILE_NAME);
7066
+ if (!dryRun && fs7.existsSync(strayPath)) {
7067
+ fs7.rmSync(strayPath);
6918
7068
  }
6919
7069
  return {
6920
7070
  outputDir,
@@ -6935,13 +7085,13 @@ async function generateBridgeRegistry(opts) {
6935
7085
  const content = buildBridgeRegistryContent(triggers);
6936
7086
  const file = {
6937
7087
  name: OUTPUT_FILE_NAME,
6938
- outputPath: path9.join(outputDir, OUTPUT_FILE_NAME),
7088
+ outputPath: path10.join(outputDir, OUTPUT_FILE_NAME),
6939
7089
  content
6940
7090
  };
6941
7091
  let written = false;
6942
7092
  if (!dryRun) {
6943
- fs6.mkdirSync(outputDir, { recursive: true });
6944
- fs6.writeFileSync(file.outputPath, file.content);
7093
+ fs7.mkdirSync(outputDir, { recursive: true });
7094
+ fs7.writeFileSync(file.outputPath, file.content);
6945
7095
  written = true;
6946
7096
  }
6947
7097
  const eventTypeCount = new Set(triggers.map((t) => t.event)).size;
@@ -6957,8 +7107,8 @@ async function generateBridgeRegistry(opts) {
6957
7107
  }
6958
7108
 
6959
7109
  // src/cli/shared/orchestration-generator.ts
6960
- import fs7 from "fs";
6961
- import path10 from "path";
7110
+ import fs8 from "fs";
7111
+ import path11 from "path";
6962
7112
  var OrchestrationEmissionError = class extends Error {
6963
7113
  constructor(issueType, patternName, message) {
6964
7114
  super(`[${issueType}] ${patternName}: ${message}`);
@@ -6969,7 +7119,7 @@ var OrchestrationEmissionError = class extends Error {
6969
7119
  patternName;
6970
7120
  name = "OrchestrationEmissionError";
6971
7121
  };
6972
- var HEADER5 = `// AUTO-GENERATED by @pattern-stack/codegen. Do not edit.
7122
+ var HEADER6 = `// AUTO-GENERATED by @pattern-stack/codegen. Do not edit.
6973
7123
  // See ADR-032 \u2014 Orchestration Patterns.
6974
7124
  `;
6975
7125
  function splitWords(str) {
@@ -7133,7 +7283,7 @@ function buildTokensTs(pattern) {
7133
7283
  typeImports.push({ specifier: reg.valueTypeImport, name: reg.valueType });
7134
7284
  }
7135
7285
  const lines = [];
7136
- lines.push(HEADER5.trimEnd());
7286
+ lines.push(HEADER6.trimEnd());
7137
7287
  lines.push("");
7138
7288
  for (const i of emitTypeImports(typeImports)) lines.push(i);
7139
7289
  lines.push("");
@@ -7166,7 +7316,7 @@ function buildProvidersTs(pattern) {
7166
7316
  }
7167
7317
  const optsType = forRootOptionsTypeName(pattern);
7168
7318
  const lines = [];
7169
- lines.push(HEADER5.trimEnd());
7319
+ lines.push(HEADER6.trimEnd());
7170
7320
  lines.push("");
7171
7321
  lines.push(`import type { Provider } from '@nestjs/common';`);
7172
7322
  for (const i of emitTypeImports(typeImports)) lines.push(i);
@@ -7233,7 +7383,7 @@ function buildDispatcherTs(pattern) {
7233
7383
  const tokenValues = registries.map(({ names: names2 }) => names2.tokenConst);
7234
7384
  const mapTypes = registries.map(({ names: names2 }) => names2.mapType);
7235
7385
  const lines = [];
7236
- lines.push(HEADER5.trimEnd());
7386
+ lines.push(HEADER6.trimEnd());
7237
7387
  lines.push("");
7238
7388
  lines.push(`import { Inject, Injectable } from '@nestjs/common';`);
7239
7389
  for (const i of emitTypeImports(typeImports)) lines.push(i);
@@ -7307,7 +7457,7 @@ function buildModuleTs(pattern) {
7307
7457
  }
7308
7458
  const tokenValues = registries.map(({ names: names2 }) => names2.tokenConst);
7309
7459
  const lines = [];
7310
- lines.push(HEADER5.trimEnd());
7460
+ lines.push(HEADER6.trimEnd());
7311
7461
  lines.push("");
7312
7462
  lines.push(`import { type DynamicModule, Module } from '@nestjs/common';`);
7313
7463
  for (const i of emitTypeImports(typeImports)) lines.push(i);
@@ -7341,7 +7491,7 @@ function buildModuleTs(pattern) {
7341
7491
  }
7342
7492
  function buildIndexTs(pattern) {
7343
7493
  const lines = [];
7344
- lines.push(HEADER5.trimEnd());
7494
+ lines.push(HEADER6.trimEnd());
7345
7495
  lines.push("");
7346
7496
  lines.push(`export * from './tokens.js';`);
7347
7497
  lines.push(`export * from './dispatcher.js';`);
@@ -7352,7 +7502,7 @@ function buildIndexTs(pattern) {
7352
7502
  }
7353
7503
  function buildRootBarrelTs(patterns) {
7354
7504
  const lines = [];
7355
- lines.push(HEADER5.trimEnd());
7505
+ lines.push(HEADER6.trimEnd());
7356
7506
  lines.push("");
7357
7507
  if (patterns.length === 0) {
7358
7508
  lines.push("// No orchestration patterns registered.");
@@ -7370,11 +7520,11 @@ function buildRootBarrelTs(patterns) {
7370
7520
  function buildPatternFiles(pattern, outputRoot) {
7371
7521
  assertEmittable(pattern);
7372
7522
  const slug = toKebabCase2(pattern.name);
7373
- const outputDir = path10.join(outputRoot, slug);
7523
+ const outputDir = path11.join(outputRoot, slug);
7374
7524
  const make = (name, content) => ({
7375
7525
  name,
7376
- outputPath: path10.join(outputDir, name),
7377
- relativePath: path10.join(slug, name),
7526
+ outputPath: path11.join(outputDir, name),
7527
+ relativePath: path11.join(slug, name),
7378
7528
  content
7379
7529
  });
7380
7530
  const files = [
@@ -7402,21 +7552,21 @@ function generateOrchestrationModules(opts) {
7402
7552
  }
7403
7553
  const rootBarrel = {
7404
7554
  name: "index.ts",
7405
- outputPath: path10.join(outputRoot, "index.ts"),
7555
+ outputPath: path11.join(outputRoot, "index.ts"),
7406
7556
  relativePath: "index.ts",
7407
7557
  content: buildRootBarrelTs(patterns)
7408
7558
  };
7409
7559
  allFiles.push(rootBarrel);
7410
7560
  let written = false;
7411
7561
  if (!dryRun && patterns.length > 0) {
7412
- fs7.mkdirSync(outputRoot, { recursive: true });
7562
+ fs8.mkdirSync(outputRoot, { recursive: true });
7413
7563
  for (const r of perPattern) {
7414
- fs7.mkdirSync(r.outputDir, { recursive: true });
7564
+ fs8.mkdirSync(r.outputDir, { recursive: true });
7415
7565
  for (const f of r.files) {
7416
- fs7.writeFileSync(f.outputPath, f.content);
7566
+ fs8.writeFileSync(f.outputPath, f.content);
7417
7567
  }
7418
7568
  }
7419
- fs7.writeFileSync(rootBarrel.outputPath, rootBarrel.content);
7569
+ fs8.writeFileSync(rootBarrel.outputPath, rootBarrel.content);
7420
7570
  written = true;
7421
7571
  }
7422
7572
  return {
@@ -7428,8 +7578,8 @@ function generateOrchestrationModules(opts) {
7428
7578
  }
7429
7579
 
7430
7580
  // src/cli/shared/event-codegen-generator.ts
7431
- import fs8 from "fs";
7432
- import path11 from "path";
7581
+ import fs9 from "fs";
7582
+ import path12 from "path";
7433
7583
 
7434
7584
  // src/parser/load-events.ts
7435
7585
  import { basename as basename2, resolve as resolve4 } from "path";
@@ -7559,7 +7709,7 @@ function isEventFieldType(s) {
7559
7709
  }
7560
7710
 
7561
7711
  // src/cli/shared/event-codegen-generator.ts
7562
- var HEADER6 = `// AUTO-GENERATED by @pattern-stack/codegen. Do not edit.
7712
+ var HEADER7 = `// AUTO-GENERATED by @pattern-stack/codegen. Do not edit.
7563
7713
  // Run \`codegen entity new --all\` to refresh.
7564
7714
  `;
7565
7715
  function toCamelCase2(input) {
@@ -7613,7 +7763,7 @@ function aggregateTypeLiteral(ev) {
7613
7763
  function collectEntityEvents(entitiesDir) {
7614
7764
  const events = [];
7615
7765
  const issues = [];
7616
- if (!fs8.existsSync(entitiesDir)) {
7766
+ if (!fs9.existsSync(entitiesDir)) {
7617
7767
  return { events, issues };
7618
7768
  }
7619
7769
  const files = findYamlFiles(entitiesDir);
@@ -7657,7 +7807,7 @@ function mergeEvents(topLevel, entitySugar) {
7657
7807
  function collectMergedEvents(opts) {
7658
7808
  const { entitiesDir, eventsDir } = opts;
7659
7809
  const entityNames = [];
7660
- if (fs8.existsSync(entitiesDir)) {
7810
+ if (fs9.existsSync(entitiesDir)) {
7661
7811
  const entityFiles = findYamlFiles(entitiesDir);
7662
7812
  for (const f of entityFiles) {
7663
7813
  const result = loadEntityFromYaml(f);
@@ -7680,7 +7830,7 @@ function collectMergedEvents(opts) {
7680
7830
  function buildTypesContent(events) {
7681
7831
  const sorted = [...events].sort((a, b) => a.type.localeCompare(b.type));
7682
7832
  if (sorted.length === 0) {
7683
- return HEADER6 + `
7833
+ return HEADER7 + `
7684
7834
  import type { DomainEvent } from '../event-bus.protocol';
7685
7835
 
7686
7836
  export type AppDomainEvent = never;
@@ -7691,7 +7841,7 @@ export type PayloadOfType<T extends EventTypeName> = DomainEvent['payload'];
7691
7841
  `;
7692
7842
  }
7693
7843
  const chunks = [];
7694
- chunks.push(HEADER6);
7844
+ chunks.push(HEADER7);
7695
7845
  chunks.push("");
7696
7846
  chunks.push(`import type { DomainEvent } from '../event-bus.protocol';`);
7697
7847
  chunks.push("");
@@ -7739,7 +7889,7 @@ export type PayloadOfType<T extends EventTypeName> = DomainEvent['payload'];
7739
7889
  function buildSchemasContent(events) {
7740
7890
  const sorted = [...events].sort((a, b) => a.type.localeCompare(b.type));
7741
7891
  if (sorted.length === 0) {
7742
- return HEADER6 + `
7892
+ return HEADER7 + `
7743
7893
  import { z } from 'zod';
7744
7894
  import type { EventTypeName } from './types';
7745
7895
 
@@ -7747,7 +7897,7 @@ export const eventPayloadSchemas = {} as Record<EventTypeName, z.ZodType>;
7747
7897
  `;
7748
7898
  }
7749
7899
  const chunks = [];
7750
- chunks.push(HEADER6);
7900
+ chunks.push(HEADER7);
7751
7901
  chunks.push("");
7752
7902
  chunks.push(`import { z } from 'zod';`);
7753
7903
  chunks.push(`import type { EventTypeName } from './types';`);
@@ -7802,7 +7952,7 @@ var REGISTRY_GETTER = [
7802
7952
  function buildRegistryContent(events) {
7803
7953
  const sorted = [...events].sort((a, b) => a.type.localeCompare(b.type));
7804
7954
  const chunks = [];
7805
- chunks.push(HEADER6);
7955
+ chunks.push(HEADER7);
7806
7956
  chunks.push("");
7807
7957
  chunks.push(`import type { EventTypeName } from './types';`);
7808
7958
  chunks.push("");
@@ -7982,10 +8132,10 @@ export class TypedEventBus {
7982
8132
  }
7983
8133
  `;
7984
8134
  function buildBusContent(_events) {
7985
- return HEADER6 + "\n" + BUS_BODY;
8135
+ return HEADER7 + "\n" + BUS_BODY;
7986
8136
  }
7987
8137
  function buildIndexContent(_events) {
7988
- return HEADER6 + `
8138
+ return HEADER7 + `
7989
8139
  export * from './types';
7990
8140
  export * from './schemas';
7991
8141
  export * from './registry';
@@ -8014,15 +8164,15 @@ async function generateEventCodegen(opts) {
8014
8164
  };
8015
8165
  const files = OUTPUT_FILE_NAMES.map((name) => ({
8016
8166
  name,
8017
- outputPath: path11.join(outputDir, name),
8167
+ outputPath: path12.join(outputDir, name),
8018
8168
  content: builders[name](merged)
8019
8169
  }));
8020
8170
  const hasError = issues.some((i) => i.severity === "error");
8021
8171
  let written = false;
8022
8172
  if (!dryRun && !hasError) {
8023
- fs8.mkdirSync(outputDir, { recursive: true });
8173
+ fs9.mkdirSync(outputDir, { recursive: true });
8024
8174
  for (const file of files) {
8025
- fs8.writeFileSync(file.outputPath, file.content);
8175
+ fs9.writeFileSync(file.outputPath, file.content);
8026
8176
  }
8027
8177
  written = true;
8028
8178
  }
@@ -8105,163 +8255,18 @@ function validateEntityEmits(entities, events) {
8105
8255
  }
8106
8256
 
8107
8257
  // src/cli/shared/provider-module-generator.ts
8108
- import { existsSync as existsSync9, mkdirSync as mkdirSync2, readFileSync as readFileSync7, statSync as statSync5, writeFileSync as writeFileSync2 } from "fs";
8109
- import { dirname, isAbsolute as isAbsolute2, join as join11, resolve as resolve5 } from "path";
8110
- function providerPascalCase(slug) {
8111
- return slug.split("-").filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
8112
- }
8113
- function providerConstantCase(slug) {
8114
- return slug.replace(/-/g, "_").toUpperCase();
8115
- }
8116
- function providerModuleBanner(sourceYaml) {
8117
- return `// @generated by @pattern-stack/codegen from ${sourceYaml} \u2014 DO NOT EDIT.
8118
- // Hand edits are overwritten on re-emit. Regenerate with \`bun run codegen\`. To change this provider, edit its \`definitions/providers/*.yaml\`.`;
8119
- }
8120
- function generateProviderModule(def, sourceYaml) {
8121
- const { slug } = def;
8122
- const Pascal = providerPascalCase(slug);
8123
- const CONST = providerConstantCase(slug);
8124
- const strategy = parseImportRef(def.auth.strategy);
8125
- const client = parseImportRef(def.client.class);
8126
- const strategyToken = `${CONST}_AUTH_STRATEGY`;
8127
- const clientToken = `${CONST}_CLIENT`;
8128
- const surfaces = def.surfaces.join(", ");
8129
- const title = def.display_name ? `${def.display_name} (\`${slug}\`)` : `\`${slug}\``;
8130
- return `${providerModuleBanner(sourceYaml)}
8131
- /**
8132
- * Provider module for ${title}.
8133
- *
8134
- * Surfaces: ${surfaces}.
8135
- *
8136
- * Wires the declared auth strategy and API client under the provider-specific
8137
- * DI tokens \`${strategyToken}\` and \`${clientToken}\`. Per the auth subsystem
8138
- * contract, strategies are registered under provider-specific tokens rather
8139
- * than a single \`AUTH_STRATEGY\`. Registry aggregation (RFC-0001 \xA73) is
8140
- * emitted by a later codegen step.
8141
- */
8142
- import { Module } from '@nestjs/common';
8143
- import { ${strategy.exportName} } from '${strategy.path}';
8144
- import { ${client.exportName} } from '${client.path}';
8145
-
8146
- /** DI token for the \`${slug}\` provider's auth strategy. */
8147
- export const ${strategyToken} = Symbol('${strategyToken}');
8148
- /** DI token for the \`${slug}\` provider's API client. */
8149
- export const ${clientToken} = Symbol('${clientToken}');
8150
-
8151
- @Module({
8152
- providers: [
8153
- ${strategy.exportName},
8154
- ${client.exportName},
8155
- { provide: ${strategyToken}, useExisting: ${strategy.exportName} },
8156
- { provide: ${clientToken}, useExisting: ${client.exportName} },
8157
- ],
8158
- exports: [
8159
- ${strategy.exportName},
8160
- ${client.exportName},
8161
- ${strategyToken},
8162
- ${clientToken},
8163
- ],
8164
- })
8165
- export class ${Pascal}ProviderModule {}
8166
- `;
8167
- }
8168
- function resolveTsconfigAliases(consumerRoot) {
8169
- const tsconfigPath = join11(consumerRoot, "tsconfig.json");
8170
- if (!existsSync9(tsconfigPath)) return null;
8171
- let parsed;
8172
- try {
8173
- parsed = JSON.parse(stripJsonComments(readFileSync7(tsconfigPath, "utf-8")));
8174
- } catch {
8175
- return null;
8176
- }
8177
- const compilerOptions = parsed.compilerOptions ?? {};
8178
- const baseUrl = compilerOptions.baseUrl ?? ".";
8179
- const sourceRoot = isAbsolute2(baseUrl) ? baseUrl : resolve5(consumerRoot, baseUrl);
8180
- const aliases = {};
8181
- for (const [pattern, targets] of Object.entries(compilerOptions.paths ?? {})) {
8182
- if (!Array.isArray(targets) || targets.length === 0) continue;
8183
- const aliasKey = pattern.replace(/\/\*$/, "");
8184
- const target = targets[0].replace(/\/\*$/, "");
8185
- aliases[aliasKey] = isAbsolute2(target) ? target : resolve5(sourceRoot, target);
8186
- }
8187
- return { sourceRoot, aliases };
8188
- }
8189
- function stripJsonComments(input) {
8190
- return input.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:])\/\/.*$/gm, "$1");
8191
- }
8192
- function generateProviderModules(opts) {
8193
- const base = {
8194
- providersDir: opts.providersDir,
8195
- skipped: false,
8196
- written: [],
8197
- loadFailures: [],
8198
- issues: []
8199
- };
8200
- if (!existsSync9(opts.providersDir) || !statSync5(opts.providersDir).isDirectory()) {
8201
- return { ...base, skipped: true };
8202
- }
8203
- const files = findYamlFiles(opts.providersDir);
8204
- if (files.length === 0) return { ...base, skipped: true };
8205
- const { successes, failures } = loadProvidersFromYaml(files);
8206
- const loaded = successes.map((s) => ({
8207
- definition: s.definition,
8208
- filePath: s.filePath
8209
- }));
8210
- const issues = failures.map((f) => ({
8211
- severity: "error",
8212
- type: "provider_load_failed",
8213
- message: `${f.error}${f.details?.length ? ` \u2014 ${f.details.join("; ")}` : ""}`,
8214
- path: f.filePath
8215
- }));
8216
- issues.push(
8217
- ...validateProviders(loaded, {
8218
- entitySurfaces: opts.entitySurfaces,
8219
- sourceRoot: opts.sourceRoot,
8220
- aliases: opts.aliases,
8221
- skipImportCheck: opts.skipImportCheck
8222
- })
8223
- );
8224
- if (issues.some((i) => i.severity === "error")) {
8225
- return { ...base, loadFailures: failures, issues };
8226
- }
8227
- const written = [];
8228
- for (const { definition, filePath } of loaded) {
8229
- const sourceYaml = relativeSource(filePath);
8230
- const content = generateProviderModule(definition, sourceYaml);
8231
- const outPath = join11(
8232
- opts.outputRoot,
8233
- definition.slug,
8234
- `${definition.slug}.provider.module.ts`
8235
- );
8236
- if (!opts.dryRun) {
8237
- writeIfChanged(outPath, content);
8238
- }
8239
- written.push(outPath);
8240
- }
8241
- return { ...base, written, loadFailures: failures, issues };
8242
- }
8243
- function writeIfChanged(outPath, content) {
8244
- if (existsSync9(outPath) && readFileSync7(outPath, "utf-8") === content) return;
8245
- mkdirSync2(dirname(outPath), { recursive: true });
8246
- writeFileSync2(outPath, content);
8247
- }
8248
- function relativeSource(filePath) {
8249
- const marker = "definitions/providers/";
8250
- const idx = filePath.lastIndexOf(marker);
8251
- if (idx !== -1) return filePath.slice(idx);
8252
- const slash = filePath.lastIndexOf("/");
8253
- return slash === -1 ? filePath : `definitions/providers/${filePath.slice(slash + 1)}`;
8254
- }
8258
+ import { existsSync as existsSync10, mkdirSync as mkdirSync3, readFileSync as readFileSync8, statSync as statSync6, writeFileSync as writeFileSync3 } from "fs";
8259
+ import { dirname as dirname2, isAbsolute as isAbsolute2, join as join12, resolve as resolve6 } from "path";
8255
8260
 
8256
8261
  // src/cli/shared/adapter-emission-generator.ts
8257
8262
  import {
8258
- existsSync as existsSync10,
8259
- mkdirSync as mkdirSync3,
8260
- readFileSync as readFileSync8,
8261
- statSync as statSync6,
8262
- writeFileSync as writeFileSync3
8263
+ existsSync as existsSync9,
8264
+ mkdirSync as mkdirSync2,
8265
+ readFileSync as readFileSync7,
8266
+ statSync as statSync5,
8267
+ writeFileSync as writeFileSync2
8263
8268
  } from "fs";
8264
- import { dirname as dirname2, join as join12 } from "path";
8269
+ import { dirname, join as join11 } from "path";
8265
8270
 
8266
8271
  // src/cli/shared/sink-emission-generator.ts
8267
8272
  var SCAFFOLD_SENTINEL = "// <CODEGEN-SCAFFOLD-V1>";
@@ -8321,7 +8326,7 @@ function generateDefaultSink(input) {
8321
8326
  // for entities with external FK join-keys, fill the marked TODO(s) below.
8322
8327
  // Source: definitions entity '${input.entityName}' (surface: ${input.surface}).
8323
8328
  import { Injectable } from '@nestjs/common';
8324
- import type { IIntegrationSink } from '@pattern-stack/codegen/subsystems';
8329
+ import type { IIntegrationSink } from '${subsystemsImport(input.mode ?? "package", "integration")}';
8325
8330
  import {
8326
8331
  ${n.repoClass},
8327
8332
  type ${n.projectionType},
@@ -8374,7 +8379,7 @@ function relationLabel(writeKey) {
8374
8379
  }
8375
8380
 
8376
8381
  // src/cli/shared/assembly-emission-generator.ts
8377
- import { relative, resolve as resolve6, sep } from "path";
8382
+ import { relative, resolve as resolve5, sep } from "path";
8378
8383
  function generatedBanner(sourceDesc) {
8379
8384
  return `// @generated by @pattern-stack/codegen from ${sourceDesc} \u2014 DO NOT EDIT.
8380
8385
  // Hand edits are overwritten on re-emit. Regenerate with \`bun run codegen\`.`;
@@ -8412,7 +8417,7 @@ import {
8412
8417
  ExecuteIntegrationUseCase,
8413
8418
  INTEGRATION_CHANGE_SOURCE,
8414
8419
  INTEGRATION_SINK,
8415
- } from '@pattern-stack/codegen/subsystems';
8420
+ } from '${subsystemsImport(input.mode ?? "package", "integration")}';
8416
8421
  import { ${adapterClass} } from '${adapterImport}';
8417
8422
  import { ${adapterModuleClass} } from '${adapterModuleImport}';
8418
8423
  import { ${sinkClass} } from '${sinkImport}';
@@ -8425,7 +8430,7 @@ import { ${token} } from '${tokensImport}';
8425
8430
  * inbound-integration assembly (RFC-0002 \xA72, Option A).
8426
8431
  *
8427
8432
  * Binds this module's INTEGRATION_CHANGE_SOURCE from the adapter's
8428
- * \`changeSources['${input.entityName}']\` and INTEGRATION_SINK from
8433
+ * \`changeSources.${input.entityName}\` and INTEGRATION_SINK from
8429
8434
  * ${sinkClass}, provides a local ExecuteIntegrationUseCase, and aliases+exports
8430
8435
  * it under ${token} (the bare class token is ambiguous at app root \u2014 every
8431
8436
  * assembly provides it). The substrate (cursor store, run recorder, differ,
@@ -8437,7 +8442,7 @@ import { ${token} } from '${tokensImport}';
8437
8442
  providers: [
8438
8443
  {
8439
8444
  provide: INTEGRATION_CHANGE_SOURCE,
8440
- useFactory: (adapter: ${adapterClass}) => adapter.changeSources['${input.entityName}'],
8445
+ useFactory: (adapter: ${adapterClass}) => adapter.changeSources.${input.entityName},
8441
8446
  inject: [${adapterClass}],
8442
8447
  },
8443
8448
  {
@@ -8486,8 +8491,8 @@ function generateIntegrationAggregator(surface, entries) {
8486
8491
  );
8487
8492
  const importLines = sorted.map((e) => {
8488
8493
  const cls = assemblyModuleClass(e.entityName, e.provider);
8489
- const path34 = `./modules/${e.provider}/${e.entityName}-integration.module`;
8490
- return `import { ${cls} } from '${path34}';`;
8494
+ const path36 = `./modules/${e.provider}/${e.entityName}-integration.module`;
8495
+ return `import { ${cls} } from '${path36}';`;
8491
8496
  }).join("\n");
8492
8497
  const membersInline = moduleClasses.join(", ");
8493
8498
  return `${generatedBanner(`surface: ${surface}`)}
@@ -8539,17 +8544,17 @@ function resolveEntityModuleImports(input) {
8539
8544
  const repoClass = `${entityClass}Repository`;
8540
8545
  const moduleClass = `${pluralPascalCase(input.entityPlural)}Module`;
8541
8546
  const moduleGroupSegs = input.context ? ["modules", input.context, input.entityPlural] : ["modules", input.entityPlural];
8542
- const repoFileAbs = resolve6(
8547
+ const repoFileAbs = resolve5(
8543
8548
  input.backendSrcAbs,
8544
8549
  ...moduleGroupSegs,
8545
8550
  `${input.entityName}.repository.ts`
8546
8551
  );
8547
- const moduleFileAbs = resolve6(
8552
+ const moduleFileAbs = resolve5(
8548
8553
  input.backendSrcAbs,
8549
8554
  ...moduleGroupSegs,
8550
8555
  `${input.entityPlural}.module.ts`
8551
8556
  );
8552
- const assemblyDirAbs = resolve6(
8557
+ const assemblyDirAbs = resolve5(
8553
8558
  input.backendSrcAbs,
8554
8559
  "integrations",
8555
8560
  input.surface,
@@ -8638,6 +8643,9 @@ var SURFACE_REGISTRY = {
8638
8643
  readPrimitive: true
8639
8644
  }
8640
8645
  };
8646
+ function isClientlessProvider(surfaces) {
8647
+ return surfaces.length > 0 && surfaces.every((s) => SURFACE_REGISTRY[s]?.readPrimitive === true);
8648
+ }
8641
8649
  var SCAFFOLD_SENTINEL2 = "// <CODEGEN-SCAFFOLD-V1>";
8642
8650
  function generatedBanner2(sourceDesc) {
8643
8651
  return `// @generated by @pattern-stack/codegen from ${sourceDesc} \u2014 DO NOT EDIT.
@@ -8692,7 +8700,7 @@ function serializeFilterArray(filters) {
8692
8700
  ${items.join("\n")}
8693
8701
  ]`;
8694
8702
  }
8695
- function buildReadPrimitiveEmission(providerSlug, providerPascal, surface, entities, entityDetection, clientExportName) {
8703
+ function buildReadPrimitiveEmission(providerSlug, providerPascal, surface, entities, entityDetection) {
8696
8704
  const canonicalTypes = [];
8697
8705
  const blocks = [];
8698
8706
  const entries = [];
@@ -8724,24 +8732,32 @@ export class ${className} extends IncrementalReadBase<${canonical}, ResolvedFilt
8724
8732
  // (e.g. Gmail \`q=\`); leave \`false\` to filter post-hydrate via \`matchesRecord\`.
8725
8733
  protected override readonly filterPushdown = false;${cursorOverride}
8726
8734
 
8727
- constructor(
8728
- private readonly auth: IAuthStrategy,
8729
- private readonly client: ${clientExportName},
8730
- ) {
8735
+ constructor(private readonly auth: IAuthStrategy) {
8731
8736
  super();
8732
8737
  }
8733
8738
 
8734
- /** TODO: walk the vendor list endpoint \u2192 pages of \`Ref\` (id + cursor + meta). */
8739
+ /**
8740
+ * TODO: walk the vendor list endpoint \u2192 pages of \`Ref\` (id + cursor + meta).
8741
+ * Per-connection (multi-account) adapters resolve credentials here from the
8742
+ * threaded subscription, e.g.
8743
+ * \`const client = <vendorClientFactory>({ accessToken: async () => (await this.auth.resolve(_ctx!.subscription!.externalRef)).accessToken });\`
8744
+ * \u2014 there is no provider-level singleton client. Provider-level-auth adapters
8745
+ * ignore \`_ctx\`.
8746
+ */
8735
8747
  protected async *enumerate(
8736
8748
  _mode: ReadMode,
8737
8749
  _filter?: ResolvedFilter[],
8738
8750
  _pageSize?: number,
8751
+ _ctx?: ReadContext,
8739
8752
  ): AsyncIterable<Ref[]> {
8740
8753
  throw new Error('not implemented: ${className}.enumerate');
8741
8754
  }
8742
8755
 
8743
- /** TODO: batched fetch-by-id \u2192 \`Map<id, raw>\` (\`mapConcurrent\`, or a vendor /batch). */
8744
- protected async hydrate(_ids: string[]): Promise<Map<string, unknown>> {
8756
+ /**
8757
+ * TODO: batched fetch-by-id \u2192 \`Map<id, raw>\` (\`mapConcurrent\`, or a vendor /batch).
8758
+ * Use \`_ctx?.subscription?.id\` to key raw-landing rows per connection.
8759
+ */
8760
+ protected async hydrate(_ids: string[], _ctx?: ReadContext): Promise<Map<string, unknown>> {
8745
8761
  throw new Error('not implemented: ${className}.hydrate');
8746
8762
  }
8747
8763
 
@@ -8756,15 +8772,16 @@ export class ${className} extends IncrementalReadBase<${canonical}, ResolvedFilt
8756
8772
  return ${constName};
8757
8773
  }
8758
8774
  }`);
8759
- entries.push(` ${entity}: new ${className}(this.auth, this.client),`);
8775
+ entries.push(` ${entity}: new ${className}(this.auth),`);
8760
8776
  }
8761
8777
  return { canonicalTypes, preamble: blocks.join("\n\n"), changeSourceEntries: entries };
8762
8778
  }
8763
- function generateAdapterScaffold(def, surface, entities, entityDetection) {
8779
+ function generateAdapterScaffold(def, surface, entities, entityDetection, mode = "package") {
8764
8780
  const spec = SURFACE_REGISTRY[surface];
8765
8781
  if (!spec) throw new Error(`no surface package for '${surface}'`);
8766
8782
  const n = names(def.slug, surface);
8767
8783
  const client = parseImportRef(def.client.class);
8784
+ const subsystemsSpec = subsystemsImport(mode, "integration");
8768
8785
  const entitiesLiteral = entities.length ? `[${entities.map((e) => `'${e}'`).join(", ")}]` : "[]";
8769
8786
  const readPrimitive = !!spec.readPrimitive && entities.length > 0;
8770
8787
  const rp = readPrimitive ? buildReadPrimitiveEmission(
@@ -8772,21 +8789,26 @@ function generateAdapterScaffold(def, surface, entities, entityDetection) {
8772
8789
  n.providerPascal,
8773
8790
  surface,
8774
8791
  entities,
8775
- entityDetection,
8776
- client.exportName
8792
+ entityDetection
8777
8793
  ) : null;
8778
8794
  const surfaceTypeImports = [
8779
8795
  spec.portType,
8780
8796
  ...spec.l2Ports.map((p) => p.type),
8781
8797
  spec.capabilitiesType,
8782
8798
  ...rp ? rp.canonicalTypes : []
8783
- ].map((t) => ` ${t},`).join("\n");
8784
- const subsystemValueImport = rp ? `import { IncrementalReadBase } from '@pattern-stack/codegen/subsystems';
8799
+ ].sort().map((t) => ` ${t},`).join("\n");
8800
+ const subsystemValueImport = rp ? `import { IncrementalReadBase } from '${subsystemsSpec}';
8785
8801
  ` : "";
8786
8802
  const subsystemTypeImports = [
8787
8803
  "IAuthStrategy",
8788
8804
  "IChangeSource",
8789
- ...rp ? ["IntegrationSubscriptionView", "ReadMode", "Ref", "ResolvedFilter"] : []
8805
+ ...rp ? [
8806
+ "IntegrationSubscriptionView",
8807
+ "ReadContext",
8808
+ "ReadMode",
8809
+ "Ref",
8810
+ "ResolvedFilter"
8811
+ ] : []
8790
8812
  ].map((t) => ` ${t},`).join("\n");
8791
8813
  const changeSourcesAssign = rp ? `
8792
8814
  this.changeSources = {
@@ -8826,6 +8848,14 @@ ${rp.preamble}
8826
8848
  const l2Section = l2Members ? `
8827
8849
  ${l2Members}
8828
8850
  ` : "";
8851
+ const clientTypeImport = rp ? "" : `import type { ${client.exportName} } from '${client.path}';
8852
+ `;
8853
+ const providerTokenImport = rp ? `import { ${n.strategyToken} } from '../../../providers/${def.slug}/${def.slug}.provider.module';` : `import { ${n.strategyToken}, ${n.clientToken} } from '../../../providers/${def.slug}/${def.slug}.provider.module';`;
8854
+ const ctorClientParam = rp ? "" : `
8855
+ @Inject(${n.clientToken}) private readonly client: ${client.exportName},`;
8856
+ const ctorOpen = rp ? ` constructor(@Inject(${n.strategyToken}) readonly auth: IAuthStrategy) {${changeSourcesAssign}}` : ` constructor(
8857
+ @Inject(${n.strategyToken}) readonly auth: IAuthStrategy,${ctorClientParam}
8858
+ ) {${changeSourcesAssign}}`;
8829
8859
  return `${SCAFFOLD_SENTINEL2}
8830
8860
  // Scaffolded once by @pattern-stack/codegen, then author-owned. Re-running
8831
8861
  // codegen detects the sentinel above and SKIPS this file \u2014 your edits are safe.
@@ -8837,9 +8867,8 @@ ${surfaceTypeImports}
8837
8867
  import { ${spec.noCapsConst} } from '${spec.packageName}';
8838
8868
  ${subsystemValueImport}import type {
8839
8869
  ${subsystemTypeImports}
8840
- } from '@pattern-stack/codegen/subsystems';
8841
- import type { ${client.exportName} } from '${client.path}';
8842
- import { ${n.strategyToken}, ${n.clientToken} } from '../../../providers/${def.slug}/${def.slug}.provider.module';
8870
+ } from '${subsystemsSpec}';
8871
+ ${clientTypeImport}${providerTokenImport}
8843
8872
  ${preambleSection}
8844
8873
  @Injectable()
8845
8874
  export class ${n.adapterClass} implements ${spec.portType} {
@@ -8848,10 +8877,7 @@ export class ${n.adapterClass} implements ${spec.portType} {
8848
8877
  ${capabilityBody}
8849
8878
  };
8850
8879
 
8851
- constructor(
8852
- @Inject(${n.strategyToken}) readonly auth: IAuthStrategy,
8853
- @Inject(${n.clientToken}) private readonly client: ${client.exportName},
8854
- ) {${changeSourcesAssign}}
8880
+ ${ctorOpen}
8855
8881
  ${l2Section}
8856
8882
  ${changeSourcesDecl}
8857
8883
 
@@ -8883,10 +8909,10 @@ function generateAdaptersBarrel(surface, providerSlugs) {
8883
8909
  ${lines}
8884
8910
  `;
8885
8911
  }
8886
- function generateSurfaceTokens(surface) {
8912
+ function generateSurfaceTokens(surface, mode = "package") {
8887
8913
  const n = names("__placeholder__", surface);
8888
8914
  return `${generatedBanner2(`surface: ${surface}`)}
8889
- import type { IChangeSource } from '@pattern-stack/codegen/subsystems';
8915
+ import type { IChangeSource } from '${subsystemsImport(mode, "integration")}';
8890
8916
 
8891
8917
  /** The assembled list of every ${surface} adapter's contribution. */
8892
8918
  export const ${n.contributionsToken} = Symbol.for('@app/integrations/${surface}.adapter-contributions');
@@ -8903,7 +8929,7 @@ export interface AdapterContribution {
8903
8929
  }
8904
8930
  `;
8905
8931
  }
8906
- function generateSurfaceAggregator(surface, providerSlugs) {
8932
+ function generateSurfaceAggregator(surface, providerSlugs, mode = "package") {
8907
8933
  const n = names("__placeholder__", surface);
8908
8934
  const slugs = [...providerSlugs].sort();
8909
8935
  const per = slugs.map((slug) => names(slug, surface));
@@ -8930,7 +8956,7 @@ import {
8930
8956
  MemoryEntityChangeSourceRegistry,
8931
8957
  type IChangeSource,
8932
8958
  type IEntityChangeSourceRegistry,
8933
- } from '@pattern-stack/codegen/subsystems';
8959
+ } from '${subsystemsImport(mode, "integration")}';
8934
8960
  ${moduleImport}
8935
8961
  ${adapterImports}
8936
8962
  import {
@@ -9019,6 +9045,7 @@ function jsKey(key) {
9019
9045
  return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key) ? key : `'${key}'`;
9020
9046
  }
9021
9047
  function emitAdapters(opts) {
9048
+ const mode = opts.mode ?? "package";
9022
9049
  const result = {
9023
9050
  written: [],
9024
9051
  scaffoldsWritten: [],
@@ -9049,14 +9076,14 @@ function emitAdapters(opts) {
9049
9076
  }
9050
9077
  const defBySlug = new Map(opts.providers.map((p) => [p.definition.slug, p.definition]));
9051
9078
  for (const [surface, slugs] of bySurface) {
9052
- const surfaceDir = join12(opts.outputRoot, surface);
9053
- const adaptersDir = join12(surfaceDir, "adapters");
9079
+ const surfaceDir = join11(opts.outputRoot, surface);
9080
+ const adaptersDir = join11(surfaceDir, "adapters");
9054
9081
  for (const slug of slugs) {
9055
9082
  const def = defBySlug.get(slug);
9056
- const providerDir = join12(adaptersDir, slug);
9057
- const scaffoldPath = join12(providerDir, `${slug}-${surface}.adapter.ts`);
9058
- const modulePath = join12(providerDir, `${slug}-${surface}.adapter.module.ts`);
9059
- if (existsSync10(scaffoldPath)) {
9083
+ const providerDir = join11(adaptersDir, slug);
9084
+ const scaffoldPath = join11(providerDir, `${slug}-${surface}.adapter.ts`);
9085
+ const modulePath = join11(providerDir, `${slug}-${surface}.adapter.module.ts`);
9086
+ if (existsSync9(scaffoldPath)) {
9060
9087
  result.scaffoldsSkipped.push(scaffoldPath);
9061
9088
  } else {
9062
9089
  const surfaceEntityNames = entitiesBySurface.get(surface) ?? [];
@@ -9069,36 +9096,37 @@ function emitAdapters(opts) {
9069
9096
  def,
9070
9097
  surface,
9071
9098
  surfaceEntityNames,
9072
- entityDetection
9099
+ entityDetection,
9100
+ mode
9073
9101
  );
9074
9102
  if (!opts.dryRun) writeFile(scaffoldPath, content);
9075
9103
  result.scaffoldsWritten.push(scaffoldPath);
9076
9104
  }
9077
9105
  const moduleContent = generateAdapterModule(def, surface);
9078
- if (!opts.dryRun) writeIfChanged2(modulePath, moduleContent);
9106
+ if (!opts.dryRun) writeIfChanged(modulePath, moduleContent);
9079
9107
  result.written.push(modulePath);
9080
9108
  }
9081
- const barrelPath = join12(adaptersDir, "index.ts");
9082
- const tokensPath = join12(surfaceDir, `${surface}-adapters.tokens.ts`);
9083
- const aggregatorPath = join12(surfaceDir, `${surface}-adapters.module.ts`);
9084
- const typedViewPath = join12(surfaceDir, "types.generated.ts");
9109
+ const barrelPath = join11(adaptersDir, "index.ts");
9110
+ const tokensPath = join11(surfaceDir, `${surface}-adapters.tokens.ts`);
9111
+ const aggregatorPath = join11(surfaceDir, `${surface}-adapters.module.ts`);
9112
+ const typedViewPath = join11(surfaceDir, "types.generated.ts");
9085
9113
  const files = [
9086
9114
  [barrelPath, generateAdaptersBarrel(surface, slugs)],
9087
- [tokensPath, generateSurfaceTokens(surface)],
9088
- [aggregatorPath, generateSurfaceAggregator(surface, slugs)],
9115
+ [tokensPath, generateSurfaceTokens(surface, mode)],
9116
+ [aggregatorPath, generateSurfaceAggregator(surface, slugs, mode)],
9089
9117
  [typedViewPath, generateTypedView(surface, slugs, entitiesBySurface.get(surface) ?? [])]
9090
9118
  ];
9091
- for (const [path34, content] of files) {
9092
- if (!opts.dryRun) writeIfChanged2(path34, content);
9093
- result.written.push(path34);
9119
+ for (const [path36, content] of files) {
9120
+ if (!opts.dryRun) writeIfChanged(path36, content);
9121
+ result.written.push(path36);
9094
9122
  }
9095
9123
  if (opts.backendSrcAbs) {
9096
9124
  const aliases = opts.aliases ?? {};
9097
9125
  const surfaceEntities = entitiesBySurface.get(surface) ?? [];
9098
9126
  const tokenEntries = [];
9099
9127
  const assemblyEntries = [];
9100
- const sinksDir = join12(surfaceDir, "sinks");
9101
- const modulesDir = join12(surfaceDir, "modules");
9128
+ const sinksDir = join11(surfaceDir, "sinks");
9129
+ const modulesDir = join11(surfaceDir, "modules");
9102
9130
  for (const entityName of surfaceEntities) {
9103
9131
  const def = entityByName.get(entityName);
9104
9132
  const pattern = def?.entity.pattern ?? (Array.isArray(def?.entity.patterns) ? def?.entity.patterns?.[0] : void 0);
@@ -9123,17 +9151,17 @@ function emitAdapters(opts) {
9123
9151
  backendSrcAbs: opts.backendSrcAbs,
9124
9152
  aliases
9125
9153
  });
9126
- const sinkPath = join12(sinksDir, `${entityName}.sink.ts`);
9127
- if (existsSync10(sinkPath)) {
9154
+ const sinkPath = join11(sinksDir, `${entityName}.sink.ts`);
9155
+ if (existsSync9(sinkPath)) {
9128
9156
  result.scaffoldsSkipped.push(sinkPath);
9129
9157
  } else {
9130
9158
  const sinkInput = buildSinkInput(def, surface, slugs[0], loc.repoImportSpecifier);
9131
- const sinkContent = generateDefaultSink(sinkInput);
9159
+ const sinkContent = generateDefaultSink({ ...sinkInput, mode });
9132
9160
  if (!opts.dryRun) writeFile(sinkPath, sinkContent);
9133
9161
  result.scaffoldsWritten.push(sinkPath);
9134
9162
  }
9135
9163
  for (const slug of slugs) {
9136
- const assemblyPath = join12(
9164
+ const assemblyPath = join11(
9137
9165
  modulesDir,
9138
9166
  slug,
9139
9167
  `${entityName}-integration.module.ts`
@@ -9147,23 +9175,24 @@ function emitAdapters(opts) {
9147
9175
  moduleClass: loc.moduleClass,
9148
9176
  repoImportSpecifier: loc.repoImportSpecifier,
9149
9177
  repoClass: loc.repoClass,
9150
- sourceDesc: `definitions/providers/${slug}.yaml`
9178
+ sourceDesc: `definitions/providers/${slug}.yaml`,
9179
+ mode
9151
9180
  });
9152
- if (!opts.dryRun) writeIfChanged2(assemblyPath, assemblyContent);
9181
+ if (!opts.dryRun) writeIfChanged(assemblyPath, assemblyContent);
9153
9182
  result.assembliesWritten.push(assemblyPath);
9154
9183
  tokenEntries.push({ entityName, entityClass: loc.entityClass, provider: slug });
9155
9184
  assemblyEntries.push({ entityName, provider: slug });
9156
9185
  }
9157
9186
  }
9158
- const integrationTokensPath = join12(
9187
+ const integrationTokensPath = join11(
9159
9188
  surfaceDir,
9160
9189
  `${surface}-integration.tokens.ts`
9161
9190
  );
9162
9191
  const tokensContent = generateIntegrationTokens(surface, tokenEntries);
9163
- if (!opts.dryRun) writeIfChanged2(integrationTokensPath, tokensContent);
9192
+ if (!opts.dryRun) writeIfChanged(integrationTokensPath, tokensContent);
9164
9193
  result.tokensWritten.push(integrationTokensPath);
9165
9194
  if (assemblyEntries.length > 0) {
9166
- const integrationAggregatorPath = join12(
9195
+ const integrationAggregatorPath = join11(
9167
9196
  surfaceDir,
9168
9197
  `${surface}-integration.module.ts`
9169
9198
  );
@@ -9171,7 +9200,7 @@ function emitAdapters(opts) {
9171
9200
  surface,
9172
9201
  assemblyEntries
9173
9202
  );
9174
- if (!opts.dryRun) writeIfChanged2(integrationAggregatorPath, aggregatorContent);
9203
+ if (!opts.dryRun) writeIfChanged(integrationAggregatorPath, aggregatorContent);
9175
9204
  result.integrationAggregatorsWritten.push(integrationAggregatorPath);
9176
9205
  }
9177
9206
  }
@@ -9228,44 +9257,240 @@ function pascalFromSnake(s) {
9228
9257
  return camel.charAt(0).toUpperCase() + camel.slice(1);
9229
9258
  }
9230
9259
  function writeFile(outPath, content) {
9231
- mkdirSync3(dirname2(outPath), { recursive: true });
9232
- writeFileSync3(outPath, content);
9260
+ mkdirSync2(dirname(outPath), { recursive: true });
9261
+ writeFileSync2(outPath, content);
9233
9262
  }
9234
- function writeIfChanged2(outPath, content) {
9235
- if (existsSync10(outPath) && statSync6(outPath).isFile() && readFileSync8(outPath, "utf-8") === content) {
9263
+ function writeIfChanged(outPath, content) {
9264
+ if (existsSync9(outPath) && statSync5(outPath).isFile() && readFileSync7(outPath, "utf-8") === content) {
9236
9265
  return;
9237
9266
  }
9238
9267
  writeFile(outPath, content);
9239
9268
  }
9240
9269
 
9241
- // src/cli/shared/events-path.ts
9242
- import path12 from "path";
9243
- var FALLBACK = "events";
9244
- function resolveEventsDirFromConfig(cwd, config) {
9245
- const configured = config?.paths?.events_dir;
9246
- if (typeof configured === "string" && configured.length > 0) {
9247
- return path12.resolve(cwd, configured);
9248
- }
9249
- return path12.resolve(cwd, FALLBACK);
9250
- }
9251
- function resolveEventsDir(ctx) {
9252
- return resolveEventsDirFromConfig(ctx.cwd, ctx.config);
9253
- }
9254
-
9255
- // src/cli/ui/output.ts
9256
- var MAX_ERROR_LEN = 500;
9257
- function printSuccess(msg) {
9258
- if (isJsonMode()) return;
9259
- console.log(`${theme.success(icons.success)} ${msg}`);
9270
+ // src/cli/shared/provider-module-generator.ts
9271
+ function providerPascalCase(slug) {
9272
+ return slug.split("-").filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
9260
9273
  }
9261
- function printError(msg) {
9262
- if (isJsonMode()) return;
9263
- const truncated = msg.length > MAX_ERROR_LEN ? msg.slice(0, MAX_ERROR_LEN) + "\u2026" : msg;
9264
- console.error(`${theme.error(icons.error)} ${truncated}`);
9274
+ function providerConstantCase(slug) {
9275
+ return slug.replace(/-/g, "_").toUpperCase();
9265
9276
  }
9266
- function printWarning(msg) {
9267
- if (isJsonMode()) return;
9268
- console.warn(`${theme.warning(icons.warning)} ${msg}`);
9277
+ function providerModuleBanner(sourceYaml) {
9278
+ return `// @generated by @pattern-stack/codegen from ${sourceYaml} \u2014 DO NOT EDIT.
9279
+ // Hand edits are overwritten on re-emit. Regenerate with \`bun run codegen\`. To change this provider, edit its \`definitions/providers/*.yaml\`.`;
9280
+ }
9281
+ function generateProviderModule(def, sourceYaml, mode = "package") {
9282
+ const { slug } = def;
9283
+ const Pascal = providerPascalCase(slug);
9284
+ const CONST = providerConstantCase(slug);
9285
+ const strategy = parseImportRef(def.auth.strategy);
9286
+ const client = parseImportRef(def.client.class);
9287
+ const strategyToken = `${CONST}_AUTH_STRATEGY`;
9288
+ const clientToken = `${CONST}_CLIENT`;
9289
+ const surfaces = def.surfaces.join(", ");
9290
+ const title = def.display_name ? `${def.display_name} (\`${slug}\`)` : `\`${slug}\``;
9291
+ if (isClientlessProvider(def.surfaces)) {
9292
+ return `${providerModuleBanner(sourceYaml)}
9293
+ /**
9294
+ * Provider module for ${title}.
9295
+ *
9296
+ * Surfaces: ${surfaces}.
9297
+ *
9298
+ * Per-connection (read-primitive) provider \u2014 exposes \`${strategyToken}\`, the
9299
+ * per-connection credential resolver the interaction adapters use (RFC-0003 R5:
9300
+ * \`auth.resolve(ctx.subscription.externalRef)\`). There is NO provider-level
9301
+ * singleton client; adapters build a per-connection client inside their
9302
+ * \`enumerate\`/\`hydrate\`. \`${strategyToken}\` resolves the already-built
9303
+ * \`${slug}\` strategy from the @Global \`STRATEGY_REGISTRY\` (wired by the
9304
+ * consumer's AuthBindings module) \u2014 the strategy may need DI deps a bare class
9305
+ * can't satisfy, so it is registry-resolved, not provided directly.
9306
+ */
9307
+ import { Module } from '@nestjs/common';
9308
+ import {
9309
+ type ProviderStrategyRegistry,
9310
+ STRATEGY_REGISTRY,
9311
+ } from '${subsystemsImport(mode, "auth")}';
9312
+
9313
+ /** DI token for the \`${slug}\` provider's auth strategy (resolved from STRATEGY_REGISTRY). */
9314
+ export const ${strategyToken} = Symbol('${strategyToken}');
9315
+
9316
+ const PROVIDER_SLUG = '${slug}';
9317
+
9318
+ @Module({
9319
+ providers: [
9320
+ {
9321
+ provide: ${strategyToken},
9322
+ useFactory: (registry: ProviderStrategyRegistry) => {
9323
+ const strategy = registry.get(PROVIDER_SLUG);
9324
+ if (!strategy) {
9325
+ throw new Error(
9326
+ \`${Pascal}ProviderModule: no '\${PROVIDER_SLUG}' strategy registered in STRATEGY_REGISTRY (wire it in your consumer AuthBindings module)\`,
9327
+ );
9328
+ }
9329
+ return strategy;
9330
+ },
9331
+ inject: [STRATEGY_REGISTRY],
9332
+ },
9333
+ ],
9334
+ exports: [${strategyToken}],
9335
+ })
9336
+ export class ${Pascal}ProviderModule {}
9337
+ `;
9338
+ }
9339
+ return `${providerModuleBanner(sourceYaml)}
9340
+ /**
9341
+ * Provider module for ${title}.
9342
+ *
9343
+ * Surfaces: ${surfaces}.
9344
+ *
9345
+ * Wires the declared auth strategy and API client under the provider-specific
9346
+ * DI tokens \`${strategyToken}\` and \`${clientToken}\`. Per the auth subsystem
9347
+ * contract, strategies are registered under provider-specific tokens rather
9348
+ * than a single \`AUTH_STRATEGY\`. Registry aggregation (RFC-0001 \xA73) is
9349
+ * emitted by a later codegen step.
9350
+ */
9351
+ import { Module } from '@nestjs/common';
9352
+ import { ${strategy.exportName} } from '${strategy.path}';
9353
+ import { ${client.exportName} } from '${client.path}';
9354
+
9355
+ /** DI token for the \`${slug}\` provider's auth strategy. */
9356
+ export const ${strategyToken} = Symbol('${strategyToken}');
9357
+ /** DI token for the \`${slug}\` provider's API client. */
9358
+ export const ${clientToken} = Symbol('${clientToken}');
9359
+
9360
+ @Module({
9361
+ providers: [
9362
+ ${strategy.exportName},
9363
+ ${client.exportName},
9364
+ { provide: ${strategyToken}, useExisting: ${strategy.exportName} },
9365
+ { provide: ${clientToken}, useExisting: ${client.exportName} },
9366
+ ],
9367
+ exports: [
9368
+ ${strategy.exportName},
9369
+ ${client.exportName},
9370
+ ${strategyToken},
9371
+ ${clientToken},
9372
+ ],
9373
+ })
9374
+ export class ${Pascal}ProviderModule {}
9375
+ `;
9376
+ }
9377
+ function resolveTsconfigAliases(consumerRoot) {
9378
+ const tsconfigPath = join12(consumerRoot, "tsconfig.json");
9379
+ if (!existsSync10(tsconfigPath)) return null;
9380
+ let parsed;
9381
+ try {
9382
+ parsed = JSON.parse(stripJsonComments(readFileSync8(tsconfigPath, "utf-8")));
9383
+ } catch {
9384
+ return null;
9385
+ }
9386
+ const compilerOptions = parsed.compilerOptions ?? {};
9387
+ const baseUrl = compilerOptions.baseUrl ?? ".";
9388
+ const sourceRoot = isAbsolute2(baseUrl) ? baseUrl : resolve6(consumerRoot, baseUrl);
9389
+ const aliases = {};
9390
+ for (const [pattern, targets] of Object.entries(compilerOptions.paths ?? {})) {
9391
+ if (!Array.isArray(targets) || targets.length === 0) continue;
9392
+ const aliasKey = pattern.replace(/\/\*$/, "");
9393
+ const target = targets[0].replace(/\/\*$/, "");
9394
+ aliases[aliasKey] = isAbsolute2(target) ? target : resolve6(sourceRoot, target);
9395
+ }
9396
+ return { sourceRoot, aliases };
9397
+ }
9398
+ function stripJsonComments(input) {
9399
+ return input.replace(/\/\*[\s\S]*?\*\//g, "").replace(/(^|[^:])\/\/.*$/gm, "$1");
9400
+ }
9401
+ function generateProviderModules(opts) {
9402
+ const base = {
9403
+ providersDir: opts.providersDir,
9404
+ skipped: false,
9405
+ written: [],
9406
+ loadFailures: [],
9407
+ issues: []
9408
+ };
9409
+ if (!existsSync10(opts.providersDir) || !statSync6(opts.providersDir).isDirectory()) {
9410
+ return { ...base, skipped: true };
9411
+ }
9412
+ const files = findYamlFiles(opts.providersDir);
9413
+ if (files.length === 0) return { ...base, skipped: true };
9414
+ const { successes, failures } = loadProvidersFromYaml(files);
9415
+ const loaded = successes.map((s) => ({
9416
+ definition: s.definition,
9417
+ filePath: s.filePath
9418
+ }));
9419
+ const issues = failures.map((f) => ({
9420
+ severity: "error",
9421
+ type: "provider_load_failed",
9422
+ message: `${f.error}${f.details?.length ? ` \u2014 ${f.details.join("; ")}` : ""}`,
9423
+ path: f.filePath
9424
+ }));
9425
+ issues.push(
9426
+ ...validateProviders(loaded, {
9427
+ entitySurfaces: opts.entitySurfaces,
9428
+ sourceRoot: opts.sourceRoot,
9429
+ aliases: opts.aliases,
9430
+ skipImportCheck: opts.skipImportCheck
9431
+ })
9432
+ );
9433
+ if (issues.some((i) => i.severity === "error")) {
9434
+ return { ...base, loadFailures: failures, issues };
9435
+ }
9436
+ const mode = opts.mode ?? "package";
9437
+ const written = [];
9438
+ for (const { definition, filePath } of loaded) {
9439
+ const sourceYaml = relativeSource(filePath);
9440
+ const content = generateProviderModule(definition, sourceYaml, mode);
9441
+ const outPath = join12(
9442
+ opts.outputRoot,
9443
+ definition.slug,
9444
+ `${definition.slug}.provider.module.ts`
9445
+ );
9446
+ if (!opts.dryRun) {
9447
+ writeIfChanged2(outPath, content);
9448
+ }
9449
+ written.push(outPath);
9450
+ }
9451
+ return { ...base, written, loadFailures: failures, issues };
9452
+ }
9453
+ function writeIfChanged2(outPath, content) {
9454
+ if (existsSync10(outPath) && readFileSync8(outPath, "utf-8") === content) return;
9455
+ mkdirSync3(dirname2(outPath), { recursive: true });
9456
+ writeFileSync3(outPath, content);
9457
+ }
9458
+ function relativeSource(filePath) {
9459
+ const marker = "definitions/providers/";
9460
+ const idx = filePath.lastIndexOf(marker);
9461
+ if (idx !== -1) return filePath.slice(idx);
9462
+ const slash = filePath.lastIndexOf("/");
9463
+ return slash === -1 ? filePath : `definitions/providers/${filePath.slice(slash + 1)}`;
9464
+ }
9465
+
9466
+ // src/cli/shared/events-path.ts
9467
+ import path13 from "path";
9468
+ var FALLBACK = "events";
9469
+ function resolveEventsDirFromConfig(cwd, config) {
9470
+ const configured = config?.paths?.events_dir;
9471
+ if (typeof configured === "string" && configured.length > 0) {
9472
+ return path13.resolve(cwd, configured);
9473
+ }
9474
+ return path13.resolve(cwd, FALLBACK);
9475
+ }
9476
+ function resolveEventsDir(ctx) {
9477
+ return resolveEventsDirFromConfig(ctx.cwd, ctx.config);
9478
+ }
9479
+
9480
+ // src/cli/ui/output.ts
9481
+ var MAX_ERROR_LEN = 500;
9482
+ function printSuccess(msg) {
9483
+ if (isJsonMode()) return;
9484
+ console.log(`${theme.success(icons.success)} ${msg}`);
9485
+ }
9486
+ function printError(msg) {
9487
+ if (isJsonMode()) return;
9488
+ const truncated = msg.length > MAX_ERROR_LEN ? msg.slice(0, MAX_ERROR_LEN) + "\u2026" : msg;
9489
+ console.error(`${theme.error(icons.error)} ${truncated}`);
9490
+ }
9491
+ function printWarning(msg) {
9492
+ if (isJsonMode()) return;
9493
+ console.warn(`${theme.warning(icons.warning)} ${msg}`);
9269
9494
  }
9270
9495
  function printInfo(msg) {
9271
9496
  if (isJsonMode()) return;
@@ -9275,10 +9500,10 @@ function printInfo(msg) {
9275
9500
  // src/cli/commands/entity.ts
9276
9501
  function resolveProvidersDir(ctx) {
9277
9502
  const fromConfig = ctx.config?.paths?.providers;
9278
- return fromConfig != null ? path13.resolve(ctx.cwd, fromConfig) : path13.resolve(ctx.cwd, "definitions/providers");
9503
+ return fromConfig != null ? path14.resolve(ctx.cwd, fromConfig) : path14.resolve(ctx.cwd, "definitions/providers");
9279
9504
  }
9280
9505
  function listEntityYamls2(dir, providersDir) {
9281
- if (!fs9.existsSync(dir)) return [];
9506
+ if (!fs10.existsSync(dir)) return [];
9282
9507
  return findYamlFiles(dir, {
9283
9508
  excludeDirs: providersDir ? [providersDir] : []
9284
9509
  });
@@ -9357,11 +9582,11 @@ async function hints(ctx) {
9357
9582
  { command: "codegen entity validate", description: "Validate YAML definitions" },
9358
9583
  { command: "codegen entity list", description: "List entities as a table" }
9359
9584
  ];
9360
- const providersDir = ctx.config?.paths?.providers != null ? path13.resolve(
9585
+ const providersDir = ctx.config?.paths?.providers != null ? path14.resolve(
9361
9586
  ctx.cwd,
9362
9587
  ctx.config.paths.providers
9363
- ) : path13.resolve(ctx.cwd, "definitions/providers");
9364
- if (fs9.existsSync(providersDir)) {
9588
+ ) : path14.resolve(ctx.cwd, "definitions/providers");
9589
+ if (fs10.existsSync(providersDir)) {
9365
9590
  baseHints.push({
9366
9591
  command: "codegen entity new --all",
9367
9592
  description: "Regenerate provider modules + adapter scaffolds (Track D)"
@@ -9416,14 +9641,14 @@ var EntityNewCommand = class extends Command2 {
9416
9641
  }
9417
9642
  let targets = [];
9418
9643
  if (this.all) {
9419
- const dir = ctx.entitiesDir ?? path13.resolve(ctx.cwd, "entities");
9644
+ const dir = ctx.entitiesDir ?? path14.resolve(ctx.cwd, "entities");
9420
9645
  targets = listEntityYamls2(dir, resolveProvidersDir(ctx));
9421
9646
  if (targets.length === 0) {
9422
9647
  printError(`No entity YAML files found in ${dir}`);
9423
9648
  return 1;
9424
9649
  }
9425
9650
  } else if (this.yaml) {
9426
- targets = [path13.resolve(ctx.cwd, this.yaml)];
9651
+ targets = [path14.resolve(ctx.cwd, this.yaml)];
9427
9652
  } else {
9428
9653
  printError("Missing YAML path. Pass a file or --all.");
9429
9654
  return 2;
@@ -9440,7 +9665,7 @@ var EntityNewCommand = class extends Command2 {
9440
9665
  }
9441
9666
  if (invalid.length > 0 && !this.continueOnError) {
9442
9667
  for (const i of invalid) {
9443
- printError(`${path13.basename(i.file)} \u2014 ${i.message}`);
9668
+ printError(`${path14.basename(i.file)} \u2014 ${i.message}`);
9444
9669
  for (const detail of i.details ?? []) {
9445
9670
  printError(` \u2022 ${detail}`);
9446
9671
  }
@@ -9449,7 +9674,7 @@ var EntityNewCommand = class extends Command2 {
9449
9674
  return 1;
9450
9675
  }
9451
9676
  }
9452
- const entitiesDirForEmits = ctx.entitiesDir ?? path13.resolve(ctx.cwd, "entities");
9677
+ const entitiesDirForEmits = ctx.entitiesDir ?? path14.resolve(ctx.cwd, "entities");
9453
9678
  const eventsDirForEmits = resolveEventsDir(ctx);
9454
9679
  const allEntitiesForEmits = loadEntities(entitiesDirForEmits, {
9455
9680
  excludeDirs: [resolveProvidersDir(ctx)]
@@ -9498,34 +9723,35 @@ var EntityNewCommand = class extends Command2 {
9498
9723
  if (!isJsonMode()) return 1;
9499
9724
  }
9500
9725
  }
9501
- const entitiesDir = ctx.entitiesDir ?? path13.resolve(ctx.cwd, "entities");
9502
- const relationshipsDir = path13.resolve(ctx.cwd, "relationships");
9726
+ const entitiesDir = ctx.entitiesDir ?? path14.resolve(ctx.cwd, "entities");
9727
+ const relationshipsDir = path14.resolve(ctx.cwd, "relationships");
9503
9728
  const generatedDir = resolveGeneratedDir(ctx);
9504
9729
  const architecture = resolveArchitecture(ctx);
9505
9730
  const subsystemsRoot = resolveSubsystemsRoot(ctx);
9506
- const scopeEntityTypePath = path13.resolve(
9731
+ const scopeEntityTypePath = path14.resolve(
9507
9732
  subsystemsRoot,
9508
9733
  "jobs/generated/scope-entity-type.ts"
9509
9734
  );
9510
9735
  const eventsDir = resolveEventsDir(ctx);
9511
- const eventCodegenOutputDir = path13.resolve(
9736
+ const eventCodegenOutputDir = path14.resolve(
9512
9737
  subsystemsRoot,
9513
9738
  "events/generated"
9514
9739
  );
9515
- const bridgeRegistryOutputDir = path13.resolve(
9740
+ const bridgeRegistryOutputDir = path14.resolve(
9516
9741
  subsystemsRoot,
9517
9742
  "bridge/generated"
9518
9743
  );
9519
9744
  const backendSrcForHandlers = ctx.config?.paths?.backend_src ?? "src";
9520
- const bridgeHandlersDir = path13.resolve(
9745
+ const runtimeMode = resolveRuntimeMode(ctx.config);
9746
+ const bridgeHandlersDir = path14.resolve(
9521
9747
  ctx.cwd,
9522
9748
  backendSrcForHandlers,
9523
9749
  "jobs"
9524
9750
  );
9525
9751
  const orchestrationConfigured = ctx.config?.paths?.orchestration_src;
9526
- const orchestrationOutputRoot = path13.resolve(
9752
+ const orchestrationOutputRoot = path14.resolve(
9527
9753
  ctx.cwd,
9528
- typeof orchestrationConfigured === "string" && orchestrationConfigured.length > 0 ? orchestrationConfigured : path13.join(backendSrcForHandlers, "orchestration")
9754
+ typeof orchestrationConfigured === "string" && orchestrationConfigured.length > 0 ? orchestrationConfigured : path14.join(backendSrcForHandlers, "orchestration")
9529
9755
  );
9530
9756
  const orchestrationGlobs = (() => {
9531
9757
  const fromCfg = ctx.config?.patterns;
@@ -9653,7 +9879,7 @@ var EntityNewCommand = class extends Command2 {
9653
9879
  }
9654
9880
  if (invalid.length > 0) {
9655
9881
  for (const i of invalid) {
9656
- printWarning(`${path13.basename(i.file)} \u2014 ${i.message}`);
9882
+ printWarning(`${path14.basename(i.file)} \u2014 ${i.message}`);
9657
9883
  }
9658
9884
  }
9659
9885
  console.log("");
@@ -9671,7 +9897,7 @@ var EntityNewCommand = class extends Command2 {
9671
9897
  }
9672
9898
  const succeeded = [];
9673
9899
  const failed = [
9674
- ...invalid.map((i) => ({ name: path13.basename(i.file), file: i.file, message: i.message }))
9900
+ ...invalid.map((i) => ({ name: path14.basename(i.file), file: i.file, message: i.message }))
9675
9901
  ];
9676
9902
  for (const v of validated) {
9677
9903
  if (!isJsonMode()) {
@@ -9714,6 +9940,14 @@ var EntityNewCommand = class extends Command2 {
9714
9940
  printWarning(`subsystem barrel regeneration failed \u2014 ${msg}`);
9715
9941
  }
9716
9942
  }
9943
+ try {
9944
+ await regenerateSubsystemSchemaBarrel({ ctx, generatedDir });
9945
+ } catch (err) {
9946
+ const msg = err instanceof Error ? err.message : String(err);
9947
+ if (!isJsonMode()) {
9948
+ printWarning(`subsystem schema barrel regeneration failed \u2014 ${msg}`);
9949
+ }
9950
+ }
9717
9951
  let scopeResult = null;
9718
9952
  try {
9719
9953
  scopeResult = await generateScopeEntityType({
@@ -9786,12 +10020,12 @@ var EntityNewCommand = class extends Command2 {
9786
10020
  let providerResult = null;
9787
10021
  try {
9788
10022
  const providersDir = resolveProvidersDir(ctx);
9789
- const providerOutputRoot = path13.resolve(
10023
+ const providerOutputRoot = path14.resolve(
9790
10024
  ctx.cwd,
9791
10025
  backendSrcForHandlers,
9792
10026
  "integrations/providers"
9793
10027
  );
9794
- const entitySurfaces = fs9.existsSync(entitiesDir) ? collectEntitySurfaces(
10028
+ const entitySurfaces = fs10.existsSync(entitiesDir) ? collectEntitySurfaces(
9795
10029
  loadEntitiesFromYaml(
9796
10030
  findYamlFiles(entitiesDir, { excludeDirs: [providersDir] })
9797
10031
  ).successes.map((s) => s.definition)
@@ -9803,7 +10037,8 @@ var EntityNewCommand = class extends Command2 {
9803
10037
  entitySurfaces,
9804
10038
  sourceRoot: tsAliases?.sourceRoot,
9805
10039
  aliases: tsAliases?.aliases,
9806
- skipImportCheck: tsAliases === null
10040
+ skipImportCheck: tsAliases === null,
10041
+ mode: runtimeMode
9807
10042
  });
9808
10043
  if (!providerResult.skipped && !isJsonMode()) {
9809
10044
  for (const issue of providerResult.issues) {
@@ -9827,12 +10062,12 @@ var EntityNewCommand = class extends Command2 {
9827
10062
  try {
9828
10063
  if (providerResult && !providerResult.skipped && providerResult.issues.length === 0) {
9829
10064
  const providersDir = providerResult.providersDir;
9830
- const adapterOutputRoot = path13.resolve(
10065
+ const adapterOutputRoot = path14.resolve(
9831
10066
  ctx.cwd,
9832
10067
  backendSrcForHandlers,
9833
10068
  "integrations"
9834
10069
  );
9835
- const entityDefs = fs9.existsSync(entitiesDir) ? loadEntitiesFromYaml(
10070
+ const entityDefs = fs10.existsSync(entitiesDir) ? loadEntitiesFromYaml(
9836
10071
  findYamlFiles(entitiesDir, { excludeDirs: [providersDir] })
9837
10072
  ).successes.map((s) => s.definition) : [];
9838
10073
  const loadedProviders = loadProvidersFromYaml(
@@ -9846,8 +10081,9 @@ var EntityNewCommand = class extends Command2 {
9846
10081
  providers: loadedProviders,
9847
10082
  entities: entityDefs,
9848
10083
  outputRoot: adapterOutputRoot,
9849
- backendSrcAbs: path13.resolve(ctx.cwd, backendSrcForHandlers),
9850
- aliases: assemblyTsAliases?.aliases ?? {}
10084
+ backendSrcAbs: path14.resolve(ctx.cwd, backendSrcForHandlers),
10085
+ aliases: assemblyTsAliases?.aliases ?? {},
10086
+ mode: runtimeMode
9851
10087
  });
9852
10088
  if (!isJsonMode()) {
9853
10089
  if (adapterResult.written.length || adapterResult.scaffoldsWritten.length) {
@@ -9947,22 +10183,22 @@ var EntityNewCommand = class extends Command2 {
9947
10183
  }
9948
10184
  if (barrelResult) {
9949
10185
  printInfo(
9950
- `barrels regenerated (${barrelResult.entityCount} entities) \u2192 ${path13.relative(ctx.cwd, barrelResult.modulesBarrel)}, ${path13.relative(ctx.cwd, barrelResult.schemaBarrel)}`
10186
+ `barrels regenerated (${barrelResult.entityCount} entities) \u2192 ${path14.relative(ctx.cwd, barrelResult.modulesBarrel)}, ${path14.relative(ctx.cwd, barrelResult.schemaBarrel)}`
9951
10187
  );
9952
10188
  }
9953
10189
  if (scopeResult) {
9954
10190
  printInfo(
9955
- `scope-entity-type regenerated (${scopeResult.scopeableNames.length} scopeable) \u2192 ${path13.relative(ctx.cwd, scopeResult.outputPath)}`
10191
+ `scope-entity-type regenerated (${scopeResult.scopeableNames.length} scopeable) \u2192 ${path14.relative(ctx.cwd, scopeResult.outputPath)}`
9956
10192
  );
9957
10193
  }
9958
10194
  if (eventCodegenResult) {
9959
10195
  printInfo(
9960
- `event codegen regenerated (${eventCodegenResult.eventCount} events) \u2192 ${path13.relative(ctx.cwd, eventCodegenResult.outputDir)}`
10196
+ `event codegen regenerated (${eventCodegenResult.eventCount} events) \u2192 ${path14.relative(ctx.cwd, eventCodegenResult.outputDir)}`
9961
10197
  );
9962
10198
  }
9963
10199
  if (orchestrationResult && orchestrationResult.patterns.length > 0) {
9964
10200
  printInfo(
9965
- `orchestration regenerated (${orchestrationResult.patterns.length} patterns, ${orchestrationResult.files.length} files) \u2192 ${path13.relative(ctx.cwd, orchestrationResult.outputRoot)}`
10201
+ `orchestration regenerated (${orchestrationResult.patterns.length} patterns, ${orchestrationResult.files.length} files) \u2192 ${path14.relative(ctx.cwd, orchestrationResult.outputRoot)}`
9966
10202
  );
9967
10203
  }
9968
10204
  }
@@ -10048,8 +10284,8 @@ var EntityValidateCommand = class extends Command2 {
10048
10284
  json: this.json,
10049
10285
  skipDetection: true
10050
10286
  });
10051
- const targetDir = this.dir ? path13.resolve(ctx.cwd, this.dir) : ctx.entitiesDir ?? path13.resolve(ctx.cwd, "entities");
10052
- if (!fs9.existsSync(targetDir)) {
10287
+ const targetDir = this.dir ? path14.resolve(ctx.cwd, this.dir) : ctx.entitiesDir ?? path14.resolve(ctx.cwd, "entities");
10288
+ if (!fs10.existsSync(targetDir)) {
10053
10289
  printError(`Directory not found: ${targetDir}`);
10054
10290
  return 1;
10055
10291
  }
@@ -10100,8 +10336,8 @@ var entityNoun = {
10100
10336
  var entity_default = entityNoun;
10101
10337
 
10102
10338
  // src/cli/commands/subsystem.ts
10103
- import fs11 from "fs";
10104
- import path22 from "path";
10339
+ import fs13 from "fs";
10340
+ import path24 from "path";
10105
10341
  import { Command as Command3, Option as Option3 } from "clipanion";
10106
10342
 
10107
10343
  // src/cli/shared/config-block-detect.ts
@@ -10134,26 +10370,26 @@ function stripConfigBlock(yamlSource, subsystem) {
10134
10370
  }
10135
10371
 
10136
10372
  // src/cli/shared/events-scaffold-locals.ts
10137
- import path14 from "path";
10373
+ import path15 from "path";
10138
10374
  function resolveEventsScaffoldLocals(input) {
10139
10375
  const { cwd, config } = input;
10140
10376
  void input.fileExists;
10141
10377
  const eventsBlock = config?.events ?? {};
10142
10378
  const subsystemsRoot = resolveSubsystemsRootFromConfig(cwd, config);
10143
- const configPath = path14.resolve(cwd, "codegen.config.yaml");
10144
- const schemaPath = path14.resolve(
10379
+ const configPath = path15.resolve(cwd, "codegen.config.yaml");
10380
+ const schemaPath = path15.resolve(
10145
10381
  subsystemsRoot,
10146
10382
  "events",
10147
10383
  "domain-events.schema.ts"
10148
10384
  );
10149
- const generatedKeepPath = path14.resolve(
10385
+ const generatedKeepPath = path15.resolve(
10150
10386
  subsystemsRoot,
10151
10387
  "events",
10152
10388
  "generated",
10153
10389
  ".gitkeep"
10154
10390
  );
10155
10391
  return {
10156
- appName: path14.basename(cwd),
10392
+ appName: path15.basename(cwd),
10157
10393
  multiTenant: normaliseMultiTenant(eventsBlock.multi_tenant),
10158
10394
  configPath,
10159
10395
  schemaPath,
@@ -10179,7 +10415,7 @@ function localsToHygenArgs(locals) {
10179
10415
  }
10180
10416
 
10181
10417
  // src/cli/shared/jobs-scaffold-locals.ts
10182
- import path15 from "path";
10418
+ import path16 from "path";
10183
10419
  var MAIN_HOOK_SENTINEL = "JOBS \u2014 Embedded worker mode (optional)";
10184
10420
  function workerSkipValue(exists) {
10185
10421
  return exists ? "true" : "";
@@ -10188,10 +10424,10 @@ function resolveJobsScaffoldLocals(input) {
10188
10424
  const { cwd, config, fileExists, readFile } = input;
10189
10425
  const jobsBlock = config?.jobs ?? {};
10190
10426
  const subsystemsRoot = resolveSubsystemsRootFromConfig(cwd, config);
10191
- const workerPath = path15.resolve(cwd, "worker.ts");
10192
- const mainTsPath = path15.resolve(cwd, "src/main.ts");
10193
- const configPath = path15.resolve(cwd, "codegen.config.yaml");
10194
- const schemaPath = path15.resolve(
10427
+ const workerPath = path16.resolve(cwd, "worker.ts");
10428
+ const mainTsPath = path16.resolve(cwd, "src/main.ts");
10429
+ const configPath = path16.resolve(cwd, "codegen.config.yaml");
10430
+ const schemaPath = path16.resolve(
10195
10431
  subsystemsRoot,
10196
10432
  "jobs",
10197
10433
  "job-orchestration.schema.ts"
@@ -10199,7 +10435,7 @@ function resolveJobsScaffoldLocals(input) {
10199
10435
  const mainContent = readFile(mainTsPath);
10200
10436
  const mainHookInjected = mainContent !== null && mainContent.includes(MAIN_HOOK_SENTINEL);
10201
10437
  return {
10202
- appName: path15.basename(cwd),
10438
+ appName: path16.basename(cwd),
10203
10439
  workerMode: normaliseWorkerMode(jobsBlock.worker_mode),
10204
10440
  multiTenant: normaliseMultiTenant2(jobsBlock.multi_tenant),
10205
10441
  mainTsPath,
@@ -10241,20 +10477,20 @@ function localsToHygenArgs2(locals) {
10241
10477
  }
10242
10478
 
10243
10479
  // src/cli/shared/integration-scaffold-locals.ts
10244
- import path16 from "path";
10480
+ import path17 from "path";
10245
10481
  function resolveIntegrationScaffoldLocals(input) {
10246
10482
  const { cwd, config } = input;
10247
10483
  void input.fileExists;
10248
10484
  const integrationBlock = config?.integration ?? {};
10249
10485
  const subsystemsRoot = resolveSubsystemsRootFromConfig(cwd, config);
10250
- const configPath = path16.resolve(cwd, "codegen.config.yaml");
10251
- const schemaPath = path16.resolve(
10486
+ const configPath = path17.resolve(cwd, "codegen.config.yaml");
10487
+ const schemaPath = path17.resolve(
10252
10488
  subsystemsRoot,
10253
10489
  "integration",
10254
10490
  "integration-audit.schema.ts"
10255
10491
  );
10256
10492
  return {
10257
- appName: path16.basename(cwd),
10493
+ appName: path17.basename(cwd),
10258
10494
  multiTenant: normaliseMultiTenant3(integrationBlock.multi_tenant),
10259
10495
  configPath,
10260
10496
  schemaPath
@@ -10277,21 +10513,21 @@ function localsToHygenArgs3(locals) {
10277
10513
  }
10278
10514
 
10279
10515
  // src/cli/shared/bridge-scaffold-locals.ts
10280
- import path17 from "path";
10516
+ import path18 from "path";
10281
10517
  function resolveBridgeScaffoldLocals(input) {
10282
10518
  const { cwd, config } = input;
10283
10519
  void input.fileExists;
10284
10520
  const bridgeBlock = config?.bridge ?? {};
10285
10521
  const subsystemsRoot = resolveSubsystemsRootFromConfig(cwd, config);
10286
- const configPath = path17.resolve(cwd, "codegen.config.yaml");
10287
- const generatedKeepPath = path17.resolve(
10522
+ const configPath = path18.resolve(cwd, "codegen.config.yaml");
10523
+ const generatedKeepPath = path18.resolve(
10288
10524
  subsystemsRoot,
10289
10525
  "bridge",
10290
10526
  "generated",
10291
10527
  ".gitkeep"
10292
10528
  );
10293
10529
  return {
10294
- appName: path17.basename(cwd),
10530
+ appName: path18.basename(cwd),
10295
10531
  multiTenant: normaliseMultiTenant4(bridgeBlock.multi_tenant),
10296
10532
  configPath,
10297
10533
  generatedKeepPath
@@ -10314,19 +10550,19 @@ function localsToHygenArgs4(locals) {
10314
10550
  }
10315
10551
 
10316
10552
  // src/cli/shared/observability-scaffold-locals.ts
10317
- import path18 from "path";
10553
+ import path19 from "path";
10318
10554
  var FALLBACK_BACKEND_SRC2 = "src";
10319
10555
  function resolveObservabilityScaffoldLocals(input) {
10320
10556
  const { cwd, config } = input;
10321
10557
  void input.fileExists;
10322
10558
  const backendSrc = typeof config?.paths?.backend_src === "string" && config.paths.backend_src.length > 0 ? config.paths.backend_src : FALLBACK_BACKEND_SRC2;
10323
- const appModulePath = path18.resolve(cwd, backendSrc, "app.module.ts");
10324
- const configPath = path18.resolve(cwd, "codegen.config.yaml");
10559
+ const appModulePath = path19.resolve(cwd, backendSrc, "app.module.ts");
10560
+ const configPath = path19.resolve(cwd, "codegen.config.yaml");
10325
10561
  const obsBlock = config?.observability ?? {};
10326
10562
  const reporters = obsBlock.reporters ?? {};
10327
10563
  const bridgeMetrics = reporters.bridgeMetrics ?? {};
10328
10564
  return {
10329
- appName: path18.basename(cwd),
10565
+ appName: path19.basename(cwd),
10330
10566
  appModulePath,
10331
10567
  configPath,
10332
10568
  bridgeMetricsEnabled: bridgeMetrics.enabled === true
@@ -10347,7 +10583,7 @@ function localsToHygenArgs5(locals) {
10347
10583
 
10348
10584
  // src/cli/shared/auth-scaffold-locals.ts
10349
10585
  import crypto2 from "crypto";
10350
- import path19 from "path";
10586
+ import path20 from "path";
10351
10587
  var FALLBACK_BACKEND_SRC3 = "src";
10352
10588
  var DEFAULT_REDIRECT_URI_BASE = "http://localhost:3000";
10353
10589
  function resolveAuthScaffoldLocals(input) {
@@ -10359,15 +10595,15 @@ function resolveAuthScaffoldLocals(input) {
10359
10595
  const redirectUriBase = typeof redirectRaw === "string" && redirectRaw.length > 0 ? redirectRaw : DEFAULT_REDIRECT_URI_BASE;
10360
10596
  const tokenEncryptionKey = crypto2.randomBytes(32).toString("base64");
10361
10597
  return {
10362
- appName: path19.basename(cwd),
10363
- configPath: path19.resolve(cwd, "codegen.config.yaml"),
10364
- schemaPath: path19.resolve(
10598
+ appName: path20.basename(cwd),
10599
+ configPath: path20.resolve(cwd, "codegen.config.yaml"),
10600
+ schemaPath: path20.resolve(
10365
10601
  subsystemsRoot,
10366
10602
  "auth",
10367
10603
  "auth-oauth-state.schema.ts"
10368
10604
  ),
10369
- appModulePath: path19.resolve(cwd, backendSrc, "app.module.ts"),
10370
- envConfigPath: path19.resolve(cwd, ".env.config"),
10605
+ appModulePath: path20.resolve(cwd, backendSrc, "app.module.ts"),
10606
+ envConfigPath: path20.resolve(cwd, ".env.config"),
10371
10607
  redirectUriBase,
10372
10608
  tokenEncryptionKey
10373
10609
  };
@@ -10392,7 +10628,7 @@ function localsToHygenArgs6(locals) {
10392
10628
  }
10393
10629
 
10394
10630
  // src/cli/shared/auth-integrations-scaffold-locals.ts
10395
- import path20 from "path";
10631
+ import path21 from "path";
10396
10632
  var FALLBACK_BACKEND_SRC4 = "src";
10397
10633
  var DEFAULT_MODULES_DIR = "modules";
10398
10634
  var DEFAULT_DEFINITIONS_DIR = "definitions/entities";
@@ -10401,17 +10637,17 @@ function resolveAuthIntegrationsScaffoldLocals(input) {
10401
10637
  const backendSrc = typeof config?.paths?.backend_src === "string" && config.paths.backend_src.length > 0 ? config.paths.backend_src : FALLBACK_BACKEND_SRC4;
10402
10638
  const pathsAny = config?.paths;
10403
10639
  const modulesConfigured = pathsAny?.modules_dir;
10404
- const vendorRoot = typeof modulesConfigured === "string" && modulesConfigured.length > 0 ? path20.resolve(cwd, modulesConfigured) : path20.resolve(cwd, backendSrc, DEFAULT_MODULES_DIR);
10640
+ const vendorRoot = typeof modulesConfigured === "string" && modulesConfigured.length > 0 ? path21.resolve(cwd, modulesConfigured) : path21.resolve(cwd, backendSrc, DEFAULT_MODULES_DIR);
10405
10641
  const entitiesConfigured = typeof pathsAny?.entities === "string" && pathsAny.entities.length > 0 ? pathsAny.entities : typeof pathsAny?.entities_dir === "string" && pathsAny.entities_dir.length > 0 ? pathsAny.entities_dir : null;
10406
- const definitionsPath = entitiesConfigured !== null ? path20.resolve(cwd, entitiesConfigured, "connection.yaml") : path20.resolve(cwd, DEFAULT_DEFINITIONS_DIR, "connection.yaml");
10407
- const appModulePath = path20.resolve(cwd, backendSrc, "app.module.ts");
10642
+ const definitionsPath = entitiesConfigured !== null ? path21.resolve(cwd, entitiesConfigured, "connection.yaml") : path21.resolve(cwd, DEFAULT_DEFINITIONS_DIR, "connection.yaml");
10643
+ const appModulePath = path21.resolve(cwd, backendSrc, "app.module.ts");
10408
10644
  let authModuleRegistered = false;
10409
10645
  const appModuleSource = input.readFile(appModulePath);
10410
10646
  if (appModuleSource && appModuleSource.includes("AuthModule.forRoot")) {
10411
10647
  authModuleRegistered = true;
10412
10648
  }
10413
10649
  return {
10414
- appName: path20.basename(cwd),
10650
+ appName: path21.basename(cwd),
10415
10651
  appModulePath,
10416
10652
  vendorRoot,
10417
10653
  definitionsPath,
@@ -10428,11 +10664,11 @@ function localsToHygenArgs7(locals) {
10428
10664
  }
10429
10665
 
10430
10666
  // src/cli/shared/runtime-copier.ts
10431
- import fs10 from "fs";
10432
- import path21 from "path";
10667
+ import fs11 from "fs";
10668
+ import path22 from "path";
10433
10669
  function readIfExists(p) {
10434
10670
  try {
10435
- return fs10.readFileSync(p, "utf-8");
10671
+ return fs11.readFileSync(p, "utf-8");
10436
10672
  } catch {
10437
10673
  return null;
10438
10674
  }
@@ -10447,20 +10683,20 @@ function extractRelativeImports(source) {
10447
10683
  return out;
10448
10684
  }
10449
10685
  function resolveSourceImport(sourceFile, specifier) {
10450
- const base = path21.resolve(path21.dirname(sourceFile), specifier);
10451
- const candidates = [base + ".ts", base + ".tsx", path21.join(base, "index.ts")];
10686
+ const base = path22.resolve(path22.dirname(sourceFile), specifier);
10687
+ const candidates = [base + ".ts", base + ".tsx", path22.join(base, "index.ts")];
10452
10688
  for (const c of candidates) {
10453
- if (fs10.existsSync(c)) return c;
10689
+ if (fs11.existsSync(c)) return c;
10454
10690
  }
10455
10691
  return null;
10456
10692
  }
10457
10693
  async function copyRuntime(opts) {
10458
10694
  const { sourceDir, targetDir, filter, resolveDeps, dryRun, onlyExisting } = opts;
10459
- if (!fs10.existsSync(sourceDir) || !fs10.statSync(sourceDir).isDirectory()) {
10695
+ if (!fs11.existsSync(sourceDir) || !fs11.statSync(sourceDir).isDirectory()) {
10460
10696
  throw new Error(`runtime source directory not found: ${sourceDir}`);
10461
10697
  }
10462
- const runtimeRoot4 = opts.runtimeRoot ? path21.resolve(opts.runtimeRoot) : path21.resolve(sourceDir, "..", "..");
10463
- const depsTargetRoot = opts.depsTargetRoot ?? path21.resolve(targetDir, "..");
10698
+ const runtimeRoot4 = opts.runtimeRoot ? path22.resolve(opts.runtimeRoot) : path22.resolve(sourceDir, "..", "..");
10699
+ const depsTargetRoot = opts.depsTargetRoot ?? path22.resolve(targetDir, "..");
10464
10700
  const result = {
10465
10701
  written: [],
10466
10702
  updated: [],
@@ -10470,9 +10706,9 @@ async function copyRuntime(opts) {
10470
10706
  };
10471
10707
  const queue = [];
10472
10708
  function walk(dir) {
10473
- for (const entry of fs10.readdirSync(dir)) {
10474
- const src = path21.join(dir, entry);
10475
- const stat = fs10.statSync(src);
10709
+ for (const entry of fs11.readdirSync(dir)) {
10710
+ const src = path22.join(dir, entry);
10711
+ const stat = fs11.statSync(src);
10476
10712
  if (stat.isDirectory()) {
10477
10713
  if (entry === "generated") continue;
10478
10714
  walk(src);
@@ -10480,9 +10716,9 @@ async function copyRuntime(opts) {
10480
10716
  }
10481
10717
  if (!stat.isFile()) continue;
10482
10718
  if (!entry.endsWith(".ts") && !entry.endsWith(".tsx")) continue;
10483
- const rel2 = path21.relative(sourceDir, src);
10719
+ const rel2 = path22.relative(sourceDir, src);
10484
10720
  if (filter && !filter(rel2) && !filter(entry)) continue;
10485
- queue.push({ src, dest: path21.join(targetDir, rel2), isDep: false });
10721
+ queue.push({ src, dest: path22.join(targetDir, rel2), isDep: false });
10486
10722
  }
10487
10723
  }
10488
10724
  walk(sourceDir);
@@ -10491,10 +10727,10 @@ async function copyRuntime(opts) {
10491
10727
  const next = queue.shift();
10492
10728
  if (visited.has(next.src)) continue;
10493
10729
  visited.add(next.src);
10494
- if (onlyExisting && !fs10.existsSync(next.dest)) {
10730
+ if (onlyExisting && !fs11.existsSync(next.dest)) {
10495
10731
  continue;
10496
10732
  }
10497
- const content = fs10.readFileSync(next.src, "utf-8");
10733
+ const content = fs11.readFileSync(next.src, "utf-8");
10498
10734
  result.planned.push(next.dest);
10499
10735
  const existing = readIfExists(next.dest);
10500
10736
  const status = existing === content ? "unchanged" : existing === null ? "written" : "updated";
@@ -10503,18 +10739,18 @@ async function copyRuntime(opts) {
10503
10739
  else result.unchanged.push(next.dest);
10504
10740
  if (next.isDep) result.dependenciesCopied.push(next.dest);
10505
10741
  if (!dryRun && status !== "unchanged") {
10506
- fs10.mkdirSync(path21.dirname(next.dest), { recursive: true });
10507
- fs10.writeFileSync(next.dest, content);
10742
+ fs11.mkdirSync(path22.dirname(next.dest), { recursive: true });
10743
+ fs11.writeFileSync(next.dest, content);
10508
10744
  }
10509
10745
  if (resolveDeps) {
10510
10746
  for (const spec of extractRelativeImports(content)) {
10511
10747
  const resolvedSrc = resolveSourceImport(next.src, spec);
10512
10748
  if (!resolvedSrc) continue;
10513
- const relToRuntime = path21.relative(runtimeRoot4, resolvedSrc);
10514
- if (relToRuntime.startsWith("..") || path21.isAbsolute(relToRuntime)) continue;
10515
- const relToSource = path21.relative(sourceDir, resolvedSrc);
10516
- if (!relToSource.startsWith("..") && !path21.isAbsolute(relToSource)) continue;
10517
- const depDest = path21.join(depsTargetRoot, relToRuntime);
10749
+ const relToRuntime = path22.relative(runtimeRoot4, resolvedSrc);
10750
+ if (relToRuntime.startsWith("..") || path22.isAbsolute(relToRuntime)) continue;
10751
+ const relToSource = path22.relative(sourceDir, resolvedSrc);
10752
+ if (!relToSource.startsWith("..") && !path22.isAbsolute(relToSource)) continue;
10753
+ const depDest = path22.join(depsTargetRoot, relToRuntime);
10518
10754
  queue.push({ src: resolvedSrc, dest: depDest, isDep: true });
10519
10755
  }
10520
10756
  }
@@ -10522,19 +10758,87 @@ async function copyRuntime(opts) {
10522
10758
  return result;
10523
10759
  }
10524
10760
 
10761
+ // src/cli/shared/subsystems-install-config.ts
10762
+ import fs12 from "fs";
10763
+ import path23 from "path";
10764
+ import yaml2 from "yaml";
10765
+ function readInstallList(config) {
10766
+ const raw = config?.subsystems?.install;
10767
+ if (!Array.isArray(raw)) return [];
10768
+ return raw.filter((e) => typeof e === "string");
10769
+ }
10770
+ function ensureSubsystemInstalled(configPath, name) {
10771
+ if (!fs12.existsSync(configPath)) {
10772
+ fs12.mkdirSync(path23.dirname(configPath), { recursive: true });
10773
+ fs12.writeFileSync(
10774
+ configPath,
10775
+ `subsystems:
10776
+ install:
10777
+ - ${name}
10778
+ `,
10779
+ "utf-8"
10780
+ );
10781
+ return { outcome: "added", install: [name] };
10782
+ }
10783
+ const source = fs12.readFileSync(configPath, "utf-8");
10784
+ let doc;
10785
+ try {
10786
+ doc = yaml2.parseDocument(source);
10787
+ if (doc.errors.length > 0) {
10788
+ return { outcome: "parse-error", install: [] };
10789
+ }
10790
+ } catch {
10791
+ return { outcome: "parse-error", install: [] };
10792
+ }
10793
+ const current = readInstallList(
10794
+ doc.toJS()
10795
+ );
10796
+ if (current.includes(name)) {
10797
+ return { outcome: "already", install: current };
10798
+ }
10799
+ const subsystemsNode = doc.get("subsystems", true);
10800
+ const installSeq = subsystemsNode && typeof subsystemsNode.get === "function" ? subsystemsNode.get("install", true) : void 0;
10801
+ if (installSeq && Array.isArray(installSeq.items) && installSeq.items.length > 0) {
10802
+ const lastItem = installSeq.items[installSeq.items.length - 1];
10803
+ const range = lastItem.range;
10804
+ if (range) {
10805
+ const insertAt = range[1];
10806
+ const lineStart = source.lastIndexOf("\n", range[0]) + 1;
10807
+ const indent = source.slice(lineStart, range[0]).match(/^\s*/)?.[0] ?? " ";
10808
+ const before = source.slice(0, insertAt);
10809
+ const after = source.slice(insertAt);
10810
+ const next = `${before}
10811
+ ${indent}- ${name}${after}`;
10812
+ fs12.writeFileSync(configPath, next, "utf-8");
10813
+ return { outcome: "added", install: [...current, name] };
10814
+ }
10815
+ }
10816
+ doc.setIn(["subsystems", "install"], [...current, name]);
10817
+ fs12.writeFileSync(configPath, String(doc), "utf-8");
10818
+ return { outcome: "added", install: [...current, name] };
10819
+ }
10820
+
10525
10821
  // src/cli/commands/subsystem.ts
10526
10822
  function runtimeRoot() {
10527
- const pkgRoot = path22.resolve(import.meta.dirname, "..", "..", "..");
10528
- const topLevel = path22.join(pkgRoot, "runtime");
10529
- if (fs11.existsSync(topLevel)) return topLevel;
10530
- return path22.join(pkgRoot, "dist", "runtime");
10823
+ const pkgRoot = path24.resolve(import.meta.dirname, "..", "..", "..");
10824
+ const topLevel = path24.join(pkgRoot, "runtime");
10825
+ if (fs13.existsSync(topLevel)) return topLevel;
10826
+ return path24.join(pkgRoot, "dist", "runtime");
10531
10827
  }
10532
10828
  function subsystemSource(name) {
10533
- return path22.join(runtimeRoot(), "subsystems", name);
10829
+ return path24.join(runtimeRoot(), "subsystems", name);
10534
10830
  }
10535
10831
  function describeSubsystem(name) {
10536
10832
  return SUBSYSTEMS.find((s) => s.name === name) ?? null;
10537
10833
  }
10834
+ var PACKAGE_CONFIG_BLOCK = {
10835
+ events: { detector: "events", actionFolder: "events-config" },
10836
+ jobs: { detector: "jobs", actionFolder: "jobs-config" },
10837
+ integration: { detector: "integration", actionFolder: "integration-config" },
10838
+ bridge: { detector: "bridge", actionFolder: "bridge-config" },
10839
+ observability: { detector: "observability", actionFolder: "observability-config" },
10840
+ auth: { detector: "auth", actionFolder: "auth-config" }
10841
+ };
10538
10842
  async function summary2(ctx) {
10539
10843
  const installed = await detectInstalledSubsystems(ctx);
10540
10844
  const installedNames = new Set(installed.map((i) => i.name));
@@ -10557,7 +10861,7 @@ async function summary2(ctx) {
10557
10861
  }
10558
10862
  body.push(theme.muted("Installed:"));
10559
10863
  for (const i of installed) {
10560
- const rel2 = path22.relative(ctx.cwd, i.path) || i.path;
10864
+ const rel2 = path24.relative(ctx.cwd, i.path) || i.path;
10561
10865
  body.push(
10562
10866
  ` ${theme.success(icons.check)} ${i.name.padEnd(10)} ${theme.muted(
10563
10867
  `${i.backend} backend`
@@ -10680,6 +10984,9 @@ var SubsystemInstallCommand = class extends Command3 {
10680
10984
  if (desc3.name === "auth-integrations") {
10681
10985
  return this.executeAuthIntegrations(ctx);
10682
10986
  }
10987
+ if (resolveRuntimeMode(ctx.config) === "package") {
10988
+ return this.executePackageMode(ctx, desc3, backend);
10989
+ }
10683
10990
  const installed = await detectInstalledSubsystems(ctx);
10684
10991
  const already = installed.find((i) => i.name === desc3.name);
10685
10992
  if (already && !this.force) {
@@ -10697,14 +11004,14 @@ var SubsystemInstallCommand = class extends Command3 {
10697
11004
  return 0;
10698
11005
  }
10699
11006
  const targetRoot = resolveSubsystemsRoot(ctx, this.target);
10700
- const subsystemTarget = path22.join(targetRoot, desc3.name);
11007
+ const subsystemTarget = path24.join(targetRoot, desc3.name);
10701
11008
  const source = subsystemSource(desc3.name);
10702
- if (!fs11.existsSync(source)) {
11009
+ if (!fs13.existsSync(source)) {
10703
11010
  printError(`Runtime subsystem source missing: ${source}`);
10704
11011
  return 1;
10705
11012
  }
10706
11013
  if (!this.force) {
10707
- const gitCheck = checkGitSafety([path22.relative(ctx.cwd, subsystemTarget) || subsystemTarget], ctx.cwd);
11014
+ const gitCheck = checkGitSafety([path24.relative(ctx.cwd, subsystemTarget) || subsystemTarget], ctx.cwd);
10708
11015
  if (gitCheck.inRepo && !gitCheck.clean) {
10709
11016
  printWarning(
10710
11017
  `Uncommitted changes under ${subsystemTarget}. Pass --force to overwrite.`
@@ -10713,7 +11020,7 @@ var SubsystemInstallCommand = class extends Command3 {
10713
11020
  }
10714
11021
  }
10715
11022
  if (!isJsonMode()) {
10716
- printInfo(`target = ${path22.relative(ctx.cwd, subsystemTarget) || subsystemTarget}`);
11023
+ printInfo(`target = ${path24.relative(ctx.cwd, subsystemTarget) || subsystemTarget}`);
10717
11024
  printInfo(`backend = ${backend}`);
10718
11025
  }
10719
11026
  const result = await copyRuntime({
@@ -10722,7 +11029,7 @@ var SubsystemInstallCommand = class extends Command3 {
10722
11029
  filter: backendFileFilter(backend, desc3.name),
10723
11030
  resolveDeps: true,
10724
11031
  runtimeRoot: runtimeRoot(),
10725
- depsTargetRoot: path22.resolve(targetRoot, ".."),
11032
+ depsTargetRoot: path24.resolve(targetRoot, ".."),
10726
11033
  dryRun: this.dryRun
10727
11034
  });
10728
11035
  const jobsScaffold = desc3.name === "jobs" ? runJobsScaffold(ctx.cwd, ctx.config, {
@@ -10817,14 +11124,14 @@ var SubsystemInstallCommand = class extends Command3 {
10817
11124
  if (this.dryRun) {
10818
11125
  printInfo(`Dry run \u2014 ${result.planned.length} files would be written`);
10819
11126
  for (const p of result.planned) {
10820
- console.log(` ${theme.muted(icons.arrow)} ${path22.relative(ctx.cwd, p) || p}`);
11127
+ console.log(` ${theme.muted(icons.arrow)} ${path24.relative(ctx.cwd, p) || p}`);
10821
11128
  }
10822
11129
  if (jobsScaffold?.planned?.length) {
10823
11130
  printInfo(
10824
11131
  `Jobs scaffold \u2014 ${jobsScaffold.planned.length} template targets`
10825
11132
  );
10826
11133
  for (const p of jobsScaffold.planned) {
10827
- console.log(` ${theme.muted(icons.arrow)} ${path22.relative(ctx.cwd, p) || p}`);
11134
+ console.log(` ${theme.muted(icons.arrow)} ${path24.relative(ctx.cwd, p) || p}`);
10828
11135
  }
10829
11136
  }
10830
11137
  if (eventsScaffold?.planned?.length) {
@@ -10832,7 +11139,7 @@ var SubsystemInstallCommand = class extends Command3 {
10832
11139
  `Events scaffold \u2014 ${eventsScaffold.planned.length} template targets`
10833
11140
  );
10834
11141
  for (const p of eventsScaffold.planned) {
10835
- console.log(` ${theme.muted(icons.arrow)} ${path22.relative(ctx.cwd, p) || p}`);
11142
+ console.log(` ${theme.muted(icons.arrow)} ${path24.relative(ctx.cwd, p) || p}`);
10836
11143
  }
10837
11144
  }
10838
11145
  if (integrationScaffold?.planned?.length) {
@@ -10840,7 +11147,7 @@ var SubsystemInstallCommand = class extends Command3 {
10840
11147
  `Integration scaffold \u2014 ${integrationScaffold.planned.length} template targets`
10841
11148
  );
10842
11149
  for (const p of integrationScaffold.planned) {
10843
- console.log(` ${theme.muted(icons.arrow)} ${path22.relative(ctx.cwd, p) || p}`);
11150
+ console.log(` ${theme.muted(icons.arrow)} ${path24.relative(ctx.cwd, p) || p}`);
10844
11151
  }
10845
11152
  }
10846
11153
  if (bridgeScaffold?.planned?.length) {
@@ -10848,7 +11155,7 @@ var SubsystemInstallCommand = class extends Command3 {
10848
11155
  `Bridge scaffold \u2014 ${bridgeScaffold.planned.length} template targets`
10849
11156
  );
10850
11157
  for (const p of bridgeScaffold.planned) {
10851
- console.log(` ${theme.muted(icons.arrow)} ${path22.relative(ctx.cwd, p) || p}`);
11158
+ console.log(` ${theme.muted(icons.arrow)} ${path24.relative(ctx.cwd, p) || p}`);
10852
11159
  }
10853
11160
  }
10854
11161
  if (observabilityScaffold?.planned?.length) {
@@ -10856,7 +11163,7 @@ var SubsystemInstallCommand = class extends Command3 {
10856
11163
  `Observability scaffold \u2014 ${observabilityScaffold.planned.length} template targets`
10857
11164
  );
10858
11165
  for (const p of observabilityScaffold.planned) {
10859
- console.log(` ${theme.muted(icons.arrow)} ${path22.relative(ctx.cwd, p) || p}`);
11166
+ console.log(` ${theme.muted(icons.arrow)} ${path24.relative(ctx.cwd, p) || p}`);
10860
11167
  }
10861
11168
  }
10862
11169
  if (authScaffold?.planned?.length) {
@@ -10864,7 +11171,7 @@ var SubsystemInstallCommand = class extends Command3 {
10864
11171
  `Auth scaffold \u2014 ${authScaffold.planned.length} template targets`
10865
11172
  );
10866
11173
  for (const p of authScaffold.planned) {
10867
- console.log(` ${theme.muted(icons.arrow)} ${path22.relative(ctx.cwd, p) || p}`);
11174
+ console.log(` ${theme.muted(icons.arrow)} ${path24.relative(ctx.cwd, p) || p}`);
10868
11175
  }
10869
11176
  }
10870
11177
  return 0;
@@ -10973,6 +11280,143 @@ var SubsystemInstallCommand = class extends Command3 {
10973
11280
  }
10974
11281
  return 0;
10975
11282
  }
11283
+ /**
11284
+ * ADR-037: package-mode install. The subsystem runtime lives in the
11285
+ * published `@pattern-stack/codegen` package, so installing reduces to a
11286
+ * config + barrel operation with NO file vendoring:
11287
+ *
11288
+ * 1. record the name under `subsystems.install` (the package-mode
11289
+ * source of truth for "installed");
11290
+ * 2. inject the per-subsystem `<name>:` config block via the same Hygen
11291
+ * action vendored mode uses (the block is runtime-agnostic — it only
11292
+ * writes YAML, never code); cache/storage have no config block, so this
11293
+ * step is skipped for them;
11294
+ * 3. regenerate the composition barrel (`<generated>/subsystems.ts`) and
11295
+ * the schema barrel (`<generated>/subsystems-schema.ts`) so AppModule's
11296
+ * `...SUBSYSTEM_MODULES` and drizzle-kit's schema pick up the new
11297
+ * install.
11298
+ *
11299
+ * Idempotent: a name already in `subsystems.install` is a no-op unless
11300
+ * `--force` is passed (which still re-runs config-block injection under
11301
+ * `--force-config` and always regenerates the barrels).
11302
+ */
11303
+ async executePackageMode(ctx, desc3, backend) {
11304
+ const configPath = path24.join(ctx.cwd, "codegen.config.yaml");
11305
+ const installed = configuredSubsystemNames(
11306
+ ctx.config
11307
+ );
11308
+ const already = installed.includes(desc3.name);
11309
+ if (already && !this.force) {
11310
+ if (isJsonMode()) {
11311
+ printJson({
11312
+ command: "subsystem install",
11313
+ subsystem: desc3.name,
11314
+ runtime: "package",
11315
+ status: "already-installed"
11316
+ });
11317
+ } else {
11318
+ printInfo(
11319
+ `${desc3.name} is already in subsystems.install (runtime: package \u2014 nothing to vendor). Pass --force to refresh the config block + barrels.`
11320
+ );
11321
+ }
11322
+ return 0;
11323
+ }
11324
+ const configSubsystem = PACKAGE_CONFIG_BLOCK[desc3.name];
11325
+ const configBlockOutcome = configSubsystem ? planConfigBlockAction(configPath, configSubsystem.detector, this.forceConfig) : null;
11326
+ if (configBlockOutcome === "parse-error") {
11327
+ printError(
11328
+ `codegen.config.yaml is not valid YAML: refusing to inject ${desc3.name} config block. Fix the YAML and re-run.`
11329
+ );
11330
+ return 1;
11331
+ }
11332
+ if (this.dryRun) {
11333
+ if (isJsonMode()) {
11334
+ printJson({
11335
+ command: "subsystem install",
11336
+ subsystem: desc3.name,
11337
+ runtime: "package",
11338
+ dryRun: true,
11339
+ installList: already ? installed : [...installed, desc3.name],
11340
+ configBlockOutcome
11341
+ });
11342
+ } else {
11343
+ printInfo(`Dry run \u2014 runtime: package (no files vendored).`);
11344
+ if (!already) printInfo(` would add '${desc3.name}' to subsystems.install`);
11345
+ if (configBlockOutcome) {
11346
+ printInfo(` ${desc3.name} config block would be ${configBlockOutcome}`);
11347
+ }
11348
+ printInfo(" would regenerate <generated>/subsystems.ts + subsystems-schema.ts");
11349
+ }
11350
+ return 0;
11351
+ }
11352
+ const installResult = ensureSubsystemInstalled(configPath, desc3.name);
11353
+ if (installResult.outcome === "parse-error") {
11354
+ printError(
11355
+ "codegen.config.yaml is not valid YAML: refusing to update subsystems.install. Fix the YAML and re-run."
11356
+ );
11357
+ return 1;
11358
+ }
11359
+ if (configSubsystem && configBlockOutcome) {
11360
+ const configResult = runConfigBlockAction({
11361
+ cwd: ctx.cwd,
11362
+ actionFolder: configSubsystem.actionFolder,
11363
+ configPath,
11364
+ subsystem: configSubsystem.detector,
11365
+ outcome: configBlockOutcome,
11366
+ json: isJsonMode()
11367
+ });
11368
+ if (!configResult.ok) {
11369
+ printError(
11370
+ `${desc3.name} config-block injection failed: ${configResult.error ?? "unknown error"}`
11371
+ );
11372
+ return 1;
11373
+ }
11374
+ }
11375
+ const refreshed = await loadContext({
11376
+ cwd: ctx.cwd,
11377
+ configPath: this.configPath,
11378
+ json: this.json,
11379
+ skipDetection: true
11380
+ });
11381
+ let barrelEmitted = [];
11382
+ let schemaEmitted = [];
11383
+ try {
11384
+ const generatedDir = resolveGeneratedDir(refreshed);
11385
+ const barrel = await regenerateSubsystemBarrel({ ctx: refreshed, generatedDir });
11386
+ barrelEmitted = barrel.emitted;
11387
+ const schema = await regenerateSubsystemSchemaBarrel({ ctx: refreshed, generatedDir });
11388
+ schemaEmitted = schema.emitted;
11389
+ } catch (err) {
11390
+ const msg = err instanceof Error ? err.message : String(err);
11391
+ printWarning(`barrel regeneration failed \u2014 ${msg}`);
11392
+ }
11393
+ if (isJsonMode()) {
11394
+ printJson({
11395
+ command: "subsystem install",
11396
+ subsystem: desc3.name,
11397
+ runtime: "package",
11398
+ backend,
11399
+ vendored: false,
11400
+ installList: installResult.install,
11401
+ installOutcome: installResult.outcome,
11402
+ configBlockOutcome,
11403
+ barrelEmitted,
11404
+ schemaEmitted
11405
+ });
11406
+ return 0;
11407
+ }
11408
+ printSuccess(`${desc3.name} installed (runtime: package \u2014 no files vendored).`);
11409
+ if (installResult.outcome === "added") {
11410
+ printInfo(`Added '${desc3.name}' to subsystems.install.`);
11411
+ }
11412
+ printInfo(
11413
+ `Regenerated <generated>/subsystems.ts (${barrelEmitted.join(", ") || "none"}) + subsystems-schema.ts (${schemaEmitted.join(", ") || "none"}).`
11414
+ );
11415
+ printInfo(
11416
+ "Wire once (if not already): `import { SUBSYSTEM_MODULES } from './generated/subsystems'` into AppModule, and `export * from './generated/subsystems-schema'` into your drizzle-kit schema entrypoint."
11417
+ );
11418
+ return 0;
11419
+ }
10976
11420
  /**
10977
11421
  * OPENAPI-4: install flow for the config-only `openapi-config`
10978
11422
  * pseudo-subsystem.
@@ -10984,7 +11428,7 @@ var SubsystemInstallCommand = class extends Command3 {
10984
11428
  * semantics as jobs/events/integration/bridge.
10985
11429
  */
10986
11430
  async executeOpenApiConfig(ctx) {
10987
- const configPath = path22.join(ctx.cwd, "codegen.config.yaml");
11431
+ const configPath = path24.join(ctx.cwd, "codegen.config.yaml");
10988
11432
  const outcome = planConfigBlockAction(configPath, "openapi", this.forceConfig);
10989
11433
  if (outcome === "parse-error") {
10990
11434
  printError(
@@ -11003,7 +11447,7 @@ var SubsystemInstallCommand = class extends Command3 {
11003
11447
  });
11004
11448
  } else {
11005
11449
  printInfo(`Dry run \u2014 openapi config block would be ${outcome}`);
11006
- console.log(` ${theme.muted(icons.arrow)} ${path22.relative(ctx.cwd, configPath) || configPath}`);
11450
+ console.log(` ${theme.muted(icons.arrow)} ${path24.relative(ctx.cwd, configPath) || configPath}`);
11007
11451
  }
11008
11452
  return 0;
11009
11453
  }
@@ -11098,7 +11542,7 @@ var SubsystemInstallCommand = class extends Command3 {
11098
11542
  );
11099
11543
  for (const p of scaffold.planned) {
11100
11544
  console.log(
11101
- ` ${theme.muted(icons.arrow)} ${path22.relative(ctx.cwd, p) || p}`
11545
+ ` ${theme.muted(icons.arrow)} ${path24.relative(ctx.cwd, p) || p}`
11102
11546
  );
11103
11547
  }
11104
11548
  return 0;
@@ -11122,10 +11566,10 @@ var SubsystemInstallCommand = class extends Command3 {
11122
11566
  }
11123
11567
  };
11124
11568
  function planConfigBlockAction(configPath, subsystem, forceConfig) {
11125
- if (!fs11.existsSync(configPath)) {
11569
+ if (!fs13.existsSync(configPath)) {
11126
11570
  return "inject";
11127
11571
  }
11128
- const source = fs11.readFileSync(configPath, "utf-8");
11572
+ const source = fs13.readFileSync(configPath, "utf-8");
11129
11573
  const state = detectConfigBlock(source, subsystem);
11130
11574
  if (state === "parse-error") return "parse-error";
11131
11575
  if (state === "missing") return "inject";
@@ -11148,9 +11592,9 @@ function runConfigBlockAction(input) {
11148
11592
  );
11149
11593
  }
11150
11594
  try {
11151
- const source = fs11.readFileSync(input.configPath, "utf-8");
11595
+ const source = fs13.readFileSync(input.configPath, "utf-8");
11152
11596
  const stripped = stripConfigBlock(source, input.subsystem);
11153
- fs11.writeFileSync(input.configPath, stripped, "utf-8");
11597
+ fs13.writeFileSync(input.configPath, stripped, "utf-8");
11154
11598
  } catch (err) {
11155
11599
  const message = err instanceof Error ? err.message : String(err);
11156
11600
  return { ok: false, error: `strip failed: ${message}` };
@@ -11188,8 +11632,8 @@ function runJobsScaffold(cwd, config, opts) {
11188
11632
  const locals = resolveJobsScaffoldLocals({
11189
11633
  cwd,
11190
11634
  config,
11191
- fileExists: (p) => fs11.existsSync(p),
11192
- readFile: (p) => fs11.existsSync(p) ? fs11.readFileSync(p, "utf-8") : null
11635
+ fileExists: (p) => fs13.existsSync(p),
11636
+ readFile: (p) => fs13.existsSync(p) ? fs13.readFileSync(p, "utf-8") : null
11193
11637
  });
11194
11638
  const planned = [
11195
11639
  ...!locals.workerExists ? [locals.workerPath] : [],
@@ -11246,7 +11690,7 @@ function runEventsScaffold(cwd, config, opts) {
11246
11690
  const locals = resolveEventsScaffoldLocals({
11247
11691
  cwd,
11248
11692
  config,
11249
- fileExists: (p) => fs11.existsSync(p)
11693
+ fileExists: (p) => fs13.existsSync(p)
11250
11694
  });
11251
11695
  const planned = [
11252
11696
  locals.configPath,
@@ -11302,7 +11746,7 @@ function runIntegrationScaffold(cwd, config, opts) {
11302
11746
  const locals = resolveIntegrationScaffoldLocals({
11303
11747
  cwd,
11304
11748
  config,
11305
- fileExists: (p) => fs11.existsSync(p)
11749
+ fileExists: (p) => fs13.existsSync(p)
11306
11750
  });
11307
11751
  const planned = [
11308
11752
  locals.configPath,
@@ -11357,7 +11801,7 @@ function runBridgeScaffold(cwd, config, opts) {
11357
11801
  const locals = resolveBridgeScaffoldLocals({
11358
11802
  cwd,
11359
11803
  config,
11360
- fileExists: (p) => fs11.existsSync(p)
11804
+ fileExists: (p) => fs13.existsSync(p)
11361
11805
  });
11362
11806
  const planned = [
11363
11807
  locals.configPath,
@@ -11411,7 +11855,7 @@ function runObservabilityScaffold(cwd, config, opts) {
11411
11855
  const locals = resolveObservabilityScaffoldLocals({
11412
11856
  cwd,
11413
11857
  config,
11414
- fileExists: (p) => fs11.existsSync(p)
11858
+ fileExists: (p) => fs13.existsSync(p)
11415
11859
  });
11416
11860
  const planned = [locals.configPath, locals.appModulePath];
11417
11861
  const configBlockOutcome = planConfigBlockAction(
@@ -11480,9 +11924,9 @@ function runAuthScaffold(cwd, config, opts) {
11480
11924
  if (opts.dryRun) {
11481
11925
  return { ok: true, planned, configBlockOutcome };
11482
11926
  }
11483
- if (!fs11.existsSync(locals.envConfigPath)) {
11484
- fs11.mkdirSync(path22.dirname(locals.envConfigPath), { recursive: true });
11485
- fs11.writeFileSync(locals.envConfigPath, "", "utf-8");
11927
+ if (!fs13.existsSync(locals.envConfigPath)) {
11928
+ fs13.mkdirSync(path24.dirname(locals.envConfigPath), { recursive: true });
11929
+ fs13.writeFileSync(locals.envConfigPath, "", "utf-8");
11486
11930
  }
11487
11931
  const result = invokeHygen({
11488
11932
  generator: "subsystem",
@@ -11518,57 +11962,57 @@ function runAuthScaffold(cwd, config, opts) {
11518
11962
  return { ok: true, planned, configBlockOutcome };
11519
11963
  }
11520
11964
  function authIntegrationsExamplesRoot() {
11521
- const pkgRoot = path22.resolve(import.meta.dirname, "..", "..", "..");
11522
- const topLevel = path22.join(pkgRoot, "examples", "auth-integrations");
11523
- if (fs11.existsSync(topLevel)) return topLevel;
11524
- return path22.join(pkgRoot, "dist", "examples", "auth-integrations");
11965
+ const pkgRoot = path24.resolve(import.meta.dirname, "..", "..", "..");
11966
+ const topLevel = path24.join(pkgRoot, "examples", "auth-integrations");
11967
+ if (fs13.existsSync(topLevel)) return topLevel;
11968
+ return path24.join(pkgRoot, "dist", "examples", "auth-integrations");
11525
11969
  }
11526
11970
  function copyTreeIdempotent(srcDir, destDir, force, transform) {
11527
11971
  const written = [];
11528
11972
  const skipped = [];
11529
11973
  const walk = (src, dest) => {
11530
- const entries = fs11.readdirSync(src, { withFileTypes: true });
11974
+ const entries = fs13.readdirSync(src, { withFileTypes: true });
11531
11975
  for (const entry of entries) {
11532
- const srcPath = path22.join(src, entry.name);
11533
- const destPath = path22.join(dest, entry.name);
11976
+ const srcPath = path24.join(src, entry.name);
11977
+ const destPath = path24.join(dest, entry.name);
11534
11978
  if (entry.isDirectory()) {
11535
- fs11.mkdirSync(destPath, { recursive: true });
11979
+ fs13.mkdirSync(destPath, { recursive: true });
11536
11980
  walk(srcPath, destPath);
11537
11981
  continue;
11538
11982
  }
11539
11983
  if (!entry.isFile()) continue;
11540
- if (fs11.existsSync(destPath) && !force) {
11984
+ if (fs13.existsSync(destPath) && !force) {
11541
11985
  skipped.push(destPath);
11542
11986
  continue;
11543
11987
  }
11544
- fs11.mkdirSync(path22.dirname(destPath), { recursive: true });
11988
+ fs13.mkdirSync(path24.dirname(destPath), { recursive: true });
11545
11989
  const isTextSource = transform && (entry.name.endsWith(".ts") || entry.name.endsWith(".tsx"));
11546
11990
  if (isTextSource && transform) {
11547
- const raw = fs11.readFileSync(srcPath, "utf-8");
11548
- fs11.writeFileSync(destPath, transform(raw, destPath), "utf-8");
11991
+ const raw = fs13.readFileSync(srcPath, "utf-8");
11992
+ fs13.writeFileSync(destPath, transform(raw, destPath), "utf-8");
11549
11993
  } else {
11550
- fs11.copyFileSync(srcPath, destPath);
11994
+ fs13.copyFileSync(srcPath, destPath);
11551
11995
  }
11552
11996
  written.push(destPath);
11553
11997
  }
11554
11998
  };
11555
- if (!fs11.existsSync(srcDir)) return { written, skipped };
11556
- fs11.mkdirSync(destDir, { recursive: true });
11999
+ if (!fs13.existsSync(srcDir)) return { written, skipped };
12000
+ fs13.mkdirSync(destDir, { recursive: true });
11557
12001
  walk(srcDir, destDir);
11558
12002
  return { written, skipped };
11559
12003
  }
11560
12004
  var AUTH_BARE_IMPORT_RE = /(['"])@pattern-stack\/codegen\/runtime\/subsystems\/auth\1/g;
11561
12005
  function buildAuthImportRewriter(subsystemsRoot) {
11562
- const authRoot = path22.join(subsystemsRoot, "auth");
12006
+ const authRoot = path24.join(subsystemsRoot, "auth");
11563
12007
  return (content, destPath) => {
11564
12008
  if (!AUTH_BARE_IMPORT_RE.test(content)) {
11565
12009
  AUTH_BARE_IMPORT_RE.lastIndex = 0;
11566
12010
  return content;
11567
12011
  }
11568
12012
  AUTH_BARE_IMPORT_RE.lastIndex = 0;
11569
- let rel2 = path22.relative(path22.dirname(destPath), authRoot);
12013
+ let rel2 = path24.relative(path24.dirname(destPath), authRoot);
11570
12014
  if (!rel2.startsWith(".")) rel2 = `./${rel2}`;
11571
- const relPosix = rel2.split(path22.sep).join("/");
12015
+ const relPosix = rel2.split(path24.sep).join("/");
11572
12016
  return content.replace(
11573
12017
  AUTH_BARE_IMPORT_RE,
11574
12018
  (_match, quote) => `${quote}${relPosix}${quote}`
@@ -11579,20 +12023,20 @@ function runAuthIntegrationsScaffold(cwd, config, opts) {
11579
12023
  const locals = resolveAuthIntegrationsScaffoldLocals({
11580
12024
  cwd,
11581
12025
  config,
11582
- fileExists: (p) => fs11.existsSync(p),
11583
- readFile: (p) => fs11.existsSync(p) ? fs11.readFileSync(p, "utf-8") : null
12026
+ fileExists: (p) => fs13.existsSync(p),
12027
+ readFile: (p) => fs13.existsSync(p) ? fs13.readFileSync(p, "utf-8") : null
11584
12028
  });
11585
12029
  const examplesRoot = authIntegrationsExamplesRoot();
11586
- if (!fs11.existsSync(examplesRoot)) {
12030
+ if (!fs13.existsSync(examplesRoot)) {
11587
12031
  return {
11588
12032
  ok: false,
11589
12033
  planned: [],
11590
12034
  error: `auth-integrations starter source missing: ${examplesRoot}`
11591
12035
  };
11592
12036
  }
11593
- const adaptersSrc = path22.join(examplesRoot, "runtime", "connections");
11594
- const adaptersDest = path22.join(locals.vendorRoot, "connections");
11595
- const connectionYamlSrc = path22.join(
12037
+ const adaptersSrc = path24.join(examplesRoot, "runtime", "connections");
12038
+ const adaptersDest = path24.join(locals.vendorRoot, "connections");
12039
+ const connectionYamlSrc = path24.join(
11596
12040
  examplesRoot,
11597
12041
  "definitions",
11598
12042
  "entities",
@@ -11621,11 +12065,11 @@ function runAuthIntegrationsScaffold(cwd, config, opts) {
11621
12065
  let yamlWritten = false;
11622
12066
  let yamlSkipped = false;
11623
12067
  try {
11624
- if (fs11.existsSync(connectionYamlDest) && !opts.force) {
12068
+ if (fs13.existsSync(connectionYamlDest) && !opts.force) {
11625
12069
  yamlSkipped = true;
11626
- } else if (fs11.existsSync(connectionYamlSrc)) {
11627
- fs11.mkdirSync(path22.dirname(connectionYamlDest), { recursive: true });
11628
- fs11.copyFileSync(connectionYamlSrc, connectionYamlDest);
12070
+ } else if (fs13.existsSync(connectionYamlSrc)) {
12071
+ fs13.mkdirSync(path24.dirname(connectionYamlDest), { recursive: true });
12072
+ fs13.copyFileSync(connectionYamlSrc, connectionYamlDest);
11629
12073
  yamlWritten = true;
11630
12074
  }
11631
12075
  } catch (err) {
@@ -11690,7 +12134,7 @@ var SubsystemListCommand = class extends Command3 {
11690
12134
  name: s.name,
11691
12135
  status: inst ? inst.status : "available",
11692
12136
  backend: inst ? inst.backend : null,
11693
- path: inst ? path22.relative(ctx.cwd, inst.path) || inst.path : null
12137
+ path: inst ? path24.relative(ctx.cwd, inst.path) || inst.path : null
11694
12138
  };
11695
12139
  });
11696
12140
  if (isJsonMode()) {
@@ -11779,14 +12223,14 @@ var SubsystemRemoveCommand = class extends Command3 {
11779
12223
  return 1;
11780
12224
  }
11781
12225
  const subsystemDir = target.path;
11782
- if (!fs11.existsSync(subsystemDir)) {
12226
+ if (!fs13.existsSync(subsystemDir)) {
11783
12227
  printError(
11784
12228
  `Detected install at ${subsystemDir} but the directory is gone \u2014 refusing to act.`
11785
12229
  );
11786
12230
  return 1;
11787
12231
  }
11788
12232
  if (!this.force) {
11789
- const rel2 = path22.relative(ctx.cwd, subsystemDir) || subsystemDir;
12233
+ const rel2 = path24.relative(ctx.cwd, subsystemDir) || subsystemDir;
11790
12234
  const gitCheck = checkGitSafety([rel2], ctx.cwd);
11791
12235
  if (gitCheck.inRepo && !gitCheck.clean) {
11792
12236
  printWarning(
@@ -11796,7 +12240,7 @@ var SubsystemRemoveCommand = class extends Command3 {
11796
12240
  }
11797
12241
  }
11798
12242
  try {
11799
- fs11.rmSync(subsystemDir, { recursive: true, force: true });
12243
+ fs13.rmSync(subsystemDir, { recursive: true, force: true });
11800
12244
  } catch (err) {
11801
12245
  const message = err instanceof Error ? err.message : String(err);
11802
12246
  printError(`Failed to remove ${subsystemDir}: ${message}`);
@@ -11822,7 +12266,7 @@ var SubsystemRemoveCommand = class extends Command3 {
11822
12266
  return 0;
11823
12267
  }
11824
12268
  printSuccess(
11825
- `${desc3.name} subsystem removed (${path22.relative(ctx.cwd, subsystemDir) || subsystemDir}).`
12269
+ `${desc3.name} subsystem removed (${path24.relative(ctx.cwd, subsystemDir) || subsystemDir}).`
11826
12270
  );
11827
12271
  if (barrelRegenerated) {
11828
12272
  printInfo("Regenerated <generated>/subsystems.ts barrel.");
@@ -11850,28 +12294,28 @@ var subsystemNoun = {
11850
12294
  var subsystem_default = subsystemNoun;
11851
12295
 
11852
12296
  // src/cli/commands/project.ts
11853
- import fs17 from "fs";
11854
- import path28 from "path";
12297
+ import fs19 from "fs";
12298
+ import path30 from "path";
11855
12299
  import readline from "readline";
11856
12300
  import { Command as Command7, Option as Option7 } from "clipanion";
11857
12301
  import { stringify as stringifyYaml2 } from "yaml";
11858
12302
 
11859
12303
  // src/cli/shared/init-scaffold.ts
11860
- import fs12 from "fs";
11861
- import path23 from "path";
12304
+ import fs14 from "fs";
12305
+ import path25 from "path";
11862
12306
  import { stringify as stringifyYaml } from "yaml";
11863
12307
  function runtimeRoot2() {
11864
- const pkgRoot = path23.resolve(import.meta.dirname, "..", "..", "..");
11865
- const topLevel = path23.join(pkgRoot, "runtime");
11866
- if (fs12.existsSync(topLevel)) return topLevel;
11867
- return path23.join(pkgRoot, "dist", "runtime");
12308
+ const pkgRoot = path25.resolve(import.meta.dirname, "..", "..", "..");
12309
+ const topLevel = path25.join(pkgRoot, "runtime");
12310
+ if (fs14.existsSync(topLevel)) return topLevel;
12311
+ return path25.join(pkgRoot, "dist", "runtime");
11868
12312
  }
11869
12313
  function resolveRuntimePath(cwd) {
11870
- const shimDir = path23.join(cwd, "src", "shared", "base-classes");
11871
- return path23.relative(shimDir, runtimeRoot2());
12314
+ const shimDir = path25.join(cwd, "src", "shared", "base-classes");
12315
+ return path25.relative(shimDir, runtimeRoot2());
11872
12316
  }
11873
12317
  function loadRuntimeFile(relPath2) {
11874
- return fs12.readFileSync(path23.join(runtimeRoot2(), relPath2), "utf-8");
12318
+ return fs14.readFileSync(path25.join(runtimeRoot2(), relPath2), "utf-8");
11875
12319
  }
11876
12320
  var VENDORED_RUNTIME_FILES = [
11877
12321
  // base-classes — consumer-facing inheritance targets
@@ -11920,12 +12364,13 @@ var VENDORED_RUNTIME_FILES = [
11920
12364
  },
11921
12365
  { runtime: "shared/openapi/index.ts", target: "src/shared/openapi/index.ts" }
11922
12366
  ];
11923
- function databaseModuleContent() {
12367
+ function databaseModuleContent(mode) {
12368
+ const drizzleTokenImport = mode === "vendored" ? "../constants/tokens" : runtimeImport(mode, "constants/tokens");
11924
12369
  return `import { Module, Global } from '@nestjs/common';
11925
12370
  import { drizzle } from 'drizzle-orm/node-postgres';
11926
12371
  import { Pool } from 'pg';
11927
12372
  import * as schema from '../../schema';
11928
- import { DRIZZLE } from '../constants/tokens';
12373
+ import { DRIZZLE } from '${drizzleTokenImport}';
11929
12374
 
11930
12375
  export { DRIZZLE };
11931
12376
  export type DrizzleDB = ReturnType<typeof drizzle<typeof schema>>;
@@ -11952,11 +12397,12 @@ export type DrizzleDB = ReturnType<typeof drizzle<typeof schema>>;
11952
12397
  export class DatabaseModule {}
11953
12398
  `;
11954
12399
  }
11955
- function appModuleContent() {
12400
+ function appModuleContent(mode) {
12401
+ const openApiImport = mode === "vendored" ? "./shared/openapi" : runtimeImport(mode, "shared/openapi");
11956
12402
  return `import { Global, Module } from '@nestjs/common';
11957
12403
  import { DatabaseModule } from './shared/database/database.module';
11958
12404
  import { GENERATED_MODULES } from './generated/modules';
11959
- import { OPENAPI_REGISTRY, OpenApiRegistry } from './shared/openapi';
12405
+ import { OPENAPI_REGISTRY, OpenApiRegistry } from '${openApiImport}';
11960
12406
 
11961
12407
  /**
11962
12408
  * OpenApiModule \u2014 @Global() wrapper around the OPENAPI_REGISTRY singleton.
@@ -11998,7 +12444,8 @@ class OpenApiModule {}
11998
12444
  export class AppModule {}
11999
12445
  `;
12000
12446
  }
12001
- function mainTsContent() {
12447
+ function mainTsContent(mode) {
12448
+ const openApiImport = mode === "vendored" ? "./shared/openapi" : runtimeImport(mode, "shared/openapi");
12002
12449
  return `import 'reflect-metadata';
12003
12450
  import fs from 'node:fs';
12004
12451
  import path from 'node:path';
@@ -12006,7 +12453,7 @@ import { NestFactory } from '@nestjs/core';
12006
12453
  import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
12007
12454
  import { parse as parseYaml } from 'yaml';
12008
12455
  import { AppModule } from './app.module';
12009
- import { OPENAPI_REGISTRY, OpenApiRegistry } from './shared/openapi';
12456
+ import { OPENAPI_REGISTRY, OpenApiRegistry } from '${openApiImport}';
12010
12457
 
12011
12458
  interface OpenApiConfig {
12012
12459
  enabled?: boolean;
@@ -12285,10 +12732,10 @@ function mergeTsconfig(raw) {
12285
12732
  };
12286
12733
  }
12287
12734
  function relOf(cwd, abs) {
12288
- return path23.relative(cwd, abs) || abs;
12735
+ return path25.relative(cwd, abs) || abs;
12289
12736
  }
12290
12737
  function fileEntry(cwd, absPath, content, opts) {
12291
- const exists = fs12.existsSync(absPath);
12738
+ const exists = fs14.existsSync(absPath);
12292
12739
  let action;
12293
12740
  let reason = opts.skipReason;
12294
12741
  if (!exists) {
@@ -12303,7 +12750,7 @@ function fileEntry(cwd, absPath, content, opts) {
12303
12750
  return { path: absPath, relPath: relOf(cwd, absPath), action, content, reason };
12304
12751
  }
12305
12752
  function dirEntry(cwd, absPath) {
12306
- const exists = fs12.existsSync(absPath);
12753
+ const exists = fs14.existsSync(absPath);
12307
12754
  return {
12308
12755
  path: absPath,
12309
12756
  relPath: relOf(cwd, absPath),
@@ -12315,6 +12762,7 @@ function dirEntry(cwd, absPath) {
12315
12762
  async function buildInitPlan(ctx, options) {
12316
12763
  const cwd = options.cwd;
12317
12764
  const force = Boolean(options.force);
12765
+ const runtimeMode = options.runtimeMode === "vendored" ? "vendored" : "package";
12318
12766
  let framework = "nestjs";
12319
12767
  let orm = "drizzle";
12320
12768
  let architecture = "clean-lite-ps";
@@ -12335,8 +12783,13 @@ async function buildInitPlan(ctx, options) {
12335
12783
  const runtimePath = options.runtimePath ?? resolveRuntimePath(cwd);
12336
12784
  const entries = [];
12337
12785
  {
12338
- const configPath = path23.join(cwd, "codegen.config.yaml");
12786
+ const configPath = path25.join(cwd, "codegen.config.yaml");
12339
12787
  const config = {
12788
+ // Runtime mode (ADR-037). `package` (default) imports the runtime from
12789
+ // `@pattern-stack/codegen/*`; `vendored` imports it via `@shared/*` and
12790
+ // vendors `src/shared/**`. Existing vendored projects MUST set this to
12791
+ // `vendored` explicitly — the default does not silently flip them.
12792
+ runtime: runtimeMode,
12340
12793
  paths: {
12341
12794
  backend_src: "src",
12342
12795
  entities_dir: "entities",
@@ -12365,9 +12818,9 @@ async function buildInitPlan(ctx, options) {
12365
12818
  entries.push(fileEntry(cwd, configPath, content, { force }));
12366
12819
  }
12367
12820
  {
12368
- const tsconfigPath = path23.join(cwd, "tsconfig.json");
12369
- if (fs12.existsSync(tsconfigPath)) {
12370
- const raw = fs12.readFileSync(tsconfigPath, "utf-8");
12821
+ const tsconfigPath = path25.join(cwd, "tsconfig.json");
12822
+ if (fs14.existsSync(tsconfigPath)) {
12823
+ const raw = fs14.readFileSync(tsconfigPath, "utf-8");
12371
12824
  const merged = mergeTsconfig(raw);
12372
12825
  if (merged.parseError) {
12373
12826
  entries.push({
@@ -12412,20 +12865,22 @@ async function buildInitPlan(ctx, options) {
12412
12865
  entries.push(
12413
12866
  fileEntry(
12414
12867
  cwd,
12415
- path23.join(cwd, "src", "shared", "database", "database.module.ts"),
12416
- databaseModuleContent(),
12868
+ path25.join(cwd, "src", "shared", "database", "database.module.ts"),
12869
+ databaseModuleContent(runtimeMode),
12417
12870
  { force }
12418
12871
  )
12419
12872
  );
12420
- for (const v of VENDORED_RUNTIME_FILES) {
12421
- entries.push(
12422
- fileEntry(cwd, path23.join(cwd, v.target), loadRuntimeFile(v.runtime), { force })
12423
- );
12873
+ if (runtimeMode === "vendored") {
12874
+ for (const v of VENDORED_RUNTIME_FILES) {
12875
+ entries.push(
12876
+ fileEntry(cwd, path25.join(cwd, v.target), loadRuntimeFile(v.runtime), { force })
12877
+ );
12878
+ }
12424
12879
  }
12425
12880
  entries.push(
12426
12881
  fileEntry(
12427
12882
  cwd,
12428
- path23.join(cwd, "src", "generated", "modules.ts"),
12883
+ path25.join(cwd, "src", "generated", "modules.ts"),
12429
12884
  emptyModulesBarrel(),
12430
12885
  { force }
12431
12886
  )
@@ -12433,19 +12888,19 @@ async function buildInitPlan(ctx, options) {
12433
12888
  entries.push(
12434
12889
  fileEntry(
12435
12890
  cwd,
12436
- path23.join(cwd, "src", "generated", "schema.ts"),
12891
+ path25.join(cwd, "src", "generated", "schema.ts"),
12437
12892
  emptySchemaBarrel(),
12438
12893
  { force }
12439
12894
  )
12440
12895
  );
12441
12896
  {
12442
- const appModulePath = path23.join(cwd, "src", "app.module.ts");
12443
- if (!fs12.existsSync(appModulePath)) {
12897
+ const appModulePath = path25.join(cwd, "src", "app.module.ts");
12898
+ if (!fs14.existsSync(appModulePath)) {
12444
12899
  entries.push({
12445
12900
  path: appModulePath,
12446
12901
  relPath: relOf(cwd, appModulePath),
12447
12902
  action: "create",
12448
- content: appModuleContent()
12903
+ content: appModuleContent(runtimeMode)
12449
12904
  });
12450
12905
  } else {
12451
12906
  entries.push({
@@ -12457,13 +12912,13 @@ async function buildInitPlan(ctx, options) {
12457
12912
  }
12458
12913
  }
12459
12914
  {
12460
- const mainPath = path23.join(cwd, "src", "main.ts");
12461
- if (!fs12.existsSync(mainPath)) {
12915
+ const mainPath = path25.join(cwd, "src", "main.ts");
12916
+ if (!fs14.existsSync(mainPath)) {
12462
12917
  entries.push({
12463
12918
  path: mainPath,
12464
12919
  relPath: relOf(cwd, mainPath),
12465
12920
  action: "create",
12466
- content: mainTsContent()
12921
+ content: mainTsContent(runtimeMode)
12467
12922
  });
12468
12923
  } else {
12469
12924
  entries.push({
@@ -12475,8 +12930,8 @@ async function buildInitPlan(ctx, options) {
12475
12930
  }
12476
12931
  }
12477
12932
  {
12478
- const schemaPath = path23.join(cwd, "src", "schema.ts");
12479
- if (!fs12.existsSync(schemaPath)) {
12933
+ const schemaPath = path25.join(cwd, "src", "schema.ts");
12934
+ if (!fs14.existsSync(schemaPath)) {
12480
12935
  entries.push({
12481
12936
  path: schemaPath,
12482
12937
  relPath: relOf(cwd, schemaPath),
@@ -12492,14 +12947,14 @@ async function buildInitPlan(ctx, options) {
12492
12947
  });
12493
12948
  }
12494
12949
  }
12495
- entries.push(dirEntry(cwd, path23.join(cwd, "entities")));
12950
+ entries.push(dirEntry(cwd, path25.join(cwd, "entities")));
12496
12951
  {
12497
- const entitiesDir = path23.join(cwd, "entities");
12498
- const examplePath = path23.join(entitiesDir, "example.yaml");
12499
- const hasOtherYamls = fs12.existsSync(entitiesDir) && findYamlFiles(entitiesDir).some(
12500
- (f) => path23.basename(f) !== "example.yaml"
12952
+ const entitiesDir = path25.join(cwd, "entities");
12953
+ const examplePath = path25.join(entitiesDir, "example.yaml");
12954
+ const hasOtherYamls = fs14.existsSync(entitiesDir) && findYamlFiles(entitiesDir).some(
12955
+ (f) => path25.basename(f) !== "example.yaml"
12501
12956
  );
12502
- if (fs12.existsSync(examplePath)) {
12957
+ if (fs14.existsSync(examplePath)) {
12503
12958
  entries.push({
12504
12959
  path: examplePath,
12505
12960
  relPath: relOf(cwd, examplePath),
@@ -12545,7 +13000,7 @@ function writePlan(plan) {
12545
13000
  continue;
12546
13001
  }
12547
13002
  if (e.directory) {
12548
- fs12.mkdirSync(e.path, { recursive: true });
13003
+ fs14.mkdirSync(e.path, { recursive: true });
12549
13004
  created.push(e);
12550
13005
  continue;
12551
13006
  }
@@ -12553,8 +13008,8 @@ function writePlan(plan) {
12553
13008
  skipped.push(e);
12554
13009
  continue;
12555
13010
  }
12556
- fs12.mkdirSync(path23.dirname(e.path), { recursive: true });
12557
- fs12.writeFileSync(e.path, e.content, "utf-8");
13011
+ fs14.mkdirSync(path25.dirname(e.path), { recursive: true });
13012
+ fs14.writeFileSync(e.path, e.content, "utf-8");
12558
13013
  if (e.action === "create") created.push(e);
12559
13014
  else if (e.action === "merge") merged.push(e);
12560
13015
  else if (e.action === "overwrite") overwritten.push(e);
@@ -12563,8 +13018,8 @@ function writePlan(plan) {
12563
13018
  }
12564
13019
 
12565
13020
  // src/cli/commands/project-upgrade-openapi.ts
12566
- import fs13 from "fs";
12567
- import path24 from "path";
13021
+ import fs15 from "fs";
13022
+ import path26 from "path";
12568
13023
  import { Command as Command4, Option as Option4 } from "clipanion";
12569
13024
  import { Project, IndentationText, QuoteKind, NewLineKind } from "ts-morph";
12570
13025
 
@@ -12803,35 +13258,35 @@ var MAIN_SWAGGER_IMPORTS = [
12803
13258
  "import { OPENAPI_REGISTRY, OpenApiRegistry } from './shared/openapi';"
12804
13259
  ];
12805
13260
  function runtimeRoot3() {
12806
- const pkgRoot = path24.resolve(import.meta.dirname, "..", "..", "..");
12807
- const topLevel = path24.join(pkgRoot, "runtime");
12808
- if (fs13.existsSync(topLevel)) return topLevel;
12809
- return path24.join(pkgRoot, "dist", "runtime");
13261
+ const pkgRoot = path26.resolve(import.meta.dirname, "..", "..", "..");
13262
+ const topLevel = path26.join(pkgRoot, "runtime");
13263
+ if (fs15.existsSync(topLevel)) return topLevel;
13264
+ return path26.join(pkgRoot, "dist", "runtime");
12810
13265
  }
12811
13266
  function loadRuntimeFile2(rel2) {
12812
- return fs13.readFileSync(path24.join(runtimeRoot3(), rel2), "utf-8");
13267
+ return fs15.readFileSync(path26.join(runtimeRoot3(), rel2), "utf-8");
12813
13268
  }
12814
13269
  function resolveProjectRoot(startDir) {
12815
- let dir = path24.resolve(startDir);
13270
+ let dir = path26.resolve(startDir);
12816
13271
  for (let i = 0; i < 16; i++) {
12817
- if (fs13.existsSync(path24.join(dir, "codegen.config.yaml")) || fs13.existsSync(path24.join(dir, "package.json"))) {
13272
+ if (fs15.existsSync(path26.join(dir, "codegen.config.yaml")) || fs15.existsSync(path26.join(dir, "package.json"))) {
12818
13273
  return dir;
12819
13274
  }
12820
- const parent = path24.dirname(dir);
13275
+ const parent = path26.dirname(dir);
12821
13276
  if (parent === dir) break;
12822
13277
  dir = parent;
12823
13278
  }
12824
- return path24.resolve(startDir);
13279
+ return path26.resolve(startDir);
12825
13280
  }
12826
13281
  async function runUpgradeOpenapi(opts) {
12827
13282
  const { projectRoot, dryRun, force } = opts;
12828
13283
  const changes = [];
12829
13284
  for (const v of OPENAPI_VENDORED_FILES) {
12830
- const target = path24.join(projectRoot, v.target);
12831
- const exists = fs13.existsSync(target);
13285
+ const target = path26.join(projectRoot, v.target);
13286
+ const exists = fs15.existsSync(target);
12832
13287
  const newContent = loadRuntimeFile2(v.runtime);
12833
13288
  if (exists && !force) {
12834
- const existing = fs13.readFileSync(target, "utf-8");
13289
+ const existing = fs15.readFileSync(target, "utf-8");
12835
13290
  if (existing === newContent) {
12836
13291
  changes.push({ path: v.target, action: "unchanged" });
12837
13292
  } else {
@@ -12843,8 +13298,8 @@ async function runUpgradeOpenapi(opts) {
12843
13298
  }
12844
13299
  } else {
12845
13300
  if (!dryRun) {
12846
- fs13.mkdirSync(path24.dirname(target), { recursive: true });
12847
- fs13.writeFileSync(target, newContent);
13301
+ fs15.mkdirSync(path26.dirname(target), { recursive: true });
13302
+ fs15.writeFileSync(target, newContent);
12848
13303
  }
12849
13304
  changes.push({
12850
13305
  path: v.target,
@@ -12852,8 +13307,8 @@ async function runUpgradeOpenapi(opts) {
12852
13307
  });
12853
13308
  }
12854
13309
  }
12855
- const appModulePath = path24.join(projectRoot, "src", "app.module.ts");
12856
- if (!fs13.existsSync(appModulePath)) {
13310
+ const appModulePath = path26.join(projectRoot, "src", "app.module.ts");
13311
+ if (!fs15.existsSync(appModulePath)) {
12857
13312
  return {
12858
13313
  projectRoot,
12859
13314
  changes,
@@ -12936,8 +13391,8 @@ async function runUpgradeOpenapi(opts) {
12936
13391
  } else {
12937
13392
  changes.push({ path: "src/app.module.ts", action: "unchanged" });
12938
13393
  }
12939
- const mainPath = path24.join(projectRoot, "src", "main.ts");
12940
- if (fs13.existsSync(mainPath)) {
13394
+ const mainPath = path26.join(projectRoot, "src", "main.ts");
13395
+ if (fs15.existsSync(mainPath)) {
12941
13396
  const mainSource = project.addSourceFileAtPath(mainPath);
12942
13397
  const mainBefore = mainSource.getFullText();
12943
13398
  const result = ensureMainSwaggerBlock(mainSource, {
@@ -13017,8 +13472,8 @@ var ProjectUpgradeOpenapiCommand = class extends Command4 {
13017
13472
  json = Option4.Boolean("--json", false);
13018
13473
  async execute() {
13019
13474
  if (this.json) setJsonMode(true);
13020
- const startDir = this.pathOpt ? path24.resolve(this.pathOpt) : process.cwd();
13021
- if (!fs13.existsSync(startDir)) {
13475
+ const startDir = this.pathOpt ? path26.resolve(this.pathOpt) : process.cwd();
13476
+ if (!fs15.existsSync(startDir)) {
13022
13477
  printError(`Directory not found: ${startDir}`);
13023
13478
  return 1;
13024
13479
  }
@@ -13093,18 +13548,18 @@ ${CONSUMER_SETUP_POINTER}
13093
13548
  };
13094
13549
 
13095
13550
  // src/cli/commands/project-update.ts
13096
- import fs16 from "fs";
13097
- import path27 from "path";
13551
+ import fs18 from "fs";
13552
+ import path29 from "path";
13098
13553
  import { Command as Command6, Option as Option6 } from "clipanion";
13099
13554
 
13100
13555
  // src/cli/commands/skills.ts
13101
- import fs15 from "fs";
13102
- import path26 from "path";
13556
+ import fs17 from "fs";
13557
+ import path28 from "path";
13103
13558
  import { Command as Command5, Option as Option5 } from "clipanion";
13104
13559
 
13105
13560
  // src/cli/shared/tree-copier.ts
13106
- import fs14 from "fs";
13107
- import path25 from "path";
13561
+ import fs16 from "fs";
13562
+ import path27 from "path";
13108
13563
  var TEXT_EXTENSIONS = [".ts", ".tsx", ".md", ".mdx", ".yaml", ".yml", ".json"];
13109
13564
  function isTextFile(name) {
13110
13565
  return TEXT_EXTENSIONS.some((ext) => name.endsWith(ext));
@@ -13117,26 +13572,26 @@ function copyTreeWithReport(opts) {
13117
13572
  updated: [],
13118
13573
  unchanged: []
13119
13574
  };
13120
- if (!fs14.existsSync(srcDir) || !fs14.statSync(srcDir).isDirectory()) {
13575
+ if (!fs16.existsSync(srcDir) || !fs16.statSync(srcDir).isDirectory()) {
13121
13576
  throw new Error(`tree-copier source directory not found: ${srcDir}`);
13122
13577
  }
13123
13578
  const walk = (relDir) => {
13124
- const absSrcDir = path25.join(srcDir, relDir);
13125
- for (const entry of fs14.readdirSync(absSrcDir, { withFileTypes: true })) {
13126
- const relPath2 = relDir ? path25.posix.join(relDir, entry.name) : entry.name;
13127
- const absSrc = path25.join(srcDir, relPath2);
13579
+ const absSrcDir = path27.join(srcDir, relDir);
13580
+ for (const entry of fs16.readdirSync(absSrcDir, { withFileTypes: true })) {
13581
+ const relPath2 = relDir ? path27.posix.join(relDir, entry.name) : entry.name;
13582
+ const absSrc = path27.join(srcDir, relPath2);
13128
13583
  if (entry.isDirectory()) {
13129
13584
  walk(relPath2);
13130
13585
  continue;
13131
13586
  }
13132
13587
  if (!entry.isFile()) continue;
13133
13588
  if (include && !include(relPath2)) continue;
13134
- const dest = path25.join(destDir, relPath2);
13135
- let content = fs14.readFileSync(absSrc, "utf-8");
13589
+ const dest = path27.join(destDir, relPath2);
13590
+ let content = fs16.readFileSync(absSrc, "utf-8");
13136
13591
  if (transform && isTextFile(entry.name)) {
13137
13592
  content = transform(content, dest);
13138
13593
  }
13139
- const existing = fs14.existsSync(dest) ? fs14.readFileSync(dest, "utf-8") : null;
13594
+ const existing = fs16.existsSync(dest) ? fs16.readFileSync(dest, "utf-8") : null;
13140
13595
  let action;
13141
13596
  if (existing === null) {
13142
13597
  action = "created";
@@ -13146,8 +13601,8 @@ function copyTreeWithReport(opts) {
13146
13601
  action = "updated";
13147
13602
  }
13148
13603
  if (!dryRun && action !== "unchanged") {
13149
- fs14.mkdirSync(path25.dirname(dest), { recursive: true });
13150
- fs14.writeFileSync(dest, content, "utf-8");
13604
+ fs16.mkdirSync(path27.dirname(dest), { recursive: true });
13605
+ fs16.writeFileSync(dest, content, "utf-8");
13151
13606
  }
13152
13607
  const record = { relPath: relPath2, dest, action };
13153
13608
  report.entries.push(record);
@@ -13160,23 +13615,23 @@ function copyTreeWithReport(opts) {
13160
13615
 
13161
13616
  // src/cli/commands/skills.ts
13162
13617
  function consumerSkillsRoot() {
13163
- const pkgRoot = path26.resolve(import.meta.dirname, "..", "..", "..");
13164
- const topLevel = path26.join(pkgRoot, "consumer-skills");
13165
- if (fs15.existsSync(topLevel)) return topLevel;
13166
- return path26.join(pkgRoot, "dist", "consumer-skills");
13618
+ const pkgRoot = path28.resolve(import.meta.dirname, "..", "..", "..");
13619
+ const topLevel = path28.join(pkgRoot, "consumer-skills");
13620
+ if (fs17.existsSync(topLevel)) return topLevel;
13621
+ return path28.join(pkgRoot, "dist", "consumer-skills");
13167
13622
  }
13168
13623
  function skillsTargetDir(cwd) {
13169
- return path26.join(cwd, ".claude", "skills");
13624
+ return path28.join(cwd, ".claude", "skills");
13170
13625
  }
13171
13626
  function availableSkills() {
13172
13627
  const root = consumerSkillsRoot();
13173
- if (!fs15.existsSync(root)) return [];
13174
- return fs15.readdirSync(root, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).sort();
13628
+ if (!fs17.existsSync(root)) return [];
13629
+ return fs17.readdirSync(root, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).sort();
13175
13630
  }
13176
13631
  function runSkillsInstall(opts) {
13177
13632
  const sourceRoot = consumerSkillsRoot();
13178
13633
  const targetDir = skillsTargetDir(opts.cwd);
13179
- if (!fs15.existsSync(sourceRoot)) {
13634
+ if (!fs17.existsSync(sourceRoot)) {
13180
13635
  return {
13181
13636
  ok: false,
13182
13637
  sourceRoot,
@@ -13194,8 +13649,8 @@ function runSkillsInstall(opts) {
13194
13649
  async function summary3(ctx) {
13195
13650
  const skills = availableSkills();
13196
13651
  const targetDir = skillsTargetDir(ctx.cwd);
13197
- const installedDirs = fs15.existsSync(targetDir) ? new Set(
13198
- fs15.readdirSync(targetDir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name)
13652
+ const installedDirs = fs17.existsSync(targetDir) ? new Set(
13653
+ fs17.readdirSync(targetDir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name)
13199
13654
  ) : /* @__PURE__ */ new Set();
13200
13655
  const body = [];
13201
13656
  if (skills.length === 0) {
@@ -13213,13 +13668,13 @@ async function summary3(ctx) {
13213
13668
  return {
13214
13669
  title: "skills",
13215
13670
  body,
13216
- footer: `${installedCount} of ${skills.length} skills installed \u2192 ${path26.relative(ctx.cwd, targetDir) || targetDir}`
13671
+ footer: `${installedCount} of ${skills.length} skills installed \u2192 ${path28.relative(ctx.cwd, targetDir) || targetDir}`
13217
13672
  };
13218
13673
  }
13219
13674
  async function hints3(ctx) {
13220
13675
  const skills = availableSkills();
13221
13676
  const targetDir = skillsTargetDir(ctx.cwd);
13222
- const allPresent = skills.length > 0 && fs15.existsSync(targetDir) && skills.every((s) => fs15.existsSync(path26.join(targetDir, s)));
13677
+ const allPresent = skills.length > 0 && fs17.existsSync(targetDir) && skills.every((s) => fs17.existsSync(path28.join(targetDir, s)));
13223
13678
  if (allPresent) {
13224
13679
  return [
13225
13680
  { command: "codegen update", description: "Re-sync skills + runtime after a package bump" }
@@ -13294,7 +13749,7 @@ var SkillsInstallCommand = class extends Command5 {
13294
13749
  });
13295
13750
  return 0;
13296
13751
  }
13297
- printInfo(`target = ${path26.relative(ctx.cwd, result.targetDir) || result.targetDir}`);
13752
+ printInfo(`target = ${path28.relative(ctx.cwd, result.targetDir) || result.targetDir}`);
13298
13753
  console.log("");
13299
13754
  renderTreeReport(report);
13300
13755
  console.log("");
@@ -13322,8 +13777,8 @@ var SkillsListCommand = class extends Command5 {
13322
13777
  const skills = availableSkills();
13323
13778
  const targetDir = skillsTargetDir(ctx.cwd);
13324
13779
  const rows = skills.map((name) => {
13325
- const dir = path26.join(targetDir, name);
13326
- return { name, status: fs15.existsSync(dir) ? "installed" : "available" };
13780
+ const dir = path28.join(targetDir, name);
13781
+ return { name, status: fs17.existsSync(dir) ? "installed" : "available" };
13327
13782
  });
13328
13783
  if (isJsonMode()) {
13329
13784
  printJson({ command: "skills list", target: targetDir, skills: rows });
@@ -13352,16 +13807,16 @@ var NON_RUNTIME_SUBSYSTEMS = /* @__PURE__ */ new Set(["openapi-config", "auth-in
13352
13807
  function syncVendoredRuntime(cwd, write) {
13353
13808
  const changes = [];
13354
13809
  for (const v of VENDORED_RUNTIME_FILES) {
13355
- const dest = path27.join(cwd, v.target);
13810
+ const dest = path29.join(cwd, v.target);
13356
13811
  const content = loadRuntimeFile(v.runtime);
13357
- const existing = fs16.existsSync(dest) ? fs16.readFileSync(dest, "utf-8") : null;
13812
+ const existing = fs18.existsSync(dest) ? fs18.readFileSync(dest, "utf-8") : null;
13358
13813
  let action;
13359
13814
  if (existing === null) action = "created";
13360
13815
  else if (existing === content) action = "unchanged";
13361
13816
  else action = "updated";
13362
13817
  if (write && action !== "unchanged") {
13363
- fs16.mkdirSync(path27.dirname(dest), { recursive: true });
13364
- fs16.writeFileSync(dest, content, "utf-8");
13818
+ fs18.mkdirSync(path29.dirname(dest), { recursive: true });
13819
+ fs18.writeFileSync(dest, content, "utf-8");
13365
13820
  }
13366
13821
  changes.push({ path: v.target, action });
13367
13822
  }
@@ -13372,17 +13827,17 @@ async function syncSubsystemRuntime(cwd, inst, write) {
13372
13827
  return { name: inst.name, changes: [], skippedReason: "config-only / vendored elsewhere" };
13373
13828
  }
13374
13829
  const source = subsystemSource(inst.name);
13375
- if (!fs16.existsSync(source)) {
13830
+ if (!fs18.existsSync(source)) {
13376
13831
  return { name: inst.name, changes: [], skippedReason: "no runtime source in package" };
13377
13832
  }
13378
- const subsystemsRoot = path27.dirname(inst.path);
13833
+ const subsystemsRoot = path29.dirname(inst.path);
13379
13834
  const result = await copyRuntime({
13380
13835
  sourceDir: source,
13381
13836
  targetDir: inst.path,
13382
13837
  filter: backendFileFilter(inst.backend, inst.name),
13383
13838
  resolveDeps: true,
13384
13839
  runtimeRoot: runtimeRoot2(),
13385
- depsTargetRoot: path27.resolve(subsystemsRoot, ".."),
13840
+ depsTargetRoot: path29.resolve(subsystemsRoot, ".."),
13386
13841
  dryRun: !write,
13387
13842
  // Refresh files already vendored for this subsystem; never install new
13388
13843
  // ones (that's `subsystem install`). copyRuntime classifies accurately
@@ -13396,7 +13851,7 @@ async function syncSubsystemRuntime(cwd, inst, write) {
13396
13851
  return { name: inst.name, changes };
13397
13852
  }
13398
13853
  function rel(cwd, abs) {
13399
- return path27.relative(cwd, abs) || abs;
13854
+ return path29.relative(cwd, abs) || abs;
13400
13855
  }
13401
13856
  var ProjectUpdateCommand = class extends Command6 {
13402
13857
  static paths = [["project", "update"]];
@@ -13435,7 +13890,7 @@ var ProjectUpdateCommand = class extends Command6 {
13435
13890
  const installed = this.skipSubsystems ? [] : await detectInstalledSubsystems(ctx);
13436
13891
  if (!this.dryRun && !this.force) {
13437
13892
  const vendoredDry = syncVendoredRuntime(ctx.cwd, false);
13438
- const vendoredDirtyCandidates = vendoredDry.filter((c) => c.action === "updated").map((c) => path27.join(ctx.cwd, c.path));
13893
+ const vendoredDirtyCandidates = vendoredDry.filter((c) => c.action === "updated").map((c) => path29.join(ctx.cwd, c.path));
13439
13894
  const skillDirtyCandidates = this.skipSkills ? [] : runSkillsInstall({ cwd: ctx.cwd, dryRun: true }).report?.updated.map((e) => e.dest) ?? [];
13440
13895
  const subsystemDirs = installed.filter((i) => !NON_RUNTIME_SUBSYSTEMS.has(i.name)).map((i) => i.path);
13441
13896
  const gate = checkGitSafety(
@@ -13606,7 +14061,8 @@ var ProjectInitCommand = class extends Command7 {
13606
14061
  static usage = Command7.Usage({
13607
14062
  description: "Scaffold a consumer project (config, shims, barrels, app.module)",
13608
14063
  examples: [
13609
- ["Initialize with defaults", "codegen project init --yes"],
14064
+ ["Initialize with defaults (package runtime)", "codegen project init --yes"],
14065
+ ["Vendored runtime (legacy @shared/** model)", "codegen project init --yes --runtime vendored"],
13610
14066
  ["Preview without writing", "codegen project init --dry-run"],
13611
14067
  ["Create tsconfig if missing", "codegen project init --yes --with-tsconfig"],
13612
14068
  ["Overwrite existing shims", "codegen project init --force"]
@@ -13616,6 +14072,9 @@ var ProjectInitCommand = class extends Command7 {
13616
14072
  dryRun = Option7.Boolean("--dry-run", false);
13617
14073
  force = Option7.Boolean("--force", false);
13618
14074
  withTsconfig = Option7.Boolean("--with-tsconfig", false);
14075
+ // Runtime mode (ADR-037). `package` (default) ⇒ depend on the npm package,
14076
+ // vendor nothing; `vendored` ⇒ vendor src/shared/** and import via @shared/*.
14077
+ runtime = Option7.String("--runtime", "package");
13619
14078
  // Vendor consumer skills into .claude/skills by default; opt out with --no-skills.
13620
14079
  skills = Option7.Boolean("--skills", true);
13621
14080
  json = Option7.Boolean("--json", false);
@@ -13627,11 +14086,18 @@ var ProjectInitCommand = class extends Command7 {
13627
14086
  json: this.json,
13628
14087
  skipDetection: false
13629
14088
  });
14089
+ const runtimeMode = this.runtime === "vendored" ? "vendored" : "package";
14090
+ if (this.runtime !== "package" && this.runtime !== "vendored" && !isJsonMode()) {
14091
+ printWarning(
14092
+ `--runtime '${this.runtime}' is not recognized (expected 'package' or 'vendored'); using 'package'.`
14093
+ );
14094
+ }
13630
14095
  const plan = await buildInitPlan(ctx, {
13631
14096
  cwd: ctx.cwd,
13632
14097
  force: this.force,
13633
14098
  withTsconfig: this.withTsconfig,
13634
- skipScan: false
14099
+ skipScan: false,
14100
+ runtimeMode
13635
14101
  });
13636
14102
  if (this.force && !isJsonMode()) {
13637
14103
  printWarning("--force: existing scaffold files will be overwritten.");
@@ -13775,9 +14241,9 @@ var ProjectScanCommand = class extends Command7 {
13775
14241
  cwd = Option7.String("--cwd", { required: false });
13776
14242
  async execute() {
13777
14243
  if (this.json) setJsonMode(true);
13778
- const baseCwd = this.cwd ? path28.resolve(this.cwd) : process.cwd();
13779
- const target = this.directory ? path28.resolve(baseCwd, this.directory) : baseCwd;
13780
- if (!fs17.existsSync(target)) {
14244
+ const baseCwd = this.cwd ? path30.resolve(this.cwd) : process.cwd();
14245
+ const target = this.directory ? path30.resolve(baseCwd, this.directory) : baseCwd;
14246
+ if (!fs19.existsSync(target)) {
13781
14247
  printError(`Directory not found: ${target}`);
13782
14248
  return 1;
13783
14249
  }
@@ -13827,8 +14293,8 @@ var ProjectScanCommand = class extends Command7 {
13827
14293
  `architecture: ${profile.architecture.evidence.join(", ") || "\u2014"}`
13828
14294
  ]);
13829
14295
  }
13830
- const outPath = path28.join(target, "codegen.config.yaml");
13831
- const existsNow = fs17.existsSync(outPath);
14296
+ const outPath = path30.join(target, "codegen.config.yaml");
14297
+ const existsNow = fs19.existsSync(outPath);
13832
14298
  if (this.dryRun) {
13833
14299
  console.log("");
13834
14300
  printInfo("Dry run \u2014 proposed codegen.config.yaml:");
@@ -13841,7 +14307,7 @@ var ProjectScanCommand = class extends Command7 {
13841
14307
  printWarning(`${outPath} already exists \u2014 pass --force via edit; skipping.`);
13842
14308
  return 0;
13843
14309
  }
13844
- fs17.writeFileSync(outPath, yamlText);
14310
+ fs19.writeFileSync(outPath, yamlText);
13845
14311
  printSuccess(`wrote ${outPath}`);
13846
14312
  return 0;
13847
14313
  }
@@ -13948,12 +14414,12 @@ var ProjectInspectCommand = class extends Command7 {
13948
14414
  return 2;
13949
14415
  }
13950
14416
  resolveEntitiesDir(ctx) {
13951
- if (this.dir) return path28.resolve(ctx.cwd, this.dir);
13952
- return ctx.entitiesDir ?? path28.resolve(ctx.cwd, "entities");
14417
+ if (this.dir) return path30.resolve(ctx.cwd, this.dir);
14418
+ return ctx.entitiesDir ?? path30.resolve(ctx.cwd, "entities");
13953
14419
  }
13954
14420
  async runAnalysis(ctx, kind) {
13955
14421
  const entitiesDir = this.resolveEntitiesDir(ctx);
13956
- if (!entitiesDir || !fs17.existsSync(entitiesDir)) {
14422
+ if (!entitiesDir || !fs19.existsSync(entitiesDir)) {
13957
14423
  printError(`Directory not found: ${entitiesDir ?? "(no entities/ dir)"}`);
13958
14424
  return 1;
13959
14425
  }
@@ -13983,7 +14449,7 @@ var ProjectInspectCommand = class extends Command7 {
13983
14449
  out = formatConsole(filtered);
13984
14450
  }
13985
14451
  if (this.output) {
13986
- fs17.writeFileSync(this.output, out);
14452
+ fs19.writeFileSync(this.output, out);
13987
14453
  if (!isJsonMode()) printSuccess(`wrote ${this.output}`);
13988
14454
  } else {
13989
14455
  console.log(out);
@@ -13996,7 +14462,7 @@ var ProjectInspectCommand = class extends Command7 {
13996
14462
  }
13997
14463
  async runManifest(ctx) {
13998
14464
  const entitiesDir = this.resolveEntitiesDir(ctx);
13999
- if (!entitiesDir || !fs17.existsSync(entitiesDir)) {
14465
+ if (!entitiesDir || !fs19.existsSync(entitiesDir)) {
14000
14466
  printError(`Directory not found: ${entitiesDir ?? "(no entities/ dir)"}`);
14001
14467
  return 1;
14002
14468
  }
@@ -14152,17 +14618,17 @@ var ProjectGraphCommand = class extends Command7 {
14152
14618
  json: this.json,
14153
14619
  skipDetection: true
14154
14620
  });
14155
- const entitiesDir = this.dir ? path28.resolve(ctx.cwd, this.dir) : ctx.entitiesDir ?? path28.resolve(ctx.cwd, "entities");
14156
- if (!fs17.existsSync(entitiesDir)) {
14621
+ const entitiesDir = this.dir ? path30.resolve(ctx.cwd, this.dir) : ctx.entitiesDir ?? path30.resolve(ctx.cwd, "entities");
14622
+ if (!fs19.existsSync(entitiesDir)) {
14157
14623
  printError(`Entity directory not found: ${entitiesDir}`);
14158
14624
  return 1;
14159
14625
  }
14160
14626
  const relCandidates = [
14161
- path28.resolve(path28.dirname(entitiesDir), "relationships"),
14162
- path28.resolve(entitiesDir, "relationships"),
14163
- path28.resolve(ctx.cwd, "relationships")
14627
+ path30.resolve(path30.dirname(entitiesDir), "relationships"),
14628
+ path30.resolve(entitiesDir, "relationships"),
14629
+ path30.resolve(ctx.cwd, "relationships")
14164
14630
  ];
14165
- const relationshipsDir = relCandidates.find((d) => fs17.existsSync(d));
14631
+ const relationshipsDir = relCandidates.find((d) => fs19.existsSync(d));
14166
14632
  const result = await analyzeDomain(entitiesDir, relationshipsDir);
14167
14633
  const serialized = serializeDomainGraph(result.graph);
14168
14634
  if (isJsonMode()) {
@@ -14176,20 +14642,20 @@ var ProjectGraphCommand = class extends Command7 {
14176
14642
  return 0;
14177
14643
  }
14178
14644
  if (this.output) {
14179
- const outPath = path28.resolve(ctx.cwd, this.output);
14180
- fs17.writeFileSync(outPath, JSON.stringify(serialized, null, 2));
14645
+ const outPath = path30.resolve(ctx.cwd, this.output);
14646
+ fs19.writeFileSync(outPath, JSON.stringify(serialized, null, 2));
14181
14647
  printSuccess(`Graph written to ${outPath}`);
14182
14648
  printInfo(`${result.entities.length} entities, ${result.relationshipDefinitions.length} relationships, ${result.graph.edges.length} edges`);
14183
14649
  return 0;
14184
14650
  }
14185
14651
  const os = await import("os");
14186
- const tmpDir = fs17.mkdtempSync(path28.join(os.default.tmpdir(), "codegen-graph-"));
14187
- const graphPath = path28.join(tmpDir, "graph.json");
14188
- fs17.writeFileSync(graphPath, JSON.stringify(serialized, null, 2));
14189
- const viewerDir = path28.resolve(import.meta.dirname, "..", "..", "..", "tools", "schema-graph-viewer");
14190
- const viewerDist = path28.join(viewerDir, "dist", "index.html");
14191
- if (fs17.existsSync(viewerDist)) {
14192
- fs17.copyFileSync(graphPath, path28.join(viewerDir, "dist", "graph.json"));
14652
+ const tmpDir = fs19.mkdtempSync(path30.join(os.default.tmpdir(), "codegen-graph-"));
14653
+ const graphPath = path30.join(tmpDir, "graph.json");
14654
+ fs19.writeFileSync(graphPath, JSON.stringify(serialized, null, 2));
14655
+ const viewerDir = path30.resolve(import.meta.dirname, "..", "..", "..", "tools", "schema-graph-viewer");
14656
+ const viewerDist = path30.join(viewerDir, "dist", "index.html");
14657
+ if (fs19.existsSync(viewerDist)) {
14658
+ fs19.copyFileSync(graphPath, path30.join(viewerDir, "dist", "graph.json"));
14193
14659
  printSuccess("Graph exported");
14194
14660
  printInfo(`${result.entities.length} entities, ${result.relationshipDefinitions.length} relationships, ${result.graph.edges.length} edges`);
14195
14661
  printInfo(`Graph JSON: ${graphPath}`);
@@ -14220,8 +14686,8 @@ var projectNoun = {
14220
14686
  var project_default = projectNoun;
14221
14687
 
14222
14688
  // src/cli/commands/dev.ts
14223
- import fs18 from "fs";
14224
- import path29 from "path";
14689
+ import fs20 from "fs";
14690
+ import path31 from "path";
14225
14691
  import { execSync as execSync3, spawn, spawnSync } from "child_process";
14226
14692
  import { Command as Command8, Option as Option8 } from "clipanion";
14227
14693
  var DEFAULT_APP_PORT = 3e3;
@@ -14254,33 +14720,33 @@ function getRedisPort(_ctx) {
14254
14720
  return Number(process.env.DEV_REDIS_PORT ?? DEFAULT_REDIS_PORT);
14255
14721
  }
14256
14722
  function composeFilePath(cwd) {
14257
- const devPath = path29.join(cwd, COMPOSE_FILE);
14258
- if (fs18.existsSync(devPath)) return devPath;
14259
- const rootPath = path29.join(cwd, "docker-compose.yml");
14260
- if (fs18.existsSync(rootPath)) return rootPath;
14723
+ const devPath = path31.join(cwd, COMPOSE_FILE);
14724
+ if (fs20.existsSync(devPath)) return devPath;
14725
+ const rootPath = path31.join(cwd, "docker-compose.yml");
14726
+ if (fs20.existsSync(rootPath)) return rootPath;
14261
14727
  return devPath;
14262
14728
  }
14263
14729
  function pidFilePath(cwd) {
14264
- return path29.join(cwd, PID_FILE);
14730
+ return path31.join(cwd, PID_FILE);
14265
14731
  }
14266
14732
  function readAppPid(cwd) {
14267
14733
  const p = pidFilePath(cwd);
14268
- if (!fs18.existsSync(p)) return null;
14269
- const pid = parseInt(fs18.readFileSync(p, "utf-8").trim(), 10);
14734
+ if (!fs20.existsSync(p)) return null;
14735
+ const pid = parseInt(fs20.readFileSync(p, "utf-8").trim(), 10);
14270
14736
  if (isNaN(pid)) return null;
14271
14737
  try {
14272
14738
  process.kill(pid, 0);
14273
14739
  return pid;
14274
14740
  } catch {
14275
- fs18.rmSync(p, { force: true });
14741
+ fs20.rmSync(p, { force: true });
14276
14742
  return null;
14277
14743
  }
14278
14744
  }
14279
14745
  function writeAppPid(cwd, pid) {
14280
- fs18.writeFileSync(pidFilePath(cwd), String(pid));
14746
+ fs20.writeFileSync(pidFilePath(cwd), String(pid));
14281
14747
  }
14282
14748
  function clearAppPid(cwd) {
14283
- fs18.rmSync(pidFilePath(cwd), { force: true });
14749
+ fs20.rmSync(pidFilePath(cwd), { force: true });
14284
14750
  }
14285
14751
  function checkPostgres(cwd, port) {
14286
14752
  const r = runCmd(`docker exec codegen-dev-postgres pg_isready -U postgres`, cwd, {
@@ -14320,9 +14786,9 @@ function checkApp(cwd, port) {
14320
14786
  };
14321
14787
  }
14322
14788
  function listEntityNames(ctx) {
14323
- if (!ctx.entitiesDir || !fs18.existsSync(ctx.entitiesDir)) return [];
14789
+ if (!ctx.entitiesDir || !fs20.existsSync(ctx.entitiesDir)) return [];
14324
14790
  return findYamlFiles(ctx.entitiesDir).map(
14325
- (f) => path29.basename(f).replace(/\.ya?ml$/, "")
14791
+ (f) => path31.basename(f).replace(/\.ya?ml$/, "")
14326
14792
  );
14327
14793
  }
14328
14794
  function formatServiceLine(svc) {
@@ -14332,8 +14798,8 @@ function formatServiceLine(svc) {
14332
14798
  return `${icon} ${svc.name.padEnd(12)} ${theme.muted(`${svc.host}:${svc.port}`)} ${status}${pidStr}`;
14333
14799
  }
14334
14800
  function ensureComposeFile(cwd, pgPort, redisPort) {
14335
- const composePath = path29.join(cwd, COMPOSE_FILE);
14336
- if (fs18.existsSync(composePath)) return composePath;
14801
+ const composePath = path31.join(cwd, COMPOSE_FILE);
14802
+ if (fs20.existsSync(composePath)) return composePath;
14337
14803
  const content = `# Auto-generated by codegen dev
14338
14804
  # Ports offset from defaults to avoid conflicts with other local services.
14339
14805
  services:
@@ -14368,7 +14834,7 @@ services:
14368
14834
  volumes:
14369
14835
  codegen-dev-pgdata:
14370
14836
  `;
14371
- fs18.writeFileSync(composePath, content);
14837
+ fs20.writeFileSync(composePath, content);
14372
14838
  return composePath;
14373
14839
  }
14374
14840
  var DevUpCommand = class extends Command8 {
@@ -14417,7 +14883,7 @@ var DevUpCommand = class extends Command8 {
14417
14883
  if (!pgReady) printWarning("postgres did not become healthy in time");
14418
14884
  if (!redisReady) printWarning("redis did not become healthy in time");
14419
14885
  const drizzleConfig = ["drizzle.config.ts", "drizzle.config.js"].find(
14420
- (f) => fs18.existsSync(path29.join(ctx.cwd, f))
14886
+ (f) => fs20.existsSync(path31.join(ctx.cwd, f))
14421
14887
  );
14422
14888
  if (drizzleConfig) {
14423
14889
  if (!isJsonMode()) printInfo("pushing database schema...");
@@ -14437,8 +14903,8 @@ var DevUpCommand = class extends Command8 {
14437
14903
  if (!isJsonMode()) printInfo("starting NestJS app...");
14438
14904
  const dbUrl = `postgres://postgres:postgres@localhost:${pgPort}/codegen_dev`;
14439
14905
  const redisUrl = `redis://localhost:${redisPort}`;
14440
- const logFile = path29.join(ctx.cwd, ".dev-app.log");
14441
- const logFd = fs18.openSync(logFile, "a");
14906
+ const logFile = path31.join(ctx.cwd, ".dev-app.log");
14907
+ const logFd = fs20.openSync(logFile, "a");
14442
14908
  const child = spawn("bun", ["src/main.ts"], {
14443
14909
  cwd: ctx.cwd,
14444
14910
  detached: true,
@@ -14451,7 +14917,7 @@ var DevUpCommand = class extends Command8 {
14451
14917
  }
14452
14918
  });
14453
14919
  child.unref();
14454
- fs18.closeSync(logFd);
14920
+ fs20.closeSync(logFd);
14455
14921
  if (child.pid) {
14456
14922
  writeAppPid(ctx.cwd, child.pid);
14457
14923
  spawnSync("sleep", ["2"]);
@@ -14595,8 +15061,8 @@ var DevLogsCommand = class extends Command8 {
14595
15061
  }
14596
15062
  return 0;
14597
15063
  }
14598
- const logFile = path29.join(ctx.cwd, ".dev-app.log");
14599
- if (!fs18.existsSync(logFile)) {
15064
+ const logFile = path31.join(ctx.cwd, ".dev-app.log");
15065
+ if (!fs20.existsSync(logFile)) {
14600
15066
  printInfo("no app logs found \u2014 is the app running?");
14601
15067
  return 0;
14602
15068
  }
@@ -14639,8 +15105,8 @@ var DevRestartCommand = class extends Command8 {
14639
15105
  spawnSync("sleep", ["1"]);
14640
15106
  const dbUrl = `postgres://postgres:postgres@localhost:${pgPort}/codegen_dev`;
14641
15107
  const redisUrl = `redis://localhost:${redisPort}`;
14642
- const logFile = path29.join(ctx.cwd, ".dev-app.log");
14643
- const logFd = fs18.openSync(logFile, "a");
15108
+ const logFile = path31.join(ctx.cwd, ".dev-app.log");
15109
+ const logFd = fs20.openSync(logFile, "a");
14644
15110
  const child = spawn("bun", ["src/main.ts"], {
14645
15111
  cwd: ctx.cwd,
14646
15112
  detached: true,
@@ -14653,7 +15119,7 @@ var DevRestartCommand = class extends Command8 {
14653
15119
  }
14654
15120
  });
14655
15121
  child.unref();
14656
- fs18.closeSync(logFd);
15122
+ fs20.closeSync(logFd);
14657
15123
  if (child.pid) {
14658
15124
  writeAppPid(ctx.cwd, child.pid);
14659
15125
  spawnSync("sleep", ["2"]);
@@ -14768,11 +15234,11 @@ var devNoun = {
14768
15234
  var dev_default = devNoun;
14769
15235
 
14770
15236
  // src/cli/commands/relationship.ts
14771
- import fs19 from "fs";
14772
- import path30 from "path";
15237
+ import fs21 from "fs";
15238
+ import path32 from "path";
14773
15239
  import { Command as Command9, Option as Option9 } from "clipanion";
14774
15240
  function listRelationshipYamls2(dir) {
14775
- if (!fs19.existsSync(dir)) return [];
15241
+ if (!fs21.existsSync(dir)) return [];
14776
15242
  return findYamlFiles(dir).filter(
14777
15243
  (full) => detectYamlType(full) === "relationship"
14778
15244
  );
@@ -14796,7 +15262,7 @@ function padRight2(s, n) {
14796
15262
  return s.length >= n ? s : s + " ".repeat(n - s.length);
14797
15263
  }
14798
15264
  async function summary6(ctx) {
14799
- const relDir = path30.resolve(ctx.cwd, "relationships");
15265
+ const relDir = path32.resolve(ctx.cwd, "relationships");
14800
15266
  const files = listRelationshipYamls2(relDir);
14801
15267
  if (files.length === 0) {
14802
15268
  return {
@@ -14866,14 +15332,14 @@ var RelationshipNewCommand = class extends Command9 {
14866
15332
  }
14867
15333
  let targets = [];
14868
15334
  if (this.all) {
14869
- const dir = path30.resolve(ctx.cwd, "relationships");
15335
+ const dir = path32.resolve(ctx.cwd, "relationships");
14870
15336
  targets = listRelationshipYamls2(dir);
14871
15337
  if (targets.length === 0) {
14872
15338
  printError(`No relationship YAML files found in ${dir}`);
14873
15339
  return 1;
14874
15340
  }
14875
15341
  } else if (this.yaml) {
14876
- targets = [path30.resolve(ctx.cwd, this.yaml)];
15342
+ targets = [path32.resolve(ctx.cwd, this.yaml)];
14877
15343
  } else {
14878
15344
  printError("Missing YAML path. Pass a file or --all.");
14879
15345
  return 2;
@@ -14890,7 +15356,7 @@ var RelationshipNewCommand = class extends Command9 {
14890
15356
  }
14891
15357
  if (invalid.length > 0) {
14892
15358
  for (const i of invalid) {
14893
- printError(`${path30.basename(i.file)} \u2014 ${i.message}`);
15359
+ printError(`${path32.basename(i.file)} \u2014 ${i.message}`);
14894
15360
  }
14895
15361
  if (!isJsonMode()) return 1;
14896
15362
  }
@@ -14921,7 +15387,7 @@ var RelationshipNewCommand = class extends Command9 {
14921
15387
  }
14922
15388
  const succeeded = [];
14923
15389
  const failed = [
14924
- ...invalid.map((i) => ({ name: path30.basename(i.file), file: i.file, message: i.message }))
15390
+ ...invalid.map((i) => ({ name: path32.basename(i.file), file: i.file, message: i.message }))
14925
15391
  ];
14926
15392
  for (const v of validated) {
14927
15393
  if (!isJsonMode()) {
@@ -14940,8 +15406,8 @@ var RelationshipNewCommand = class extends Command9 {
14940
15406
  if (!isJsonMode()) printError(`${v.name} \u2014 ${res.stderr ?? "failed"}`);
14941
15407
  }
14942
15408
  }
14943
- const entitiesDir = ctx.entitiesDir ?? path30.resolve(ctx.cwd, "entities");
14944
- const relationshipsDir = path30.resolve(ctx.cwd, "relationships");
15409
+ const entitiesDir = ctx.entitiesDir ?? path32.resolve(ctx.cwd, "entities");
15410
+ const relationshipsDir = path32.resolve(ctx.cwd, "relationships");
14945
15411
  const generatedDir = resolveGeneratedDir(ctx);
14946
15412
  const architecture = resolveArchitecture(ctx);
14947
15413
  let barrelResult = null;
@@ -14986,7 +15452,7 @@ var RelationshipNewCommand = class extends Command9 {
14986
15452
  }
14987
15453
  if (barrelResult) {
14988
15454
  printInfo(
14989
- `barrels regenerated (${barrelResult.entityCount} modules) \u2192 ${path30.relative(ctx.cwd, barrelResult.modulesBarrel)}, ${path30.relative(ctx.cwd, barrelResult.schemaBarrel)}`
15455
+ `barrels regenerated (${barrelResult.entityCount} modules) \u2192 ${path32.relative(ctx.cwd, barrelResult.modulesBarrel)}, ${path32.relative(ctx.cwd, barrelResult.schemaBarrel)}`
14990
15456
  );
14991
15457
  }
14992
15458
  }
@@ -15009,7 +15475,7 @@ var RelationshipListCommand = class extends Command9 {
15009
15475
  json: this.json,
15010
15476
  skipDetection: true
15011
15477
  });
15012
- const relDir = path30.resolve(ctx.cwd, "relationships");
15478
+ const relDir = path32.resolve(ctx.cwd, "relationships");
15013
15479
  const files = listRelationshipYamls2(relDir);
15014
15480
  if (files.length === 0) {
15015
15481
  printInfo("No relationship definitions found.");
@@ -15049,7 +15515,7 @@ var relationshipNoun = {
15049
15515
  var relationship_default = relationshipNoun;
15050
15516
 
15051
15517
  // src/cli/commands/junction.ts
15052
- import path31 from "path";
15518
+ import path33 from "path";
15053
15519
  import { Command as Command10, Option as Option10 } from "clipanion";
15054
15520
  function summarizeJunctionFile(filePath) {
15055
15521
  const result = loadJunctionFromYaml(filePath);
@@ -15072,7 +15538,7 @@ function padRight3(s, n) {
15072
15538
  return s.length >= n ? s : s + " ".repeat(n - s.length);
15073
15539
  }
15074
15540
  async function summary7(ctx) {
15075
- const junctionDir = path31.resolve(ctx.cwd, "junctions");
15541
+ const junctionDir = path33.resolve(ctx.cwd, "junctions");
15076
15542
  const files = listJunctionYamls(junctionDir);
15077
15543
  if (files.length === 0) {
15078
15544
  return {
@@ -15142,14 +15608,14 @@ var JunctionNewCommand = class extends Command10 {
15142
15608
  }
15143
15609
  let targets = [];
15144
15610
  if (this.all) {
15145
- const dir = path31.resolve(ctx.cwd, "junctions");
15611
+ const dir = path33.resolve(ctx.cwd, "junctions");
15146
15612
  targets = listJunctionYamls(dir);
15147
15613
  if (targets.length === 0) {
15148
15614
  printError(`No junction YAML files found in ${dir}`);
15149
15615
  return 1;
15150
15616
  }
15151
15617
  } else if (this.yaml) {
15152
- targets = [path31.resolve(ctx.cwd, this.yaml)];
15618
+ targets = [path33.resolve(ctx.cwd, this.yaml)];
15153
15619
  } else {
15154
15620
  printError("Missing YAML path. Pass a file or --all.");
15155
15621
  return 2;
@@ -15168,7 +15634,7 @@ var JunctionNewCommand = class extends Command10 {
15168
15634
  }
15169
15635
  if (invalid.length > 0) {
15170
15636
  for (const i of invalid) {
15171
- printError(`${path31.basename(i.file)} \u2014 ${i.message}`);
15637
+ printError(`${path33.basename(i.file)} \u2014 ${i.message}`);
15172
15638
  }
15173
15639
  if (!isJsonMode()) return 1;
15174
15640
  }
@@ -15199,7 +15665,7 @@ var JunctionNewCommand = class extends Command10 {
15199
15665
  }
15200
15666
  const succeeded = [];
15201
15667
  const failed = [
15202
- ...invalid.map((i) => ({ name: path31.basename(i.file), file: i.file, message: i.message }))
15668
+ ...invalid.map((i) => ({ name: path33.basename(i.file), file: i.file, message: i.message }))
15203
15669
  ];
15204
15670
  for (const v of validated) {
15205
15671
  if (!isJsonMode()) {
@@ -15218,9 +15684,9 @@ var JunctionNewCommand = class extends Command10 {
15218
15684
  if (!isJsonMode()) printError(`${v.name} \u2014 ${res.stderr ?? "failed"}`);
15219
15685
  }
15220
15686
  }
15221
- const entitiesDir = ctx.entitiesDir ?? path31.resolve(ctx.cwd, "entities");
15222
- const relationshipsDir = path31.resolve(ctx.cwd, "relationships");
15223
- const junctionsDir = path31.resolve(ctx.cwd, "junctions");
15687
+ const entitiesDir = ctx.entitiesDir ?? path33.resolve(ctx.cwd, "entities");
15688
+ const relationshipsDir = path33.resolve(ctx.cwd, "relationships");
15689
+ const junctionsDir = path33.resolve(ctx.cwd, "junctions");
15224
15690
  const generatedDir = resolveGeneratedDir(ctx);
15225
15691
  const architecture = resolveArchitecture(ctx);
15226
15692
  let barrelResult = null;
@@ -15266,7 +15732,7 @@ var JunctionNewCommand = class extends Command10 {
15266
15732
  }
15267
15733
  if (barrelResult) {
15268
15734
  printInfo(
15269
- `barrels regenerated (${barrelResult.entityCount} modules) \u2192 ${path31.relative(ctx.cwd, barrelResult.modulesBarrel)}, ${path31.relative(ctx.cwd, barrelResult.schemaBarrel)}`
15735
+ `barrels regenerated (${barrelResult.entityCount} modules) \u2192 ${path33.relative(ctx.cwd, barrelResult.modulesBarrel)}, ${path33.relative(ctx.cwd, barrelResult.schemaBarrel)}`
15270
15736
  );
15271
15737
  }
15272
15738
  }
@@ -15289,7 +15755,7 @@ var JunctionListCommand = class extends Command10 {
15289
15755
  json: this.json,
15290
15756
  skipDetection: true
15291
15757
  });
15292
- const junctionDir = path31.resolve(ctx.cwd, "junctions");
15758
+ const junctionDir = path33.resolve(ctx.cwd, "junctions");
15293
15759
  const files = listJunctionYamls(junctionDir);
15294
15760
  if (files.length === 0) {
15295
15761
  printInfo("No junction definitions found.");
@@ -15329,8 +15795,8 @@ var junctionNoun = {
15329
15795
  var junction_default = junctionNoun;
15330
15796
 
15331
15797
  // src/cli/commands/events.ts
15332
- import fs20 from "fs";
15333
- import path32 from "path";
15798
+ import fs22 from "fs";
15799
+ import path34 from "path";
15334
15800
  import ts3 from "typescript";
15335
15801
  import { Command as Command11, Option as Option11 } from "clipanion";
15336
15802
  function scanSourceFileForConsumers(sourceFile, filePath, eventType) {
@@ -15429,7 +15895,7 @@ function scanDirectoryForConsumers(rootDir, eventType) {
15429
15895
  const tier1 = [];
15430
15896
  let hasEventFlowImport = false;
15431
15897
  for (const filePath of files) {
15432
- const text2 = fs20.readFileSync(filePath, "utf8");
15898
+ const text2 = fs22.readFileSync(filePath, "utf8");
15433
15899
  const sourceFile = ts3.createSourceFile(
15434
15900
  filePath,
15435
15901
  text2,
@@ -15466,7 +15932,7 @@ function suggestEventTypes(target, known, limit = 3) {
15466
15932
  return known.map((t) => ({ t, d: levenshtein(target, t) })).sort((a, b) => a.d - b.d).slice(0, limit).map((x) => x.t);
15467
15933
  }
15468
15934
  function renderConsumerReport(result, cwd) {
15469
- const rel2 = (p) => path32.relative(cwd, p) || p;
15935
+ const rel2 = (p) => path34.relative(cwd, p) || p;
15470
15936
  const lines = [];
15471
15937
  const total = result.tier3.length + result.tier2.length + result.tier1.length;
15472
15938
  lines.push(`Event: ${result.eventType}`);
@@ -15502,7 +15968,7 @@ function renderConsumerReport(result, cwd) {
15502
15968
  return lines;
15503
15969
  }
15504
15970
  function runConsumersScan(opts) {
15505
- const scanRoot = opts.scanRoot ?? path32.join(opts.cwd, "src");
15971
+ const scanRoot = opts.scanRoot ?? path34.join(opts.cwd, "src");
15506
15972
  const handlersDir = opts.handlersDir ?? scanRoot;
15507
15973
  const allTriggers = scanHandlerFiles(handlersDir);
15508
15974
  const tier3 = allTriggers.filter((t) => t.event === opts.eventType).map((t) => ({
@@ -15511,8 +15977,8 @@ function runConsumersScan(opts) {
15511
15977
  sourceFile: t.sourceFile,
15512
15978
  sourceLine: t.sourceLine
15513
15979
  }));
15514
- const tier21 = fs20.existsSync(scanRoot) ? scanDirectoryForConsumers(scanRoot, opts.eventType) : { tier2: [], tier1: [], hasEventFlowImport: false };
15515
- const eventsGeneratedDir = opts.eventsGeneratedDir ?? path32.join(
15980
+ const tier21 = fs22.existsSync(scanRoot) ? scanDirectoryForConsumers(scanRoot, opts.eventType) : { tier2: [], tier1: [], hasEventFlowImport: false };
15981
+ const eventsGeneratedDir = opts.eventsGeneratedDir ?? path34.join(
15516
15982
  resolveSubsystemsRootFromContext(opts.cwd, opts.config),
15517
15983
  "events",
15518
15984
  "generated"
@@ -15533,11 +15999,11 @@ function runConsumersScan(opts) {
15533
15999
  function resolveSubsystemsRootFromContext(cwd, config) {
15534
16000
  const configured = config?.paths?.subsystems;
15535
16001
  if (typeof configured === "string" && configured.length > 0) {
15536
- return path32.resolve(cwd, configured);
16002
+ return path34.resolve(cwd, configured);
15537
16003
  }
15538
16004
  const backendSrc = config?.paths?.backend_src;
15539
16005
  const base = typeof backendSrc === "string" && backendSrc.length > 0 ? backendSrc : "src";
15540
- return path32.resolve(cwd, base, "shared", "subsystems");
16006
+ return path34.resolve(cwd, base, "shared", "subsystems");
15541
16007
  }
15542
16008
  var EventsConsumersCommand = class extends Command11 {
15543
16009
  static paths = [["events", "consumers"]];
@@ -15626,7 +16092,7 @@ var eventsNoun = {
15626
16092
  var events_default = eventsNoun;
15627
16093
 
15628
16094
  // src/cli/commands/orchestration.ts
15629
- import path33 from "path";
16095
+ import path35 from "path";
15630
16096
  import { Command as Command12, Option as Option12 } from "clipanion";
15631
16097
  var DEFAULT_PATTERN_GLOBS = ["src/patterns/*.pattern.ts"];
15632
16098
  function resolvePatternGlobs(ctx) {
@@ -15640,10 +16106,10 @@ function resolveOrchestrationOutputRoot(ctx) {
15640
16106
  const paths = ctx.config?.paths;
15641
16107
  const explicit = paths?.orchestration_src;
15642
16108
  if (typeof explicit === "string" && explicit.length > 0) {
15643
- return path33.resolve(ctx.cwd, explicit);
16109
+ return path35.resolve(ctx.cwd, explicit);
15644
16110
  }
15645
16111
  const backendSrc = typeof paths?.backend_src === "string" && paths.backend_src.length > 0 ? paths.backend_src : "app/backend/src";
15646
- return path33.resolve(ctx.cwd, backendSrc, "orchestration");
16112
+ return path35.resolve(ctx.cwd, backendSrc, "orchestration");
15647
16113
  }
15648
16114
  async function reloadRegistry(ctx) {
15649
16115
  _resetRegistryForTests({ includeLibrary: false });
@@ -15732,12 +16198,12 @@ var OrchestrationGenCommand = class extends Command12 {
15732
16198
  );
15733
16199
  for (const f of result.files) {
15734
16200
  console.log(
15735
- ` ${theme.muted(icons.arrow)} ${path33.relative(ctx.cwd, f.outputPath)}`
16201
+ ` ${theme.muted(icons.arrow)} ${path35.relative(ctx.cwd, f.outputPath)}`
15736
16202
  );
15737
16203
  }
15738
16204
  } else {
15739
16205
  printSuccess(
15740
- `Emitted ${result.files.length} file(s) across ${targets.length} pattern(s) \u2192 ${path33.relative(ctx.cwd, outputRoot)}`
16206
+ `Emitted ${result.files.length} file(s) across ${targets.length} pattern(s) \u2192 ${path35.relative(ctx.cwd, outputRoot)}`
15741
16207
  );
15742
16208
  }
15743
16209
  return 0;