@kitsy/cnos 1.5.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/dist/build/index.cjs +333 -117
  2. package/dist/build/index.d.cts +3 -2
  3. package/dist/build/index.d.ts +3 -2
  4. package/dist/build/index.js +13 -8
  5. package/dist/{chunk-HMM76UYZ.js → chunk-BMAD24KC.js} +1 -1
  6. package/dist/{chunk-ZTPSFXWP.js → chunk-JYWQFMW5.js} +1 -1
  7. package/dist/{chunk-FWJC4Y2D.js → chunk-MW4OVAT3.js} +1 -1
  8. package/dist/chunk-QU5CXL47.js +577 -0
  9. package/dist/{chunk-APIU4GTB.js → chunk-S7H2UULC.js} +315 -107
  10. package/dist/{chunk-WCHX2QFY.js → chunk-UJBQS7CJ.js} +1 -1
  11. package/dist/{chunk-RYGSG3GR.js → chunk-UOKVLCFL.js} +10 -10
  12. package/dist/{chunk-T6Y57KTT.js → chunk-UR7CHHNN.js} +1 -1
  13. package/dist/{chunk-J4K4JUJL.js → chunk-VGZREX5D.js} +1 -1
  14. package/dist/{chunk-EQSKV3DP.js → chunk-XSUP7JKH.js} +23 -1
  15. package/dist/configure/index.cjs +332 -122
  16. package/dist/configure/index.d.cts +3 -3
  17. package/dist/configure/index.d.ts +3 -3
  18. package/dist/configure/index.js +8 -8
  19. package/dist/{envNaming-Dvm_LP2D.d.ts → envNaming-B7Mztkcf.d.ts} +1 -1
  20. package/dist/{envNaming-S4B-dHUx.d.cts → envNaming-gMVnPOfe.d.cts} +1 -1
  21. package/dist/index.cjs +754 -143
  22. package/dist/index.d.cts +1 -1
  23. package/dist/index.d.ts +1 -1
  24. package/dist/index.js +10 -10
  25. package/dist/internal.cjs +229 -103
  26. package/dist/internal.d.cts +16 -28
  27. package/dist/internal.d.ts +16 -28
  28. package/dist/internal.js +11 -3
  29. package/dist/plugin/basic-schema.cjs +22 -15
  30. package/dist/plugin/basic-schema.d.cts +1 -1
  31. package/dist/plugin/basic-schema.d.ts +1 -1
  32. package/dist/plugin/basic-schema.js +2 -2
  33. package/dist/plugin/cli-args.cjs +27 -18
  34. package/dist/plugin/cli-args.d.cts +1 -1
  35. package/dist/plugin/cli-args.d.ts +1 -1
  36. package/dist/plugin/cli-args.js +2 -2
  37. package/dist/plugin/dotenv.cjs +35 -26
  38. package/dist/plugin/dotenv.d.cts +2 -2
  39. package/dist/plugin/dotenv.d.ts +2 -2
  40. package/dist/plugin/dotenv.js +2 -2
  41. package/dist/plugin/env-export.cjs +34 -22
  42. package/dist/plugin/env-export.d.cts +2 -2
  43. package/dist/plugin/env-export.d.ts +2 -2
  44. package/dist/plugin/env-export.js +2 -2
  45. package/dist/plugin/filesystem.cjs +42 -33
  46. package/dist/plugin/filesystem.d.cts +1 -1
  47. package/dist/plugin/filesystem.d.ts +1 -1
  48. package/dist/plugin/filesystem.js +2 -2
  49. package/dist/plugin/process-env.cjs +24 -17
  50. package/dist/plugin/process-env.d.cts +2 -2
  51. package/dist/plugin/process-env.d.ts +2 -2
  52. package/dist/plugin/process-env.js +2 -2
  53. package/dist/{plugin-B4xwySxw.d.cts → plugin-CKrBlWGI.d.cts} +52 -3
  54. package/dist/{plugin-B4xwySxw.d.ts → plugin-CKrBlWGI.d.ts} +52 -3
  55. package/dist/runtime/index.cjs +752 -143
  56. package/dist/runtime/index.d.cts +19 -1
  57. package/dist/runtime/index.d.ts +19 -1
  58. package/dist/runtime/index.js +10 -10
  59. package/dist/{toPublicEnv-ggmphZFs.d.cts → toPublicEnv-CmBsy53P.d.cts} +1 -1
  60. package/dist/{toPublicEnv-CvhGAfsB.d.ts → toPublicEnv-q6VwWxXZ.d.ts} +1 -1
  61. package/package.json +1 -1
  62. package/dist/chunk-TO76YYS4.js +0 -189
