@pattern-stack/codegen 0.14.0 → 0.14.2

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 (33) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/dist/runtime/subsystems/bridge/bridge-delivery.memory-backend.d.ts +1 -1
  3. package/dist/runtime/subsystems/bridge/bridge-delivery.memory-backend.js +2 -2
  4. package/dist/runtime/subsystems/bridge/bridge-delivery.memory-backend.js.map +1 -1
  5. package/dist/runtime/subsystems/bridge/bridge.module.d.ts +22 -0
  6. package/dist/runtime/subsystems/bridge/bridge.module.js +177 -160
  7. package/dist/runtime/subsystems/bridge/bridge.module.js.map +1 -1
  8. package/dist/runtime/subsystems/bridge/index.js +159 -142
  9. package/dist/runtime/subsystems/bridge/index.js.map +1 -1
  10. package/dist/runtime/subsystems/index.js +161 -148
  11. package/dist/runtime/subsystems/index.js.map +1 -1
  12. package/dist/runtime/subsystems/jobs/index.js +128 -115
  13. package/dist/runtime/subsystems/jobs/index.js.map +1 -1
  14. package/dist/runtime/subsystems/jobs/job-orchestrator.memory-backend.js +128 -6
  15. package/dist/runtime/subsystems/jobs/job-orchestrator.memory-backend.js.map +1 -1
  16. package/dist/runtime/subsystems/jobs/job-run-service.memory-backend.js +17 -0
  17. package/dist/runtime/subsystems/jobs/job-run-service.memory-backend.js.map +1 -1
  18. package/dist/runtime/subsystems/jobs/job-step-service.memory-backend.js +25 -2
  19. package/dist/runtime/subsystems/jobs/job-step-service.memory-backend.js.map +1 -1
  20. package/dist/runtime/subsystems/jobs/job-worker.module.d.ts +26 -1
  21. package/dist/runtime/subsystems/jobs/job-worker.module.js +150 -137
  22. package/dist/runtime/subsystems/jobs/job-worker.module.js.map +1 -1
  23. package/dist/runtime/subsystems/jobs/jobs-domain.module.js +133 -124
  24. package/dist/runtime/subsystems/jobs/jobs-domain.module.js.map +1 -1
  25. package/dist/src/cli/index.js +1040 -635
  26. package/dist/src/cli/index.js.map +1 -1
  27. package/package.json +1 -1
  28. package/runtime/subsystems/bridge/bridge-delivery.memory-backend.ts +8 -1
  29. package/runtime/subsystems/bridge/bridge.module.ts +26 -1
  30. package/runtime/subsystems/jobs/job-orchestrator.memory-backend.ts +8 -3
  31. package/runtime/subsystems/jobs/job-run-service.memory-backend.ts +4 -1
  32. package/runtime/subsystems/jobs/job-step-service.memory-backend.ts +7 -2
  33. package/runtime/subsystems/jobs/job-worker.module.ts +13 -1
@@ -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
 
@@ -6273,12 +6273,30 @@ async function generateScopeEntityType(opts) {
6273
6273
  }
6274
6274
 
6275
6275
  // src/cli/shared/subsystem-barrel-generator.ts
6276
- import fs5 from "fs";
6277
- import path8 from "path";
6276
+ import fs6 from "fs";
6277
+ import path9 from "path";
6278
6278
 
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";
@@ -6493,172 +6541,16 @@ function resolveSubsystemsRoot(ctx, overrideTarget) {
6493
6541
  return resolveSubsystemsRootFromConfig(ctx.cwd, ctx.config);
6494
6542
  }
6495
6543
 
6496
- // src/cli/shared/subsystem-barrel-generator.ts
6497
- function quoteOpts(opts) {
6498
- const entries = Object.entries(opts).filter(([, v]) => v !== void 0);
6499
- if (entries.length === 0) return "";
6500
- return "{ " + entries.map(([k, v]) => `${k}: ${typeof v === "string" ? `'${v}'` : String(v)}`).join(", ") + " }";
6501
- }
6502
- function jsonToTs(value) {
6503
- if (value === null || value === void 0) return "undefined";
6504
- if (typeof value === "string") return `'${value.replace(/'/g, "\\'")}'`;
6505
- if (typeof value === "number" || typeof value === "boolean") return String(value);
6506
- if (Array.isArray(value)) return `[${value.map(jsonToTs).join(", ")}]`;
6507
- if (typeof value === "object") {
6508
- const entries = Object.entries(value).filter(
6509
- ([, v]) => v !== void 0
6510
- );
6511
- return `{ ${entries.map(([k, v]) => `${k}: ${jsonToTs(v)}`).join(", ")} }`;
6512
- }
6513
- return "undefined";
6514
- }
6515
- function quoteBullmqDomainOpts(input) {
6516
- const { backend, multiTenant, bullExt } = input;
6517
- if (backend !== "bullmq" || !bullExt) {
6518
- return quoteOpts({ backend, multiTenant });
6519
- }
6520
- const parts = [`backend: 'bullmq'`];
6521
- if (multiTenant) parts.push(`multiTenant: true`);
6522
- parts.push(`extensions: { bullmq: ${jsonToTs(bullExt)} }`);
6523
- return `{ ${parts.join(", ")} }`;
6524
- }
6525
- var COMPOSERS = {
6526
- events: ({ subsystemsRel, cfg }) => {
6527
- const backend = cfg?.backend ?? "drizzle";
6528
- const multiTenant = Boolean(cfg?.multi_tenant);
6529
- return {
6530
- imports: [
6531
- `import { EventsModule } from '${subsystemsRel}/events/events.module';`
6532
- ],
6533
- calls: [
6534
- ` EventsModule.forRoot(${quoteOpts({ backend, multiTenant })}),`
6535
- ]
6536
- };
6537
- },
6538
- jobs: ({ subsystemsRel, cfg }) => {
6539
- const backend = cfg?.backend ?? "drizzle";
6540
- const multiTenant = Boolean(cfg?.multi_tenant);
6541
- const workerMode = (cfg?.worker_mode ?? "standalone").trim();
6542
- const imports = [
6543
- `import { JobsDomainModule } from '${subsystemsRel}/jobs/jobs-domain.module';`
6544
- ];
6545
- const bullExt = backend === "bullmq" ? cfg?.extensions?.bullmq : void 0;
6546
- const domainOpts = quoteBullmqDomainOpts({ backend, multiTenant, bullExt });
6547
- const calls = [` JobsDomainModule.forRoot(${domainOpts}),`];
6548
- if (workerMode === "embedded") {
6549
- imports.push(
6550
- `import { JobWorkerModule } from '${subsystemsRel}/jobs/job-worker.module';`
6551
- );
6552
- const workerOpts = backend === "bullmq" ? `{ mode: 'embedded', backend: 'bullmq'${bullExt ? `, domainModuleExtensions: { bullmq: ${jsonToTs(bullExt)} }` : ""} }` : `{ mode: 'embedded' }`;
6553
- calls.push(` JobWorkerModule.forRoot(${workerOpts}),`);
6554
- }
6555
- return { imports, calls };
6556
- },
6557
- bridge: ({ subsystemsRel, cfg }) => {
6558
- const backend = cfg?.backend ?? "drizzle";
6559
- const multiTenant = Boolean(cfg?.multi_tenant);
6560
- return {
6561
- imports: [
6562
- `import { BridgeModule } from '${subsystemsRel}/bridge/bridge.module';`
6563
- ],
6564
- calls: [
6565
- ` BridgeModule.forRoot(${quoteOpts({ backend, multiTenant })}),`
6566
- ]
6567
- };
6568
- },
6569
- integration: ({ subsystemsRel, cfg }) => {
6570
- const backend = cfg?.backend ?? "drizzle";
6571
- const multiTenant = Boolean(cfg?.multi_tenant);
6572
- return {
6573
- imports: [
6574
- `import { IntegrationModule } from '${subsystemsRel}/integration/integration.module';`
6575
- ],
6576
- calls: [
6577
- ` IntegrationModule.forRoot(${quoteOpts({ backend, multiTenant })}),`
6578
- ]
6579
- };
6580
- }
6581
- };
6582
- var COMPOSABLE_ORDER = ["events", "jobs", "bridge", "integration"];
6583
- var HEADER3 = `// AUTO-GENERATED by @pattern-stack/codegen. DO NOT EDIT.
6584
- // Subsystem composition barrel \u2014 reflects \`subsystems.install\` in
6585
- // codegen.config.yaml and the per-subsystem option blocks
6586
- // (\`events:\`, \`jobs:\`, \`bridge:\`, \`integration:\`).
6587
- //
6588
- // Wire into AppModule once:
6589
- //
6590
- // import { SUBSYSTEM_MODULES } from './generated/subsystems';
6591
- // @Module({ imports: [DatabaseModule, ...SUBSYSTEM_MODULES, ...GENERATED_MODULES] })
6592
- //
6593
- // Regenerated by every \`codegen entity new\` / \`codegen subsystem install\`.
6594
-
6595
- `;
6596
- function buildSubsystemBarrel(installed, config, subsystemsRel) {
6597
- const actable = installed.filter((i) => i.status !== "incomplete");
6598
- const installedNames = new Set(actable.map((i) => i.name));
6599
- const emitted = [];
6600
- const skipped = [];
6601
- const allImports = [`import type { DynamicModule } from '@nestjs/common';`];
6602
- const allCalls = [];
6603
- for (const name of COMPOSABLE_ORDER) {
6604
- if (!installedNames.has(name)) continue;
6605
- const composer = COMPOSERS[name];
6606
- if (!composer) {
6607
- skipped.push(name);
6608
- continue;
6609
- }
6610
- const cfg = config?.[name] ?? void 0;
6611
- const out = composer({ subsystemsRel, cfg });
6612
- allImports.push(...out.imports);
6613
- allCalls.push(...out.calls);
6614
- emitted.push(name);
6615
- }
6616
- for (const inst of actable) {
6617
- if (!COMPOSABLE_ORDER.includes(inst.name) && !COMPOSERS[inst.name]) {
6618
- skipped.push(inst.name);
6619
- }
6620
- }
6621
- const exportLine = allCalls.length === 0 ? `export const SUBSYSTEM_MODULES: DynamicModule[] = [];
6622
- ` : `export const SUBSYSTEM_MODULES: DynamicModule[] = [
6623
- ${allCalls.join("\n")}
6624
- ];
6625
- `;
6626
- const body = allImports.join("\n") + "\n\n" + exportLine;
6627
- return { content: HEADER3 + body, emitted, skipped };
6628
- }
6629
- async function regenerateSubsystemBarrel(opts) {
6630
- const { ctx, dryRun = false } = opts;
6631
- const generatedDir = opts.generatedDir ?? resolveGeneratedDir(ctx);
6632
- const installed = await detectInstalledSubsystems(ctx);
6633
- const subsystemsAbs = resolveSubsystemsRoot(ctx);
6634
- const barrelAbs = path8.resolve(generatedDir, "subsystems.ts");
6635
- let subsystemsRel = path8.relative(path8.dirname(barrelAbs), subsystemsAbs).split(path8.sep).join("/");
6636
- if (!subsystemsRel.startsWith(".")) subsystemsRel = "./" + subsystemsRel;
6637
- const { content, emitted, skipped } = buildSubsystemBarrel(
6638
- installed,
6639
- ctx.config,
6640
- subsystemsRel
6641
- );
6642
- let written = false;
6643
- if (!dryRun) {
6644
- fs5.mkdirSync(path8.dirname(barrelAbs), { recursive: true });
6645
- fs5.writeFileSync(barrelAbs, content);
6646
- written = true;
6647
- }
6648
- return {
6649
- subsystemBarrel: barrelAbs,
6650
- emitted,
6651
- skipped,
6652
- content,
6653
- written
6654
- };
6655
- }
6656
-
6657
6544
  // src/cli/shared/bridge-registry-generator.ts
6658
- import fs6 from "fs";
6659
- import path9 from "path";
6545
+ import fs5 from "fs";
6546
+ import path8 from "path";
6660
6547
  import ts2 from "typescript";
6661
- var HEADER4 = `// AUTO-GENERATED by @pattern-stack/codegen. Do not edit.
6548
+ var PACKAGE_BRIDGE_TYPE_IMPORT = "@pattern-stack/codegen/runtime/subsystems/bridge/index";
6549
+ var OUTPUT_FILE_BY_MODE = {
6550
+ vendored: "registry.ts",
6551
+ package: "bridge-registry.ts"
6552
+ };
6553
+ var HEADER3 = `// AUTO-GENERATED by @pattern-stack/codegen. Do not edit.
6662
6554
  // Run \`codegen entity new --all\` to refresh.