package/dist/internal.cjs CHANGED
@@ -31,6 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var internal_exports = {};
32
32
  __export(internal_exports, {
33
33
  CNOS_GRAPH_ENV_VAR: () => CNOS_GRAPH_ENV_VAR,
34
+ CNOS_PROJECTION_ENV_VAR: () => CNOS_PROJECTION_ENV_VAR,
34
35
  CNOS_SECRET_PAYLOAD_ENV_VAR: () => CNOS_SECRET_PAYLOAD_ENV_VAR,
35
36
  CNOS_SESSION_KEY_ENV_VAR: () => CNOS_SESSION_KEY_ENV_VAR,
36
37
  CnosAuthenticationError: () => CnosAuthenticationError,
@@ -44,6 +45,7 @@ __export(internal_exports, {
44
45
  deleteLocalSecret: () => deleteLocalSecret,
45
46
  deriveVaultKey: () => deriveVaultKey,
46
47
  deserializeRuntimeGraph: () => deserializeRuntimeGraph,
48
+ deserializeServerProjection: () => deserializeServerProjection,
47
49
  detectLegacyVaultFormat: () => detectLegacyVaultFormat,
48
50
  diffGraphs: () => diffGraphs,
49
51
  ensureProjectionAllowed: () => ensureProjectionAllowed,
@@ -64,6 +66,7 @@ __export(internal_exports, {
64
66
  readKeychain: () => readKeychain,
65
67
  readLocalSecret: () => readLocalSecret,
66
68
  readRuntimeGraphFromEnv: () => readRuntimeGraphFromEnv,
69
+ readServerProjectionFromEnv: () => readServerProjectionFromEnv,
67
70
  readVaultMetadata: () => readVaultMetadata,
68
71
  removeLocalVaultFiles: () => removeLocalVaultFiles,
69
72
  resolveCodegenPaths: () => resolveCodegenPaths,
@@ -80,6 +83,7 @@ __export(internal_exports, {
80
83
  scanEnvUsage: () => scanEnvUsage,
81
84
  serializeRuntimeGraph: () => serializeRuntimeGraph,
82
85
  serializeSecretPayload: () => serializeSecretPayload,
86
+ serializeServerProjection: () => serializeServerProjection,
83
87
  stringifyYaml: () => stringifyYaml,
84
88
  validateRuntime: () => validateRuntime,
85
89
  watchFiles: () => watchFiles,
@@ -105,6 +109,11 @@ var CnosManifestError = class extends CnosError {
105
109
  }
106
110
  manifestPath;
107
111
  };
112
+ var CnosDiscoveryError = class extends CnosError {
113
+ constructor(message) {
114
+ super(message);
115
+ }
116
+ };
108
117
  var CnosSecurityError = class extends CnosError {
109
118
  constructor(message) {
110
119
  super(message);
@@ -223,32 +232,110 @@ async function writeKeychain(entry, value) {
223
232
  }
224
233
 
225
234
  // ../core/src/manifest/loadManifest.ts
235
+ var import_promises3 = require("fs/promises");
236
+ var import_node_path3 = __toESM(require("path"), 1);
237
+
238
+ // ../core/src/utils/path.ts
226
239
  var import_promises2 = require("fs/promises");
240
+ var import_node_os = __toESM(require("os"), 1);
227
241
  var import_node_path2 = __toESM(require("path"), 1);
228
242
 
229
- // ../core/src/utils/path.ts
243
+ // ../core/src/discovery/findCnosrc.ts
230
244
  var import_promises = require("fs/promises");
231
- var import_node_os = __toESM(require("os"), 1);
232
245
  var import_node_path = __toESM(require("path"), 1);
246
+
247
+ // ../core/src/utils/yaml.ts
248
+ var import_yaml = require("yaml");
249
+ function parseYaml(source) {
250
+ return (0, import_yaml.parse)(source);
251
+ }
252
+ function stringifyYaml(value) {
253
+ return (0, import_yaml.stringify)(value);
254
+ }
255
+
256
+ // ../core/src/discovery/findCnosrc.ts
257
+ async function exists(targetPath) {
258
+ try {
259
+ await (0, import_promises.access)(targetPath);
260
+ return true;
261
+ } catch {
262
+ return false;
263
+ }
264
+ }
265
+ function validateCnosrc(value, filePath) {
266
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
267
+ throw new CnosManifestError(".cnosrc.yml must be a YAML object", filePath);
268
+ }
269
+ const root = typeof value.root === "string" ? value.root.trim() : "";
270
+ const workspace = typeof value.workspace === "string" ? value.workspace.trim() : void 0;
271
+ if (!root) {
272
+ throw new CnosManifestError(".cnosrc.yml requires root", filePath);
273
+ }
274
+ return {
275
+ root,
276
+ ...workspace ? { workspace } : {}
277
+ };
278
+ }
279
+ async function findCnosrc(startDir = process.cwd(), maxLevels = 3) {
280
+ let current = import_node_path.default.resolve(startDir);
281
+ for (let depth = 0; depth <= maxLevels; depth += 1) {
282
+ const candidate = import_node_path.default.join(current, ".cnosrc.yml");
283
+ if (await exists(candidate)) {
284
+ return candidate;
285
+ }
286
+ const parent = import_node_path.default.dirname(current);
287
+ if (parent === current) {
288
+ break;
289
+ }
290
+ current = parent;
291
+ }
292
+ return void 0;
293
+ }
294
+ async function discoverCnosAnchor(startDir = process.cwd(), maxLevels = 3) {
295
+ const anchorPath = await findCnosrc(startDir, maxLevels);
296
+ if (!anchorPath) {
297
+ throw new CnosDiscoveryError(
298
+ "No .cnosrc.yml found. Run cnos init or create .cnosrc.yml in your package root."
299
+ );
300
+ }
301
+ const source = await (0, import_promises.readFile)(anchorPath, "utf8");
302
+ const parsed = validateCnosrc(parseYaml(source), anchorPath);
303
+ const consumerRoot = import_node_path.default.dirname(anchorPath);
304
+ const manifestRoot = import_node_path.default.resolve(consumerRoot, parsed.root);
305
+ const manifestPath = import_node_path.default.join(manifestRoot, "cnos.yml");
306
+ if (!await exists(manifestPath)) {
307
+ throw new CnosDiscoveryError(
308
+ `.cnosrc.yml points to ${manifestRoot} but no cnos.yml found there.`
309
+ );
310
+ }
311
+ return {
312
+ anchorPath,
313
+ consumerRoot,
314
+ manifestRoot,
315
+ ...parsed.workspace ? { workspace: parsed.workspace } : {}
316
+ };
317
+ }
318
+
319
+ // ../core/src/utils/path.ts
233
320
  var PRIMARY_CNOS_DIR = ".cnos";
234
321
  var LEGACY_CNOS_DIR = "cnos";
235
- async function exists(filePath) {
322
+ async function exists2(filePath) {
236
323
  try {
237
- await (0, import_promises.access)(filePath);
324
+ await (0, import_promises2.access)(filePath);
238
325
  return true;
239
326
  } catch {
240
327
  return false;
241
328
  }
242
329
  }
243
330
  async function resolveCnosRoot(root = process.cwd()) {
244
- const basePath = import_node_path.default.resolve(root);
331
+ const basePath = import_node_path2.default.resolve(root);
245
332
  const candidates = [
246
- import_node_path.default.join(basePath, PRIMARY_CNOS_DIR),
247
- import_node_path.default.join(basePath, LEGACY_CNOS_DIR),
333
+ import_node_path2.default.join(basePath, PRIMARY_CNOS_DIR),
334
+ import_node_path2.default.join(basePath, LEGACY_CNOS_DIR),
248
335
  basePath
249
336
  ];
250
337
  for (const candidate of candidates) {
251
- if (await exists(import_node_path.default.join(candidate, "cnos.yml"))) {
338
+ if (await exists2(import_node_path2.default.join(candidate, "cnos.yml"))) {
252
339
  return candidate;
253
340
  }
254
341
  }
@@ -256,38 +343,44 @@ async function resolveCnosRoot(root = process.cwd()) {
256
343
  `Could not locate .cnos/cnos.yml or cnos/cnos.yml from root: ${basePath}`
257
344
  );
258
345
  }
259
- async function resolveManifestRoot(root = process.cwd()) {
260
- return resolveCnosRoot(root);
346
+ async function resolveManifestRoot(options = {}) {
347
+ if (options.root) {
348
+ const manifestRoot = await resolveCnosRoot(options.root);
349
+ const resolvedRoot = import_node_path2.default.resolve(options.root);
350
+ const consumerRoot = import_node_path2.default.basename(manifestRoot) === PRIMARY_CNOS_DIR || import_node_path2.default.basename(manifestRoot) === LEGACY_CNOS_DIR ? import_node_path2.default.dirname(manifestRoot) : resolvedRoot;
351
+ return {
352
+ manifestRoot,
353
+ consumerRoot
354
+ };
355
+ }
356
+ const discovered = await discoverCnosAnchor(options.cwd ?? process.cwd());
357
+ return {
358
+ manifestRoot: discovered.manifestRoot,
359
+ consumerRoot: discovered.consumerRoot,
360
+ anchorPath: discovered.anchorPath,
361
+ ...discovered.workspace ? { workspace: discovered.workspace } : {}
362
+ };
261
363
  }
262
364
  function expandHomePath(targetPath) {
263
365
  if (targetPath === "~") {
264
366
  return import_node_os.default.homedir();
265
367
  }
266
368
  if (targetPath.startsWith("~/") || targetPath.startsWith("~\\")) {
267
- return import_node_path.default.join(import_node_os.default.homedir(), targetPath.slice(2));
369
+ return import_node_path2.default.join(import_node_os.default.homedir(), targetPath.slice(2));
268
370
  }
269
371
  return targetPath;
270
372
  }
271
373
  function resolveNamespaceDirectory(workspaceRoot, namespace, profile) {
272
374
  const rootFolder = namespace === "value" ? "values" : namespace === "secret" ? "secrets" : namespace;
273
375
  if (profile && profile !== "base") {
274
- return import_node_path.default.resolve(workspaceRoot, "profiles", profile, rootFolder);
376
+ return import_node_path2.default.resolve(workspaceRoot, "profiles", profile, rootFolder);
275
377
  }
276
- return import_node_path.default.resolve(workspaceRoot, rootFolder);
378
+ return import_node_path2.default.resolve(workspaceRoot, rootFolder);
277
379
  }
278
380
  function resolveConfigDocumentPath(workspaceRoot, namespace, configPath, profile) {
279
381
  const namespaceRoot = resolveNamespaceDirectory(workspaceRoot, namespace, profile);
280
382
  const fileName = `${configPath.split(".").shift() ?? "app"}.yml`;
281
- return import_node_path.default.resolve(namespaceRoot, fileName);
282
- }
283
-
284
- // ../core/src/utils/yaml.ts
285
- var import_yaml = require("yaml");
286
- function parseYaml(source) {
287
- return (0, import_yaml.parse)(source);
288
- }
289
- function stringifyYaml(value) {
290
- return (0, import_yaml.stringify)(value);
383
+ return import_node_path2.default.resolve(namespaceRoot, fileName);
291
384
  }
292
385
 
293
386
  // ../core/src/manifest/normalizeManifest.ts
@@ -305,7 +398,8 @@ var DEFAULT_INSPECTORS = ["provenance"];
305
398
  var DEFAULT_FRAMEWORK_PREFIXES = {
306
399
  next: "NEXT_PUBLIC_",
307
400
  vite: "VITE_",
308
- nuxt: "NUXT_PUBLIC_"
401
+ nuxt: "NUXT_PUBLIC_",
402
+ webpack: ""
309
403
  };
310
404
  var DEFAULT_NAMESPACES = {
311
405
  value: {
@@ -558,11 +652,15 @@ function normalizeManifest(manifest) {
558
652
 
559
653
  // ../core/src/manifest/loadManifest.ts
560
654
  async function loadManifest(options = {}) {
561
- const manifestRoot = await resolveManifestRoot(options.root);
562
- const manifestPath = import_node_path2.default.join(manifestRoot, "cnos.yml");
655
+ const resolved = await resolveManifestRoot({
656
+ ...options.root ? { root: options.root } : {},
657
+ ...options.cwd ? { cwd: options.cwd } : {}
658
+ });
659
+ const manifestRoot = resolved.manifestRoot;
660
+ const manifestPath = import_node_path3.default.join(manifestRoot, "cnos.yml");
563
661
  let source;
564
662
  try {
565
- source = await (0, import_promises2.readFile)(manifestPath, "utf8");
663
+ source = await (0, import_promises3.readFile)(manifestPath, "utf8");
566
664
  } catch {
567
665
  throw new CnosManifestError("Unable to read CNOS manifest", manifestPath);
568
666
  }
@@ -572,7 +670,10 @@ async function loadManifest(options = {}) {
572
670
  }
573
671
  return {
574
672
  manifestRoot,
575
- repoRoot: import_node_path2.default.dirname(manifestRoot),
673
+ repoRoot: import_node_path3.default.dirname(manifestRoot),
674
+ consumerRoot: resolved.consumerRoot,
675
+ ...resolved.anchorPath ? { anchorPath: resolved.anchorPath } : {},
676
+ ...resolved.workspace ? { anchoredWorkspace: resolved.workspace } : {},
576
677
  manifestPath,
577
678
  manifest: normalizeManifest(rawManifest),
578
679
  rawManifest
@@ -580,13 +681,13 @@ async function loadManifest(options = {}) {
580
681
  }
581
682
 
582
683
  // ../core/src/manifest/loadWorkspaceFile.ts
583
- var import_promises3 = require("fs/promises");
584
- var import_node_path3 = __toESM(require("path"), 1);
585
-
586
- // ../core/src/profiles/expandProfileChain.ts
587
684
  var import_promises4 = require("fs/promises");
588
685
  var import_node_path4 = __toESM(require("path"), 1);
589
686
 
687
+ // ../core/src/profiles/expandProfileChain.ts
688
+ var import_promises5 = require("fs/promises");
689
+ var import_node_path5 = __toESM(require("path"), 1);
690
+
590
691
  // ../core/src/promotions/validatePromotion.ts
591
692
  var DEFAULT_DATA_NAMESPACE = {
592
693
  kind: "data",
@@ -636,42 +737,42 @@ function validateProjectionIssue(manifest, key, target) {
636
737
  }
637
738
 
638
739
  // ../core/src/workspaces/resolveWorkspaceContext.ts
639
- var import_promises5 = require("fs/promises");
640
- var import_node_path5 = __toESM(require("path"), 1);
740
+ var import_promises6 = require("fs/promises");
741
+ var import_node_path6 = __toESM(require("path"), 1);
641
742
 
642
743
  // ../core/src/secrets/auditLog.ts
643
- var import_promises8 = require("fs/promises");
644
- var import_node_path8 = __toESM(require("path"), 1);
744
+ var import_promises9 = require("fs/promises");
745
+ var import_node_path9 = __toESM(require("path"), 1);
645
746
 
646
747
  // ../core/src/utils/secretStore.ts
647
748
  var import_node_crypto = require("crypto");
648
- var import_promises7 = require("fs/promises");
649
- var import_node_path7 = __toESM(require("path"), 1);
749
+ var import_promises8 = require("fs/promises");
750
+ var import_node_path8 = __toESM(require("path"), 1);
650
751
 
651
752
  // ../core/src/secrets/sessionStore.ts
652
- var import_promises6 = require("fs/promises");
653
- var import_node_path6 = __toESM(require("path"), 1);
753
+ var import_promises7 = require("fs/promises");
754
+ var import_node_path7 = __toESM(require("path"), 1);
654
755
  function buildSessionRoot(processEnv = process.env) {
655
- return import_node_path6.default.join(import_node_path6.default.resolve(expandHomePath(processEnv.CNOS_SECRET_HOME ?? "~/.cnos/secrets")), "sessions");
756
+ return import_node_path7.default.join(import_node_path7.default.resolve(expandHomePath(processEnv.CNOS_SECRET_HOME ?? "~/.cnos/secrets")), "sessions");
656
757
  }
657
758
  function buildSessionPath(vault, processEnv) {
658
- return import_node_path6.default.join(buildSessionRoot(processEnv), `${vault}.json`);
759
+ return import_node_path7.default.join(buildSessionRoot(processEnv), `${vault}.json`);
659
760
  }
660
761
  async function writeVaultSessionKey(vault, derivedKey, processEnv) {
661
762
  const filePath = buildSessionPath(vault, processEnv);
662
- await (0, import_promises6.mkdir)(import_node_path6.default.dirname(filePath), { recursive: true });
763
+ await (0, import_promises7.mkdir)(import_node_path7.default.dirname(filePath), { recursive: true });
663
764
  const document = {
664
765
  version: 1,
665
766
  vault,
666
767
  derivedKey: derivedKey.toString("hex"),
667
768
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
668
769
  };
669
- await (0, import_promises6.writeFile)(filePath, JSON.stringify(document, null, 2), "utf8");
770
+ await (0, import_promises7.writeFile)(filePath, JSON.stringify(document, null, 2), "utf8");
670
771
  return filePath;
671
772
  }
672
773
  async function readVaultSessionKey(vault, processEnv) {
673
774
  try {
674
- const source = await (0, import_promises6.readFile)(buildSessionPath(vault, processEnv), "utf8");
775
+ const source = await (0, import_promises7.readFile)(buildSessionPath(vault, processEnv), "utf8");
675
776
  const document = JSON.parse(source);
676
777
  if (document.version !== 1 || typeof document.derivedKey !== "string") {
677
778
  return void 0;
@@ -683,13 +784,13 @@ async function readVaultSessionKey(vault, processEnv) {
683
784
  }
684
785
  }
685
786
  async function clearVaultSessionKey(vault, processEnv) {
686
- await (0, import_promises6.rm)(buildSessionPath(vault, processEnv), { force: true });
787
+ await (0, import_promises7.rm)(buildSessionPath(vault, processEnv), { force: true });
687
788
  }
688
789
  async function clearAllVaultSessionKeys(processEnv) {
689
790
  const root = buildSessionRoot(processEnv);
690
791
  try {
691
- const entries = await (0, import_promises6.readdir)(root);
692
- await Promise.all(entries.map((entry) => (0, import_promises6.rm)(import_node_path6.default.join(root, entry), { force: true })));
792
+ const entries = await (0, import_promises7.readdir)(root);
793
+ await Promise.all(entries.map((entry) => (0, import_promises7.rm)(import_node_path7.default.join(root, entry), { force: true })));
693
794
  } catch {
694
795
  }
695
796
  }
@@ -711,7 +812,7 @@ function isSecretReference(value) {
711
812
  return isObject(value) && typeof value.provider === "string" && value.provider.trim().length > 0 && typeof value.ref === "string" && value.ref.trim().length > 0 && (value.vault === void 0 && true || typeof value.vault === "string" && value.vault.trim().length > 0) && Object.keys(value).every((key) => ["provider", "ref", "vault"].includes(key));
712
813
  }
713
814
  function resolveSecretStoreRoot(processEnv = process.env) {
714
- return import_node_path7.default.resolve(expandHomePath(processEnv.CNOS_SECRET_HOME ?? "~/.cnos/secrets"));
815
+ return import_node_path8.default.resolve(expandHomePath(processEnv.CNOS_SECRET_HOME ?? "~/.cnos/secrets"));
715
816
  }
716
817
  function normalizeVaultToken(vault = "default") {
717
818
  return vault.replace(/[^A-Za-z0-9]+/g, "_").replace(/^_+|_+$/g, "").toUpperCase();
@@ -746,19 +847,19 @@ function deriveVaultKey(passphrase, salt, iterations = PBKDF2_ITERATIONS) {
746
847
  return (0, import_node_crypto.pbkdf2Sync)(passphrase, salt, iterations, KEY_LENGTH, "sha512");
747
848
  }
748
849
  function buildMetaPath(storeRoot, vault = "default") {
749
- return import_node_path7.default.join(storeRoot, "vaults", vault, META_FILENAME);
850
+ return import_node_path8.default.join(storeRoot, "vaults", vault, META_FILENAME);
750
851
  }
751
852
  function resolveSecretVaultFile(storeRoot, vault = "default") {
752
853
  return buildMetaPath(storeRoot, vault);
753
854
  }
754
855
  function buildKeystorePath(storeRoot, vault = "default") {
755
- return import_node_path7.default.join(storeRoot, "vaults", vault, KEYSTORE_FILENAME);
856
+ return import_node_path8.default.join(storeRoot, "vaults", vault, KEYSTORE_FILENAME);
756
857
  }
757
858
  function buildLegacyVaultFile(storeRoot, vault = "default") {
758
- return import_node_path7.default.join(storeRoot, "vaults", `${vault}.json`);
859
+ return import_node_path8.default.join(storeRoot, "vaults", `${vault}.json`);
759
860
  }
760
861
  function buildLegacyVaultStoreRoot(storeRoot, vault = "default") {
761
- return import_node_path7.default.join(storeRoot, "vaults", vault, "store");
862
+ return import_node_path8.default.join(storeRoot, "vaults", vault, "store");
762
863
  }
763
864
  function assertVaultMetadata(value, filePath) {
764
865
  if (!isObject(value)) {
@@ -769,9 +870,9 @@ function assertVaultMetadata(value, filePath) {
769
870
  }
770
871
  return value;
771
872
  }
772
- async function exists2(targetPath) {
873
+ async function exists3(targetPath) {
773
874
  try {
774
- await (0, import_promises7.stat)(targetPath);
875
+ await (0, import_promises8.stat)(targetPath);
775
876
  return true;
776
877
  } catch {
777
878
  return false;
@@ -780,10 +881,10 @@ async function exists2(targetPath) {
780
881
  async function detectLegacyVaultFormat(storeRoot, vault = "default") {
781
882
  const legacyFile = buildLegacyVaultFile(storeRoot, vault);
782
883
  const legacyStore = buildLegacyVaultStoreRoot(storeRoot, vault);
783
- if (await exists2(legacyFile)) {
884
+ if (await exists3(legacyFile)) {
784
885
  return legacyFile;
785
886
  }
786
- if (await exists2(legacyStore)) {
887
+ if (await exists3(legacyStore)) {
787
888
  return legacyStore;
788
889
  }
789
890
  return void 0;
@@ -855,15 +956,15 @@ function buildInitialPayload() {
855
956
  async function writeVaultFiles(storeRoot, vault, meta, payload, key) {
856
957
  const metaPath = buildMetaPath(storeRoot, vault);
857
958
  const keystorePath = buildKeystorePath(storeRoot, vault);
858
- await (0, import_promises7.mkdir)(import_node_path7.default.dirname(metaPath), { recursive: true });
859
- await (0, import_promises7.writeFile)(metaPath, stringifyYaml(meta), "utf8");
860
- await (0, import_promises7.writeFile)(keystorePath, encryptPayload(payload, key));
959
+ await (0, import_promises8.mkdir)(import_node_path8.default.dirname(metaPath), { recursive: true });
960
+ await (0, import_promises8.writeFile)(metaPath, stringifyYaml(meta), "utf8");
961
+ await (0, import_promises8.writeFile)(keystorePath, encryptPayload(payload, key));
861
962
  }
862
963
  async function readVaultMetadata(storeRoot, vault = "default") {
863
964
  await assertNoLegacyVaultFormat(storeRoot, vault);
864
965
  const metaPath = buildMetaPath(storeRoot, vault);
865
966
  try {
866
- const source = await (0, import_promises7.readFile)(metaPath, "utf8");
967
+ const source = await (0, import_promises8.readFile)(metaPath, "utf8");
867
968
  return assertVaultMetadata(parseYaml(source), metaPath);
868
969
  } catch (error) {
869
970
  if (error.code === "ENOENT") {
@@ -873,11 +974,11 @@ async function readVaultMetadata(storeRoot, vault = "default") {
873
974
  }
874
975
  }
875
976
  async function listSecretVaults(storeRoot) {
876
- const vaultRoot = import_node_path7.default.join(storeRoot, "vaults");
977
+ const vaultRoot = import_node_path8.default.join(storeRoot, "vaults");
877
978
  try {
878
- const entries = await (0, import_promises7.readdir)(vaultRoot, { withFileTypes: true });
979
+ const entries = await (0, import_promises8.readdir)(vaultRoot, { withFileTypes: true });
879
980
  const vaults = await Promise.all(
880
- entries.filter((entry) => entry.isDirectory()).map(async (entry) => await exists2(import_node_path7.default.join(vaultRoot, entry.name, META_FILENAME)) ? entry.name : void 0)
981
+ entries.filter((entry) => entry.isDirectory()).map(async (entry) => await exists3(import_node_path8.default.join(vaultRoot, entry.name, META_FILENAME)) ? entry.name : void 0)
881
982
  );
882
983
  return vaults.filter((value) => Boolean(value)).sort((left, right) => left.localeCompare(right));
883
984
  } catch {
@@ -966,7 +1067,7 @@ async function loadVaultPayload(storeRoot, vault, auth) {
966
1067
  if (!key) {
967
1068
  throw new CnosAuthenticationError(`Vault "${vault}" requires authentication before access.`);
968
1069
  }
969
- const buffer = await (0, import_promises7.readFile)(buildKeystorePath(storeRoot, vault));
1070
+ const buffer = await (0, import_promises8.readFile)(buildKeystorePath(storeRoot, vault));
970
1071
  return {
971
1072
  meta,
972
1073
  payload: decryptPayload(buffer, key),
@@ -1039,14 +1140,14 @@ function resolveVaultDefinition(vaults, vault = "default") {
1039
1140
  };
1040
1141
  }
1041
1142
  async function removeLocalVaultFiles(storeRoot, vault = "default") {
1042
- await (0, import_promises7.rm)(import_node_path7.default.join(storeRoot, "vaults", vault), { recursive: true, force: true });
1143
+ await (0, import_promises8.rm)(import_node_path8.default.join(storeRoot, "vaults", vault), { recursive: true, force: true });
1043
1144
  }
1044
1145
 
1045
1146
  // ../core/src/secrets/auditLog.ts
1046
1147
  async function appendAuditEvent(event, processEnv = process.env) {
1047
- const auditFile = processEnv.CNOS_AUDIT_FILE ?? import_node_path8.default.join(resolveSecretStoreRoot(processEnv), "audit", "access.log");
1048
- await (0, import_promises8.mkdir)(import_node_path8.default.dirname(auditFile), { recursive: true });
1049
- await (0, import_promises8.appendFile)(
1148
+ const auditFile = processEnv.CNOS_AUDIT_FILE ?? import_node_path9.default.join(resolveSecretStoreRoot(processEnv), "audit", "access.log");
1149
+ await (0, import_promises9.mkdir)(import_node_path9.default.dirname(auditFile), { recursive: true });
1150
+ await (0, import_promises9.appendFile)(
1050
1151
  auditFile,
1051
1152
  `${JSON.stringify({
1052
1153
  ts: (/* @__PURE__ */ new Date()).toISOString(),
@@ -1312,9 +1413,12 @@ async function resolveVaultAuth(vaultId, definition, processEnv = process.env) {
1312
1413
  throw toAuthError(vaultId, [getVaultSessionKeyEnvVar(vaultId), ...sources]);
1313
1414
  }
1314
1415
 
1416
+ // ../core/src/runtime/toServerProjection.ts
1417
+ var import_node_crypto2 = require("crypto");
1418
+
1315
1419
  // ../core/src/runtime/dump.ts
1316
- var import_promises9 = require("fs/promises");
1317
- var import_node_path9 = __toESM(require("path"), 1);
1420
+ var import_promises10 = require("fs/promises");
1421
+ var import_node_path10 = __toESM(require("path"), 1);
1318
1422
 
1319
1423
  // ../core/src/utils/envNaming.ts
1320
1424
  function normalizeMappingConfig(config = {}) {
@@ -1326,8 +1430,8 @@ function normalizeMappingConfig(config = {}) {
1326
1430
  function toScreamingSnakeSegment(segment) {
1327
1431
  return segment.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/[^A-Za-z0-9]+/g, "_").replace(/_+/g, "_").replace(/^_+|_+$/g, "").toUpperCase();
1328
1432
  }
1329
- function toScreamingSnake(path13) {
1330
- return path13.split(".").map((segment) => toScreamingSnakeSegment(segment)).filter(Boolean).join("_");
1433
+ function toScreamingSnake(path14) {
1434
+ return path14.split(".").map((segment) => toScreamingSnakeSegment(segment)).filter(Boolean).join("_");
1331
1435
  }
1332
1436
  function logicalKeyToEnvVar(key, config = {}) {
1333
1437
  const normalized = normalizeMappingConfig(config);
@@ -1460,10 +1564,21 @@ async function validateRuntime(runtime) {
1460
1564
  }
1461
1565
 
1462
1566
  // src/runtime/bootstrap.ts
1463
- var import_node_crypto2 = require("crypto");
1567
+ var import_node_crypto3 = require("crypto");
1464
1568
  var CNOS_GRAPH_ENV_VAR = "__CNOS_GRAPH__";
1569
+ var CNOS_PROJECTION_ENV_VAR = "__CNOS_PROJECTION__";
1465
1570
  var CNOS_SECRET_PAYLOAD_ENV_VAR = "__CNOS_SECRET_PAYLOAD__";
1466
1571
  var CNOS_SESSION_KEY_ENV_VAR = "__CNOS_SESSION_KEY__";
1572
+ function serializeServerProjection(projection) {
1573
+ return JSON.stringify(projection);
1574
+ }
1575
+ function deserializeServerProjection(source) {
1576
+ const payload = JSON.parse(source);
1577
+ if (!payload || payload.version !== 1 || typeof payload.workspace !== "string" || typeof payload.profile !== "string" || typeof payload.resolvedAt !== "string" || typeof payload.configHash !== "string" || !payload.values || typeof payload.values !== "object" || Array.isArray(payload.values) || !payload.secretRefs || typeof payload.secretRefs !== "object" || Array.isArray(payload.secretRefs) || !Array.isArray(payload.publicKeys) || !payload.meta || typeof payload.meta !== "object") {
1578
+ throw new Error("Invalid CNOS server projection payload");
1579
+ }
1580
+ return payload;
1581
+ }
1467
1582
  function serializeRuntimeGraph(graph) {
1468
1583
  const payload = {
1469
1584
  entries: Array.from(graph.entries.values()),
@@ -1507,15 +1622,15 @@ function decryptSecretPayload(serialized, sessionKey) {
1507
1622
  const iv = Buffer.from(payload.iv, "base64");
1508
1623
  const tag = Buffer.from(payload.tag, "base64");
1509
1624
  const ciphertext = Buffer.from(payload.ciphertext, "base64");
1510
- const decipher = (0, import_node_crypto2.createDecipheriv)("aes-256-gcm", key, iv);
1625
+ const decipher = (0, import_node_crypto3.createDecipheriv)("aes-256-gcm", key, iv);
1511
1626
  decipher.setAuthTag(tag);
1512
1627
  const plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString("utf8");
1513
1628
  return JSON.parse(plaintext);
1514
1629
  }
1515
1630
  function serializeSecretPayload(values) {
1516
- const key = (0, import_node_crypto2.randomBytes)(32);
1517
- const iv = (0, import_node_crypto2.randomBytes)(12);
1518
- const cipher = (0, import_node_crypto2.createCipheriv)("aes-256-gcm", key, iv);
1631
+ const key = (0, import_node_crypto3.randomBytes)(32);
1632
+ const iv = (0, import_node_crypto3.randomBytes)(12);
1633
+ const cipher = (0, import_node_crypto3.createCipheriv)("aes-256-gcm", key, iv);
1519
1634
  const ciphertext = Buffer.concat([cipher.update(JSON.stringify(values), "utf8"), cipher.final()]);
1520
1635
  const tag = cipher.getAuthTag();
1521
1636
  return {
@@ -1546,6 +1661,13 @@ function readRuntimeGraphFromEnv(processEnv = process.env) {
1546
1661
  }
1547
1662
  return graph;
1548
1663
  }
1664
+ function readServerProjectionFromEnv(processEnv = process.env) {
1665
+ const serialized = processEnv[CNOS_PROJECTION_ENV_VAR];
1666
+ if (!serialized) {
1667
+ return void 0;
1668
+ }
1669
+ return deserializeServerProjection(serialized);
1670
+ }
1549
1671
  function graphRequiresSecretHydration(graph) {
1550
1672
  return Array.from(graph.entries.values()).some((entry) => entry.namespace === "secret" && isSecretReference(entry.value));
1551
1673
  }
@@ -1581,10 +1703,10 @@ function buildNamespaceInterfaces(schema) {
1581
1703
  continue;
1582
1704
  }
1583
1705
  const namespace = logicalKey.slice(0, separatorIndex);
1584
- const path13 = logicalKey.slice(separatorIndex + 1);
1706
+ const path14 = logicalKey.slice(separatorIndex + 1);
1585
1707
  const existing = namespaceGroups.get(namespace) ?? [];
1586
1708
  existing.push({
1587
- key: path13,
1709
+ key: path14,
1588
1710
  rule
1589
1711
  });
1590
1712
  namespaceGroups.set(namespace, existing);
@@ -1689,15 +1811,15 @@ function generateCodegenContent(manifest, sourcePath, typeModuleImport = "./cnos
1689
1811
  }
1690
1812
 
1691
1813
  // src/codegen/writeOutput.ts
1692
- var import_promises10 = require("fs/promises");
1693
- var import_node_path10 = __toESM(require("path"), 1);
1814
+ var import_promises11 = require("fs/promises");
1815
+ var import_node_path11 = __toESM(require("path"), 1);
1694
1816
  function stripTsExtension(filePath) {
1695
1817
  return filePath.replace(/(\.d)?\.[cm]?tsx?$/i, "").replace(/\.[cm]?jsx?$/i, "");
1696
1818
  }
1697
1819
  function resolveCodegenPaths(repoRoot, out) {
1698
- const typesPath = out ? import_node_path10.default.resolve(repoRoot, out) : import_node_path10.default.join(repoRoot, ".cnos", "types", "cnos.d.ts");
1699
- const runtimePath = import_node_path10.default.join(import_node_path10.default.dirname(typesPath), "runtime.ts");
1700
- const typeImportPath = `./${import_node_path10.default.basename(stripTsExtension(typesPath))}`;
1820
+ const typesPath = out ? import_node_path11.default.resolve(repoRoot, out) : import_node_path11.default.join(repoRoot, ".cnos", "types", "cnos.d.ts");
1821
+ const runtimePath = import_node_path11.default.join(import_node_path11.default.dirname(typesPath), "runtime.ts");
1822
+ const typeImportPath = `./${import_node_path11.default.basename(stripTsExtension(typesPath))}`;
1701
1823
  return {
1702
1824
  typesPath,
1703
1825
  runtimePath,
@@ -1708,10 +1830,10 @@ async function writeCodegenOutput(options = {}) {
1708
1830
  const loadedManifest = await loadManifest(options.root ? { root: options.root } : {});
1709
1831
  const paths = resolveCodegenPaths(loadedManifest.repoRoot, options.out);
1710
1832
  const generated = generateCodegenContent(loadedManifest.manifest, loadedManifest.manifestPath, paths.typeImportPath);
1711
- await (0, import_promises10.mkdir)(import_node_path10.default.dirname(paths.typesPath), { recursive: true });
1712
- await (0, import_promises10.mkdir)(import_node_path10.default.dirname(paths.runtimePath), { recursive: true });
1713
- await (0, import_promises10.writeFile)(paths.typesPath, generated.typesContent, "utf8");
1714
- await (0, import_promises10.writeFile)(paths.runtimePath, generated.runtimeContent, "utf8");
1833
+ await (0, import_promises11.mkdir)(import_node_path11.default.dirname(paths.typesPath), { recursive: true });
1834
+ await (0, import_promises11.mkdir)(import_node_path11.default.dirname(paths.runtimePath), { recursive: true });
1835
+ await (0, import_promises11.writeFile)(paths.typesPath, generated.typesContent, "utf8");
1836
+ await (0, import_promises11.writeFile)(paths.runtimePath, generated.runtimeContent, "utf8");
1715
1837
  return {
1716
1838
  manifestPath: loadedManifest.manifestPath,
1717
1839
  typesPath: paths.typesPath,
@@ -1897,7 +2019,7 @@ function formatDriftReport(report) {
1897
2019
  }
1898
2020
 
1899
2021
  // src/migrate/applyManifest.ts
1900
- var import_promises11 = require("fs/promises");
2022
+ var import_promises12 = require("fs/promises");
1901
2023
  function sortRecord(record) {
1902
2024
  return Object.fromEntries(Object.entries(record).sort(([left], [right]) => left.localeCompare(right)));
1903
2025
  }
@@ -1932,7 +2054,7 @@ async function applyManifestMappings(proposals, root) {
1932
2054
  promote: Array.from(promoted).sort((left, right) => left.localeCompare(right))
1933
2055
  };
1934
2056
  }
1935
- await (0, import_promises11.writeFile)(loadedManifest.manifestPath, stringifyYaml(rawManifest), "utf8");
2057
+ await (0, import_promises12.writeFile)(loadedManifest.manifestPath, stringifyYaml(rawManifest), "utf8");
1936
2058
  return {
1937
2059
  manifestPath: loadedManifest.manifestPath,
1938
2060
  appliedMappings,
@@ -1967,7 +2089,7 @@ function proposeMapping(envVar) {
1967
2089
  }
1968
2090
 
1969
2091
  // src/migrate/rewriteSource.ts
1970
- var import_promises12 = require("fs/promises");
2092
+ var import_promises13 = require("fs/promises");
1971
2093
  function importStatementFor(kind) {
1972
2094
  return kind === "import-meta-env" ? "import cnos from '@kitsy/cnos/browser';" : "import cnos from '@kitsy/cnos';";
1973
2095
  }
@@ -1988,7 +2110,7 @@ async function rewriteSourceFiles(usages, proposals) {
1988
2110
  const backupFiles = [];
1989
2111
  const skippedUsages = [];
1990
2112
  for (const [filePath, fileUsages] of fileGroups.entries()) {
1991
- const original = await (0, import_promises12.readFile)(filePath, "utf8");
2113
+ const original = await (0, import_promises13.readFile)(filePath, "utf8");
1992
2114
  let nextSource = original;
1993
2115
  let changed = false;
1994
2116
  const importKinds = /* @__PURE__ */ new Set();
@@ -2015,7 +2137,7 @@ async function rewriteSourceFiles(usages, proposals) {
2015
2137
  continue;
2016
2138
  }
2017
2139
  const backupPath = `${filePath}.bak`;
2018
- await (0, import_promises12.copyFile)(filePath, backupPath);
2140
+ await (0, import_promises13.copyFile)(filePath, backupPath);
2019
2141
  backupFiles.push(backupPath);
2020
2142
  for (const kind of Array.from(importKinds)) {
2021
2143
  const importStatement = importStatementFor(kind);
@@ -2024,7 +2146,7 @@ async function rewriteSourceFiles(usages, proposals) {
2024
2146
  ${nextSource}`;
2025
2147
  }
2026
2148
  }
2027
- await (0, import_promises12.writeFile)(filePath, nextSource, "utf8");
2149
+ await (0, import_promises13.writeFile)(filePath, nextSource, "utf8");
2028
2150
  rewrittenFiles.push(filePath);
2029
2151
  }
2030
2152
  return {
@@ -2035,18 +2157,18 @@ ${nextSource}`;
2035
2157
  }
2036
2158
 
2037
2159
  // src/migrate/scanEnvUsage.ts
2038
- var import_promises13 = require("fs/promises");
2039
- var import_node_path11 = __toESM(require("path"), 1);
2160
+ var import_promises14 = require("fs/promises");
2161
+ var import_node_path12 = __toESM(require("path"), 1);
2040
2162
  var SOURCE_EXTENSIONS = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".mts", ".cts", ".mjs", ".cjs"]);
2041
2163
  var PROCESS_ENV_DOT = /process\.env\.([A-Z][A-Z0-9_]*)/g;
2042
2164
  var PROCESS_ENV_BRACKET = /process\.env\[['"]([A-Z][A-Z0-9_]*)['"]\]/g;
2043
2165
  var IMPORT_META_ENV_DOT = /import\.meta\.env\.([A-Z][A-Z0-9_]*)/g;
2044
2166
  var IMPORT_META_ENV_BRACKET = /import\.meta\.env\[['"]([A-Z][A-Z0-9_]*)['"]\]/g;
2045
2167
  async function collectFiles(root) {
2046
- const entries = await (0, import_promises13.readdir)(root, { withFileTypes: true });
2168
+ const entries = await (0, import_promises14.readdir)(root, { withFileTypes: true });
2047
2169
  const files = [];
2048
2170
  for (const entry of entries) {
2049
- const filePath = import_node_path11.default.join(root, entry.name);
2171
+ const filePath = import_node_path12.default.join(root, entry.name);
2050
2172
  if (entry.isDirectory()) {
2051
2173
  if (entry.name === "node_modules" || entry.name === "dist" || entry.name === ".git") {
2052
2174
  continue;
@@ -2054,7 +2176,7 @@ async function collectFiles(root) {
2054
2176
  files.push(...await collectFiles(filePath));
2055
2177
  continue;
2056
2178
  }
2057
- if (SOURCE_EXTENSIONS.has(import_node_path11.default.extname(entry.name))) {
2179
+ if (SOURCE_EXTENSIONS.has(import_node_path12.default.extname(entry.name))) {
2058
2180
  files.push(filePath);
2059
2181
  }
2060
2182
  }
@@ -2080,7 +2202,7 @@ async function scanEnvUsage(scanRoot) {
2080
2202
  const files = await collectFiles(scanRoot);
2081
2203
  const usages = [];
2082
2204
  for (const filePath of files) {
2083
- const source = await (0, import_promises13.readFile)(filePath, "utf8");
2205
+ const source = await (0, import_promises14.readFile)(filePath, "utf8");
2084
2206
  usages.push(...collectMatches(filePath, source, PROCESS_ENV_DOT, "process-env"));
2085
2207
  usages.push(...collectMatches(filePath, source, PROCESS_ENV_BRACKET, "process-env"));
2086
2208
  usages.push(...collectMatches(filePath, source, IMPORT_META_ENV_DOT, "import-meta-env"));
@@ -2121,7 +2243,7 @@ function diffGraphs(previous, next) {
2121
2243
  }
2122
2244
 
2123
2245
  // src/watch/watchFiles.ts
2124
- var import_node_path12 = __toESM(require("path"), 1);
2246
+ var import_node_path13 = __toESM(require("path"), 1);
2125
2247
  async function watchFiles(runtime, root) {
2126
2248
  const manifest = await loadManifest(root ? { root } : {});
2127
2249
  const roots = Array.from(
@@ -2129,7 +2251,7 @@ async function watchFiles(runtime, root) {
2129
2251
  ).sort((left, right) => left.localeCompare(right));
2130
2252
  const files = Array.from(
2131
2253
  new Set(
2132
- Array.from(runtime.graph.entries.values()).map((entry) => entry.winner.origin?.file).filter((file) => Boolean(file)).map((file) => import_node_path12.default.resolve(manifest.repoRoot, file))
2254
+ Array.from(runtime.graph.entries.values()).map((entry) => entry.winner.origin?.file).filter((file) => Boolean(file)).map((file) => import_node_path13.default.resolve(manifest.repoRoot, file))
2133
2255
  )
2134
2256
  ).sort((left, right) => left.localeCompare(right));
2135
2257
  return {
@@ -2141,6 +2263,7 @@ async function watchFiles(runtime, root) {
2141
2263
  // Annotate the CommonJS export names for ESM import in node:
2142
2264
  0 && (module.exports = {
2143
2265
  CNOS_GRAPH_ENV_VAR,
2266
+ CNOS_PROJECTION_ENV_VAR,
2144
2267
  CNOS_SECRET_PAYLOAD_ENV_VAR,
2145
2268
  CNOS_SESSION_KEY_ENV_VAR,
2146
2269
  CnosAuthenticationError,
@@ -2154,6 +2277,7 @@ async function watchFiles(runtime, root) {
2154
2277
  deleteLocalSecret,
2155
2278
  deriveVaultKey,
2156
2279
  deserializeRuntimeGraph,
2280
+ deserializeServerProjection,
2157
2281
  detectLegacyVaultFormat,
2158
2282
  diffGraphs,
2159
2283
  ensureProjectionAllowed,
@@ -2174,6 +2298,7 @@ async function watchFiles(runtime, root) {
2174
2298
  readKeychain,
2175
2299
  readLocalSecret,
2176
2300
  readRuntimeGraphFromEnv,
2301
+ readServerProjectionFromEnv,
2177
2302
  readVaultMetadata,
2178
2303
  removeLocalVaultFiles,
2179
2304
  resolveCodegenPaths,
@@ -2190,6 +2315,7 @@ async function watchFiles(runtime, root) {
2190
2315
  scanEnvUsage,
2191
2316
  serializeRuntimeGraph,
2192
2317
  serializeSecretPayload,
2318
+ serializeServerProjection,
2193
2319
  stringifyYaml,
2194
2320
  validateRuntime,
2195
2321
  watchFiles,