6663
6555
  `;
6664
6556
  var DuplicateTriggerError = class extends Error {
@@ -6716,12 +6608,12 @@ var UnknownTriggerEventError = class extends Error {
6716
6608
  name = "UnknownTriggerEventError";
6717
6609
  };
6718
6610
  function findHandlerFiles(dir) {
6719
- if (!fs6.existsSync(dir)) return [];
6611
+ if (!fs5.existsSync(dir)) return [];
6720
6612
  const out = [];
6721
- for (const entry of fs6.readdirSync(dir, { withFileTypes: true })) {
6613
+ for (const entry of fs5.readdirSync(dir, { withFileTypes: true })) {
6722
6614
  if (entry.name.startsWith(".")) continue;
6723
6615
  if (entry.name === "node_modules" || entry.name === "generated") continue;
6724
- const full = path9.join(dir, entry.name);
6616
+ const full = path8.join(dir, entry.name);
6725
6617
  if (entry.isDirectory()) {
6726
6618
  out.push(...findHandlerFiles(full));
6727
6619
  } else if (entry.isFile() && entry.name.endsWith(".ts") && !entry.name.endsWith(".d.ts")) {
@@ -6784,7 +6676,7 @@ function scanHandlerFiles(handlersDir) {
6784
6676
  const files = findHandlerFiles(handlersDir);
6785
6677
  const out = [];
6786
6678
  for (const filePath of files) {
6787
- const text2 = fs6.readFileSync(filePath, "utf8");
6679
+ const text2 = fs5.readFileSync(filePath, "utf8");
6788
6680
  const sourceFile = ts2.createSourceFile(
6789
6681
  filePath,
6790
6682
  text2,
@@ -6799,9 +6691,9 @@ function scanHandlerFiles(handlersDir) {
6799
6691
  }
6800
6692
  function readKnownEventTypes(eventsGeneratedDir) {
6801
6693
  if (!eventsGeneratedDir) return [];
6802
- const registryPath = path9.join(eventsGeneratedDir, "registry.ts");
6803
- if (!fs6.existsSync(registryPath)) return [];
6804
- const text2 = fs6.readFileSync(registryPath, "utf8");
6694
+ const registryPath = path8.join(eventsGeneratedDir, "registry.ts");
6695
+ if (!fs5.existsSync(registryPath)) return [];
6696
+ const text2 = fs5.readFileSync(registryPath, "utf8");
6805
6697
  const out = /* @__PURE__ */ new Set();
6806
6698
  const re = /^\s*'([a-zA-Z0-9_.-]+)':\s*\{/gm;
6807
6699
  let m;
@@ -6813,9 +6705,9 @@ function readKnownEventTypes(eventsGeneratedDir) {
6813
6705
  function readEventTiers(eventsGeneratedDir) {
6814
6706
  const out = /* @__PURE__ */ new Map();
6815
6707
  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");
6708
+ const registryPath = path8.join(eventsGeneratedDir, "registry.ts");
6709
+ if (!fs5.existsSync(registryPath)) return out;
6710
+ const text2 = fs5.readFileSync(registryPath, "utf8");
6819
6711
  const re = /'([a-zA-Z0-9_.-]+)':\s*\{[^}]*?tier:\s*'(domain|audit)'/g;
6820
6712
  let m;
6821
6713
  while ((m = re.exec(text2)) !== null) {
@@ -6870,11 +6762,11 @@ function validateAgainstEventRegistry(triggers, knownEventTypes) {
6870
6762
  }
6871
6763
  }
6872
6764
  }
6873
- function buildBridgeRegistryContent(triggers) {
6765
+ function buildBridgeRegistryContent(triggers, typeImport = "../bridge.protocol") {
6874
6766
  const chunks = [];
6875
- chunks.push(HEADER4);
6767
+ chunks.push(HEADER3);
6876
6768
  chunks.push("");
6877
- chunks.push(`import type { BridgeRegistry } from '../bridge.protocol';`);
6769
+ chunks.push(`import type { BridgeRegistry } from '${typeImport}';`);
6878
6770
  chunks.push("");
6879
6771
  if (triggers.length === 0) {
6880
6772
  chunks.push(`export const bridgeRegistry: BridgeRegistry = {};`);
@@ -6907,14 +6799,22 @@ function buildBridgeRegistryContent(triggers) {
6907
6799
  chunks.push("");
6908
6800
  return chunks.join("\n");
6909
6801
  }
6910
- var OUTPUT_FILE_NAME = "registry.ts";
6911
6802
  async function generateBridgeRegistry(opts) {
6912
- 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);
6803
+ const {
6804
+ handlersDir,
6805
+ eventsGeneratedDir,
6806
+ outputDir,
6807
+ mode = "vendored",
6808
+ bridgeInstalled = false,
6809
+ dryRun = false
6810
+ } = opts;
6811
+ const outputFileName = OUTPUT_FILE_BY_MODE[mode];
6812
+ const typeImport = mode === "package" ? PACKAGE_BRIDGE_TYPE_IMPORT : "../bridge.protocol";
6813
+ const installed = mode === "package" ? bridgeInstalled : fs5.existsSync(path8.resolve(outputDir, "..", "bridge.protocol.ts"));
6814
+ if (!installed) {
6815
+ const strayPath = path8.join(outputDir, outputFileName);
6816
+ if (!dryRun && fs5.existsSync(strayPath)) {
6817
+ fs5.rmSync(strayPath);
6918
6818
  }
6919
6819
  return {
6920
6820
  outputDir,
@@ -6926,39 +6826,340 @@ async function generateBridgeRegistry(opts) {
6926
6826
  skipped: true
6927
6827
  };
6928
6828
  }
6929
- const triggers = scanHandlerFiles(handlersDir);
6930
- validateNoDuplicateTriggers(triggers);
6931
- const knownEventTypes = readKnownEventTypes(eventsGeneratedDir);
6932
- validateAgainstEventRegistry(triggers, knownEventTypes);
6933
- const eventTiers = readEventTiers(eventsGeneratedDir);
6934
- validateNoAuditTriggers(triggers, eventTiers);
6935
- const content = buildBridgeRegistryContent(triggers);
6936
- const file = {
6937
- name: OUTPUT_FILE_NAME,
6938
- outputPath: path9.join(outputDir, OUTPUT_FILE_NAME),
6939
- content
6940
- };
6829
+ const triggers = scanHandlerFiles(handlersDir);
6830
+ validateNoDuplicateTriggers(triggers);
6831
+ const knownEventTypes = readKnownEventTypes(eventsGeneratedDir);
6832
+ validateAgainstEventRegistry(triggers, knownEventTypes);
6833
+ const eventTiers = readEventTiers(eventsGeneratedDir);
6834
+ validateNoAuditTriggers(triggers, eventTiers);
6835
+ const content = buildBridgeRegistryContent(triggers, typeImport);
6836
+ const file = {
6837
+ name: outputFileName,
6838
+ outputPath: path8.join(outputDir, outputFileName),
6839
+ content
6840
+ };
6841
+ let written = false;
6842
+ if (!dryRun) {
6843
+ fs5.mkdirSync(outputDir, { recursive: true });
6844
+ fs5.writeFileSync(file.outputPath, file.content);
6845
+ written = true;
6846
+ }
6847
+ const eventTypeCount = new Set(triggers.map((t) => t.event)).size;
6848
+ return {
6849
+ outputDir,
6850
+ triggerCount: triggers.length,
6851
+ triggers,
6852
+ eventTypeCount,
6853
+ written,
6854
+ files: [file],
6855
+ skipped: false
6856
+ };
6857
+ }
6858
+
6859
+ // src/cli/shared/subsystem-barrel-generator.ts
6860
+ function quoteOpts(opts) {
6861
+ const entries = Object.entries(opts).filter(([, v]) => v !== void 0);
6862
+ if (entries.length === 0) return "";
6863
+ return "{ " + entries.map(([k, v]) => `${k}: ${typeof v === "string" ? `'${v}'` : String(v)}`).join(", ") + " }";
6864
+ }
6865
+ function jsonToTs(value) {
6866
+ if (value === null || value === void 0) return "undefined";
6867
+ if (typeof value === "string") return `'${value.replace(/'/g, "\\'")}'`;
6868
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
6869
+ if (Array.isArray(value)) return `[${value.map(jsonToTs).join(", ")}]`;
6870
+ if (typeof value === "object") {
6871
+ const entries = Object.entries(value).filter(
6872
+ ([, v]) => v !== void 0
6873
+ );
6874
+ return `{ ${entries.map(([k, v]) => `${k}: ${jsonToTs(v)}`).join(", ")} }`;
6875
+ }
6876
+ return "undefined";
6877
+ }
6878
+ function quoteBullmqDomainOpts(input) {
6879
+ const { backend, multiTenant, bullExt } = input;
6880
+ if (backend !== "bullmq" || !bullExt) {
6881
+ return quoteOpts({ backend, multiTenant });
6882
+ }
6883
+ const parts = [`backend: 'bullmq'`];
6884
+ if (multiTenant) parts.push(`multiTenant: true`);
6885
+ parts.push(`extensions: { bullmq: ${jsonToTs(bullExt)} }`);
6886
+ return `{ ${parts.join(", ")} }`;
6887
+ }
6888
+ function workerPoolsClause(cfg, bridgeInstalled) {
6889
+ const explicit = cfg?.worker_pools;
6890
+ if (Array.isArray(explicit) && explicit.length > 0) {
6891
+ const list = explicit.filter((p) => typeof p === "string").map((p) => `'${p}'`).join(", ");
6892
+ if (list.length > 0) return `pools: [${list}]`;
6893
+ }
6894
+ if (cfg?.all_pools === true) return "allPools: true";
6895
+ if (bridgeInstalled) return "allPools: true";
6896
+ return "";
6897
+ }
6898
+ var COMPOSERS = {
6899
+ events: ({ moduleImport, cfg }) => {
6900
+ const backend = cfg?.backend ?? "drizzle";
6901
+ const multiTenant = Boolean(cfg?.multi_tenant);
6902
+ return {
6903
+ imports: [
6904
+ `import { EventsModule } from '${moduleImport("events", "events.module")}';`
6905
+ ],
6906
+ calls: [
6907
+ ` EventsModule.forRoot(${quoteOpts({ backend, multiTenant })}),`
6908
+ ]
6909
+ };
6910
+ },
6911
+ jobs: ({ moduleImport, cfg, bridgeInstalled }) => {
6912
+ const backend = cfg?.backend ?? "drizzle";
6913
+ const multiTenant = Boolean(cfg?.multi_tenant);
6914
+ const workerMode = (cfg?.worker_mode ?? "standalone").trim();
6915
+ const imports = [
6916
+ `import { JobsDomainModule } from '${moduleImport("jobs", "jobs-domain.module")}';`
6917
+ ];
6918
+ const bullExt = backend === "bullmq" ? cfg?.extensions?.bullmq : void 0;
6919
+ const domainOpts = quoteBullmqDomainOpts({ backend, multiTenant, bullExt });
6920
+ const calls = [` JobsDomainModule.forRoot(${domainOpts}),`];
6921
+ if (workerMode === "embedded") {
6922
+ imports.push(
6923
+ `import { JobWorkerModule } from '${moduleImport("jobs", "job-worker.module")}';`
6924
+ );
6925
+ const parts = [`mode: 'embedded'`];
6926
+ if (backend === "bullmq") {
6927
+ parts.push(`backend: 'bullmq'`);
6928
+ if (bullExt) {
6929
+ parts.push(`domainModuleExtensions: { bullmq: ${jsonToTs(bullExt)} }`);
6930
+ }
6931
+ }
6932
+ const poolsClause = workerPoolsClause(cfg, bridgeInstalled);
6933
+ if (poolsClause) parts.push(poolsClause);
6934
+ calls.push(` JobWorkerModule.forRoot({ ${parts.join(", ")} }),`);
6935
+ }
6936
+ return { imports, calls };
6937
+ },
6938
+ bridge: ({ moduleImport, cfg, mode }) => {
6939
+ const backend = cfg?.backend ?? "drizzle";
6940
+ const multiTenant = Boolean(cfg?.multi_tenant);
6941
+ const imports = [
6942
+ `import { BridgeModule } from '${moduleImport("bridge", "bridge.module")}';`
6943
+ ];
6944
+ if (mode === "package") {
6945
+ imports.push(`import { bridgeRegistry } from './bridge-registry';`);
6946
+ return {
6947
+ imports,
6948
+ calls: [
6949
+ ` BridgeModule.forRoot({ backend: '${backend}', multiTenant: ${multiTenant}, registry: bridgeRegistry }),`
6950
+ ]
6951
+ };
6952
+ }
6953
+ return {
6954
+ imports,
6955
+ calls: [
6956
+ ` BridgeModule.forRoot(${quoteOpts({ backend, multiTenant })}),`
6957
+ ]
6958
+ };
6959
+ },
6960
+ integration: ({ moduleImport, cfg }) => {
6961
+ const backend = cfg?.backend ?? "drizzle";
6962
+ const multiTenant = Boolean(cfg?.multi_tenant);
6963
+ return {
6964
+ imports: [
6965
+ `import { IntegrationModule } from '${moduleImport("integration", "integration.module")}';`
6966
+ ],
6967
+ calls: [
6968
+ ` IntegrationModule.forRoot(${quoteOpts({ backend, multiTenant })}),`
6969
+ ]
6970
+ };
6971
+ }
6972
+ };
6973
+ var PACKAGE2 = "@pattern-stack/codegen";
6974
+ function makeModuleImport(mode, subsystemsRel) {
6975
+ if (mode === "vendored") {
6976
+ return (subsystem, moduleBasename) => `${subsystemsRel}/${subsystem}/${moduleBasename}`;
6977
+ }
6978
+ return (subsystem) => subsystem === "events" ? `${PACKAGE2}/subsystems` : `${PACKAGE2}/runtime/subsystems/${subsystem}/index`;
6979
+ }
6980
+ var COMPOSABLE_ORDER = ["events", "jobs", "bridge", "integration"];
6981
+ var HEADER4 = `// AUTO-GENERATED by @pattern-stack/codegen. DO NOT EDIT.
6982
+ // Subsystem composition barrel \u2014 reflects \`subsystems.install\` in
6983
+ // codegen.config.yaml and the per-subsystem option blocks
6984
+ // (\`events:\`, \`jobs:\`, \`bridge:\`, \`integration:\`).
6985
+ //
6986
+ // Wire into AppModule once:
6987
+ //
6988
+ // import { SUBSYSTEM_MODULES } from './generated/subsystems';
6989
+ // @Module({ imports: [DatabaseModule, ...SUBSYSTEM_MODULES, ...GENERATED_MODULES] })
6990
+ //
6991
+ // Regenerated by every \`codegen entity new\` / \`codegen subsystem install\`.
6992
+
6993
+ `;
6994
+ function buildSubsystemBarrel(installed, config, subsystemsRel, mode = "vendored") {
6995
+ const moduleImport = makeModuleImport(mode, subsystemsRel);
6996
+ const actable = installed.filter((i) => i.status !== "incomplete");
6997
+ const installedNames = new Set(actable.map((i) => i.name));
6998
+ const bridgeInstalled = installedNames.has("bridge");
6999
+ const emitted = [];
7000
+ const skipped = [];
7001
+ const allImports = [`import type { DynamicModule } from '@nestjs/common';`];
7002
+ const allCalls = [];
7003
+ for (const name of COMPOSABLE_ORDER) {
7004
+ if (!installedNames.has(name)) continue;
7005
+ const composer = COMPOSERS[name];
7006
+ if (!composer) {
7007
+ skipped.push(name);
7008
+ continue;
7009
+ }
7010
+ const cfg = config?.[name] ?? void 0;
7011
+ const out = composer({ moduleImport, cfg, mode, bridgeInstalled });
7012
+ allImports.push(...out.imports);
7013
+ allCalls.push(...out.calls);
7014
+ emitted.push(name);
7015
+ }
7016
+ for (const inst of actable) {
7017
+ if (!COMPOSABLE_ORDER.includes(inst.name) && !COMPOSERS[inst.name]) {
7018
+ skipped.push(inst.name);
7019
+ }
7020
+ }
7021
+ const exportLine = allCalls.length === 0 ? `export const SUBSYSTEM_MODULES: DynamicModule[] = [];
7022
+ ` : `export const SUBSYSTEM_MODULES: DynamicModule[] = [
7023
+ ${allCalls.join("\n")}
7024
+ ];
7025
+ `;
7026
+ const body = allImports.join("\n") + "\n\n" + exportLine;
7027
+ return { content: HEADER4 + body, emitted, skipped };
7028
+ }
7029
+ async function regenerateSubsystemBarrel(opts) {
7030
+ const { ctx, dryRun = false } = opts;
7031
+ const generatedDir = opts.generatedDir ?? resolveGeneratedDir(ctx);
7032
+ const mode = resolveRuntimeMode(ctx.config);
7033
+ const installed = mode === "package" ? configuredInstalledSubsystems(
7034
+ ctx.config
7035
+ ) : await detectInstalledSubsystems(ctx);
7036
+ const subsystemsAbs = resolveSubsystemsRoot(ctx);
7037
+ const barrelAbs = path9.resolve(generatedDir, "subsystems.ts");
7038
+ let subsystemsRel = path9.relative(path9.dirname(barrelAbs), subsystemsAbs).split(path9.sep).join("/");
7039
+ if (!subsystemsRel.startsWith(".")) subsystemsRel = "./" + subsystemsRel;
7040
+ const { content, emitted, skipped } = buildSubsystemBarrel(
7041
+ installed,
7042
+ ctx.config,
7043
+ subsystemsRel,
7044
+ mode
7045
+ );
7046
+ let written = false;
7047
+ if (!dryRun) {
7048
+ fs6.mkdirSync(path9.dirname(barrelAbs), { recursive: true });
7049
+ fs6.writeFileSync(barrelAbs, content);
7050
+ written = true;
7051
+ if (mode === "package" && emitted.includes("bridge")) {
7052
+ const registryPath = path9.resolve(generatedDir, "bridge-registry.ts");
7053
+ if (!fs6.existsSync(registryPath)) {
7054
+ fs6.writeFileSync(
7055
+ registryPath,
7056
+ buildBridgeRegistryContent([], PACKAGE_BRIDGE_TYPE_IMPORT)
7057
+ );
7058
+ }
7059
+ }
7060
+ }
7061
+ return {
7062
+ subsystemBarrel: barrelAbs,
7063
+ emitted,
7064
+ skipped,
7065
+ content,
7066
+ written
7067
+ };
7068
+ }
7069
+
7070
+ // src/cli/shared/subsystem-schema-generator.ts
7071
+ import fs7 from "fs";
7072
+ import path10 from "path";
7073
+ var PACKAGE3 = "@pattern-stack/codegen";
7074
+ var SCHEMA_SYMBOLS = {
7075
+ events: ["domainEvents"],
7076
+ jobs: [
7077
+ "jobs",
7078
+ "jobRuns",
7079
+ "jobSteps",
7080
+ "jobRunStatusEnum",
7081
+ "jobStepKindEnum",
7082
+ "jobStepStatusEnum",
7083
+ "collisionModeEnum",
7084
+ "replayFromEnum",
7085
+ "parentClosePolicyEnum",
7086
+ "waitKindEnum",
7087
+ "triggerSourceEnum"
7088
+ ],
7089
+ bridge: ["bridgeDelivery", "bridgeDeliveryStatusEnum"],
7090
+ integration: [
7091
+ "integrationSubscriptions",
7092
+ "integrationRuns",
7093
+ "integrationRunItems",
7094
+ "integrationRunDirectionEnum",
7095
+ "integrationRunActionEnum",
7096
+ "integrationRunStatusEnum",
7097
+ "integrationRunItemOperationEnum",
7098
+ "integrationRunItemStatusEnum"
7099
+ ]
7100
+ };
7101
+ var SCHEMA_ORDER = ["events", "jobs", "bridge", "integration"];
7102
+ var HEADER5 = `// AUTO-GENERATED by @pattern-stack/codegen. Do not edit.
7103
+ // Subsystem Drizzle schema barrel \u2014 re-exports the tables + pgEnums of every
7104
+ // installed subsystem so drizzle-kit emits their CREATE TABLE / CREATE TYPE.
7105
+ //
7106
+ // Fold into your drizzle-kit schema entrypoint once, alongside the entity
7107
+ // schema barrel:
7108
+ //
7109
+ // // src/schema.ts
7110
+ // export * from './generated/schema'; // entity tables
7111
+ // export * from './generated/subsystems-schema'; // subsystem tables + enums
7112
+ //
7113
+ // Regenerated by every \`codegen entity new\` / \`codegen subsystem install\`.
7114
+
7115
+ `;
7116
+ function schemaImportFor(mode, subsystem, subsystemsRel) {
7117
+ return mode === "vendored" ? `${subsystemsRel}/${subsystem}` : `${PACKAGE3}/runtime/subsystems/${subsystem}/index`;
7118
+ }
7119
+ function buildSubsystemSchemaBarrel(installed, subsystemsRel, mode) {
7120
+ const actable = installed.filter((i) => i.status !== "incomplete");
7121
+ const installedNames = new Set(actable.map((i) => i.name));
7122
+ const emitted = [];
7123
+ const lines = [];
7124
+ for (const name of SCHEMA_ORDER) {
7125
+ if (!installedNames.has(name)) continue;
7126
+ const symbols = SCHEMA_SYMBOLS[name];
7127
+ if (!symbols || symbols.length === 0) continue;
7128
+ const importSpec = schemaImportFor(mode, name, subsystemsRel);
7129
+ lines.push(`export { ${symbols.join(", ")} } from '${importSpec}';`);
7130
+ emitted.push(name);
7131
+ }
7132
+ const body = lines.length === 0 ? "export {};\n" : lines.join("\n") + "\n";
7133
+ return { content: HEADER5 + body, emitted };
7134
+ }
7135
+ async function regenerateSubsystemSchemaBarrel(opts) {
7136
+ const { ctx, dryRun = false } = opts;
7137
+ const generatedDir = opts.generatedDir ?? resolveGeneratedDir(ctx);
7138
+ const mode = resolveRuntimeMode(ctx.config);
7139
+ const installed = mode === "package" ? configuredInstalledSubsystems(
7140
+ ctx.config
7141
+ ) : await detectInstalledSubsystems(ctx);
7142
+ const subsystemsAbs = resolveSubsystemsRoot(ctx);
7143
+ const barrelAbs = path10.resolve(generatedDir, "subsystems-schema.ts");
7144
+ let subsystemsRel = path10.relative(path10.dirname(barrelAbs), subsystemsAbs).split(path10.sep).join("/");
7145
+ if (!subsystemsRel.startsWith(".")) subsystemsRel = "./" + subsystemsRel;
7146
+ const { content, emitted } = buildSubsystemSchemaBarrel(
7147
+ installed,
7148
+ subsystemsRel,
7149
+ mode
7150
+ );
6941
7151
  let written = false;
6942
7152
  if (!dryRun) {
6943
- fs6.mkdirSync(outputDir, { recursive: true });
6944
- fs6.writeFileSync(file.outputPath, file.content);
7153
+ fs7.mkdirSync(path10.dirname(barrelAbs), { recursive: true });
7154
+ fs7.writeFileSync(barrelAbs, content);
6945
7155
  written = true;
6946
7156
  }
6947
- const eventTypeCount = new Set(triggers.map((t) => t.event)).size;
6948
- return {
6949
- outputDir,
6950
- triggerCount: triggers.length,
6951
- triggers,
6952
- eventTypeCount,
6953
- written,
6954
- files: [file],
6955
- skipped: false
6956
- };
7157
+ return { schemaBarrel: barrelAbs, emitted, content, written };
6957
7158
  }
6958
7159
 
6959
7160
  // src/cli/shared/orchestration-generator.ts
6960
- import fs7 from "fs";
6961
- import path10 from "path";
7161
+ import fs8 from "fs";
7162
+ import path11 from "path";
6962
7163
  var OrchestrationEmissionError = class extends Error {
6963
7164
  constructor(issueType, patternName, message) {
6964
7165
  super(`[${issueType}] ${patternName}: ${message}`);
@@ -6969,7 +7170,7 @@ var OrchestrationEmissionError = class extends Error {
6969
7170
  patternName;
6970
7171
  name = "OrchestrationEmissionError";
6971
7172
  };
6972
- var HEADER5 = `// AUTO-GENERATED by @pattern-stack/codegen. Do not edit.
7173
+ var HEADER6 = `// AUTO-GENERATED by @pattern-stack/codegen. Do not edit.
6973
7174
  // See ADR-032 \u2014 Orchestration Patterns.
6974
7175
  `;
6975
7176
  function splitWords(str) {
@@ -7133,7 +7334,7 @@ function buildTokensTs(pattern) {
7133
7334
  typeImports.push({ specifier: reg.valueTypeImport, name: reg.valueType });
7134
7335
  }
7135
7336
  const lines = [];
7136
- lines.push(HEADER5.trimEnd());
7337
+ lines.push(HEADER6.trimEnd());
7137
7338
  lines.push("");
7138
7339
  for (const i of emitTypeImports(typeImports)) lines.push(i);
7139
7340
  lines.push("");
@@ -7166,7 +7367,7 @@ function buildProvidersTs(pattern) {
7166
7367
  }
7167
7368
  const optsType = forRootOptionsTypeName(pattern);
7168
7369
  const lines = [];
7169
- lines.push(HEADER5.trimEnd());
7370
+ lines.push(HEADER6.trimEnd());
7170
7371
  lines.push("");
7171
7372
  lines.push(`import type { Provider } from '@nestjs/common';`);
7172
7373
  for (const i of emitTypeImports(typeImports)) lines.push(i);
@@ -7233,7 +7434,7 @@ function buildDispatcherTs(pattern) {
7233
7434
  const tokenValues = registries.map(({ names: names2 }) => names2.tokenConst);
7234
7435
  const mapTypes = registries.map(({ names: names2 }) => names2.mapType);
7235
7436
  const lines = [];
7236
- lines.push(HEADER5.trimEnd());
7437
+ lines.push(HEADER6.trimEnd());
7237
7438
  lines.push("");
7238
7439
  lines.push(`import { Inject, Injectable } from '@nestjs/common';`);
7239
7440
  for (const i of emitTypeImports(typeImports)) lines.push(i);
@@ -7307,7 +7508,7 @@ function buildModuleTs(pattern) {
7307
7508
  }
7308
7509
  const tokenValues = registries.map(({ names: names2 }) => names2.tokenConst);
7309
7510
  const lines = [];
7310
- lines.push(HEADER5.trimEnd());
7511
+ lines.push(HEADER6.trimEnd());
7311
7512
  lines.push("");
7312
7513
  lines.push(`import { type DynamicModule, Module } from '@nestjs/common';`);
7313
7514
  for (const i of emitTypeImports(typeImports)) lines.push(i);
@@ -7341,7 +7542,7 @@ function buildModuleTs(pattern) {
7341
7542
  }
7342
7543
  function buildIndexTs(pattern) {
7343
7544
  const lines = [];
7344
- lines.push(HEADER5.trimEnd());
7545
+ lines.push(HEADER6.trimEnd());
7345
7546
  lines.push("");
7346
7547
  lines.push(`export * from './tokens.js';`);
7347
7548
  lines.push(`export * from './dispatcher.js';`);
@@ -7352,7 +7553,7 @@ function buildIndexTs(pattern) {
7352
7553
  }
7353
7554
  function buildRootBarrelTs(patterns) {
7354
7555
  const lines = [];
7355
- lines.push(HEADER5.trimEnd());
7556
+ lines.push(HEADER6.trimEnd());
7356
7557
  lines.push("");
7357
7558
  if (patterns.length === 0) {
7358
7559
  lines.push("// No orchestration patterns registered.");
@@ -7370,11 +7571,11 @@ function buildRootBarrelTs(patterns) {
7370
7571
  function buildPatternFiles(pattern, outputRoot) {
7371
7572
  assertEmittable(pattern);
7372
7573
  const slug = toKebabCase2(pattern.name);
7373
- const outputDir = path10.join(outputRoot, slug);
7574
+ const outputDir = path11.join(outputRoot, slug);
7374
7575
  const make = (name, content) => ({
7375
7576
  name,
7376
- outputPath: path10.join(outputDir, name),
7377
- relativePath: path10.join(slug, name),
7577
+ outputPath: path11.join(outputDir, name),
7578
+ relativePath: path11.join(slug, name),
7378
7579
  content
7379
7580
  });
7380
7581
  const files = [
@@ -7402,21 +7603,21 @@ function generateOrchestrationModules(opts) {
7402
7603
  }
7403
7604
  const rootBarrel = {
7404
7605
  name: "index.ts",
7405
- outputPath: path10.join(outputRoot, "index.ts"),
7606
+ outputPath: path11.join(outputRoot, "index.ts"),
7406
7607
  relativePath: "index.ts",
7407
7608
  content: buildRootBarrelTs(patterns)
7408
7609
  };
7409
7610
  allFiles.push(rootBarrel);
7410
7611
  let written = false;
7411
7612
  if (!dryRun && patterns.length > 0) {
7412
- fs7.mkdirSync(outputRoot, { recursive: true });
7613
+ fs8.mkdirSync(outputRoot, { recursive: true });
7413
7614
  for (const r of perPattern) {
7414
- fs7.mkdirSync(r.outputDir, { recursive: true });
7615
+ fs8.mkdirSync(r.outputDir, { recursive: true });
7415
7616
  for (const f of r.files) {
7416
- fs7.writeFileSync(f.outputPath, f.content);
7617
+ fs8.writeFileSync(f.outputPath, f.content);
7417
7618
  }
7418
7619
  }
7419
- fs7.writeFileSync(rootBarrel.outputPath, rootBarrel.content);
7620
+ fs8.writeFileSync(rootBarrel.outputPath, rootBarrel.content);
7420
7621
  written = true;
7421
7622
  }
7422
7623
  return {
@@ -7428,8 +7629,8 @@ function generateOrchestrationModules(opts) {
7428
7629
  }
7429
7630
 
7430
7631
  // src/cli/shared/event-codegen-generator.ts
7431
- import fs8 from "fs";
7432
- import path11 from "path";
7632
+ import fs9 from "fs";
7633
+ import path12 from "path";
7433
7634
 
7434
7635
  // src/parser/load-events.ts
7435
7636
  import { basename as basename2, resolve as resolve4 } from "path";
@@ -7559,7 +7760,7 @@ function isEventFieldType(s) {
7559
7760
  }
7560
7761
 
7561
7762
  // src/cli/shared/event-codegen-generator.ts
7562
- var HEADER6 = `// AUTO-GENERATED by @pattern-stack/codegen. Do not edit.
7763
+ var HEADER7 = `// AUTO-GENERATED by @pattern-stack/codegen. Do not edit.
7563
7764
  // Run \`codegen entity new --all\` to refresh.
7564
7765
  `;
7565
7766
  function toCamelCase2(input) {
@@ -7613,7 +7814,7 @@ function aggregateTypeLiteral(ev) {
7613
7814
  function collectEntityEvents(entitiesDir) {
7614
7815
  const events = [];
7615
7816
  const issues = [];
7616
- if (!fs8.existsSync(entitiesDir)) {
7817
+ if (!fs9.existsSync(entitiesDir)) {
7617
7818
  return { events, issues };
7618
7819
  }
7619
7820
  const files = findYamlFiles(entitiesDir);
@@ -7657,7 +7858,7 @@ function mergeEvents(topLevel, entitySugar) {
7657
7858
  function collectMergedEvents(opts) {
7658
7859
  const { entitiesDir, eventsDir } = opts;
7659
7860
  const entityNames = [];
7660
- if (fs8.existsSync(entitiesDir)) {
7861
+ if (fs9.existsSync(entitiesDir)) {
7661
7862
  const entityFiles = findYamlFiles(entitiesDir);
7662
7863
  for (const f of entityFiles) {
7663
7864
  const result = loadEntityFromYaml(f);
@@ -7680,7 +7881,7 @@ function collectMergedEvents(opts) {
7680
7881
  function buildTypesContent(events) {
7681
7882
  const sorted = [...events].sort((a, b) => a.type.localeCompare(b.type));
7682
7883
  if (sorted.length === 0) {
7683
- return HEADER6 + `
7884
+ return HEADER7 + `
7684
7885
  import type { DomainEvent } from '../event-bus.protocol';
7685
7886
 
7686
7887
  export type AppDomainEvent = never;
@@ -7691,7 +7892,7 @@ export type PayloadOfType<T extends EventTypeName> = DomainEvent['payload'];
7691
7892
  `;
7692
7893
  }
7693
7894
  const chunks = [];
7694
- chunks.push(HEADER6);
7895
+ chunks.push(HEADER7);
7695
7896
  chunks.push("");
7696
7897
  chunks.push(`import type { DomainEvent } from '../event-bus.protocol';`);
7697
7898
  chunks.push("");
@@ -7739,7 +7940,7 @@ export type PayloadOfType<T extends EventTypeName> = DomainEvent['payload'];
7739
7940
  function buildSchemasContent(events) {
7740
7941
  const sorted = [...events].sort((a, b) => a.type.localeCompare(b.type));
7741
7942
  if (sorted.length === 0) {
7742
- return HEADER6 + `
7943
+ return HEADER7 + `
7743
7944
  import { z } from 'zod';
7744
7945
  import type { EventTypeName } from './types';
7745
7946
 
@@ -7747,7 +7948,7 @@ export const eventPayloadSchemas = {} as Record<EventTypeName, z.ZodType>;
7747
7948
  `;
7748
7949
  }
7749
7950
  const chunks = [];
7750
- chunks.push(HEADER6);
7951
+ chunks.push(HEADER7);
7751
7952
  chunks.push("");
7752
7953
  chunks.push(`import { z } from 'zod';`);
7753
7954
  chunks.push(`import type { EventTypeName } from './types';`);
@@ -7802,7 +8003,7 @@ var REGISTRY_GETTER = [
7802
8003
  function buildRegistryContent(events) {
7803
8004
  const sorted = [...events].sort((a, b) => a.type.localeCompare(b.type));
7804
8005
  const chunks = [];
7805
- chunks.push(HEADER6);
8006
+ chunks.push(HEADER7);
7806
8007
  chunks.push("");
7807
8008
  chunks.push(`import type { EventTypeName } from './types';`);
7808
8009
  chunks.push("");
@@ -7982,10 +8183,10 @@ export class TypedEventBus {
7982
8183
  }
7983
8184
  `;
7984
8185
  function buildBusContent(_events) {
7985
- return HEADER6 + "\n" + BUS_BODY;
8186
+ return HEADER7 + "\n" + BUS_BODY;
7986
8187
  }
7987
8188
  function buildIndexContent(_events) {
7988
- return HEADER6 + `
8189
+ return HEADER7 + `
7989
8190
  export * from './types';
7990
8191
  export * from './schemas';
7991
8192
  export * from './registry';
@@ -8014,15 +8215,15 @@ async function generateEventCodegen(opts) {
8014
8215
  };
8015
8216
  const files = OUTPUT_FILE_NAMES.map((name) => ({
8016
8217
  name,
8017
- outputPath: path11.join(outputDir, name),
8218
+ outputPath: path12.join(outputDir, name),
8018
8219
  content: builders[name](merged)
8019
8220
  }));
8020
8221
  const hasError = issues.some((i) => i.severity === "error");
8021
8222
  let written = false;
8022
8223
  if (!dryRun && !hasError) {
8023
- fs8.mkdirSync(outputDir, { recursive: true });
8224
+ fs9.mkdirSync(outputDir, { recursive: true });
8024
8225
  for (const file of files) {
8025
- fs8.writeFileSync(file.outputPath, file.content);
8226
+ fs9.writeFileSync(file.outputPath, file.content);
8026
8227
  }
8027
8228
  written = true;
8028
8229
  }
@@ -8118,22 +8319,6 @@ import {
8118
8319
  } from "fs";
8119
8320
  import { dirname, join as join11 } from "path";
8120
8321
 
8121
- // src/cli/shared/runtime-import.ts
8122
- var PACKAGE = "@pattern-stack/codegen";
8123
- function resolveRuntimeMode(config) {
8124
- return config?.runtime === "vendored" ? "vendored" : "package";
8125
- }
8126
- function subsystemsImport(mode, subsystem) {
8127
- if (mode === "vendored") {
8128
- return subsystem ? `@shared/subsystems/${subsystem}` : "@shared/subsystems";
8129
- }
8130
- return `${PACKAGE}/subsystems`;
8131
- }
8132
- function runtimeImport(mode, relpath) {
8133
- const clean = relpath.replace(/^\/+/, "");
8134
- return mode === "vendored" ? `@shared/${clean}` : `${PACKAGE}/runtime/${clean}`;
8135
- }
8136
-
8137
8322
  // src/cli/shared/sink-emission-generator.ts
8138
8323
  var SCAFFOLD_SENTINEL = "// <CODEGEN-SCAFFOLD-V1>";
8139
8324
  var USER_ID_FIELD = "userId";
@@ -8357,8 +8542,8 @@ function generateIntegrationAggregator(surface, entries) {
8357
8542
  );
8358
8543
  const importLines = sorted.map((e) => {
8359
8544
  const cls = assemblyModuleClass(e.entityName, e.provider);
8360
- const path34 = `./modules/${e.provider}/${e.entityName}-integration.module`;
8361
- return `import { ${cls} } from '${path34}';`;
8545
+ const path36 = `./modules/${e.provider}/${e.entityName}-integration.module`;
8546
+ return `import { ${cls} } from '${path36}';`;
8362
8547
  }).join("\n");
8363
8548
  const membersInline = moduleClasses.join(", ");
8364
8549
  return `${generatedBanner(`surface: ${surface}`)}
@@ -8982,9 +9167,9 @@ function emitAdapters(opts) {
8982
9167
  [aggregatorPath, generateSurfaceAggregator(surface, slugs, mode)],
8983
9168
  [typedViewPath, generateTypedView(surface, slugs, entitiesBySurface.get(surface) ?? [])]
8984
9169
  ];
8985
- for (const [path34, content] of files) {
8986
- if (!opts.dryRun) writeIfChanged(path34, content);
8987
- result.written.push(path34);
9170
+ for (const [path36, content] of files) {
9171
+ if (!opts.dryRun) writeIfChanged(path36, content);
9172
+ result.written.push(path36);
8988
9173
  }
8989
9174
  if (opts.backendSrcAbs) {
8990
9175
  const aliases = opts.aliases ?? {};
@@ -9330,14 +9515,14 @@ function relativeSource(filePath) {
9330
9515
  }
9331
9516
 
9332
9517
  // src/cli/shared/events-path.ts
9333
- import path12 from "path";
9518
+ import path13 from "path";
9334
9519
  var FALLBACK = "events";
9335
9520
  function resolveEventsDirFromConfig(cwd, config) {
9336
9521
  const configured = config?.paths?.events_dir;
9337
9522
  if (typeof configured === "string" && configured.length > 0) {
9338
- return path12.resolve(cwd, configured);
9523
+ return path13.resolve(cwd, configured);
9339
9524
  }
9340
- return path12.resolve(cwd, FALLBACK);
9525
+ return path13.resolve(cwd, FALLBACK);
9341
9526
  }
9342
9527
  function resolveEventsDir(ctx) {
9343
9528
  return resolveEventsDirFromConfig(ctx.cwd, ctx.config);
@@ -9366,10 +9551,10 @@ function printInfo(msg) {
9366
9551
  // src/cli/commands/entity.ts
9367
9552
  function resolveProvidersDir(ctx) {
9368
9553
  const fromConfig = ctx.config?.paths?.providers;
9369
- return fromConfig != null ? path13.resolve(ctx.cwd, fromConfig) : path13.resolve(ctx.cwd, "definitions/providers");
9554
+ return fromConfig != null ? path14.resolve(ctx.cwd, fromConfig) : path14.resolve(ctx.cwd, "definitions/providers");
9370
9555
  }
9371
9556
  function listEntityYamls2(dir, providersDir) {
9372
- if (!fs9.existsSync(dir)) return [];
9557
+ if (!fs10.existsSync(dir)) return [];
9373
9558
  return findYamlFiles(dir, {
9374
9559
  excludeDirs: providersDir ? [providersDir] : []
9375
9560
  });
@@ -9448,11 +9633,11 @@ async function hints(ctx) {
9448
9633
  { command: "codegen entity validate", description: "Validate YAML definitions" },
9449
9634
  { command: "codegen entity list", description: "List entities as a table" }
9450
9635
  ];
9451
- const providersDir = ctx.config?.paths?.providers != null ? path13.resolve(
9636
+ const providersDir = ctx.config?.paths?.providers != null ? path14.resolve(
9452
9637
  ctx.cwd,
9453
9638
  ctx.config.paths.providers
9454
- ) : path13.resolve(ctx.cwd, "definitions/providers");
9455
- if (fs9.existsSync(providersDir)) {
9639
+ ) : path14.resolve(ctx.cwd, "definitions/providers");
9640
+ if (fs10.existsSync(providersDir)) {
9456
9641
  baseHints.push({
9457
9642
  command: "codegen entity new --all",
9458
9643
  description: "Regenerate provider modules + adapter scaffolds (Track D)"
@@ -9507,14 +9692,14 @@ var EntityNewCommand = class extends Command2 {
9507
9692
  }
9508
9693
  let targets = [];
9509
9694
  if (this.all) {
9510
- const dir = ctx.entitiesDir ?? path13.resolve(ctx.cwd, "entities");
9695
+ const dir = ctx.entitiesDir ?? path14.resolve(ctx.cwd, "entities");
9511
9696
  targets = listEntityYamls2(dir, resolveProvidersDir(ctx));
9512
9697
  if (targets.length === 0) {
9513
9698
  printError(`No entity YAML files found in ${dir}`);
9514
9699
  return 1;
9515
9700
  }
9516
9701
  } else if (this.yaml) {
9517
- targets = [path13.resolve(ctx.cwd, this.yaml)];
9702
+ targets = [path14.resolve(ctx.cwd, this.yaml)];
9518
9703
  } else {
9519
9704
  printError("Missing YAML path. Pass a file or --all.");
9520
9705
  return 2;
@@ -9531,7 +9716,7 @@ var EntityNewCommand = class extends Command2 {
9531
9716
  }
9532
9717
  if (invalid.length > 0 && !this.continueOnError) {
9533
9718
  for (const i of invalid) {
9534
- printError(`${path13.basename(i.file)} \u2014 ${i.message}`);
9719
+ printError(`${path14.basename(i.file)} \u2014 ${i.message}`);
9535
9720
  for (const detail of i.details ?? []) {
9536
9721
  printError(` \u2022 ${detail}`);
9537
9722
  }
@@ -9540,7 +9725,7 @@ var EntityNewCommand = class extends Command2 {
9540
9725
  return 1;
9541
9726
  }
9542
9727
  }
9543
- const entitiesDirForEmits = ctx.entitiesDir ?? path13.resolve(ctx.cwd, "entities");
9728
+ const entitiesDirForEmits = ctx.entitiesDir ?? path14.resolve(ctx.cwd, "entities");
9544
9729
  const eventsDirForEmits = resolveEventsDir(ctx);
9545
9730
  const allEntitiesForEmits = loadEntities(entitiesDirForEmits, {
9546
9731
  excludeDirs: [resolveProvidersDir(ctx)]
@@ -9589,35 +9774,35 @@ var EntityNewCommand = class extends Command2 {
9589
9774
  if (!isJsonMode()) return 1;
9590
9775
  }
9591
9776
  }
9592
- const entitiesDir = ctx.entitiesDir ?? path13.resolve(ctx.cwd, "entities");
9593
- const relationshipsDir = path13.resolve(ctx.cwd, "relationships");
9777
+ const entitiesDir = ctx.entitiesDir ?? path14.resolve(ctx.cwd, "entities");
9778
+ const relationshipsDir = path14.resolve(ctx.cwd, "relationships");
9594
9779
  const generatedDir = resolveGeneratedDir(ctx);
9595
9780
  const architecture = resolveArchitecture(ctx);
9596
9781
  const subsystemsRoot = resolveSubsystemsRoot(ctx);
9597
- const scopeEntityTypePath = path13.resolve(
9782
+ const scopeEntityTypePath = path14.resolve(
9598
9783
  subsystemsRoot,
9599
9784
  "jobs/generated/scope-entity-type.ts"
9600
9785
  );
9601
9786
  const eventsDir = resolveEventsDir(ctx);
9602
- const eventCodegenOutputDir = path13.resolve(
9787
+ const eventCodegenOutputDir = path14.resolve(
9603
9788
  subsystemsRoot,
9604
9789
  "events/generated"
9605
9790
  );
9606
- const bridgeRegistryOutputDir = path13.resolve(
9607
- subsystemsRoot,
9608
- "bridge/generated"
9609
- );
9610
- const backendSrcForHandlers = ctx.config?.paths?.backend_src ?? "src";
9611
9791
  const runtimeMode = resolveRuntimeMode(ctx.config);
9612
- const bridgeHandlersDir = path13.resolve(
9792
+ const bridgeInstalledForRegistry = configuredSubsystemNames(
9793
+ ctx.config
9794
+ ).includes("bridge");
9795
+ const bridgeRegistryOutputDir = runtimeMode === "package" ? generatedDir : path14.resolve(subsystemsRoot, "bridge/generated");
9796
+ const backendSrcForHandlers = ctx.config?.paths?.backend_src ?? "src";
9797
+ const bridgeHandlersDir = path14.resolve(
9613
9798
  ctx.cwd,
9614
9799
  backendSrcForHandlers,
9615
9800
  "jobs"
9616
9801
  );
9617
9802
  const orchestrationConfigured = ctx.config?.paths?.orchestration_src;
9618
- const orchestrationOutputRoot = path13.resolve(
9803
+ const orchestrationOutputRoot = path14.resolve(
9619
9804
  ctx.cwd,
9620
- typeof orchestrationConfigured === "string" && orchestrationConfigured.length > 0 ? orchestrationConfigured : path13.join(backendSrcForHandlers, "orchestration")
9805
+ typeof orchestrationConfigured === "string" && orchestrationConfigured.length > 0 ? orchestrationConfigured : path14.join(backendSrcForHandlers, "orchestration")
9621
9806
  );
9622
9807
  const orchestrationGlobs = (() => {
9623
9808
  const fromCfg = ctx.config?.patterns;
@@ -9659,6 +9844,8 @@ var EntityNewCommand = class extends Command2 {
9659
9844
  handlersDir: bridgeHandlersDir,
9660
9845
  eventsGeneratedDir: eventCodegenOutputDir,
9661
9846
  outputDir: bridgeRegistryOutputDir,
9847
+ mode: runtimeMode,
9848
+ bridgeInstalled: bridgeInstalledForRegistry,
9662
9849
  dryRun: true
9663
9850
  });
9664
9851
  const orchestrationPatterns = await loadOrchestrationPatterns();
@@ -9745,7 +9932,7 @@ var EntityNewCommand = class extends Command2 {
9745
9932
  }
9746
9933
  if (invalid.length > 0) {
9747
9934
  for (const i of invalid) {
9748
- printWarning(`${path13.basename(i.file)} \u2014 ${i.message}`);
9935
+ printWarning(`${path14.basename(i.file)} \u2014 ${i.message}`);
9749
9936
  }
9750
9937
  }
9751
9938
  console.log("");
@@ -9763,7 +9950,7 @@ var EntityNewCommand = class extends Command2 {
9763
9950
  }
9764
9951
  const succeeded = [];
9765
9952
  const failed = [
9766
- ...invalid.map((i) => ({ name: path13.basename(i.file), file: i.file, message: i.message }))
9953
+ ...invalid.map((i) => ({ name: path14.basename(i.file), file: i.file, message: i.message }))
9767
9954
  ];
9768
9955
  for (const v of validated) {
9769
9956
  if (!isJsonMode()) {
@@ -9806,6 +9993,14 @@ var EntityNewCommand = class extends Command2 {
9806
9993
  printWarning(`subsystem barrel regeneration failed \u2014 ${msg}`);
9807
9994
  }
9808
9995
  }
9996
+ try {
9997
+ await regenerateSubsystemSchemaBarrel({ ctx, generatedDir });
9998
+ } catch (err) {
9999
+ const msg = err instanceof Error ? err.message : String(err);
10000
+ if (!isJsonMode()) {
10001
+ printWarning(`subsystem schema barrel regeneration failed \u2014 ${msg}`);
10002
+ }
10003
+ }
9809
10004
  let scopeResult = null;
9810
10005
  try {
9811
10006
  scopeResult = await generateScopeEntityType({
@@ -9845,7 +10040,9 @@ var EntityNewCommand = class extends Command2 {
9845
10040
  bridgeRegistryResult = await generateBridgeRegistry({
9846
10041
  handlersDir: bridgeHandlersDir,
9847
10042
  eventsGeneratedDir: eventCodegenOutputDir,
9848
- outputDir: bridgeRegistryOutputDir
10043
+ outputDir: bridgeRegistryOutputDir,
10044
+ mode: runtimeMode,
10045
+ bridgeInstalled: bridgeInstalledForRegistry
9849
10046
  });
9850
10047
  if (bridgeRegistryResult.skipped && !isJsonMode()) {
9851
10048
  printInfo(
@@ -9878,12 +10075,12 @@ var EntityNewCommand = class extends Command2 {
9878
10075
  let providerResult = null;
9879
10076
  try {
9880
10077
  const providersDir = resolveProvidersDir(ctx);
9881
- const providerOutputRoot = path13.resolve(
10078
+ const providerOutputRoot = path14.resolve(
9882
10079
  ctx.cwd,
9883
10080
  backendSrcForHandlers,
9884
10081
  "integrations/providers"
9885
10082
  );
9886
- const entitySurfaces = fs9.existsSync(entitiesDir) ? collectEntitySurfaces(
10083
+ const entitySurfaces = fs10.existsSync(entitiesDir) ? collectEntitySurfaces(
9887
10084
  loadEntitiesFromYaml(
9888
10085
  findYamlFiles(entitiesDir, { excludeDirs: [providersDir] })
9889
10086
  ).successes.map((s) => s.definition)
@@ -9920,12 +10117,12 @@ var EntityNewCommand = class extends Command2 {
9920
10117
  try {
9921
10118
  if (providerResult && !providerResult.skipped && providerResult.issues.length === 0) {
9922
10119
  const providersDir = providerResult.providersDir;
9923
- const adapterOutputRoot = path13.resolve(
10120
+ const adapterOutputRoot = path14.resolve(
9924
10121
  ctx.cwd,
9925
10122
  backendSrcForHandlers,
9926
10123
  "integrations"
9927
10124
  );
9928
- const entityDefs = fs9.existsSync(entitiesDir) ? loadEntitiesFromYaml(
10125
+ const entityDefs = fs10.existsSync(entitiesDir) ? loadEntitiesFromYaml(
9929
10126
  findYamlFiles(entitiesDir, { excludeDirs: [providersDir] })
9930
10127
  ).successes.map((s) => s.definition) : [];
9931
10128
  const loadedProviders = loadProvidersFromYaml(
@@ -9939,7 +10136,7 @@ var EntityNewCommand = class extends Command2 {
9939
10136
  providers: loadedProviders,
9940
10137
  entities: entityDefs,
9941
10138
  outputRoot: adapterOutputRoot,
9942
- backendSrcAbs: path13.resolve(ctx.cwd, backendSrcForHandlers),
10139
+ backendSrcAbs: path14.resolve(ctx.cwd, backendSrcForHandlers),
9943
10140
  aliases: assemblyTsAliases?.aliases ?? {},
9944
10141
  mode: runtimeMode
9945
10142
  });
@@ -10041,22 +10238,22 @@ var EntityNewCommand = class extends Command2 {
10041
10238
  }
10042
10239
  if (barrelResult) {
10043
10240
  printInfo(
10044
- `barrels regenerated (${barrelResult.entityCount} entities) \u2192 ${path13.relative(ctx.cwd, barrelResult.modulesBarrel)}, ${path13.relative(ctx.cwd, barrelResult.schemaBarrel)}`
10241
+ `barrels regenerated (${barrelResult.entityCount} entities) \u2192 ${path14.relative(ctx.cwd, barrelResult.modulesBarrel)}, ${path14.relative(ctx.cwd, barrelResult.schemaBarrel)}`
10045
10242
  );
10046
10243
  }
10047
10244
  if (scopeResult) {
10048
10245
  printInfo(
10049
- `scope-entity-type regenerated (${scopeResult.scopeableNames.length} scopeable) \u2192 ${path13.relative(ctx.cwd, scopeResult.outputPath)}`
10246
+ `scope-entity-type regenerated (${scopeResult.scopeableNames.length} scopeable) \u2192 ${path14.relative(ctx.cwd, scopeResult.outputPath)}`
10050
10247
  );
10051
10248
  }
10052
10249
  if (eventCodegenResult) {
10053
10250
  printInfo(
10054
- `event codegen regenerated (${eventCodegenResult.eventCount} events) \u2192 ${path13.relative(ctx.cwd, eventCodegenResult.outputDir)}`
10251
+ `event codegen regenerated (${eventCodegenResult.eventCount} events) \u2192 ${path14.relative(ctx.cwd, eventCodegenResult.outputDir)}`
10055
10252
  );
10056
10253
  }
10057
10254
  if (orchestrationResult && orchestrationResult.patterns.length > 0) {
10058
10255
  printInfo(
10059
- `orchestration regenerated (${orchestrationResult.patterns.length} patterns, ${orchestrationResult.files.length} files) \u2192 ${path13.relative(ctx.cwd, orchestrationResult.outputRoot)}`
10256
+ `orchestration regenerated (${orchestrationResult.patterns.length} patterns, ${orchestrationResult.files.length} files) \u2192 ${path14.relative(ctx.cwd, orchestrationResult.outputRoot)}`
10060
10257
  );
10061
10258
  }
10062
10259
  }
@@ -10142,8 +10339,8 @@ var EntityValidateCommand = class extends Command2 {
10142
10339
  json: this.json,
10143
10340
  skipDetection: true
10144
10341
  });
10145
- const targetDir = this.dir ? path13.resolve(ctx.cwd, this.dir) : ctx.entitiesDir ?? path13.resolve(ctx.cwd, "entities");
10146
- if (!fs9.existsSync(targetDir)) {
10342
+ const targetDir = this.dir ? path14.resolve(ctx.cwd, this.dir) : ctx.entitiesDir ?? path14.resolve(ctx.cwd, "entities");
10343
+ if (!fs10.existsSync(targetDir)) {
10147
10344
  printError(`Directory not found: ${targetDir}`);
10148
10345
  return 1;
10149
10346
  }
@@ -10194,8 +10391,8 @@ var entityNoun = {
10194
10391
  var entity_default = entityNoun;
10195
10392
 
10196
10393
  // src/cli/commands/subsystem.ts
10197
- import fs11 from "fs";
10198
- import path22 from "path";
10394
+ import fs13 from "fs";
10395
+ import path24 from "path";
10199
10396
  import { Command as Command3, Option as Option3 } from "clipanion";
10200
10397
 
10201
10398
  // src/cli/shared/config-block-detect.ts
@@ -10228,26 +10425,26 @@ function stripConfigBlock(yamlSource, subsystem) {
10228
10425
  }
10229
10426
 
10230
10427
  // src/cli/shared/events-scaffold-locals.ts
10231
- import path14 from "path";
10428
+ import path15 from "path";
10232
10429
  function resolveEventsScaffoldLocals(input) {
10233
10430
  const { cwd, config } = input;
10234
10431
  void input.fileExists;
10235
10432
  const eventsBlock = config?.events ?? {};
10236
10433
  const subsystemsRoot = resolveSubsystemsRootFromConfig(cwd, config);
10237
- const configPath = path14.resolve(cwd, "codegen.config.yaml");
10238
- const schemaPath = path14.resolve(
10434
+ const configPath = path15.resolve(cwd, "codegen.config.yaml");
10435
+ const schemaPath = path15.resolve(
10239
10436
  subsystemsRoot,
10240
10437
  "events",
10241
10438
  "domain-events.schema.ts"
10242
10439
  );
10243
- const generatedKeepPath = path14.resolve(
10440
+ const generatedKeepPath = path15.resolve(
10244
10441
  subsystemsRoot,
10245
10442
  "events",
10246
10443
  "generated",
10247
10444
  ".gitkeep"
10248
10445
  );
10249
10446
  return {
10250
- appName: path14.basename(cwd),
10447
+ appName: path15.basename(cwd),
10251
10448
  multiTenant: normaliseMultiTenant(eventsBlock.multi_tenant),
10252
10449
  configPath,
10253
10450
  schemaPath,
@@ -10273,7 +10470,7 @@ function localsToHygenArgs(locals) {
10273
10470
  }
10274
10471
 
10275
10472
  // src/cli/shared/jobs-scaffold-locals.ts
10276
- import path15 from "path";
10473
+ import path16 from "path";
10277
10474
  var MAIN_HOOK_SENTINEL = "JOBS \u2014 Embedded worker mode (optional)";
10278
10475
  function workerSkipValue(exists) {
10279
10476
  return exists ? "true" : "";
@@ -10282,10 +10479,10 @@ function resolveJobsScaffoldLocals(input) {
10282
10479
  const { cwd, config, fileExists, readFile } = input;
10283
10480
  const jobsBlock = config?.jobs ?? {};
10284
10481
  const subsystemsRoot = resolveSubsystemsRootFromConfig(cwd, config);
10285
- const workerPath = path15.resolve(cwd, "worker.ts");
10286
- const mainTsPath = path15.resolve(cwd, "src/main.ts");
10287
- const configPath = path15.resolve(cwd, "codegen.config.yaml");
10288
- const schemaPath = path15.resolve(
10482
+ const workerPath = path16.resolve(cwd, "worker.ts");
10483
+ const mainTsPath = path16.resolve(cwd, "src/main.ts");
10484
+ const configPath = path16.resolve(cwd, "codegen.config.yaml");
10485
+ const schemaPath = path16.resolve(
10289
10486
  subsystemsRoot,
10290
10487
  "jobs",
10291
10488
  "job-orchestration.schema.ts"
@@ -10293,7 +10490,7 @@ function resolveJobsScaffoldLocals(input) {
10293
10490
  const mainContent = readFile(mainTsPath);
10294
10491
  const mainHookInjected = mainContent !== null && mainContent.includes(MAIN_HOOK_SENTINEL);
10295
10492
  return {
10296
- appName: path15.basename(cwd),
10493
+ appName: path16.basename(cwd),
10297
10494
  workerMode: normaliseWorkerMode(jobsBlock.worker_mode),
10298
10495
  multiTenant: normaliseMultiTenant2(jobsBlock.multi_tenant),
10299
10496
  mainTsPath,
@@ -10335,20 +10532,20 @@ function localsToHygenArgs2(locals) {
10335
10532
  }
10336
10533
 
10337
10534
  // src/cli/shared/integration-scaffold-locals.ts
10338
- import path16 from "path";
10535
+ import path17 from "path";
10339
10536
  function resolveIntegrationScaffoldLocals(input) {
10340
10537
  const { cwd, config } = input;
10341
10538
  void input.fileExists;
10342
10539
  const integrationBlock = config?.integration ?? {};
10343
10540
  const subsystemsRoot = resolveSubsystemsRootFromConfig(cwd, config);
10344
- const configPath = path16.resolve(cwd, "codegen.config.yaml");
10345
- const schemaPath = path16.resolve(
10541
+ const configPath = path17.resolve(cwd, "codegen.config.yaml");
10542
+ const schemaPath = path17.resolve(
10346
10543
  subsystemsRoot,
10347
10544
  "integration",
10348
10545
  "integration-audit.schema.ts"
10349
10546
  );
10350
10547
  return {
10351
- appName: path16.basename(cwd),
10548
+ appName: path17.basename(cwd),
10352
10549
  multiTenant: normaliseMultiTenant3(integrationBlock.multi_tenant),
10353
10550
  configPath,
10354
10551
  schemaPath
@@ -10371,21 +10568,21 @@ function localsToHygenArgs3(locals) {
10371
10568
  }
10372
10569
 
10373
10570
  // src/cli/shared/bridge-scaffold-locals.ts
10374
- import path17 from "path";
10571
+ import path18 from "path";
10375
10572
  function resolveBridgeScaffoldLocals(input) {
10376
10573
  const { cwd, config } = input;
10377
10574
  void input.fileExists;
10378
10575
  const bridgeBlock = config?.bridge ?? {};
10379
10576
  const subsystemsRoot = resolveSubsystemsRootFromConfig(cwd, config);
10380
- const configPath = path17.resolve(cwd, "codegen.config.yaml");
10381
- const generatedKeepPath = path17.resolve(
10577
+ const configPath = path18.resolve(cwd, "codegen.config.yaml");
10578
+ const generatedKeepPath = path18.resolve(
10382
10579
  subsystemsRoot,
10383
10580
  "bridge",
10384
10581
  "generated",
10385
10582
  ".gitkeep"
10386
10583
  );
10387
10584
  return {
10388
- appName: path17.basename(cwd),
10585
+ appName: path18.basename(cwd),
10389
10586
  multiTenant: normaliseMultiTenant4(bridgeBlock.multi_tenant),
10390
10587
  configPath,
10391
10588
  generatedKeepPath
@@ -10408,19 +10605,19 @@ function localsToHygenArgs4(locals) {
10408
10605
  }
10409
10606
 
10410
10607
  // src/cli/shared/observability-scaffold-locals.ts
10411
- import path18 from "path";
10608
+ import path19 from "path";
10412
10609
  var FALLBACK_BACKEND_SRC2 = "src";
10413
10610
  function resolveObservabilityScaffoldLocals(input) {
10414
10611
  const { cwd, config } = input;
10415
10612
  void input.fileExists;
10416
10613
  const backendSrc = typeof config?.paths?.backend_src === "string" && config.paths.backend_src.length > 0 ? config.paths.backend_src : FALLBACK_BACKEND_SRC2;
10417
- const appModulePath = path18.resolve(cwd, backendSrc, "app.module.ts");
10418
- const configPath = path18.resolve(cwd, "codegen.config.yaml");
10614
+ const appModulePath = path19.resolve(cwd, backendSrc, "app.module.ts");
10615
+ const configPath = path19.resolve(cwd, "codegen.config.yaml");
10419
10616
  const obsBlock = config?.observability ?? {};
10420
10617
  const reporters = obsBlock.reporters ?? {};
10421
10618
  const bridgeMetrics = reporters.bridgeMetrics ?? {};
10422
10619
  return {
10423
- appName: path18.basename(cwd),
10620
+ appName: path19.basename(cwd),
10424
10621
  appModulePath,
10425
10622
  configPath,
10426
10623
  bridgeMetricsEnabled: bridgeMetrics.enabled === true
@@ -10441,7 +10638,7 @@ function localsToHygenArgs5(locals) {
10441
10638
 
10442
10639
  // src/cli/shared/auth-scaffold-locals.ts
10443
10640
  import crypto2 from "crypto";
10444
- import path19 from "path";
10641
+ import path20 from "path";
10445
10642
  var FALLBACK_BACKEND_SRC3 = "src";
10446
10643
  var DEFAULT_REDIRECT_URI_BASE = "http://localhost:3000";
10447
10644
  function resolveAuthScaffoldLocals(input) {
@@ -10453,15 +10650,15 @@ function resolveAuthScaffoldLocals(input) {
10453
10650
  const redirectUriBase = typeof redirectRaw === "string" && redirectRaw.length > 0 ? redirectRaw : DEFAULT_REDIRECT_URI_BASE;
10454
10651
  const tokenEncryptionKey = crypto2.randomBytes(32).toString("base64");
10455
10652
  return {
10456
- appName: path19.basename(cwd),
10457
- configPath: path19.resolve(cwd, "codegen.config.yaml"),
10458
- schemaPath: path19.resolve(
10653
+ appName: path20.basename(cwd),
10654
+ configPath: path20.resolve(cwd, "codegen.config.yaml"),
10655
+ schemaPath: path20.resolve(
10459
10656
  subsystemsRoot,
10460
10657
  "auth",
10461
10658
  "auth-oauth-state.schema.ts"
10462
10659
  ),
10463
- appModulePath: path19.resolve(cwd, backendSrc, "app.module.ts"),
10464
- envConfigPath: path19.resolve(cwd, ".env.config"),
10660
+ appModulePath: path20.resolve(cwd, backendSrc, "app.module.ts"),
10661
+ envConfigPath: path20.resolve(cwd, ".env.config"),
10465
10662
  redirectUriBase,
10466
10663
  tokenEncryptionKey
10467
10664
  };
@@ -10486,7 +10683,7 @@ function localsToHygenArgs6(locals) {
10486
10683
  }
10487
10684
 
10488
10685
  // src/cli/shared/auth-integrations-scaffold-locals.ts
10489
- import path20 from "path";
10686
+ import path21 from "path";
10490
10687
  var FALLBACK_BACKEND_SRC4 = "src";
10491
10688
  var DEFAULT_MODULES_DIR = "modules";
10492
10689
  var DEFAULT_DEFINITIONS_DIR = "definitions/entities";
@@ -10495,17 +10692,17 @@ function resolveAuthIntegrationsScaffoldLocals(input) {
10495
10692
  const backendSrc = typeof config?.paths?.backend_src === "string" && config.paths.backend_src.length > 0 ? config.paths.backend_src : FALLBACK_BACKEND_SRC4;
10496
10693
  const pathsAny = config?.paths;
10497
10694
  const modulesConfigured = pathsAny?.modules_dir;
10498
- const vendorRoot = typeof modulesConfigured === "string" && modulesConfigured.length > 0 ? path20.resolve(cwd, modulesConfigured) : path20.resolve(cwd, backendSrc, DEFAULT_MODULES_DIR);
10695
+ const vendorRoot = typeof modulesConfigured === "string" && modulesConfigured.length > 0 ? path21.resolve(cwd, modulesConfigured) : path21.resolve(cwd, backendSrc, DEFAULT_MODULES_DIR);
10499
10696
  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;
10500
- const definitionsPath = entitiesConfigured !== null ? path20.resolve(cwd, entitiesConfigured, "connection.yaml") : path20.resolve(cwd, DEFAULT_DEFINITIONS_DIR, "connection.yaml");
10501
- const appModulePath = path20.resolve(cwd, backendSrc, "app.module.ts");
10697
+ const definitionsPath = entitiesConfigured !== null ? path21.resolve(cwd, entitiesConfigured, "connection.yaml") : path21.resolve(cwd, DEFAULT_DEFINITIONS_DIR, "connection.yaml");
10698
+ const appModulePath = path21.resolve(cwd, backendSrc, "app.module.ts");
10502
10699
  let authModuleRegistered = false;
10503
10700
  const appModuleSource = input.readFile(appModulePath);
10504
10701
  if (appModuleSource && appModuleSource.includes("AuthModule.forRoot")) {
10505
10702
  authModuleRegistered = true;
10506
10703
  }
10507
10704
  return {
10508
- appName: path20.basename(cwd),
10705
+ appName: path21.basename(cwd),
10509
10706
  appModulePath,
10510
10707
  vendorRoot,
10511
10708
  definitionsPath,
@@ -10522,11 +10719,11 @@ function localsToHygenArgs7(locals) {
10522
10719
  }
10523
10720
 
10524
10721
  // src/cli/shared/runtime-copier.ts
10525
- import fs10 from "fs";
10526
- import path21 from "path";
10722
+ import fs11 from "fs";
10723
+ import path22 from "path";
10527
10724
  function readIfExists(p) {
10528
10725
  try {
10529
- return fs10.readFileSync(p, "utf-8");
10726
+ return fs11.readFileSync(p, "utf-8");
10530
10727
  } catch {
10531
10728
  return null;
10532
10729
  }
@@ -10541,20 +10738,20 @@ function extractRelativeImports(source) {
10541
10738
  return out;
10542
10739
  }
10543
10740
  function resolveSourceImport(sourceFile, specifier) {
10544
- const base = path21.resolve(path21.dirname(sourceFile), specifier);
10545
- const candidates = [base + ".ts", base + ".tsx", path21.join(base, "index.ts")];
10741
+ const base = path22.resolve(path22.dirname(sourceFile), specifier);
10742
+ const candidates = [base + ".ts", base + ".tsx", path22.join(base, "index.ts")];
10546
10743
  for (const c of candidates) {
10547
- if (fs10.existsSync(c)) return c;
10744
+ if (fs11.existsSync(c)) return c;
10548
10745
  }
10549
10746
  return null;
10550
10747
  }
10551
10748
  async function copyRuntime(opts) {
10552
10749
  const { sourceDir, targetDir, filter, resolveDeps, dryRun, onlyExisting } = opts;
10553
- if (!fs10.existsSync(sourceDir) || !fs10.statSync(sourceDir).isDirectory()) {
10750
+ if (!fs11.existsSync(sourceDir) || !fs11.statSync(sourceDir).isDirectory()) {
10554
10751
  throw new Error(`runtime source directory not found: ${sourceDir}`);
10555
10752
  }
10556
- const runtimeRoot4 = opts.runtimeRoot ? path21.resolve(opts.runtimeRoot) : path21.resolve(sourceDir, "..", "..");
10557
- const depsTargetRoot = opts.depsTargetRoot ?? path21.resolve(targetDir, "..");
10753
+ const runtimeRoot4 = opts.runtimeRoot ? path22.resolve(opts.runtimeRoot) : path22.resolve(sourceDir, "..", "..");
10754
+ const depsTargetRoot = opts.depsTargetRoot ?? path22.resolve(targetDir, "..");
10558
10755
  const result = {
10559
10756
  written: [],
10560
10757
  updated: [],
@@ -10564,9 +10761,9 @@ async function copyRuntime(opts) {
10564
10761
  };
10565
10762
  const queue = [];
10566
10763
  function walk(dir) {
10567
- for (const entry of fs10.readdirSync(dir)) {
10568
- const src = path21.join(dir, entry);
10569
- const stat = fs10.statSync(src);
10764
+ for (const entry of fs11.readdirSync(dir)) {
10765
+ const src = path22.join(dir, entry);
10766
+ const stat = fs11.statSync(src);
10570
10767
  if (stat.isDirectory()) {
10571
10768
  if (entry === "generated") continue;
10572
10769
  walk(src);
@@ -10574,9 +10771,9 @@ async function copyRuntime(opts) {
10574
10771
  }
10575
10772
  if (!stat.isFile()) continue;
10576
10773
  if (!entry.endsWith(".ts") && !entry.endsWith(".tsx")) continue;
10577
- const rel2 = path21.relative(sourceDir, src);
10774
+ const rel2 = path22.relative(sourceDir, src);
10578
10775
  if (filter && !filter(rel2) && !filter(entry)) continue;
10579
- queue.push({ src, dest: path21.join(targetDir, rel2), isDep: false });
10776
+ queue.push({ src, dest: path22.join(targetDir, rel2), isDep: false });
10580
10777
  }
10581
10778
  }
10582
10779
  walk(sourceDir);
@@ -10585,10 +10782,10 @@ async function copyRuntime(opts) {
10585
10782
  const next = queue.shift();
10586
10783
  if (visited.has(next.src)) continue;
10587
10784
  visited.add(next.src);
10588
- if (onlyExisting && !fs10.existsSync(next.dest)) {
10785
+ if (onlyExisting && !fs11.existsSync(next.dest)) {
10589
10786
  continue;
10590
10787
  }
10591
- const content = fs10.readFileSync(next.src, "utf-8");
10788
+ const content = fs11.readFileSync(next.src, "utf-8");
10592
10789
  result.planned.push(next.dest);
10593
10790
  const existing = readIfExists(next.dest);
10594
10791
  const status = existing === content ? "unchanged" : existing === null ? "written" : "updated";
@@ -10597,18 +10794,18 @@ async function copyRuntime(opts) {
10597
10794
  else result.unchanged.push(next.dest);
10598
10795
  if (next.isDep) result.dependenciesCopied.push(next.dest);
10599
10796
  if (!dryRun && status !== "unchanged") {
10600
- fs10.mkdirSync(path21.dirname(next.dest), { recursive: true });
10601
- fs10.writeFileSync(next.dest, content);
10797
+ fs11.mkdirSync(path22.dirname(next.dest), { recursive: true });
10798
+ fs11.writeFileSync(next.dest, content);
10602
10799
  }
10603
10800
  if (resolveDeps) {
10604
10801
  for (const spec of extractRelativeImports(content)) {
10605
10802
  const resolvedSrc = resolveSourceImport(next.src, spec);
10606
10803
  if (!resolvedSrc) continue;
10607
- const relToRuntime = path21.relative(runtimeRoot4, resolvedSrc);
10608
- if (relToRuntime.startsWith("..") || path21.isAbsolute(relToRuntime)) continue;
10609
- const relToSource = path21.relative(sourceDir, resolvedSrc);
10610
- if (!relToSource.startsWith("..") && !path21.isAbsolute(relToSource)) continue;
10611
- const depDest = path21.join(depsTargetRoot, relToRuntime);
10804
+ const relToRuntime = path22.relative(runtimeRoot4, resolvedSrc);
10805
+ if (relToRuntime.startsWith("..") || path22.isAbsolute(relToRuntime)) continue;
10806
+ const relToSource = path22.relative(sourceDir, resolvedSrc);
10807
+ if (!relToSource.startsWith("..") && !path22.isAbsolute(relToSource)) continue;
10808
+ const depDest = path22.join(depsTargetRoot, relToRuntime);
10612
10809
  queue.push({ src: resolvedSrc, dest: depDest, isDep: true });
10613
10810
  }
10614
10811
  }
@@ -10616,19 +10813,87 @@ async function copyRuntime(opts) {
10616
10813
  return result;
10617
10814
  }
10618
10815
 
10816
+ // src/cli/shared/subsystems-install-config.ts
10817
+ import fs12 from "fs";
10818
+ import path23 from "path";
10819
+ import yaml2 from "yaml";
10820
+ function readInstallList(config) {
10821
+ const raw = config?.subsystems?.install;
10822
+ if (!Array.isArray(raw)) return [];
10823
+ return raw.filter((e) => typeof e === "string");
10824
+ }
10825
+ function ensureSubsystemInstalled(configPath, name) {
10826
+ if (!fs12.existsSync(configPath)) {
10827
+ fs12.mkdirSync(path23.dirname(configPath), { recursive: true });
10828
+ fs12.writeFileSync(
10829
+ configPath,
10830
+ `subsystems:
10831
+ install:
10832
+ - ${name}
10833
+ `,
10834
+ "utf-8"
10835
+ );
10836
+ return { outcome: "added", install: [name] };
10837
+ }
10838
+ const source = fs12.readFileSync(configPath, "utf-8");
10839
+ let doc;
10840
+ try {
10841
+ doc = yaml2.parseDocument(source);
10842
+ if (doc.errors.length > 0) {
10843
+ return { outcome: "parse-error", install: [] };
10844
+ }
10845
+ } catch {
10846
+ return { outcome: "parse-error", install: [] };
10847
+ }
10848
+ const current = readInstallList(
10849
+ doc.toJS()
10850
+ );
10851
+ if (current.includes(name)) {
10852
+ return { outcome: "already", install: current };
10853
+ }
10854
+ const subsystemsNode = doc.get("subsystems", true);
10855
+ const installSeq = subsystemsNode && typeof subsystemsNode.get === "function" ? subsystemsNode.get("install", true) : void 0;
10856
+ if (installSeq && Array.isArray(installSeq.items) && installSeq.items.length > 0) {
10857
+ const lastItem = installSeq.items[installSeq.items.length - 1];
10858
+ const range = lastItem.range;
10859
+ if (range) {
10860
+ const insertAt = range[1];
10861
+ const lineStart = source.lastIndexOf("\n", range[0]) + 1;
10862
+ const indent = source.slice(lineStart, range[0]).match(/^\s*/)?.[0] ?? " ";
10863
+ const before = source.slice(0, insertAt);
10864
+ const after = source.slice(insertAt);
10865
+ const next = `${before}
10866
+ ${indent}- ${name}${after}`;
10867
+ fs12.writeFileSync(configPath, next, "utf-8");
10868
+ return { outcome: "added", install: [...current, name] };
10869
+ }
10870
+ }
10871
+ doc.setIn(["subsystems", "install"], [...current, name]);
10872
+ fs12.writeFileSync(configPath, String(doc), "utf-8");
10873
+ return { outcome: "added", install: [...current, name] };
10874
+ }
10875
+
10619
10876
  // src/cli/commands/subsystem.ts
10620
10877
  function runtimeRoot() {
10621
- const pkgRoot = path22.resolve(import.meta.dirname, "..", "..", "..");
10622
- const topLevel = path22.join(pkgRoot, "runtime");
10623
- if (fs11.existsSync(topLevel)) return topLevel;
10624
- return path22.join(pkgRoot, "dist", "runtime");
10878
+ const pkgRoot = path24.resolve(import.meta.dirname, "..", "..", "..");
10879
+ const topLevel = path24.join(pkgRoot, "runtime");
10880
+ if (fs13.existsSync(topLevel)) return topLevel;
10881
+ return path24.join(pkgRoot, "dist", "runtime");
10625
10882
  }
10626
10883
  function subsystemSource(name) {
10627
- return path22.join(runtimeRoot(), "subsystems", name);
10884
+ return path24.join(runtimeRoot(), "subsystems", name);
10628
10885
  }
10629
10886
  function describeSubsystem(name) {
10630
10887
  return SUBSYSTEMS.find((s) => s.name === name) ?? null;
10631
10888
  }
10889
+ var PACKAGE_CONFIG_BLOCK = {
10890
+ events: { detector: "events", actionFolder: "events-config" },
10891
+ jobs: { detector: "jobs", actionFolder: "jobs-config" },
10892
+ integration: { detector: "integration", actionFolder: "integration-config" },
10893
+ bridge: { detector: "bridge", actionFolder: "bridge-config" },
10894
+ observability: { detector: "observability", actionFolder: "observability-config" },
10895
+ auth: { detector: "auth", actionFolder: "auth-config" }
10896
+ };
10632
10897
  async function summary2(ctx) {
10633
10898
  const installed = await detectInstalledSubsystems(ctx);
10634
10899
  const installedNames = new Set(installed.map((i) => i.name));
@@ -10651,7 +10916,7 @@ async function summary2(ctx) {
10651
10916
  }
10652
10917
  body.push(theme.muted("Installed:"));
10653
10918
  for (const i of installed) {
10654
- const rel2 = path22.relative(ctx.cwd, i.path) || i.path;
10919
+ const rel2 = path24.relative(ctx.cwd, i.path) || i.path;
10655
10920
  body.push(
10656
10921
  ` ${theme.success(icons.check)} ${i.name.padEnd(10)} ${theme.muted(
10657
10922
  `${i.backend} backend`
@@ -10774,6 +11039,9 @@ var SubsystemInstallCommand = class extends Command3 {
10774
11039
  if (desc3.name === "auth-integrations") {
10775
11040
  return this.executeAuthIntegrations(ctx);
10776
11041
  }
11042
+ if (resolveRuntimeMode(ctx.config) === "package") {
11043
+ return this.executePackageMode(ctx, desc3, backend);
11044
+ }
10777
11045
  const installed = await detectInstalledSubsystems(ctx);
10778
11046
  const already = installed.find((i) => i.name === desc3.name);
10779
11047
  if (already && !this.force) {
@@ -10791,14 +11059,14 @@ var SubsystemInstallCommand = class extends Command3 {
10791
11059
  return 0;
10792
11060
  }
10793
11061
  const targetRoot = resolveSubsystemsRoot(ctx, this.target);
10794
- const subsystemTarget = path22.join(targetRoot, desc3.name);
11062
+ const subsystemTarget = path24.join(targetRoot, desc3.name);
10795
11063
  const source = subsystemSource(desc3.name);
10796
- if (!fs11.existsSync(source)) {
11064
+ if (!fs13.existsSync(source)) {
10797
11065
  printError(`Runtime subsystem source missing: ${source}`);
10798
11066
  return 1;
10799
11067
  }
10800
11068
  if (!this.force) {
10801
- const gitCheck = checkGitSafety([path22.relative(ctx.cwd, subsystemTarget) || subsystemTarget], ctx.cwd);
11069
+ const gitCheck = checkGitSafety([path24.relative(ctx.cwd, subsystemTarget) || subsystemTarget], ctx.cwd);
10802
11070
  if (gitCheck.inRepo && !gitCheck.clean) {
10803
11071
  printWarning(
10804
11072
  `Uncommitted changes under ${subsystemTarget}. Pass --force to overwrite.`
@@ -10807,7 +11075,7 @@ var SubsystemInstallCommand = class extends Command3 {
10807
11075
  }
10808
11076
  }
10809
11077
  if (!isJsonMode()) {
10810
- printInfo(`target = ${path22.relative(ctx.cwd, subsystemTarget) || subsystemTarget}`);
11078
+ printInfo(`target = ${path24.relative(ctx.cwd, subsystemTarget) || subsystemTarget}`);
10811
11079
  printInfo(`backend = ${backend}`);
10812
11080
  }
10813
11081
  const result = await copyRuntime({
@@ -10816,7 +11084,7 @@ var SubsystemInstallCommand = class extends Command3 {
10816
11084
  filter: backendFileFilter(backend, desc3.name),
10817
11085
  resolveDeps: true,
10818
11086
  runtimeRoot: runtimeRoot(),
10819
- depsTargetRoot: path22.resolve(targetRoot, ".."),
11087
+ depsTargetRoot: path24.resolve(targetRoot, ".."),
10820
11088
  dryRun: this.dryRun
10821
11089
  });
10822
11090
  const jobsScaffold = desc3.name === "jobs" ? runJobsScaffold(ctx.cwd, ctx.config, {
@@ -10911,14 +11179,14 @@ var SubsystemInstallCommand = class extends Command3 {
10911
11179
  if (this.dryRun) {
10912
11180
  printInfo(`Dry run \u2014 ${result.planned.length} files would be written`);
10913
11181
  for (const p of result.planned) {
10914
- console.log(` ${theme.muted(icons.arrow)} ${path22.relative(ctx.cwd, p) || p}`);
11182
+ console.log(` ${theme.muted(icons.arrow)} ${path24.relative(ctx.cwd, p) || p}`);
10915
11183
  }
10916
11184
  if (jobsScaffold?.planned?.length) {
10917
11185
  printInfo(
10918
11186
  `Jobs scaffold \u2014 ${jobsScaffold.planned.length} template targets`
10919
11187
  );
10920
11188
  for (const p of jobsScaffold.planned) {
10921
- console.log(` ${theme.muted(icons.arrow)} ${path22.relative(ctx.cwd, p) || p}`);
11189
+ console.log(` ${theme.muted(icons.arrow)} ${path24.relative(ctx.cwd, p) || p}`);
10922
11190
  }
10923
11191
  }
10924
11192
  if (eventsScaffold?.planned?.length) {
@@ -10926,7 +11194,7 @@ var SubsystemInstallCommand = class extends Command3 {
10926
11194
  `Events scaffold \u2014 ${eventsScaffold.planned.length} template targets`
10927
11195
  );
10928
11196
  for (const p of eventsScaffold.planned) {
10929
- console.log(` ${theme.muted(icons.arrow)} ${path22.relative(ctx.cwd, p) || p}`);
11197
+ console.log(` ${theme.muted(icons.arrow)} ${path24.relative(ctx.cwd, p) || p}`);
10930
11198
  }
10931
11199
  }
10932
11200
  if (integrationScaffold?.planned?.length) {
@@ -10934,7 +11202,7 @@ var SubsystemInstallCommand = class extends Command3 {
10934
11202
  `Integration scaffold \u2014 ${integrationScaffold.planned.length} template targets`
10935
11203
  );
10936
11204
  for (const p of integrationScaffold.planned) {
10937
- console.log(` ${theme.muted(icons.arrow)} ${path22.relative(ctx.cwd, p) || p}`);
11205
+ console.log(` ${theme.muted(icons.arrow)} ${path24.relative(ctx.cwd, p) || p}`);
10938
11206
  }
10939
11207
  }
10940
11208
  if (bridgeScaffold?.planned?.length) {
@@ -10942,7 +11210,7 @@ var SubsystemInstallCommand = class extends Command3 {
10942
11210
  `Bridge scaffold \u2014 ${bridgeScaffold.planned.length} template targets`
10943
11211
  );
10944
11212
  for (const p of bridgeScaffold.planned) {
10945
- console.log(` ${theme.muted(icons.arrow)} ${path22.relative(ctx.cwd, p) || p}`);
11213
+ console.log(` ${theme.muted(icons.arrow)} ${path24.relative(ctx.cwd, p) || p}`);
10946
11214
  }
10947
11215
  }
10948
11216
  if (observabilityScaffold?.planned?.length) {
@@ -10950,7 +11218,7 @@ var SubsystemInstallCommand = class extends Command3 {
10950
11218
  `Observability scaffold \u2014 ${observabilityScaffold.planned.length} template targets`
10951
11219
  );
10952
11220
  for (const p of observabilityScaffold.planned) {
10953
- console.log(` ${theme.muted(icons.arrow)} ${path22.relative(ctx.cwd, p) || p}`);
11221
+ console.log(` ${theme.muted(icons.arrow)} ${path24.relative(ctx.cwd, p) || p}`);
10954
11222
  }
10955
11223
  }
10956
11224
  if (authScaffold?.planned?.length) {
@@ -10958,7 +11226,7 @@ var SubsystemInstallCommand = class extends Command3 {
10958
11226
  `Auth scaffold \u2014 ${authScaffold.planned.length} template targets`
10959
11227
  );
10960
11228
  for (const p of authScaffold.planned) {
10961
- console.log(` ${theme.muted(icons.arrow)} ${path22.relative(ctx.cwd, p) || p}`);
11229
+ console.log(` ${theme.muted(icons.arrow)} ${path24.relative(ctx.cwd, p) || p}`);
10962
11230
  }
10963
11231
  }
10964
11232
  return 0;
@@ -11067,6 +11335,143 @@ var SubsystemInstallCommand = class extends Command3 {
11067
11335
  }
11068
11336
  return 0;
11069
11337
  }
11338
+ /**
11339
+ * ADR-037: package-mode install. The subsystem runtime lives in the
11340
+ * published `@pattern-stack/codegen` package, so installing reduces to a
11341
+ * config + barrel operation with NO file vendoring:
11342
+ *
11343
+ * 1. record the name under `subsystems.install` (the package-mode
11344
+ * source of truth for "installed");
11345
+ * 2. inject the per-subsystem `<name>:` config block via the same Hygen
11346
+ * action vendored mode uses (the block is runtime-agnostic — it only
11347
+ * writes YAML, never code); cache/storage have no config block, so this
11348
+ * step is skipped for them;
11349
+ * 3. regenerate the composition barrel (`<generated>/subsystems.ts`) and
11350
+ * the schema barrel (`<generated>/subsystems-schema.ts`) so AppModule's
11351
+ * `...SUBSYSTEM_MODULES` and drizzle-kit's schema pick up the new
11352
+ * install.
11353
+ *
11354
+ * Idempotent: a name already in `subsystems.install` is a no-op unless
11355
+ * `--force` is passed (which still re-runs config-block injection under
11356
+ * `--force-config` and always regenerates the barrels).
11357
+ */
11358
+ async executePackageMode(ctx, desc3, backend) {
11359
+ const configPath = path24.join(ctx.cwd, "codegen.config.yaml");
11360
+ const installed = configuredSubsystemNames(
11361
+ ctx.config
11362
+ );
11363
+ const already = installed.includes(desc3.name);
11364
+ if (already && !this.force) {
11365
+ if (isJsonMode()) {
11366
+ printJson({
11367
+ command: "subsystem install",
11368
+ subsystem: desc3.name,
11369
+ runtime: "package",
11370
+ status: "already-installed"
11371
+ });
11372
+ } else {
11373
+ printInfo(
11374
+ `${desc3.name} is already in subsystems.install (runtime: package \u2014 nothing to vendor). Pass --force to refresh the config block + barrels.`
11375
+ );
11376
+ }
11377
+ return 0;
11378
+ }
11379
+ const configSubsystem = PACKAGE_CONFIG_BLOCK[desc3.name];
11380
+ const configBlockOutcome = configSubsystem ? planConfigBlockAction(configPath, configSubsystem.detector, this.forceConfig) : null;
11381
+ if (configBlockOutcome === "parse-error") {
11382
+ printError(
11383
+ `codegen.config.yaml is not valid YAML: refusing to inject ${desc3.name} config block. Fix the YAML and re-run.`
11384
+ );
11385
+ return 1;
11386
+ }
11387
+ if (this.dryRun) {
11388
+ if (isJsonMode()) {
11389
+ printJson({
11390
+ command: "subsystem install",
11391
+ subsystem: desc3.name,
11392
+ runtime: "package",
11393
+ dryRun: true,
11394
+ installList: already ? installed : [...installed, desc3.name],
11395
+ configBlockOutcome
11396
+ });
11397
+ } else {
11398
+ printInfo(`Dry run \u2014 runtime: package (no files vendored).`);
11399
+ if (!already) printInfo(` would add '${desc3.name}' to subsystems.install`);
11400
+ if (configBlockOutcome) {
11401
+ printInfo(` ${desc3.name} config block would be ${configBlockOutcome}`);
11402
+ }
11403
+ printInfo(" would regenerate <generated>/subsystems.ts + subsystems-schema.ts");
11404
+ }
11405
+ return 0;
11406
+ }
11407
+ const installResult = ensureSubsystemInstalled(configPath, desc3.name);
11408
+ if (installResult.outcome === "parse-error") {
11409
+ printError(
11410
+ "codegen.config.yaml is not valid YAML: refusing to update subsystems.install. Fix the YAML and re-run."
11411
+ );
11412
+ return 1;
11413
+ }
11414
+ if (configSubsystem && configBlockOutcome) {
11415
+ const configResult = runConfigBlockAction({
11416
+ cwd: ctx.cwd,
11417
+ actionFolder: configSubsystem.actionFolder,
11418
+ configPath,
11419
+ subsystem: configSubsystem.detector,
11420
+ outcome: configBlockOutcome,
11421
+ json: isJsonMode()
11422
+ });
11423
+ if (!configResult.ok) {
11424
+ printError(
11425
+ `${desc3.name} config-block injection failed: ${configResult.error ?? "unknown error"}`
11426
+ );
11427
+ return 1;
11428
+ }
11429
+ }
11430
+ const refreshed = await loadContext({
11431
+ cwd: ctx.cwd,
11432
+ configPath: this.configPath,
11433
+ json: this.json,
11434
+ skipDetection: true
11435
+ });
11436
+ let barrelEmitted = [];
11437
+ let schemaEmitted = [];
11438
+ try {
11439
+ const generatedDir = resolveGeneratedDir(refreshed);
11440
+ const barrel = await regenerateSubsystemBarrel({ ctx: refreshed, generatedDir });
11441
+ barrelEmitted = barrel.emitted;
11442
+ const schema = await regenerateSubsystemSchemaBarrel({ ctx: refreshed, generatedDir });
11443
+ schemaEmitted = schema.emitted;
11444
+ } catch (err) {
11445
+ const msg = err instanceof Error ? err.message : String(err);
11446
+ printWarning(`barrel regeneration failed \u2014 ${msg}`);
11447
+ }
11448
+ if (isJsonMode()) {
11449
+ printJson({
11450
+ command: "subsystem install",
11451
+ subsystem: desc3.name,
11452
+ runtime: "package",
11453
+ backend,
11454
+ vendored: false,
11455
+ installList: installResult.install,
11456
+ installOutcome: installResult.outcome,
11457
+ configBlockOutcome,
11458
+ barrelEmitted,
11459
+ schemaEmitted
11460
+ });
11461
+ return 0;
11462
+ }
11463
+ printSuccess(`${desc3.name} installed (runtime: package \u2014 no files vendored).`);
11464
+ if (installResult.outcome === "added") {
11465
+ printInfo(`Added '${desc3.name}' to subsystems.install.`);
11466
+ }
11467
+ printInfo(
11468
+ `Regenerated <generated>/subsystems.ts (${barrelEmitted.join(", ") || "none"}) + subsystems-schema.ts (${schemaEmitted.join(", ") || "none"}).`
11469
+ );
11470
+ printInfo(
11471
+ "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."
11472
+ );
11473
+ return 0;
11474
+ }
11070
11475
  /**
11071
11476
  * OPENAPI-4: install flow for the config-only `openapi-config`
11072
11477
  * pseudo-subsystem.
@@ -11078,7 +11483,7 @@ var SubsystemInstallCommand = class extends Command3 {
11078
11483
  * semantics as jobs/events/integration/bridge.
11079
11484
  */
11080
11485
  async executeOpenApiConfig(ctx) {
11081
- const configPath = path22.join(ctx.cwd, "codegen.config.yaml");
11486
+ const configPath = path24.join(ctx.cwd, "codegen.config.yaml");
11082
11487
  const outcome = planConfigBlockAction(configPath, "openapi", this.forceConfig);
11083
11488
  if (outcome === "parse-error") {
11084
11489
  printError(
@@ -11097,7 +11502,7 @@ var SubsystemInstallCommand = class extends Command3 {
11097
11502
  });
11098
11503
  } else {
11099
11504
  printInfo(`Dry run \u2014 openapi config block would be ${outcome}`);
11100
- console.log(` ${theme.muted(icons.arrow)} ${path22.relative(ctx.cwd, configPath) || configPath}`);
11505
+ console.log(` ${theme.muted(icons.arrow)} ${path24.relative(ctx.cwd, configPath) || configPath}`);
11101
11506
  }
11102
11507
  return 0;
11103
11508
  }
@@ -11192,7 +11597,7 @@ var SubsystemInstallCommand = class extends Command3 {
11192
11597
  );
11193
11598
  for (const p of scaffold.planned) {
11194
11599
  console.log(
11195
- ` ${theme.muted(icons.arrow)} ${path22.relative(ctx.cwd, p) || p}`
11600
+ ` ${theme.muted(icons.arrow)} ${path24.relative(ctx.cwd, p) || p}`
11196
11601
  );
11197
11602
  }
11198
11603
  return 0;
@@ -11216,10 +11621,10 @@ var SubsystemInstallCommand = class extends Command3 {
11216
11621
  }
11217
11622
  };
11218
11623
  function planConfigBlockAction(configPath, subsystem, forceConfig) {
11219
- if (!fs11.existsSync(configPath)) {
11624
+ if (!fs13.existsSync(configPath)) {
11220
11625
  return "inject";
11221
11626
  }
11222
- const source = fs11.readFileSync(configPath, "utf-8");
11627
+ const source = fs13.readFileSync(configPath, "utf-8");
11223
11628
  const state = detectConfigBlock(source, subsystem);
11224
11629
  if (state === "parse-error") return "parse-error";
11225
11630
  if (state === "missing") return "inject";
@@ -11242,9 +11647,9 @@ function runConfigBlockAction(input) {
11242
11647
  );
11243
11648
  }
11244
11649
  try {
11245
- const source = fs11.readFileSync(input.configPath, "utf-8");
11650
+ const source = fs13.readFileSync(input.configPath, "utf-8");
11246
11651
  const stripped = stripConfigBlock(source, input.subsystem);
11247
- fs11.writeFileSync(input.configPath, stripped, "utf-8");
11652
+ fs13.writeFileSync(input.configPath, stripped, "utf-8");
11248
11653
  } catch (err) {
11249
11654
  const message = err instanceof Error ? err.message : String(err);
11250
11655
  return { ok: false, error: `strip failed: ${message}` };
@@ -11282,8 +11687,8 @@ function runJobsScaffold(cwd, config, opts) {
11282
11687
  const locals = resolveJobsScaffoldLocals({
11283
11688
  cwd,
11284
11689
  config,
11285
- fileExists: (p) => fs11.existsSync(p),
11286
- readFile: (p) => fs11.existsSync(p) ? fs11.readFileSync(p, "utf-8") : null
11690
+ fileExists: (p) => fs13.existsSync(p),
11691
+ readFile: (p) => fs13.existsSync(p) ? fs13.readFileSync(p, "utf-8") : null
11287
11692
  });
11288
11693
  const planned = [
11289
11694
  ...!locals.workerExists ? [locals.workerPath] : [],
@@ -11340,7 +11745,7 @@ function runEventsScaffold(cwd, config, opts) {
11340
11745
  const locals = resolveEventsScaffoldLocals({
11341
11746
  cwd,
11342
11747
  config,
11343
- fileExists: (p) => fs11.existsSync(p)
11748
+ fileExists: (p) => fs13.existsSync(p)
11344
11749
  });
11345
11750
  const planned = [
11346
11751
  locals.configPath,
@@ -11396,7 +11801,7 @@ function runIntegrationScaffold(cwd, config, opts) {
11396
11801
  const locals = resolveIntegrationScaffoldLocals({
11397
11802
  cwd,
11398
11803
  config,
11399
- fileExists: (p) => fs11.existsSync(p)
11804
+ fileExists: (p) => fs13.existsSync(p)
11400
11805
  });
11401
11806
  const planned = [
11402
11807
  locals.configPath,
@@ -11451,7 +11856,7 @@ function runBridgeScaffold(cwd, config, opts) {
11451
11856
  const locals = resolveBridgeScaffoldLocals({
11452
11857
  cwd,
11453
11858
  config,
11454
- fileExists: (p) => fs11.existsSync(p)
11859
+ fileExists: (p) => fs13.existsSync(p)
11455
11860
  });
11456
11861
  const planned = [
11457
11862
  locals.configPath,
@@ -11505,7 +11910,7 @@ function runObservabilityScaffold(cwd, config, opts) {
11505
11910
  const locals = resolveObservabilityScaffoldLocals({
11506
11911
  cwd,
11507
11912
  config,
11508
- fileExists: (p) => fs11.existsSync(p)
11913
+ fileExists: (p) => fs13.existsSync(p)
11509
11914
  });
11510
11915
  const planned = [locals.configPath, locals.appModulePath];
11511
11916
  const configBlockOutcome = planConfigBlockAction(
@@ -11574,9 +11979,9 @@ function runAuthScaffold(cwd, config, opts) {
11574
11979
  if (opts.dryRun) {
11575
11980
  return { ok: true, planned, configBlockOutcome };
11576
11981
  }
11577
- if (!fs11.existsSync(locals.envConfigPath)) {
11578
- fs11.mkdirSync(path22.dirname(locals.envConfigPath), { recursive: true });
11579
- fs11.writeFileSync(locals.envConfigPath, "", "utf-8");
11982
+ if (!fs13.existsSync(locals.envConfigPath)) {
11983
+ fs13.mkdirSync(path24.dirname(locals.envConfigPath), { recursive: true });
11984
+ fs13.writeFileSync(locals.envConfigPath, "", "utf-8");
11580
11985
  }
11581
11986
  const result = invokeHygen({
11582
11987
  generator: "subsystem",
@@ -11612,57 +12017,57 @@ function runAuthScaffold(cwd, config, opts) {
11612
12017
  return { ok: true, planned, configBlockOutcome };
11613
12018
  }
11614
12019
  function authIntegrationsExamplesRoot() {
11615
- const pkgRoot = path22.resolve(import.meta.dirname, "..", "..", "..");
11616
- const topLevel = path22.join(pkgRoot, "examples", "auth-integrations");
11617
- if (fs11.existsSync(topLevel)) return topLevel;
11618
- return path22.join(pkgRoot, "dist", "examples", "auth-integrations");
12020
+ const pkgRoot = path24.resolve(import.meta.dirname, "..", "..", "..");
12021
+ const topLevel = path24.join(pkgRoot, "examples", "auth-integrations");
12022
+ if (fs13.existsSync(topLevel)) return topLevel;
12023
+ return path24.join(pkgRoot, "dist", "examples", "auth-integrations");
11619
12024
  }
11620
12025
  function copyTreeIdempotent(srcDir, destDir, force, transform) {
11621
12026
  const written = [];
11622
12027
  const skipped = [];
11623
12028
  const walk = (src, dest) => {
11624
- const entries = fs11.readdirSync(src, { withFileTypes: true });
12029
+ const entries = fs13.readdirSync(src, { withFileTypes: true });
11625
12030
  for (const entry of entries) {
11626
- const srcPath = path22.join(src, entry.name);
11627
- const destPath = path22.join(dest, entry.name);
12031
+ const srcPath = path24.join(src, entry.name);
12032
+ const destPath = path24.join(dest, entry.name);
11628
12033
  if (entry.isDirectory()) {
11629
- fs11.mkdirSync(destPath, { recursive: true });
12034
+ fs13.mkdirSync(destPath, { recursive: true });
11630
12035
  walk(srcPath, destPath);
11631
12036
  continue;
11632
12037
  }
11633
12038
  if (!entry.isFile()) continue;
11634
- if (fs11.existsSync(destPath) && !force) {
12039
+ if (fs13.existsSync(destPath) && !force) {
11635
12040
  skipped.push(destPath);
11636
12041
  continue;
11637
12042
  }
11638
- fs11.mkdirSync(path22.dirname(destPath), { recursive: true });
12043
+ fs13.mkdirSync(path24.dirname(destPath), { recursive: true });
11639
12044
  const isTextSource = transform && (entry.name.endsWith(".ts") || entry.name.endsWith(".tsx"));
11640
12045
  if (isTextSource && transform) {
11641
- const raw = fs11.readFileSync(srcPath, "utf-8");
11642
- fs11.writeFileSync(destPath, transform(raw, destPath), "utf-8");
12046
+ const raw = fs13.readFileSync(srcPath, "utf-8");
12047
+ fs13.writeFileSync(destPath, transform(raw, destPath), "utf-8");
11643
12048
  } else {
11644
- fs11.copyFileSync(srcPath, destPath);
12049
+ fs13.copyFileSync(srcPath, destPath);
11645
12050
  }
11646
12051
  written.push(destPath);
11647
12052
  }
11648
12053
  };
11649
- if (!fs11.existsSync(srcDir)) return { written, skipped };
11650
- fs11.mkdirSync(destDir, { recursive: true });
12054
+ if (!fs13.existsSync(srcDir)) return { written, skipped };
12055
+ fs13.mkdirSync(destDir, { recursive: true });
11651
12056
  walk(srcDir, destDir);
11652
12057
  return { written, skipped };
11653
12058
  }
11654
12059
  var AUTH_BARE_IMPORT_RE = /(['"])@pattern-stack\/codegen\/runtime\/subsystems\/auth\1/g;
11655
12060
  function buildAuthImportRewriter(subsystemsRoot) {
11656
- const authRoot = path22.join(subsystemsRoot, "auth");
12061
+ const authRoot = path24.join(subsystemsRoot, "auth");
11657
12062
  return (content, destPath) => {
11658
12063
  if (!AUTH_BARE_IMPORT_RE.test(content)) {
11659
12064
  AUTH_BARE_IMPORT_RE.lastIndex = 0;
11660
12065
  return content;
11661
12066
  }
11662
12067
  AUTH_BARE_IMPORT_RE.lastIndex = 0;
11663
- let rel2 = path22.relative(path22.dirname(destPath), authRoot);
12068
+ let rel2 = path24.relative(path24.dirname(destPath), authRoot);
11664
12069
  if (!rel2.startsWith(".")) rel2 = `./${rel2}`;
11665
- const relPosix = rel2.split(path22.sep).join("/");
12070
+ const relPosix = rel2.split(path24.sep).join("/");
11666
12071
  return content.replace(
11667
12072
  AUTH_BARE_IMPORT_RE,
11668
12073
  (_match, quote) => `${quote}${relPosix}${quote}`
@@ -11673,20 +12078,20 @@ function runAuthIntegrationsScaffold(cwd, config, opts) {
11673
12078
  const locals = resolveAuthIntegrationsScaffoldLocals({
11674
12079
  cwd,
11675
12080
  config,
11676
- fileExists: (p) => fs11.existsSync(p),
11677
- readFile: (p) => fs11.existsSync(p) ? fs11.readFileSync(p, "utf-8") : null
12081
+ fileExists: (p) => fs13.existsSync(p),
12082
+ readFile: (p) => fs13.existsSync(p) ? fs13.readFileSync(p, "utf-8") : null
11678
12083
  });
11679
12084
  const examplesRoot = authIntegrationsExamplesRoot();
11680
- if (!fs11.existsSync(examplesRoot)) {
12085
+ if (!fs13.existsSync(examplesRoot)) {
11681
12086
  return {
11682
12087
  ok: false,
11683
12088
  planned: [],
11684
12089
  error: `auth-integrations starter source missing: ${examplesRoot}`
11685
12090
  };
11686
12091
  }
11687
- const adaptersSrc = path22.join(examplesRoot, "runtime", "connections");
11688
- const adaptersDest = path22.join(locals.vendorRoot, "connections");
11689
- const connectionYamlSrc = path22.join(
12092
+ const adaptersSrc = path24.join(examplesRoot, "runtime", "connections");
12093
+ const adaptersDest = path24.join(locals.vendorRoot, "connections");
12094
+ const connectionYamlSrc = path24.join(
11690
12095
  examplesRoot,
11691
12096
  "definitions",
11692
12097
  "entities",
@@ -11715,11 +12120,11 @@ function runAuthIntegrationsScaffold(cwd, config, opts) {
11715
12120
  let yamlWritten = false;
11716
12121
  let yamlSkipped = false;
11717
12122
  try {
11718
- if (fs11.existsSync(connectionYamlDest) && !opts.force) {
12123
+ if (fs13.existsSync(connectionYamlDest) && !opts.force) {
11719
12124
  yamlSkipped = true;
11720
- } else if (fs11.existsSync(connectionYamlSrc)) {
11721
- fs11.mkdirSync(path22.dirname(connectionYamlDest), { recursive: true });
11722
- fs11.copyFileSync(connectionYamlSrc, connectionYamlDest);
12125
+ } else if (fs13.existsSync(connectionYamlSrc)) {
12126
+ fs13.mkdirSync(path24.dirname(connectionYamlDest), { recursive: true });
12127
+ fs13.copyFileSync(connectionYamlSrc, connectionYamlDest);
11723
12128
  yamlWritten = true;
11724
12129
  }
11725
12130
  } catch (err) {
@@ -11784,7 +12189,7 @@ var SubsystemListCommand = class extends Command3 {
11784
12189
  name: s.name,
11785
12190
  status: inst ? inst.status : "available",
11786
12191
  backend: inst ? inst.backend : null,
11787
- path: inst ? path22.relative(ctx.cwd, inst.path) || inst.path : null
12192
+ path: inst ? path24.relative(ctx.cwd, inst.path) || inst.path : null
11788
12193
  };
11789
12194
  });
11790
12195
  if (isJsonMode()) {
@@ -11873,14 +12278,14 @@ var SubsystemRemoveCommand = class extends Command3 {
11873
12278
  return 1;
11874
12279
  }
11875
12280
  const subsystemDir = target.path;
11876
- if (!fs11.existsSync(subsystemDir)) {
12281
+ if (!fs13.existsSync(subsystemDir)) {
11877
12282
  printError(
11878
12283
  `Detected install at ${subsystemDir} but the directory is gone \u2014 refusing to act.`
11879
12284
  );
11880
12285
  return 1;
11881
12286
  }
11882
12287
  if (!this.force) {
11883
- const rel2 = path22.relative(ctx.cwd, subsystemDir) || subsystemDir;
12288
+ const rel2 = path24.relative(ctx.cwd, subsystemDir) || subsystemDir;
11884
12289
  const gitCheck = checkGitSafety([rel2], ctx.cwd);
11885
12290
  if (gitCheck.inRepo && !gitCheck.clean) {
11886
12291
  printWarning(
@@ -11890,7 +12295,7 @@ var SubsystemRemoveCommand = class extends Command3 {
11890
12295
  }
11891
12296
  }
11892
12297
  try {
11893
- fs11.rmSync(subsystemDir, { recursive: true, force: true });
12298
+ fs13.rmSync(subsystemDir, { recursive: true, force: true });
11894
12299
  } catch (err) {
11895
12300
  const message = err instanceof Error ? err.message : String(err);
11896
12301
  printError(`Failed to remove ${subsystemDir}: ${message}`);
@@ -11916,7 +12321,7 @@ var SubsystemRemoveCommand = class extends Command3 {
11916
12321
  return 0;
11917
12322
  }
11918
12323
  printSuccess(
11919
- `${desc3.name} subsystem removed (${path22.relative(ctx.cwd, subsystemDir) || subsystemDir}).`
12324
+ `${desc3.name} subsystem removed (${path24.relative(ctx.cwd, subsystemDir) || subsystemDir}).`
11920
12325
  );
11921
12326
  if (barrelRegenerated) {
11922
12327
  printInfo("Regenerated <generated>/subsystems.ts barrel.");
@@ -11944,28 +12349,28 @@ var subsystemNoun = {
11944
12349
  var subsystem_default = subsystemNoun;
11945
12350
 
11946
12351
  // src/cli/commands/project.ts
11947
- import fs17 from "fs";
11948
- import path28 from "path";
12352
+ import fs19 from "fs";
12353
+ import path30 from "path";
11949
12354
  import readline from "readline";
11950
12355
  import { Command as Command7, Option as Option7 } from "clipanion";
11951
12356
  import { stringify as stringifyYaml2 } from "yaml";
11952
12357
 
11953
12358
  // src/cli/shared/init-scaffold.ts
11954
- import fs12 from "fs";
11955
- import path23 from "path";
12359
+ import fs14 from "fs";
12360
+ import path25 from "path";
11956
12361
  import { stringify as stringifyYaml } from "yaml";
11957
12362
  function runtimeRoot2() {
11958
- const pkgRoot = path23.resolve(import.meta.dirname, "..", "..", "..");
11959
- const topLevel = path23.join(pkgRoot, "runtime");
11960
- if (fs12.existsSync(topLevel)) return topLevel;
11961
- return path23.join(pkgRoot, "dist", "runtime");
12363
+ const pkgRoot = path25.resolve(import.meta.dirname, "..", "..", "..");
12364
+ const topLevel = path25.join(pkgRoot, "runtime");
12365
+ if (fs14.existsSync(topLevel)) return topLevel;
12366
+ return path25.join(pkgRoot, "dist", "runtime");
11962
12367
  }
11963
12368
  function resolveRuntimePath(cwd) {
11964
- const shimDir = path23.join(cwd, "src", "shared", "base-classes");
11965
- return path23.relative(shimDir, runtimeRoot2());
12369
+ const shimDir = path25.join(cwd, "src", "shared", "base-classes");
12370
+ return path25.relative(shimDir, runtimeRoot2());
11966
12371
  }
11967
12372
  function loadRuntimeFile(relPath2) {
11968
- return fs12.readFileSync(path23.join(runtimeRoot2(), relPath2), "utf-8");
12373
+ return fs14.readFileSync(path25.join(runtimeRoot2(), relPath2), "utf-8");
11969
12374
  }
11970
12375
  var VENDORED_RUNTIME_FILES = [
11971
12376
  // base-classes — consumer-facing inheritance targets
@@ -12382,10 +12787,10 @@ function mergeTsconfig(raw) {
12382
12787
  };
12383
12788
  }
12384
12789
  function relOf(cwd, abs) {
12385
- return path23.relative(cwd, abs) || abs;
12790
+ return path25.relative(cwd, abs) || abs;
12386
12791
  }
12387
12792
  function fileEntry(cwd, absPath, content, opts) {
12388
- const exists = fs12.existsSync(absPath);
12793
+ const exists = fs14.existsSync(absPath);
12389
12794
  let action;
12390
12795
  let reason = opts.skipReason;
12391
12796
  if (!exists) {
@@ -12400,7 +12805,7 @@ function fileEntry(cwd, absPath, content, opts) {
12400
12805
  return { path: absPath, relPath: relOf(cwd, absPath), action, content, reason };
12401
12806
  }
12402
12807
  function dirEntry(cwd, absPath) {
12403
- const exists = fs12.existsSync(absPath);
12808
+ const exists = fs14.existsSync(absPath);
12404
12809
  return {
12405
12810
  path: absPath,
12406
12811
  relPath: relOf(cwd, absPath),
@@ -12433,7 +12838,7 @@ async function buildInitPlan(ctx, options) {
12433
12838
  const runtimePath = options.runtimePath ?? resolveRuntimePath(cwd);
12434
12839
  const entries = [];
12435
12840
  {
12436
- const configPath = path23.join(cwd, "codegen.config.yaml");
12841
+ const configPath = path25.join(cwd, "codegen.config.yaml");
12437
12842
  const config = {
12438
12843
  // Runtime mode (ADR-037). `package` (default) imports the runtime from
12439
12844
  // `@pattern-stack/codegen/*`; `vendored` imports it via `@shared/*` and
@@ -12468,9 +12873,9 @@ async function buildInitPlan(ctx, options) {
12468
12873
  entries.push(fileEntry(cwd, configPath, content, { force }));
12469
12874
  }
12470
12875
  {
12471
- const tsconfigPath = path23.join(cwd, "tsconfig.json");
12472
- if (fs12.existsSync(tsconfigPath)) {
12473
- const raw = fs12.readFileSync(tsconfigPath, "utf-8");
12876
+ const tsconfigPath = path25.join(cwd, "tsconfig.json");
12877
+ if (fs14.existsSync(tsconfigPath)) {
12878
+ const raw = fs14.readFileSync(tsconfigPath, "utf-8");
12474
12879
  const merged = mergeTsconfig(raw);
12475
12880
  if (merged.parseError) {
12476
12881
  entries.push({
@@ -12515,7 +12920,7 @@ async function buildInitPlan(ctx, options) {
12515
12920
  entries.push(
12516
12921
  fileEntry(
12517
12922
  cwd,
12518
- path23.join(cwd, "src", "shared", "database", "database.module.ts"),
12923
+ path25.join(cwd, "src", "shared", "database", "database.module.ts"),
12519
12924
  databaseModuleContent(runtimeMode),
12520
12925
  { force }
12521
12926
  )
@@ -12523,14 +12928,14 @@ async function buildInitPlan(ctx, options) {
12523
12928
  if (runtimeMode === "vendored") {
12524
12929
  for (const v of VENDORED_RUNTIME_FILES) {
12525
12930
  entries.push(
12526
- fileEntry(cwd, path23.join(cwd, v.target), loadRuntimeFile(v.runtime), { force })
12931
+ fileEntry(cwd, path25.join(cwd, v.target), loadRuntimeFile(v.runtime), { force })
12527
12932
  );
12528
12933
  }
12529
12934
  }
12530
12935
  entries.push(
12531
12936
  fileEntry(
12532
12937
  cwd,
12533
- path23.join(cwd, "src", "generated", "modules.ts"),
12938
+ path25.join(cwd, "src", "generated", "modules.ts"),
12534
12939
  emptyModulesBarrel(),
12535
12940
  { force }
12536
12941
  )
@@ -12538,14 +12943,14 @@ async function buildInitPlan(ctx, options) {
12538
12943
  entries.push(
12539
12944
  fileEntry(
12540
12945
  cwd,
12541
- path23.join(cwd, "src", "generated", "schema.ts"),
12946
+ path25.join(cwd, "src", "generated", "schema.ts"),
12542
12947
  emptySchemaBarrel(),
12543
12948
  { force }
12544
12949
  )
12545
12950
  );
12546
12951
  {
12547
- const appModulePath = path23.join(cwd, "src", "app.module.ts");
12548
- if (!fs12.existsSync(appModulePath)) {
12952
+ const appModulePath = path25.join(cwd, "src", "app.module.ts");
12953
+ if (!fs14.existsSync(appModulePath)) {
12549
12954
  entries.push({
12550
12955
  path: appModulePath,
12551
12956
  relPath: relOf(cwd, appModulePath),
@@ -12562,8 +12967,8 @@ async function buildInitPlan(ctx, options) {
12562
12967
  }
12563
12968
  }
12564
12969
  {
12565
- const mainPath = path23.join(cwd, "src", "main.ts");
12566
- if (!fs12.existsSync(mainPath)) {
12970
+ const mainPath = path25.join(cwd, "src", "main.ts");
12971
+ if (!fs14.existsSync(mainPath)) {
12567
12972
  entries.push({
12568
12973
  path: mainPath,
12569
12974
  relPath: relOf(cwd, mainPath),
@@ -12580,8 +12985,8 @@ async function buildInitPlan(ctx, options) {
12580
12985
  }
12581
12986
  }
12582
12987
  {
12583
- const schemaPath = path23.join(cwd, "src", "schema.ts");
12584
- if (!fs12.existsSync(schemaPath)) {
12988
+ const schemaPath = path25.join(cwd, "src", "schema.ts");
12989
+ if (!fs14.existsSync(schemaPath)) {
12585
12990
  entries.push({
12586
12991
  path: schemaPath,
12587
12992
  relPath: relOf(cwd, schemaPath),
@@ -12597,14 +13002,14 @@ async function buildInitPlan(ctx, options) {
12597
13002
  });
12598
13003
  }
12599
13004
  }
12600
- entries.push(dirEntry(cwd, path23.join(cwd, "entities")));
13005
+ entries.push(dirEntry(cwd, path25.join(cwd, "entities")));
12601
13006
  {
12602
- const entitiesDir = path23.join(cwd, "entities");
12603
- const examplePath = path23.join(entitiesDir, "example.yaml");
12604
- const hasOtherYamls = fs12.existsSync(entitiesDir) && findYamlFiles(entitiesDir).some(
12605
- (f) => path23.basename(f) !== "example.yaml"
13007
+ const entitiesDir = path25.join(cwd, "entities");
13008
+ const examplePath = path25.join(entitiesDir, "example.yaml");
13009
+ const hasOtherYamls = fs14.existsSync(entitiesDir) && findYamlFiles(entitiesDir).some(
13010
+ (f) => path25.basename(f) !== "example.yaml"
12606
13011
  );
12607
- if (fs12.existsSync(examplePath)) {
13012
+ if (fs14.existsSync(examplePath)) {
12608
13013
  entries.push({
12609
13014
  path: examplePath,
12610
13015
  relPath: relOf(cwd, examplePath),
@@ -12650,7 +13055,7 @@ function writePlan(plan) {
12650
13055
  continue;
12651
13056
  }
12652
13057
  if (e.directory) {
12653
- fs12.mkdirSync(e.path, { recursive: true });
13058
+ fs14.mkdirSync(e.path, { recursive: true });
12654
13059
  created.push(e);
12655
13060
  continue;
12656
13061
  }
@@ -12658,8 +13063,8 @@ function writePlan(plan) {
12658
13063
  skipped.push(e);
12659
13064
  continue;
12660
13065
  }
12661
- fs12.mkdirSync(path23.dirname(e.path), { recursive: true });
12662
- fs12.writeFileSync(e.path, e.content, "utf-8");
13066
+ fs14.mkdirSync(path25.dirname(e.path), { recursive: true });
13067
+ fs14.writeFileSync(e.path, e.content, "utf-8");
12663
13068
  if (e.action === "create") created.push(e);
12664
13069
  else if (e.action === "merge") merged.push(e);
12665
13070
  else if (e.action === "overwrite") overwritten.push(e);
@@ -12668,8 +13073,8 @@ function writePlan(plan) {
12668
13073
  }
12669
13074
 
12670
13075
  // src/cli/commands/project-upgrade-openapi.ts
12671
- import fs13 from "fs";
12672
- import path24 from "path";
13076
+ import fs15 from "fs";
13077
+ import path26 from "path";
12673
13078
  import { Command as Command4, Option as Option4 } from "clipanion";
12674
13079
  import { Project, IndentationText, QuoteKind, NewLineKind } from "ts-morph";
12675
13080
 
@@ -12908,35 +13313,35 @@ var MAIN_SWAGGER_IMPORTS = [
12908
13313
  "import { OPENAPI_REGISTRY, OpenApiRegistry } from './shared/openapi';"
12909
13314
  ];
12910
13315
  function runtimeRoot3() {
12911
- const pkgRoot = path24.resolve(import.meta.dirname, "..", "..", "..");
12912
- const topLevel = path24.join(pkgRoot, "runtime");
12913
- if (fs13.existsSync(topLevel)) return topLevel;
12914
- return path24.join(pkgRoot, "dist", "runtime");
13316
+ const pkgRoot = path26.resolve(import.meta.dirname, "..", "..", "..");
13317
+ const topLevel = path26.join(pkgRoot, "runtime");
13318
+ if (fs15.existsSync(topLevel)) return topLevel;
13319
+ return path26.join(pkgRoot, "dist", "runtime");
12915
13320
  }
12916
13321
  function loadRuntimeFile2(rel2) {
12917
- return fs13.readFileSync(path24.join(runtimeRoot3(), rel2), "utf-8");
13322
+ return fs15.readFileSync(path26.join(runtimeRoot3(), rel2), "utf-8");
12918
13323
  }
12919
13324
  function resolveProjectRoot(startDir) {
12920
- let dir = path24.resolve(startDir);
13325
+ let dir = path26.resolve(startDir);
12921
13326
  for (let i = 0; i < 16; i++) {
12922
- if (fs13.existsSync(path24.join(dir, "codegen.config.yaml")) || fs13.existsSync(path24.join(dir, "package.json"))) {
13327
+ if (fs15.existsSync(path26.join(dir, "codegen.config.yaml")) || fs15.existsSync(path26.join(dir, "package.json"))) {
12923
13328
  return dir;
12924
13329
  }
12925
- const parent = path24.dirname(dir);
13330
+ const parent = path26.dirname(dir);
12926
13331
  if (parent === dir) break;
12927
13332
  dir = parent;
12928
13333
  }
12929
- return path24.resolve(startDir);
13334
+ return path26.resolve(startDir);
12930
13335
  }
12931
13336
  async function runUpgradeOpenapi(opts) {
12932
13337
  const { projectRoot, dryRun, force } = opts;
12933
13338
  const changes = [];
12934
13339
  for (const v of OPENAPI_VENDORED_FILES) {
12935
- const target = path24.join(projectRoot, v.target);
12936
- const exists = fs13.existsSync(target);
13340
+ const target = path26.join(projectRoot, v.target);
13341
+ const exists = fs15.existsSync(target);
12937
13342
  const newContent = loadRuntimeFile2(v.runtime);
12938
13343
  if (exists && !force) {
12939
- const existing = fs13.readFileSync(target, "utf-8");
13344
+ const existing = fs15.readFileSync(target, "utf-8");
12940
13345
  if (existing === newContent) {
12941
13346
  changes.push({ path: v.target, action: "unchanged" });
12942
13347
  } else {
@@ -12948,8 +13353,8 @@ async function runUpgradeOpenapi(opts) {
12948
13353
  }
12949
13354
  } else {
12950
13355
  if (!dryRun) {
12951
- fs13.mkdirSync(path24.dirname(target), { recursive: true });
12952
- fs13.writeFileSync(target, newContent);
13356
+ fs15.mkdirSync(path26.dirname(target), { recursive: true });
13357
+ fs15.writeFileSync(target, newContent);
12953
13358
  }
12954
13359
  changes.push({
12955
13360
  path: v.target,
@@ -12957,8 +13362,8 @@ async function runUpgradeOpenapi(opts) {
12957
13362
  });
12958
13363
  }
12959
13364
  }
12960
- const appModulePath = path24.join(projectRoot, "src", "app.module.ts");
12961
- if (!fs13.existsSync(appModulePath)) {
13365
+ const appModulePath = path26.join(projectRoot, "src", "app.module.ts");
13366
+ if (!fs15.existsSync(appModulePath)) {
12962
13367
  return {
12963
13368
  projectRoot,
12964
13369
  changes,
@@ -13041,8 +13446,8 @@ async function runUpgradeOpenapi(opts) {
13041
13446
  } else {
13042
13447
  changes.push({ path: "src/app.module.ts", action: "unchanged" });
13043
13448
  }
13044
- const mainPath = path24.join(projectRoot, "src", "main.ts");
13045
- if (fs13.existsSync(mainPath)) {
13449
+ const mainPath = path26.join(projectRoot, "src", "main.ts");
13450
+ if (fs15.existsSync(mainPath)) {
13046
13451
  const mainSource = project.addSourceFileAtPath(mainPath);
13047
13452
  const mainBefore = mainSource.getFullText();
13048
13453
  const result = ensureMainSwaggerBlock(mainSource, {
@@ -13122,8 +13527,8 @@ var ProjectUpgradeOpenapiCommand = class extends Command4 {
13122
13527
  json = Option4.Boolean("--json", false);
13123
13528
  async execute() {
13124
13529
  if (this.json) setJsonMode(true);
13125
- const startDir = this.pathOpt ? path24.resolve(this.pathOpt) : process.cwd();
13126
- if (!fs13.existsSync(startDir)) {
13530
+ const startDir = this.pathOpt ? path26.resolve(this.pathOpt) : process.cwd();
13531
+ if (!fs15.existsSync(startDir)) {
13127
13532
  printError(`Directory not found: ${startDir}`);
13128
13533
  return 1;
13129
13534
  }
@@ -13198,18 +13603,18 @@ ${CONSUMER_SETUP_POINTER}
13198
13603
  };
13199
13604
 
13200
13605
  // src/cli/commands/project-update.ts
13201
- import fs16 from "fs";
13202
- import path27 from "path";
13606
+ import fs18 from "fs";
13607
+ import path29 from "path";
13203
13608
  import { Command as Command6, Option as Option6 } from "clipanion";
13204
13609
 
13205
13610
  // src/cli/commands/skills.ts
13206
- import fs15 from "fs";
13207
- import path26 from "path";
13611
+ import fs17 from "fs";
13612
+ import path28 from "path";
13208
13613
  import { Command as Command5, Option as Option5 } from "clipanion";
13209
13614
 
13210
13615
  // src/cli/shared/tree-copier.ts
13211
- import fs14 from "fs";
13212
- import path25 from "path";
13616
+ import fs16 from "fs";
13617
+ import path27 from "path";
13213
13618
  var TEXT_EXTENSIONS = [".ts", ".tsx", ".md", ".mdx", ".yaml", ".yml", ".json"];
13214
13619
  function isTextFile(name) {
13215
13620
  return TEXT_EXTENSIONS.some((ext) => name.endsWith(ext));
@@ -13222,26 +13627,26 @@ function copyTreeWithReport(opts) {
13222
13627
  updated: [],
13223
13628
  unchanged: []
13224
13629
  };
13225
- if (!fs14.existsSync(srcDir) || !fs14.statSync(srcDir).isDirectory()) {
13630
+ if (!fs16.existsSync(srcDir) || !fs16.statSync(srcDir).isDirectory()) {
13226
13631
  throw new Error(`tree-copier source directory not found: ${srcDir}`);
13227
13632
  }
13228
13633
  const walk = (relDir) => {
13229
- const absSrcDir = path25.join(srcDir, relDir);
13230
- for (const entry of fs14.readdirSync(absSrcDir, { withFileTypes: true })) {
13231
- const relPath2 = relDir ? path25.posix.join(relDir, entry.name) : entry.name;
13232
- const absSrc = path25.join(srcDir, relPath2);
13634
+ const absSrcDir = path27.join(srcDir, relDir);
13635
+ for (const entry of fs16.readdirSync(absSrcDir, { withFileTypes: true })) {
13636
+ const relPath2 = relDir ? path27.posix.join(relDir, entry.name) : entry.name;
13637
+ const absSrc = path27.join(srcDir, relPath2);
13233
13638
  if (entry.isDirectory()) {
13234
13639
  walk(relPath2);
13235
13640
  continue;
13236
13641
  }
13237
13642
  if (!entry.isFile()) continue;
13238
13643
  if (include && !include(relPath2)) continue;
13239
- const dest = path25.join(destDir, relPath2);
13240
- let content = fs14.readFileSync(absSrc, "utf-8");
13644
+ const dest = path27.join(destDir, relPath2);
13645
+ let content = fs16.readFileSync(absSrc, "utf-8");
13241
13646
  if (transform && isTextFile(entry.name)) {
13242
13647
  content = transform(content, dest);
13243
13648
  }
13244
- const existing = fs14.existsSync(dest) ? fs14.readFileSync(dest, "utf-8") : null;
13649
+ const existing = fs16.existsSync(dest) ? fs16.readFileSync(dest, "utf-8") : null;
13245
13650
  let action;
13246
13651
  if (existing === null) {
13247
13652
  action = "created";
@@ -13251,8 +13656,8 @@ function copyTreeWithReport(opts) {
13251
13656
  action = "updated";
13252
13657
  }
13253
13658
  if (!dryRun && action !== "unchanged") {
13254
- fs14.mkdirSync(path25.dirname(dest), { recursive: true });
13255
- fs14.writeFileSync(dest, content, "utf-8");
13659
+ fs16.mkdirSync(path27.dirname(dest), { recursive: true });
13660
+ fs16.writeFileSync(dest, content, "utf-8");
13256
13661
  }
13257
13662
  const record = { relPath: relPath2, dest, action };
13258
13663
  report.entries.push(record);
@@ -13265,23 +13670,23 @@ function copyTreeWithReport(opts) {
13265
13670
 
13266
13671
  // src/cli/commands/skills.ts
13267
13672
  function consumerSkillsRoot() {
13268
- const pkgRoot = path26.resolve(import.meta.dirname, "..", "..", "..");
13269
- const topLevel = path26.join(pkgRoot, "consumer-skills");
13270
- if (fs15.existsSync(topLevel)) return topLevel;
13271
- return path26.join(pkgRoot, "dist", "consumer-skills");
13673
+ const pkgRoot = path28.resolve(import.meta.dirname, "..", "..", "..");
13674
+ const topLevel = path28.join(pkgRoot, "consumer-skills");
13675
+ if (fs17.existsSync(topLevel)) return topLevel;
13676
+ return path28.join(pkgRoot, "dist", "consumer-skills");
13272
13677
  }
13273
13678
  function skillsTargetDir(cwd) {
13274
- return path26.join(cwd, ".claude", "skills");
13679
+ return path28.join(cwd, ".claude", "skills");
13275
13680
  }
13276
13681
  function availableSkills() {
13277
13682
  const root = consumerSkillsRoot();
13278
- if (!fs15.existsSync(root)) return [];
13279
- return fs15.readdirSync(root, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).sort();
13683
+ if (!fs17.existsSync(root)) return [];
13684
+ return fs17.readdirSync(root, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).sort();
13280
13685
  }
13281
13686
  function runSkillsInstall(opts) {
13282
13687
  const sourceRoot = consumerSkillsRoot();
13283
13688
  const targetDir = skillsTargetDir(opts.cwd);
13284
- if (!fs15.existsSync(sourceRoot)) {
13689
+ if (!fs17.existsSync(sourceRoot)) {
13285
13690
  return {
13286
13691
  ok: false,
13287
13692
  sourceRoot,
@@ -13299,8 +13704,8 @@ function runSkillsInstall(opts) {
13299
13704
  async function summary3(ctx) {
13300
13705
  const skills = availableSkills();
13301
13706
  const targetDir = skillsTargetDir(ctx.cwd);
13302
- const installedDirs = fs15.existsSync(targetDir) ? new Set(
13303
- fs15.readdirSync(targetDir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name)
13707
+ const installedDirs = fs17.existsSync(targetDir) ? new Set(
13708
+ fs17.readdirSync(targetDir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name)
13304
13709
  ) : /* @__PURE__ */ new Set();
13305
13710
  const body = [];
13306
13711
  if (skills.length === 0) {
@@ -13318,13 +13723,13 @@ async function summary3(ctx) {
13318
13723
  return {
13319
13724
  title: "skills",
13320
13725
  body,
13321
- footer: `${installedCount} of ${skills.length} skills installed \u2192 ${path26.relative(ctx.cwd, targetDir) || targetDir}`
13726
+ footer: `${installedCount} of ${skills.length} skills installed \u2192 ${path28.relative(ctx.cwd, targetDir) || targetDir}`
13322
13727
  };
13323
13728
  }
13324
13729
  async function hints3(ctx) {
13325
13730
  const skills = availableSkills();
13326
13731
  const targetDir = skillsTargetDir(ctx.cwd);
13327
- const allPresent = skills.length > 0 && fs15.existsSync(targetDir) && skills.every((s) => fs15.existsSync(path26.join(targetDir, s)));
13732
+ const allPresent = skills.length > 0 && fs17.existsSync(targetDir) && skills.every((s) => fs17.existsSync(path28.join(targetDir, s)));
13328
13733
  if (allPresent) {
13329
13734
  return [
13330
13735
  { command: "codegen update", description: "Re-sync skills + runtime after a package bump" }
@@ -13399,7 +13804,7 @@ var SkillsInstallCommand = class extends Command5 {
13399
13804
  });
13400
13805
  return 0;
13401
13806
  }
13402
- printInfo(`target = ${path26.relative(ctx.cwd, result.targetDir) || result.targetDir}`);
13807
+ printInfo(`target = ${path28.relative(ctx.cwd, result.targetDir) || result.targetDir}`);
13403
13808
  console.log("");
13404
13809
  renderTreeReport(report);
13405
13810
  console.log("");
@@ -13427,8 +13832,8 @@ var SkillsListCommand = class extends Command5 {
13427
13832
  const skills = availableSkills();
13428
13833
  const targetDir = skillsTargetDir(ctx.cwd);
13429
13834
  const rows = skills.map((name) => {
13430
- const dir = path26.join(targetDir, name);
13431
- return { name, status: fs15.existsSync(dir) ? "installed" : "available" };
13835
+ const dir = path28.join(targetDir, name);
13836
+ return { name, status: fs17.existsSync(dir) ? "installed" : "available" };
13432
13837
  });
13433
13838
  if (isJsonMode()) {
13434
13839
  printJson({ command: "skills list", target: targetDir, skills: rows });
@@ -13457,16 +13862,16 @@ var NON_RUNTIME_SUBSYSTEMS = /* @__PURE__ */ new Set(["openapi-config", "auth-in
13457
13862
  function syncVendoredRuntime(cwd, write) {
13458
13863
  const changes = [];
13459
13864
  for (const v of VENDORED_RUNTIME_FILES) {
13460
- const dest = path27.join(cwd, v.target);
13865
+ const dest = path29.join(cwd, v.target);
13461
13866
  const content = loadRuntimeFile(v.runtime);
13462
- const existing = fs16.existsSync(dest) ? fs16.readFileSync(dest, "utf-8") : null;
13867
+ const existing = fs18.existsSync(dest) ? fs18.readFileSync(dest, "utf-8") : null;
13463
13868
  let action;
13464
13869
  if (existing === null) action = "created";
13465
13870
  else if (existing === content) action = "unchanged";
13466
13871
  else action = "updated";
13467
13872
  if (write && action !== "unchanged") {
13468
- fs16.mkdirSync(path27.dirname(dest), { recursive: true });
13469
- fs16.writeFileSync(dest, content, "utf-8");
13873
+ fs18.mkdirSync(path29.dirname(dest), { recursive: true });
13874
+ fs18.writeFileSync(dest, content, "utf-8");
13470
13875
  }
13471
13876
  changes.push({ path: v.target, action });
13472
13877
  }
@@ -13477,17 +13882,17 @@ async function syncSubsystemRuntime(cwd, inst, write) {
13477
13882
  return { name: inst.name, changes: [], skippedReason: "config-only / vendored elsewhere" };
13478
13883
  }
13479
13884
  const source = subsystemSource(inst.name);
13480
- if (!fs16.existsSync(source)) {
13885
+ if (!fs18.existsSync(source)) {
13481
13886
  return { name: inst.name, changes: [], skippedReason: "no runtime source in package" };
13482
13887
  }
13483
- const subsystemsRoot = path27.dirname(inst.path);
13888
+ const subsystemsRoot = path29.dirname(inst.path);
13484
13889
  const result = await copyRuntime({
13485
13890
  sourceDir: source,
13486
13891
  targetDir: inst.path,
13487
13892
  filter: backendFileFilter(inst.backend, inst.name),
13488
13893
  resolveDeps: true,
13489
13894
  runtimeRoot: runtimeRoot2(),
13490
- depsTargetRoot: path27.resolve(subsystemsRoot, ".."),
13895
+ depsTargetRoot: path29.resolve(subsystemsRoot, ".."),
13491
13896
  dryRun: !write,
13492
13897
  // Refresh files already vendored for this subsystem; never install new
13493
13898
  // ones (that's `subsystem install`). copyRuntime classifies accurately
@@ -13501,7 +13906,7 @@ async function syncSubsystemRuntime(cwd, inst, write) {
13501
13906
  return { name: inst.name, changes };
13502
13907
  }
13503
13908
  function rel(cwd, abs) {
13504
- return path27.relative(cwd, abs) || abs;
13909
+ return path29.relative(cwd, abs) || abs;
13505
13910
  }
13506
13911
  var ProjectUpdateCommand = class extends Command6 {
13507
13912
  static paths = [["project", "update"]];
@@ -13540,7 +13945,7 @@ var ProjectUpdateCommand = class extends Command6 {
13540
13945
  const installed = this.skipSubsystems ? [] : await detectInstalledSubsystems(ctx);
13541
13946
  if (!this.dryRun && !this.force) {
13542
13947
  const vendoredDry = syncVendoredRuntime(ctx.cwd, false);
13543
- const vendoredDirtyCandidates = vendoredDry.filter((c) => c.action === "updated").map((c) => path27.join(ctx.cwd, c.path));
13948
+ const vendoredDirtyCandidates = vendoredDry.filter((c) => c.action === "updated").map((c) => path29.join(ctx.cwd, c.path));
13544
13949
  const skillDirtyCandidates = this.skipSkills ? [] : runSkillsInstall({ cwd: ctx.cwd, dryRun: true }).report?.updated.map((e) => e.dest) ?? [];
13545
13950
  const subsystemDirs = installed.filter((i) => !NON_RUNTIME_SUBSYSTEMS.has(i.name)).map((i) => i.path);
13546
13951
  const gate = checkGitSafety(
@@ -13891,9 +14296,9 @@ var ProjectScanCommand = class extends Command7 {
13891
14296
  cwd = Option7.String("--cwd", { required: false });
13892
14297
  async execute() {
13893
14298
  if (this.json) setJsonMode(true);
13894
- const baseCwd = this.cwd ? path28.resolve(this.cwd) : process.cwd();
13895
- const target = this.directory ? path28.resolve(baseCwd, this.directory) : baseCwd;
13896
- if (!fs17.existsSync(target)) {
14299
+ const baseCwd = this.cwd ? path30.resolve(this.cwd) : process.cwd();
14300
+ const target = this.directory ? path30.resolve(baseCwd, this.directory) : baseCwd;
14301
+ if (!fs19.existsSync(target)) {
13897
14302
  printError(`Directory not found: ${target}`);
13898
14303
  return 1;
13899
14304
  }
@@ -13943,8 +14348,8 @@ var ProjectScanCommand = class extends Command7 {
13943
14348
  `architecture: ${profile.architecture.evidence.join(", ") || "\u2014"}`
13944
14349
  ]);
13945
14350
  }
13946
- const outPath = path28.join(target, "codegen.config.yaml");
13947
- const existsNow = fs17.existsSync(outPath);
14351
+ const outPath = path30.join(target, "codegen.config.yaml");
14352
+ const existsNow = fs19.existsSync(outPath);
13948
14353
  if (this.dryRun) {
13949
14354
  console.log("");
13950
14355
  printInfo("Dry run \u2014 proposed codegen.config.yaml:");
@@ -13957,7 +14362,7 @@ var ProjectScanCommand = class extends Command7 {
13957
14362
  printWarning(`${outPath} already exists \u2014 pass --force via edit; skipping.`);
13958
14363
  return 0;
13959
14364
  }
13960
- fs17.writeFileSync(outPath, yamlText);
14365
+ fs19.writeFileSync(outPath, yamlText);
13961
14366
  printSuccess(`wrote ${outPath}`);
13962
14367
  return 0;
13963
14368
  }
@@ -14064,12 +14469,12 @@ var ProjectInspectCommand = class extends Command7 {
14064
14469
  return 2;
14065
14470
  }
14066
14471
  resolveEntitiesDir(ctx) {
14067
- if (this.dir) return path28.resolve(ctx.cwd, this.dir);
14068
- return ctx.entitiesDir ?? path28.resolve(ctx.cwd, "entities");
14472
+ if (this.dir) return path30.resolve(ctx.cwd, this.dir);
14473
+ return ctx.entitiesDir ?? path30.resolve(ctx.cwd, "entities");
14069
14474
  }
14070
14475
  async runAnalysis(ctx, kind) {
14071
14476
  const entitiesDir = this.resolveEntitiesDir(ctx);
14072
- if (!entitiesDir || !fs17.existsSync(entitiesDir)) {
14477
+ if (!entitiesDir || !fs19.existsSync(entitiesDir)) {
14073
14478
  printError(`Directory not found: ${entitiesDir ?? "(no entities/ dir)"}`);
14074
14479
  return 1;
14075
14480
  }
@@ -14099,7 +14504,7 @@ var ProjectInspectCommand = class extends Command7 {
14099
14504
  out = formatConsole(filtered);
14100
14505
  }
14101
14506
  if (this.output) {
14102
- fs17.writeFileSync(this.output, out);
14507
+ fs19.writeFileSync(this.output, out);
14103
14508
  if (!isJsonMode()) printSuccess(`wrote ${this.output}`);
14104
14509
  } else {
14105
14510
  console.log(out);
@@ -14112,7 +14517,7 @@ var ProjectInspectCommand = class extends Command7 {
14112
14517
  }
14113
14518
  async runManifest(ctx) {
14114
14519
  const entitiesDir = this.resolveEntitiesDir(ctx);
14115
- if (!entitiesDir || !fs17.existsSync(entitiesDir)) {
14520
+ if (!entitiesDir || !fs19.existsSync(entitiesDir)) {
14116
14521
  printError(`Directory not found: ${entitiesDir ?? "(no entities/ dir)"}`);
14117
14522
  return 1;
14118
14523
  }
@@ -14268,17 +14673,17 @@ var ProjectGraphCommand = class extends Command7 {
14268
14673
  json: this.json,
14269
14674
  skipDetection: true
14270
14675
  });
14271
- const entitiesDir = this.dir ? path28.resolve(ctx.cwd, this.dir) : ctx.entitiesDir ?? path28.resolve(ctx.cwd, "entities");
14272
- if (!fs17.existsSync(entitiesDir)) {
14676
+ const entitiesDir = this.dir ? path30.resolve(ctx.cwd, this.dir) : ctx.entitiesDir ?? path30.resolve(ctx.cwd, "entities");
14677
+ if (!fs19.existsSync(entitiesDir)) {
14273
14678
  printError(`Entity directory not found: ${entitiesDir}`);
14274
14679
  return 1;
14275
14680
  }
14276
14681
  const relCandidates = [
14277
- path28.resolve(path28.dirname(entitiesDir), "relationships"),
14278
- path28.resolve(entitiesDir, "relationships"),
14279
- path28.resolve(ctx.cwd, "relationships")
14682
+ path30.resolve(path30.dirname(entitiesDir), "relationships"),
14683
+ path30.resolve(entitiesDir, "relationships"),
14684
+ path30.resolve(ctx.cwd, "relationships")
14280
14685
  ];
14281
- const relationshipsDir = relCandidates.find((d) => fs17.existsSync(d));
14686
+ const relationshipsDir = relCandidates.find((d) => fs19.existsSync(d));
14282
14687
  const result = await analyzeDomain(entitiesDir, relationshipsDir);
14283
14688
  const serialized = serializeDomainGraph(result.graph);
14284
14689
  if (isJsonMode()) {
@@ -14292,20 +14697,20 @@ var ProjectGraphCommand = class extends Command7 {
14292
14697
  return 0;
14293
14698
  }
14294
14699
  if (this.output) {
14295
- const outPath = path28.resolve(ctx.cwd, this.output);
14296
- fs17.writeFileSync(outPath, JSON.stringify(serialized, null, 2));
14700
+ const outPath = path30.resolve(ctx.cwd, this.output);
14701
+ fs19.writeFileSync(outPath, JSON.stringify(serialized, null, 2));
14297
14702
  printSuccess(`Graph written to ${outPath}`);
14298
14703
  printInfo(`${result.entities.length} entities, ${result.relationshipDefinitions.length} relationships, ${result.graph.edges.length} edges`);
14299
14704
  return 0;
14300
14705
  }
14301
14706
  const os = await import("os");
14302
- const tmpDir = fs17.mkdtempSync(path28.join(os.default.tmpdir(), "codegen-graph-"));
14303
- const graphPath = path28.join(tmpDir, "graph.json");
14304
- fs17.writeFileSync(graphPath, JSON.stringify(serialized, null, 2));
14305
- const viewerDir = path28.resolve(import.meta.dirname, "..", "..", "..", "tools", "schema-graph-viewer");
14306
- const viewerDist = path28.join(viewerDir, "dist", "index.html");
14307
- if (fs17.existsSync(viewerDist)) {
14308
- fs17.copyFileSync(graphPath, path28.join(viewerDir, "dist", "graph.json"));
14707
+ const tmpDir = fs19.mkdtempSync(path30.join(os.default.tmpdir(), "codegen-graph-"));
14708
+ const graphPath = path30.join(tmpDir, "graph.json");
14709
+ fs19.writeFileSync(graphPath, JSON.stringify(serialized, null, 2));
14710
+ const viewerDir = path30.resolve(import.meta.dirname, "..", "..", "..", "tools", "schema-graph-viewer");
14711
+ const viewerDist = path30.join(viewerDir, "dist", "index.html");
14712
+ if (fs19.existsSync(viewerDist)) {
14713
+ fs19.copyFileSync(graphPath, path30.join(viewerDir, "dist", "graph.json"));
14309
14714
  printSuccess("Graph exported");
14310
14715
  printInfo(`${result.entities.length} entities, ${result.relationshipDefinitions.length} relationships, ${result.graph.edges.length} edges`);
14311
14716
  printInfo(`Graph JSON: ${graphPath}`);
@@ -14336,8 +14741,8 @@ var projectNoun = {
14336
14741
  var project_default = projectNoun;
14337
14742
 
14338
14743
  // src/cli/commands/dev.ts
14339
- import fs18 from "fs";
14340
- import path29 from "path";
14744
+ import fs20 from "fs";
14745
+ import path31 from "path";
14341
14746
  import { execSync as execSync3, spawn, spawnSync } from "child_process";
14342
14747
  import { Command as Command8, Option as Option8 } from "clipanion";
14343
14748
  var DEFAULT_APP_PORT = 3e3;
@@ -14370,33 +14775,33 @@ function getRedisPort(_ctx) {
14370
14775
  return Number(process.env.DEV_REDIS_PORT ?? DEFAULT_REDIS_PORT);
14371
14776
  }
14372
14777
  function composeFilePath(cwd) {
14373
- const devPath = path29.join(cwd, COMPOSE_FILE);
14374
- if (fs18.existsSync(devPath)) return devPath;
14375
- const rootPath = path29.join(cwd, "docker-compose.yml");
14376
- if (fs18.existsSync(rootPath)) return rootPath;
14778
+ const devPath = path31.join(cwd, COMPOSE_FILE);
14779
+ if (fs20.existsSync(devPath)) return devPath;
14780
+ const rootPath = path31.join(cwd, "docker-compose.yml");
14781
+ if (fs20.existsSync(rootPath)) return rootPath;
14377
14782
  return devPath;
14378
14783
  }
14379
14784
  function pidFilePath(cwd) {
14380
- return path29.join(cwd, PID_FILE);
14785
+ return path31.join(cwd, PID_FILE);
14381
14786
  }
14382
14787
  function readAppPid(cwd) {
14383
14788
  const p = pidFilePath(cwd);
14384
- if (!fs18.existsSync(p)) return null;
14385
- const pid = parseInt(fs18.readFileSync(p, "utf-8").trim(), 10);
14789
+ if (!fs20.existsSync(p)) return null;
14790
+ const pid = parseInt(fs20.readFileSync(p, "utf-8").trim(), 10);
14386
14791
  if (isNaN(pid)) return null;
14387
14792
  try {
14388
14793
  process.kill(pid, 0);
14389
14794
  return pid;
14390
14795
  } catch {
14391
- fs18.rmSync(p, { force: true });
14796
+ fs20.rmSync(p, { force: true });
14392
14797
  return null;
14393
14798
  }
14394
14799
  }
14395
14800
  function writeAppPid(cwd, pid) {
14396
- fs18.writeFileSync(pidFilePath(cwd), String(pid));
14801
+ fs20.writeFileSync(pidFilePath(cwd), String(pid));
14397
14802
  }
14398
14803
  function clearAppPid(cwd) {
14399
- fs18.rmSync(pidFilePath(cwd), { force: true });
14804
+ fs20.rmSync(pidFilePath(cwd), { force: true });
14400
14805
  }
14401
14806
  function checkPostgres(cwd, port) {
14402
14807
  const r = runCmd(`docker exec codegen-dev-postgres pg_isready -U postgres`, cwd, {
@@ -14436,9 +14841,9 @@ function checkApp(cwd, port) {
14436
14841
  };
14437
14842
  }
14438
14843
  function listEntityNames(ctx) {
14439
- if (!ctx.entitiesDir || !fs18.existsSync(ctx.entitiesDir)) return [];
14844
+ if (!ctx.entitiesDir || !fs20.existsSync(ctx.entitiesDir)) return [];
14440
14845
  return findYamlFiles(ctx.entitiesDir).map(
14441
- (f) => path29.basename(f).replace(/\.ya?ml$/, "")
14846
+ (f) => path31.basename(f).replace(/\.ya?ml$/, "")
14442
14847
  );
14443
14848
  }
14444
14849
  function formatServiceLine(svc) {
@@ -14448,8 +14853,8 @@ function formatServiceLine(svc) {
14448
14853
  return `${icon} ${svc.name.padEnd(12)} ${theme.muted(`${svc.host}:${svc.port}`)} ${status}${pidStr}`;
14449
14854
  }
14450
14855
  function ensureComposeFile(cwd, pgPort, redisPort) {
14451
- const composePath = path29.join(cwd, COMPOSE_FILE);
14452
- if (fs18.existsSync(composePath)) return composePath;
14856
+ const composePath = path31.join(cwd, COMPOSE_FILE);
14857
+ if (fs20.existsSync(composePath)) return composePath;
14453
14858
  const content = `# Auto-generated by codegen dev
14454
14859
  # Ports offset from defaults to avoid conflicts with other local services.
14455
14860
  services:
@@ -14484,7 +14889,7 @@ services:
14484
14889
  volumes:
14485
14890
  codegen-dev-pgdata:
14486
14891
  `;
14487
- fs18.writeFileSync(composePath, content);
14892
+ fs20.writeFileSync(composePath, content);
14488
14893
  return composePath;
14489
14894
  }
14490
14895
  var DevUpCommand = class extends Command8 {
@@ -14533,7 +14938,7 @@ var DevUpCommand = class extends Command8 {
14533
14938
  if (!pgReady) printWarning("postgres did not become healthy in time");
14534
14939
  if (!redisReady) printWarning("redis did not become healthy in time");
14535
14940
  const drizzleConfig = ["drizzle.config.ts", "drizzle.config.js"].find(
14536
- (f) => fs18.existsSync(path29.join(ctx.cwd, f))
14941
+ (f) => fs20.existsSync(path31.join(ctx.cwd, f))
14537
14942
  );
14538
14943
  if (drizzleConfig) {
14539
14944
  if (!isJsonMode()) printInfo("pushing database schema...");
@@ -14553,8 +14958,8 @@ var DevUpCommand = class extends Command8 {
14553
14958
  if (!isJsonMode()) printInfo("starting NestJS app...");
14554
14959
  const dbUrl = `postgres://postgres:postgres@localhost:${pgPort}/codegen_dev`;
14555
14960
  const redisUrl = `redis://localhost:${redisPort}`;
14556
- const logFile = path29.join(ctx.cwd, ".dev-app.log");
14557
- const logFd = fs18.openSync(logFile, "a");
14961
+ const logFile = path31.join(ctx.cwd, ".dev-app.log");
14962
+ const logFd = fs20.openSync(logFile, "a");
14558
14963
  const child = spawn("bun", ["src/main.ts"], {
14559
14964
  cwd: ctx.cwd,
14560
14965
  detached: true,
@@ -14567,7 +14972,7 @@ var DevUpCommand = class extends Command8 {
14567
14972
  }
14568
14973
  });
14569
14974
  child.unref();
14570
- fs18.closeSync(logFd);
14975
+ fs20.closeSync(logFd);
14571
14976
  if (child.pid) {
14572
14977
  writeAppPid(ctx.cwd, child.pid);
14573
14978
  spawnSync("sleep", ["2"]);
@@ -14711,8 +15116,8 @@ var DevLogsCommand = class extends Command8 {
14711
15116
  }
14712
15117
  return 0;
14713
15118
  }
14714
- const logFile = path29.join(ctx.cwd, ".dev-app.log");
14715
- if (!fs18.existsSync(logFile)) {
15119
+ const logFile = path31.join(ctx.cwd, ".dev-app.log");
15120
+ if (!fs20.existsSync(logFile)) {
14716
15121
  printInfo("no app logs found \u2014 is the app running?");
14717
15122
  return 0;
14718
15123
  }
@@ -14755,8 +15160,8 @@ var DevRestartCommand = class extends Command8 {
14755
15160
  spawnSync("sleep", ["1"]);
14756
15161
  const dbUrl = `postgres://postgres:postgres@localhost:${pgPort}/codegen_dev`;
14757
15162
  const redisUrl = `redis://localhost:${redisPort}`;
14758
- const logFile = path29.join(ctx.cwd, ".dev-app.log");
14759
- const logFd = fs18.openSync(logFile, "a");
15163
+ const logFile = path31.join(ctx.cwd, ".dev-app.log");
15164
+ const logFd = fs20.openSync(logFile, "a");
14760
15165
  const child = spawn("bun", ["src/main.ts"], {
14761
15166
  cwd: ctx.cwd,
14762
15167
  detached: true,
@@ -14769,7 +15174,7 @@ var DevRestartCommand = class extends Command8 {
14769
15174
  }
14770
15175
  });
14771
15176
  child.unref();
14772
- fs18.closeSync(logFd);
15177
+ fs20.closeSync(logFd);
14773
15178
  if (child.pid) {
14774
15179
  writeAppPid(ctx.cwd, child.pid);
14775
15180
  spawnSync("sleep", ["2"]);
@@ -14884,11 +15289,11 @@ var devNoun = {
14884
15289
  var dev_default = devNoun;
14885
15290
 
14886
15291
  // src/cli/commands/relationship.ts
14887
- import fs19 from "fs";
14888
- import path30 from "path";
15292
+ import fs21 from "fs";
15293
+ import path32 from "path";
14889
15294
  import { Command as Command9, Option as Option9 } from "clipanion";
14890
15295
  function listRelationshipYamls2(dir) {
14891
- if (!fs19.existsSync(dir)) return [];
15296
+ if (!fs21.existsSync(dir)) return [];
14892
15297
  return findYamlFiles(dir).filter(
14893
15298
  (full) => detectYamlType(full) === "relationship"
14894
15299
  );
@@ -14912,7 +15317,7 @@ function padRight2(s, n) {
14912
15317
  return s.length >= n ? s : s + " ".repeat(n - s.length);
14913
15318
  }
14914
15319
  async function summary6(ctx) {
14915
- const relDir = path30.resolve(ctx.cwd, "relationships");
15320
+ const relDir = path32.resolve(ctx.cwd, "relationships");
14916
15321
  const files = listRelationshipYamls2(relDir);
14917
15322
  if (files.length === 0) {
14918
15323
  return {
@@ -14982,14 +15387,14 @@ var RelationshipNewCommand = class extends Command9 {
14982
15387
  }
14983
15388
  let targets = [];
14984
15389
  if (this.all) {
14985
- const dir = path30.resolve(ctx.cwd, "relationships");
15390
+ const dir = path32.resolve(ctx.cwd, "relationships");
14986
15391
  targets = listRelationshipYamls2(dir);
14987
15392
  if (targets.length === 0) {
14988
15393
  printError(`No relationship YAML files found in ${dir}`);
14989
15394
  return 1;
14990
15395
  }
14991
15396
  } else if (this.yaml) {
14992
- targets = [path30.resolve(ctx.cwd, this.yaml)];
15397
+ targets = [path32.resolve(ctx.cwd, this.yaml)];
14993
15398
  } else {
14994
15399
  printError("Missing YAML path. Pass a file or --all.");
14995
15400
  return 2;
@@ -15006,7 +15411,7 @@ var RelationshipNewCommand = class extends Command9 {
15006
15411
  }
15007
15412
  if (invalid.length > 0) {
15008
15413
  for (const i of invalid) {
15009
- printError(`${path30.basename(i.file)} \u2014 ${i.message}`);
15414
+ printError(`${path32.basename(i.file)} \u2014 ${i.message}`);
15010
15415
  }
15011
15416
  if (!isJsonMode()) return 1;
15012
15417
  }
@@ -15037,7 +15442,7 @@ var RelationshipNewCommand = class extends Command9 {
15037
15442
  }
15038
15443
  const succeeded = [];
15039
15444
  const failed = [
15040
- ...invalid.map((i) => ({ name: path30.basename(i.file), file: i.file, message: i.message }))
15445
+ ...invalid.map((i) => ({ name: path32.basename(i.file), file: i.file, message: i.message }))
15041
15446
  ];
15042
15447
  for (const v of validated) {
15043
15448
  if (!isJsonMode()) {
@@ -15056,8 +15461,8 @@ var RelationshipNewCommand = class extends Command9 {
15056
15461
  if (!isJsonMode()) printError(`${v.name} \u2014 ${res.stderr ?? "failed"}`);
15057
15462
  }
15058
15463
  }
15059
- const entitiesDir = ctx.entitiesDir ?? path30.resolve(ctx.cwd, "entities");
15060
- const relationshipsDir = path30.resolve(ctx.cwd, "relationships");
15464
+ const entitiesDir = ctx.entitiesDir ?? path32.resolve(ctx.cwd, "entities");
15465
+ const relationshipsDir = path32.resolve(ctx.cwd, "relationships");
15061
15466
  const generatedDir = resolveGeneratedDir(ctx);
15062
15467
  const architecture = resolveArchitecture(ctx);
15063
15468
  let barrelResult = null;
@@ -15102,7 +15507,7 @@ var RelationshipNewCommand = class extends Command9 {
15102
15507
  }
15103
15508
  if (barrelResult) {
15104
15509
  printInfo(
15105
- `barrels regenerated (${barrelResult.entityCount} modules) \u2192 ${path30.relative(ctx.cwd, barrelResult.modulesBarrel)}, ${path30.relative(ctx.cwd, barrelResult.schemaBarrel)}`
15510
+ `barrels regenerated (${barrelResult.entityCount} modules) \u2192 ${path32.relative(ctx.cwd, barrelResult.modulesBarrel)}, ${path32.relative(ctx.cwd, barrelResult.schemaBarrel)}`
15106
15511
  );
15107
15512
  }
15108
15513
  }
@@ -15125,7 +15530,7 @@ var RelationshipListCommand = class extends Command9 {
15125
15530
  json: this.json,
15126
15531
  skipDetection: true
15127
15532
  });
15128
- const relDir = path30.resolve(ctx.cwd, "relationships");
15533
+ const relDir = path32.resolve(ctx.cwd, "relationships");
15129
15534
  const files = listRelationshipYamls2(relDir);
15130
15535
  if (files.length === 0) {
15131
15536
  printInfo("No relationship definitions found.");
@@ -15165,7 +15570,7 @@ var relationshipNoun = {
15165
15570
  var relationship_default = relationshipNoun;
15166
15571
 
15167
15572
  // src/cli/commands/junction.ts
15168
- import path31 from "path";
15573
+ import path33 from "path";
15169
15574
  import { Command as Command10, Option as Option10 } from "clipanion";
15170
15575
  function summarizeJunctionFile(filePath) {
15171
15576
  const result = loadJunctionFromYaml(filePath);
@@ -15188,7 +15593,7 @@ function padRight3(s, n) {
15188
15593
  return s.length >= n ? s : s + " ".repeat(n - s.length);
15189
15594
  }
15190
15595
  async function summary7(ctx) {
15191
- const junctionDir = path31.resolve(ctx.cwd, "junctions");
15596
+ const junctionDir = path33.resolve(ctx.cwd, "junctions");
15192
15597
  const files = listJunctionYamls(junctionDir);
15193
15598
  if (files.length === 0) {
15194
15599
  return {
@@ -15258,14 +15663,14 @@ var JunctionNewCommand = class extends Command10 {
15258
15663
  }
15259
15664
  let targets = [];
15260
15665
  if (this.all) {
15261
- const dir = path31.resolve(ctx.cwd, "junctions");
15666
+ const dir = path33.resolve(ctx.cwd, "junctions");
15262
15667
  targets = listJunctionYamls(dir);
15263
15668
  if (targets.length === 0) {
15264
15669
  printError(`No junction YAML files found in ${dir}`);
15265
15670
  return 1;
15266
15671
  }
15267
15672
  } else if (this.yaml) {
15268
- targets = [path31.resolve(ctx.cwd, this.yaml)];
15673
+ targets = [path33.resolve(ctx.cwd, this.yaml)];
15269
15674
  } else {
15270
15675
  printError("Missing YAML path. Pass a file or --all.");
15271
15676
  return 2;
@@ -15284,7 +15689,7 @@ var JunctionNewCommand = class extends Command10 {
15284
15689
  }
15285
15690
  if (invalid.length > 0) {
15286
15691
  for (const i of invalid) {
15287
- printError(`${path31.basename(i.file)} \u2014 ${i.message}`);
15692
+ printError(`${path33.basename(i.file)} \u2014 ${i.message}`);
15288
15693
  }
15289
15694
  if (!isJsonMode()) return 1;
15290
15695
  }
@@ -15315,7 +15720,7 @@ var JunctionNewCommand = class extends Command10 {
15315
15720
  }
15316
15721
  const succeeded = [];
15317
15722
  const failed = [
15318
- ...invalid.map((i) => ({ name: path31.basename(i.file), file: i.file, message: i.message }))
15723
+ ...invalid.map((i) => ({ name: path33.basename(i.file), file: i.file, message: i.message }))
15319
15724
  ];
15320
15725
  for (const v of validated) {
15321
15726
  if (!isJsonMode()) {
@@ -15334,9 +15739,9 @@ var JunctionNewCommand = class extends Command10 {
15334
15739
  if (!isJsonMode()) printError(`${v.name} \u2014 ${res.stderr ?? "failed"}`);
15335
15740
  }
15336
15741
  }
15337
- const entitiesDir = ctx.entitiesDir ?? path31.resolve(ctx.cwd, "entities");
15338
- const relationshipsDir = path31.resolve(ctx.cwd, "relationships");
15339
- const junctionsDir = path31.resolve(ctx.cwd, "junctions");
15742
+ const entitiesDir = ctx.entitiesDir ?? path33.resolve(ctx.cwd, "entities");
15743
+ const relationshipsDir = path33.resolve(ctx.cwd, "relationships");
15744
+ const junctionsDir = path33.resolve(ctx.cwd, "junctions");
15340
15745
  const generatedDir = resolveGeneratedDir(ctx);
15341
15746
  const architecture = resolveArchitecture(ctx);
15342
15747
  let barrelResult = null;
@@ -15382,7 +15787,7 @@ var JunctionNewCommand = class extends Command10 {
15382
15787
  }
15383
15788
  if (barrelResult) {
15384
15789
  printInfo(
15385
- `barrels regenerated (${barrelResult.entityCount} modules) \u2192 ${path31.relative(ctx.cwd, barrelResult.modulesBarrel)}, ${path31.relative(ctx.cwd, barrelResult.schemaBarrel)}`
15790
+ `barrels regenerated (${barrelResult.entityCount} modules) \u2192 ${path33.relative(ctx.cwd, barrelResult.modulesBarrel)}, ${path33.relative(ctx.cwd, barrelResult.schemaBarrel)}`
15386
15791
  );
15387
15792
  }
15388
15793
  }
@@ -15405,7 +15810,7 @@ var JunctionListCommand = class extends Command10 {
15405
15810
  json: this.json,
15406
15811
  skipDetection: true
15407
15812
  });
15408
- const junctionDir = path31.resolve(ctx.cwd, "junctions");
15813
+ const junctionDir = path33.resolve(ctx.cwd, "junctions");
15409
15814
  const files = listJunctionYamls(junctionDir);
15410
15815
  if (files.length === 0) {
15411
15816
  printInfo("No junction definitions found.");
@@ -15445,8 +15850,8 @@ var junctionNoun = {
15445
15850
  var junction_default = junctionNoun;
15446
15851
 
15447
15852
  // src/cli/commands/events.ts
15448
- import fs20 from "fs";
15449
- import path32 from "path";
15853
+ import fs22 from "fs";
15854
+ import path34 from "path";
15450
15855
  import ts3 from "typescript";
15451
15856
  import { Command as Command11, Option as Option11 } from "clipanion";
15452
15857
  function scanSourceFileForConsumers(sourceFile, filePath, eventType) {
@@ -15545,7 +15950,7 @@ function scanDirectoryForConsumers(rootDir, eventType) {
15545
15950
  const tier1 = [];
15546
15951
  let hasEventFlowImport = false;
15547
15952
  for (const filePath of files) {
15548
- const text2 = fs20.readFileSync(filePath, "utf8");
15953
+ const text2 = fs22.readFileSync(filePath, "utf8");
15549
15954
  const sourceFile = ts3.createSourceFile(
15550
15955
  filePath,
15551
15956
  text2,
@@ -15582,7 +15987,7 @@ function suggestEventTypes(target, known, limit = 3) {
15582
15987
  return known.map((t) => ({ t, d: levenshtein(target, t) })).sort((a, b) => a.d - b.d).slice(0, limit).map((x) => x.t);
15583
15988
  }
15584
15989
  function renderConsumerReport(result, cwd) {
15585
- const rel2 = (p) => path32.relative(cwd, p) || p;
15990
+ const rel2 = (p) => path34.relative(cwd, p) || p;
15586
15991
  const lines = [];
15587
15992
  const total = result.tier3.length + result.tier2.length + result.tier1.length;
15588
15993
  lines.push(`Event: ${result.eventType}`);
@@ -15618,7 +16023,7 @@ function renderConsumerReport(result, cwd) {
15618
16023
  return lines;
15619
16024
  }
15620
16025
  function runConsumersScan(opts) {
15621
- const scanRoot = opts.scanRoot ?? path32.join(opts.cwd, "src");
16026
+ const scanRoot = opts.scanRoot ?? path34.join(opts.cwd, "src");
15622
16027
  const handlersDir = opts.handlersDir ?? scanRoot;
15623
16028
  const allTriggers = scanHandlerFiles(handlersDir);
15624
16029
  const tier3 = allTriggers.filter((t) => t.event === opts.eventType).map((t) => ({
@@ -15627,8 +16032,8 @@ function runConsumersScan(opts) {
15627
16032
  sourceFile: t.sourceFile,
15628
16033
  sourceLine: t.sourceLine
15629
16034
  }));
15630
- const tier21 = fs20.existsSync(scanRoot) ? scanDirectoryForConsumers(scanRoot, opts.eventType) : { tier2: [], tier1: [], hasEventFlowImport: false };
15631
- const eventsGeneratedDir = opts.eventsGeneratedDir ?? path32.join(
16035
+ const tier21 = fs22.existsSync(scanRoot) ? scanDirectoryForConsumers(scanRoot, opts.eventType) : { tier2: [], tier1: [], hasEventFlowImport: false };
16036
+ const eventsGeneratedDir = opts.eventsGeneratedDir ?? path34.join(
15632
16037
  resolveSubsystemsRootFromContext(opts.cwd, opts.config),
15633
16038
  "events",
15634
16039
  "generated"
@@ -15649,11 +16054,11 @@ function runConsumersScan(opts) {
15649
16054
  function resolveSubsystemsRootFromContext(cwd, config) {
15650
16055
  const configured = config?.paths?.subsystems;
15651
16056
  if (typeof configured === "string" && configured.length > 0) {
15652
- return path32.resolve(cwd, configured);
16057
+ return path34.resolve(cwd, configured);
15653
16058
  }
15654
16059
  const backendSrc = config?.paths?.backend_src;
15655
16060
  const base = typeof backendSrc === "string" && backendSrc.length > 0 ? backendSrc : "src";
15656
- return path32.resolve(cwd, base, "shared", "subsystems");
16061
+ return path34.resolve(cwd, base, "shared", "subsystems");
15657
16062
  }
15658
16063
  var EventsConsumersCommand = class extends Command11 {
15659
16064
  static paths = [["events", "consumers"]];
@@ -15742,7 +16147,7 @@ var eventsNoun = {
15742
16147
  var events_default = eventsNoun;
15743
16148
 
15744
16149
  // src/cli/commands/orchestration.ts
15745
- import path33 from "path";
16150
+ import path35 from "path";
15746
16151
  import { Command as Command12, Option as Option12 } from "clipanion";
15747
16152
  var DEFAULT_PATTERN_GLOBS = ["src/patterns/*.pattern.ts"];
15748
16153
  function resolvePatternGlobs(ctx) {
@@ -15756,10 +16161,10 @@ function resolveOrchestrationOutputRoot(ctx) {
15756
16161
  const paths = ctx.config?.paths;
15757
16162
  const explicit = paths?.orchestration_src;
15758
16163
  if (typeof explicit === "string" && explicit.length > 0) {
15759
- return path33.resolve(ctx.cwd, explicit);
16164
+ return path35.resolve(ctx.cwd, explicit);
15760
16165
  }
15761
16166
  const backendSrc = typeof paths?.backend_src === "string" && paths.backend_src.length > 0 ? paths.backend_src : "app/backend/src";
15762
- return path33.resolve(ctx.cwd, backendSrc, "orchestration");
16167
+ return path35.resolve(ctx.cwd, backendSrc, "orchestration");
15763
16168
  }
15764
16169
  async function reloadRegistry(ctx) {
15765
16170
  _resetRegistryForTests({ includeLibrary: false });
@@ -15848,12 +16253,12 @@ var OrchestrationGenCommand = class extends Command12 {
15848
16253
  );
15849
16254
  for (const f of result.files) {
15850
16255
  console.log(
15851
- ` ${theme.muted(icons.arrow)} ${path33.relative(ctx.cwd, f.outputPath)}`
16256
+ ` ${theme.muted(icons.arrow)} ${path35.relative(ctx.cwd, f.outputPath)}`
15852
16257
  );
15853
16258
  }
15854
16259
  } else {
15855
16260
  printSuccess(
15856
- `Emitted ${result.files.length} file(s) across ${targets.length} pattern(s) \u2192 ${path33.relative(ctx.cwd, outputRoot)}`
16261
+ `Emitted ${result.files.length} file(s) across ${targets.length} pattern(s) \u2192 ${path35.relative(ctx.cwd, outputRoot)}`
15857
16262
  );
15858
16263
  }
15859
16264
  return 0;