@kitsy/cnos 1.2.0 → 1.3.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 (64) hide show
  1. package/README.md +3 -3
  2. package/dist/build/index.cjs +902 -113
  3. package/dist/build/index.d.cts +1 -1
  4. package/dist/build/index.d.ts +1 -1
  5. package/dist/build/index.js +22 -10
  6. package/dist/{chunk-WHUGFPE4.js → chunk-CDXJISGB.js} +1 -1
  7. package/dist/{chunk-APCTXRUN.js → chunk-DRKDNY4I.js} +998 -191
  8. package/dist/chunk-E7SE6N26.js +189 -0
  9. package/dist/{chunk-SO5XREEU.js → chunk-EDCLLCNL.js} +32 -11
  10. package/dist/{chunk-SXTMTACL.js → chunk-FC3IV6A7.js} +1 -31
  11. package/dist/{chunk-MLQGYCO7.js → chunk-JDII6O72.js} +1 -1
  12. package/dist/chunk-K6QYI2T4.js +105 -0
  13. package/dist/{chunk-EIN55XXA.js → chunk-OOKFRWTN.js} +1 -1
  14. package/dist/{chunk-ZA74BO47.js → chunk-OWUZQ4OH.js} +1 -1
  15. package/dist/{chunk-RD5WMHPM.js → chunk-QTKXPY3N.js} +1 -1
  16. package/dist/configure/index.cjs +2928 -0
  17. package/dist/configure/index.d.cts +12 -0
  18. package/dist/configure/index.d.ts +12 -0
  19. package/dist/configure/index.js +24 -0
  20. package/dist/{envNaming-BTJpH93W.d.cts → envNaming-D6k66myh.d.cts} +1 -1
  21. package/dist/{envNaming-CcsqAel3.d.ts → envNaming-Dy3WYiGK.d.ts} +1 -1
  22. package/dist/index.cjs +1142 -178
  23. package/dist/index.d.cts +2 -13
  24. package/dist/index.d.ts +2 -13
  25. package/dist/index.js +13 -25
  26. package/dist/internal.cjs +1512 -80
  27. package/dist/internal.d.cts +170 -14
  28. package/dist/internal.d.ts +170 -14
  29. package/dist/internal.js +645 -5
  30. package/dist/plugin/basic-schema.cjs +29 -2
  31. package/dist/plugin/basic-schema.d.cts +1 -1
  32. package/dist/plugin/basic-schema.d.ts +1 -1
  33. package/dist/plugin/basic-schema.js +2 -2
  34. package/dist/plugin/cli-args.cjs +29 -2
  35. package/dist/plugin/cli-args.d.cts +1 -1
  36. package/dist/plugin/cli-args.d.ts +1 -1
  37. package/dist/plugin/cli-args.js +2 -2
  38. package/dist/plugin/dotenv.cjs +36 -9
  39. package/dist/plugin/dotenv.d.cts +2 -2
  40. package/dist/plugin/dotenv.d.ts +2 -2
  41. package/dist/plugin/dotenv.js +2 -2
  42. package/dist/plugin/env-export.cjs +31 -2
  43. package/dist/plugin/env-export.d.cts +2 -2
  44. package/dist/plugin/env-export.d.ts +2 -2
  45. package/dist/plugin/env-export.js +2 -2
  46. package/dist/plugin/filesystem.cjs +46 -91
  47. package/dist/plugin/filesystem.d.cts +1 -1
  48. package/dist/plugin/filesystem.d.ts +1 -1
  49. package/dist/plugin/filesystem.js +2 -2
  50. package/dist/plugin/process-env.cjs +31 -4
  51. package/dist/plugin/process-env.d.cts +2 -2
  52. package/dist/plugin/process-env.d.ts +2 -2
  53. package/dist/plugin/process-env.js +2 -2
  54. package/dist/{plugin-DkOIT5uI.d.cts → plugin-CyNkf7Dm.d.cts} +14 -2
  55. package/dist/{plugin-DkOIT5uI.d.ts → plugin-CyNkf7Dm.d.ts} +14 -2
  56. package/dist/runtime/index.cjs +956 -128
  57. package/dist/runtime/index.d.cts +1 -1
  58. package/dist/runtime/index.d.ts +1 -1
  59. package/dist/runtime/index.js +11 -186
  60. package/dist/{toPublicEnv-DvFeV3qG.d.cts → toPublicEnv-Cz72m6y0.d.cts} +1 -1
  61. package/dist/{toPublicEnv-C9clvXLo.d.ts → toPublicEnv-D2PZkaN-.d.ts} +1 -1
  62. package/package.json +11 -1
  63. package/dist/chunk-JUHPBAEH.js +0 -20
  64. package/dist/chunk-PQ4KSV76.js +0 -50
package/dist/index.cjs CHANGED
@@ -30,13 +30,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var index_exports = {};
32
32
  __export(index_exports, {
33
- createCnos: () => createCnos2,
34
- defaultPlugins: () => defaultPlugins,
35
- planDump: () => planDump,
36
- resolveBrowserData: () => resolveBrowserData,
37
- toEnv: () => toEnv,
38
- toPublicEnv: () => toPublicEnv,
39
- writeDump: () => writeDump
33
+ cnos: () => runtime_default,
34
+ default: () => runtime_default
40
35
  });
41
36
  module.exports = __toCommonJS(index_exports);
42
37
 
@@ -59,6 +54,11 @@ var CnosSecurityError = class extends CnosError {
59
54
  super(message);
60
55
  }
61
56
  };
57
+ var CnosAuthenticationError = class extends CnosError {
58
+ constructor(message) {
59
+ super(message);
60
+ }
61
+ };
62
62
  var CnosKeyNotFoundError = class extends CnosError {
63
63
  constructor(key) {
64
64
  super(`Missing required CNOS config key: ${key}`);
@@ -111,6 +111,68 @@ function createProvenanceInspector() {
111
111
  };
112
112
  }
113
113
 
114
+ // ../core/src/keychain/linux.ts
115
+ var import_node_child_process = require("child_process");
116
+ var import_node_util = require("util");
117
+ var execFileAsync = (0, import_node_util.promisify)(import_node_child_process.execFile);
118
+ async function readLinuxKeychain(entry) {
119
+ try {
120
+ const { stdout } = await execFileAsync("secret-tool", ["lookup", "service", "cnos", "account", entry]);
121
+ const value = stdout.trim();
122
+ return value.length > 0 ? value : void 0;
123
+ } catch {
124
+ return void 0;
125
+ }
126
+ }
127
+
128
+ // ../core/src/keychain/macos.ts
129
+ var import_node_child_process2 = require("child_process");
130
+ var import_node_util2 = require("util");
131
+ var execFileAsync2 = (0, import_node_util2.promisify)(import_node_child_process2.execFile);
132
+ async function readMacosKeychain(entry) {
133
+ try {
134
+ const { stdout } = await execFileAsync2("security", ["find-generic-password", "-a", "cnos", "-s", entry, "-w"]);
135
+ const value = stdout.trim();
136
+ return value.length > 0 ? value : void 0;
137
+ } catch {
138
+ return void 0;
139
+ }
140
+ }
141
+
142
+ // ../core/src/keychain/windows.ts
143
+ var import_node_child_process3 = require("child_process");
144
+ var import_node_util3 = require("util");
145
+ var execFileAsync3 = (0, import_node_util3.promisify)(import_node_child_process3.execFile);
146
+ function wrap(script) {
147
+ return ["-NoProfile", "-Command", script];
148
+ }
149
+ async function readWindowsKeychain(entry) {
150
+ try {
151
+ const { stdout } = await execFileAsync3(
152
+ "powershell",
153
+ wrap(`Add-Type -AssemblyName System.Runtime.WindowsRuntime; [Windows.Security.Credentials.PasswordVault,Windows.Security.Credentials,ContentType=WindowsRuntime] > $null; $vault = New-Object Windows.Security.Credentials.PasswordVault; $credential = $vault.Retrieve('cnos','${entry}'); $credential.RetrievePassword(); Write-Output $credential.Password`)
154
+ );
155
+ const value = stdout.trim();
156
+ return value.length > 0 ? value : void 0;
157
+ } catch {
158
+ return void 0;
159
+ }
160
+ }
161
+
162
+ // ../core/src/keychain/index.ts
163
+ async function readKeychain(entry) {
164
+ if (process.platform === "win32") {
165
+ return readWindowsKeychain(entry);
166
+ }
167
+ if (process.platform === "darwin") {
168
+ return readMacosKeychain(entry);
169
+ }
170
+ if (process.platform === "linux") {
171
+ return readLinuxKeychain(entry);
172
+ }
173
+ return void 0;
174
+ }
175
+
114
176
  // ../core/src/manifest/loadManifest.ts
115
177
  var import_promises2 = require("fs/promises");
116
178
  var import_node_path2 = __toESM(require("path"), 1);
@@ -287,22 +349,82 @@ function normalizeNamespaces(namespaces) {
287
349
  function normalizeVaults(vaults) {
288
350
  return Object.fromEntries(
289
351
  Object.entries(vaults ?? {}).map(([name, definition]) => {
352
+ const legacyPassphrase = definition.passphrase;
353
+ if (legacyPassphrase !== void 0) {
354
+ throw new CnosManifestError(
355
+ `Vault "${name}" uses legacy passphrase configuration. Use vaults.${name}.auth instead.`
356
+ );
357
+ }
290
358
  const provider = definition.provider?.trim();
291
359
  if (!provider) {
292
360
  throw new CnosManifestError(`Vault "${name}" requires a provider`);
293
361
  }
362
+ const normalizedAuth = normalizeVaultAuth(name, provider, definition.auth);
363
+ const normalizedMapping = Object.fromEntries(
364
+ Object.entries(definition.mapping ?? {}).filter(
365
+ (entry) => typeof entry[0] === "string" && typeof entry[1] === "string"
366
+ ).map(([envVar, logicalRef]) => [envVar.trim(), logicalRef.trim()]).filter(([envVar, logicalRef]) => envVar.length > 0 && logicalRef.length > 0)
367
+ );
294
368
  return [
295
369
  name,
296
370
  {
297
371
  provider,
298
- ...definition.passphrase?.trim() ? {
299
- passphrase: definition.passphrase.trim()
372
+ auth: normalizedAuth,
373
+ ...Object.keys(normalizedMapping).length > 0 ? {
374
+ mapping: normalizedMapping
300
375
  } : {}
301
376
  }
302
377
  ];
303
378
  })
304
379
  );
305
380
  }
381
+ function normalizeAuthSources(value) {
382
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
383
+ return void 0;
384
+ }
385
+ const sources = Array.isArray(value.from) ? value.from : void 0;
386
+ const normalized = (sources ?? []).map((entry) => typeof entry === "string" ? entry.trim() : "").filter(Boolean);
387
+ return normalized.length > 0 ? normalized : void 0;
388
+ }
389
+ function normalizeVaultAuth(vaultName, provider, auth) {
390
+ if (provider === "local") {
391
+ const passphraseSources = normalizeAuthSources(auth?.passphrase);
392
+ const defaultToken = vaultName.replace(/[^A-Za-z0-9]+/g, "_").replace(/^_+|_+$/g, "").toUpperCase();
393
+ const defaultSources = [
394
+ ...defaultToken ? [`env:CNOS_SECRET_PASSPHRASE_${defaultToken}`] : [],
395
+ "env:CNOS_SECRET_PASSPHRASE",
396
+ `keychain:cnos/${vaultName}`,
397
+ "prompt"
398
+ ];
399
+ return {
400
+ method: auth?.method ?? "passphrase",
401
+ passphrase: {
402
+ from: passphraseSources ?? defaultSources
403
+ },
404
+ ...auth?.config ? { config: auth.config } : {}
405
+ };
406
+ }
407
+ if (provider === "github-secrets") {
408
+ return {
409
+ method: auth?.method ?? "environment",
410
+ ...auth?.config ? { config: auth.config } : {}
411
+ };
412
+ }
413
+ return {
414
+ ...auth?.method ? { method: auth.method } : {},
415
+ ...normalizeAuthSources(auth?.passphrase) ? {
416
+ passphrase: {
417
+ from: normalizeAuthSources(auth?.passphrase) ?? []
418
+ }
419
+ } : {},
420
+ ...normalizeAuthSources(auth?.token) ? {
421
+ token: {
422
+ from: normalizeAuthSources(auth?.token) ?? []
423
+ }
424
+ } : {},
425
+ ...auth?.config ? { config: auth.config } : {}
426
+ };
427
+ }
306
428
  function normalizeManifest(manifest) {
307
429
  const version = manifest.version ?? 1;
308
430
  if (version !== 1) {
@@ -1106,6 +1228,712 @@ async function runPipeline(options) {
1106
1228
  return collectedEntries.flat();
1107
1229
  }
1108
1230
 
1231
+ // ../core/src/secrets/auditLog.ts
1232
+ var import_promises8 = require("fs/promises");
1233
+ var import_node_path8 = __toESM(require("path"), 1);
1234
+
1235
+ // ../core/src/utils/secretStore.ts
1236
+ var import_node_crypto = require("crypto");
1237
+ var import_promises7 = require("fs/promises");
1238
+ var import_node_path7 = __toESM(require("path"), 1);
1239
+
1240
+ // ../core/src/secrets/sessionStore.ts
1241
+ var import_promises6 = require("fs/promises");
1242
+ var import_node_path6 = __toESM(require("path"), 1);
1243
+ function buildSessionRoot(processEnv = process.env) {
1244
+ return import_node_path6.default.join(import_node_path6.default.resolve(expandHomePath(processEnv.CNOS_SECRET_HOME ?? "~/.cnos/secrets")), "sessions");
1245
+ }
1246
+ function buildSessionPath(vault, processEnv) {
1247
+ return import_node_path6.default.join(buildSessionRoot(processEnv), `${vault}.json`);
1248
+ }
1249
+ async function readVaultSessionKey(vault, processEnv) {
1250
+ try {
1251
+ const source = await (0, import_promises6.readFile)(buildSessionPath(vault, processEnv), "utf8");
1252
+ const document = JSON.parse(source);
1253
+ if (document.version !== 1 || typeof document.derivedKey !== "string") {
1254
+ return void 0;
1255
+ }
1256
+ const key = Buffer.from(document.derivedKey, "hex");
1257
+ return key.length > 0 ? key : void 0;
1258
+ } catch {
1259
+ return void 0;
1260
+ }
1261
+ }
1262
+
1263
+ // ../core/src/utils/secretStore.ts
1264
+ var KEY_LENGTH = 32;
1265
+ var SALT_LENGTH = 32;
1266
+ var IV_LENGTH = 12;
1267
+ var AUTH_TAG_LENGTH = 16;
1268
+ var PBKDF2_ITERATIONS = 6e5;
1269
+ var KEYSTORE_VERSION = 1;
1270
+ var METADATA_VERSION = 1;
1271
+ var META_FILENAME = "meta.yml";
1272
+ var KEYSTORE_FILENAME = "keystore.enc";
1273
+ function isObject(value) {
1274
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
1275
+ }
1276
+ function isSecretReference(value) {
1277
+ 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));
1278
+ }
1279
+ function resolveSecretStoreRoot(processEnv = process.env) {
1280
+ return import_node_path7.default.resolve(expandHomePath(processEnv.CNOS_SECRET_HOME ?? "~/.cnos/secrets"));
1281
+ }
1282
+ function normalizeVaultToken(vault = "default") {
1283
+ return vault.replace(/[^A-Za-z0-9]+/g, "_").replace(/^_+|_+$/g, "").toUpperCase();
1284
+ }
1285
+ function getVaultPassphraseEnvVar(vault = "default") {
1286
+ const vaultToken = normalizeVaultToken(vault);
1287
+ return vaultToken && vaultToken !== "DEFAULT" ? `CNOS_SECRET_PASSPHRASE_${vaultToken}` : "CNOS_SECRET_PASSPHRASE";
1288
+ }
1289
+ function getVaultSessionKeyEnvVar(vault = "default") {
1290
+ const vaultToken = normalizeVaultToken(vault);
1291
+ return `__CNOS_VAULT_KEY_${vaultToken || "DEFAULT"}__`;
1292
+ }
1293
+ function resolveSecretPassphrase(vault = "default", processEnv = process.env) {
1294
+ return processEnv[getVaultPassphraseEnvVar(vault)] ?? processEnv.CNOS_SECRET_PASSPHRASE;
1295
+ }
1296
+ function resolveVaultSessionKey(vault = "default", processEnv = process.env) {
1297
+ const encoded = processEnv[getVaultSessionKeyEnvVar(vault)];
1298
+ if (!encoded) {
1299
+ return readVaultSessionKey(vault, processEnv);
1300
+ }
1301
+ try {
1302
+ const key = Buffer.from(encoded, "hex");
1303
+ return key.length === KEY_LENGTH ? key : void 0;
1304
+ } catch {
1305
+ return void 0;
1306
+ }
1307
+ }
1308
+ function deriveVaultKey(passphrase, salt, iterations = PBKDF2_ITERATIONS) {
1309
+ return (0, import_node_crypto.pbkdf2Sync)(passphrase, salt, iterations, KEY_LENGTH, "sha512");
1310
+ }
1311
+ function buildMetaPath(storeRoot, vault = "default") {
1312
+ return import_node_path7.default.join(storeRoot, "vaults", vault, META_FILENAME);
1313
+ }
1314
+ function buildKeystorePath(storeRoot, vault = "default") {
1315
+ return import_node_path7.default.join(storeRoot, "vaults", vault, KEYSTORE_FILENAME);
1316
+ }
1317
+ function buildLegacyVaultFile(storeRoot, vault = "default") {
1318
+ return import_node_path7.default.join(storeRoot, "vaults", `${vault}.json`);
1319
+ }
1320
+ function buildLegacyVaultStoreRoot(storeRoot, vault = "default") {
1321
+ return import_node_path7.default.join(storeRoot, "vaults", vault, "store");
1322
+ }
1323
+ function assertVaultMetadata(value, filePath) {
1324
+ if (!isObject(value)) {
1325
+ throw new CnosManifestError("Invalid CNOS vault metadata", filePath);
1326
+ }
1327
+ if (value.version !== METADATA_VERSION || value.algorithm !== "aes-256-gcm" || value.kdf !== "pbkdf2-sha512" || typeof value.iterations !== "number" || typeof value.salt !== "string" || typeof value.createdAt !== "string" || typeof value.secretCount !== "number") {
1328
+ throw new CnosManifestError("Invalid CNOS vault metadata", filePath);
1329
+ }
1330
+ return value;
1331
+ }
1332
+ async function exists3(targetPath) {
1333
+ try {
1334
+ await (0, import_promises7.stat)(targetPath);
1335
+ return true;
1336
+ } catch {
1337
+ return false;
1338
+ }
1339
+ }
1340
+ async function detectLegacyVaultFormat(storeRoot, vault = "default") {
1341
+ const legacyFile = buildLegacyVaultFile(storeRoot, vault);
1342
+ const legacyStore = buildLegacyVaultStoreRoot(storeRoot, vault);
1343
+ if (await exists3(legacyFile)) {
1344
+ return legacyFile;
1345
+ }
1346
+ if (await exists3(legacyStore)) {
1347
+ return legacyStore;
1348
+ }
1349
+ return void 0;
1350
+ }
1351
+ async function assertNoLegacyVaultFormat(storeRoot, vault = "default") {
1352
+ const legacyPath = await detectLegacyVaultFormat(storeRoot, vault);
1353
+ if (!legacyPath) {
1354
+ return;
1355
+ }
1356
+ throw new CnosSecurityError(
1357
+ `Legacy CNOS local vault format detected for vault "${vault}" at ${legacyPath}. CNOS 1.4 requires the new keystore format. Remove and recreate the vault.`
1358
+ );
1359
+ }
1360
+ function encryptPayload(payload, key) {
1361
+ const iv = (0, import_node_crypto.randomBytes)(IV_LENGTH);
1362
+ const cipher = (0, import_node_crypto.createCipheriv)("aes-256-gcm", key, iv);
1363
+ const plaintext = Buffer.from(JSON.stringify(payload), "utf8");
1364
+ const ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()]);
1365
+ const tag = cipher.getAuthTag();
1366
+ return Buffer.concat([
1367
+ Buffer.from(Uint32Array.of(KEYSTORE_VERSION).buffer),
1368
+ iv,
1369
+ tag,
1370
+ ciphertext
1371
+ ]);
1372
+ }
1373
+ function decryptPayload(buffer, key) {
1374
+ if (buffer.length < 4 + IV_LENGTH + AUTH_TAG_LENGTH) {
1375
+ throw new CnosSecurityError("Invalid CNOS local vault keystore");
1376
+ }
1377
+ const version = buffer.readUInt32LE(0);
1378
+ if (version !== KEYSTORE_VERSION) {
1379
+ throw new CnosSecurityError(`Unsupported CNOS local vault keystore version: ${version}`);
1380
+ }
1381
+ const ivOffset = 4;
1382
+ const tagOffset = ivOffset + IV_LENGTH;
1383
+ const cipherOffset = tagOffset + AUTH_TAG_LENGTH;
1384
+ const iv = buffer.subarray(ivOffset, tagOffset);
1385
+ const tag = buffer.subarray(tagOffset, cipherOffset);
1386
+ const ciphertext = buffer.subarray(cipherOffset);
1387
+ const decipher = (0, import_node_crypto.createDecipheriv)("aes-256-gcm", key, iv);
1388
+ decipher.setAuthTag(tag);
1389
+ try {
1390
+ const plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString("utf8");
1391
+ const payload = JSON.parse(plaintext);
1392
+ if (!payload || !isObject(payload.secrets) || !isObject(payload.metadata)) {
1393
+ throw new Error("invalid");
1394
+ }
1395
+ return {
1396
+ secrets: Object.fromEntries(
1397
+ Object.entries(payload.secrets).filter((entry) => typeof entry[1] === "string")
1398
+ ),
1399
+ metadata: Object.fromEntries(
1400
+ Object.entries(payload.metadata).filter(
1401
+ (entry) => isObject(entry[1]) && typeof entry[1].createdAt === "string" && typeof entry[1].updatedAt === "string"
1402
+ )
1403
+ )
1404
+ };
1405
+ } catch {
1406
+ throw new CnosAuthenticationError("Failed to decrypt CNOS local vault. Check vault authentication.");
1407
+ }
1408
+ }
1409
+ function buildInitialPayload() {
1410
+ return {
1411
+ secrets: {},
1412
+ metadata: {}
1413
+ };
1414
+ }
1415
+ async function writeVaultFiles(storeRoot, vault, meta, payload, key) {
1416
+ const metaPath = buildMetaPath(storeRoot, vault);
1417
+ const keystorePath = buildKeystorePath(storeRoot, vault);
1418
+ await (0, import_promises7.mkdir)(import_node_path7.default.dirname(metaPath), { recursive: true });
1419
+ await (0, import_promises7.writeFile)(metaPath, stringifyYaml(meta), "utf8");
1420
+ await (0, import_promises7.writeFile)(keystorePath, encryptPayload(payload, key));
1421
+ }
1422
+ async function readVaultMetadata(storeRoot, vault = "default") {
1423
+ await assertNoLegacyVaultFormat(storeRoot, vault);
1424
+ const metaPath = buildMetaPath(storeRoot, vault);
1425
+ try {
1426
+ const source = await (0, import_promises7.readFile)(metaPath, "utf8");
1427
+ return assertVaultMetadata(parseYaml(source), metaPath);
1428
+ } catch (error) {
1429
+ if (error.code === "ENOENT") {
1430
+ return void 0;
1431
+ }
1432
+ throw error;
1433
+ }
1434
+ }
1435
+ async function createSecretVault(storeRoot, vault, passphrase) {
1436
+ const normalizedVault = vault.trim() || "default";
1437
+ await assertNoLegacyVaultFormat(storeRoot, normalizedVault);
1438
+ const salt = (0, import_node_crypto.randomBytes)(SALT_LENGTH);
1439
+ const key = deriveVaultKey(passphrase, salt, PBKDF2_ITERATIONS);
1440
+ const createdAt = (/* @__PURE__ */ new Date()).toISOString();
1441
+ const meta = {
1442
+ version: METADATA_VERSION,
1443
+ algorithm: "aes-256-gcm",
1444
+ kdf: "pbkdf2-sha512",
1445
+ iterations: PBKDF2_ITERATIONS,
1446
+ salt: salt.toString("base64"),
1447
+ createdAt,
1448
+ secretCount: 0
1449
+ };
1450
+ await writeVaultFiles(storeRoot, normalizedVault, meta, buildInitialPayload(), key);
1451
+ return buildMetaPath(storeRoot, normalizedVault);
1452
+ }
1453
+ async function ensureSecretVault(storeRoot, vault, passphrase) {
1454
+ const normalizedVault = vault.trim() || "default";
1455
+ const meta = await readVaultMetadata(storeRoot, normalizedVault);
1456
+ if (meta) {
1457
+ return buildMetaPath(storeRoot, normalizedVault);
1458
+ }
1459
+ return createSecretVault(storeRoot, normalizedVault, passphrase);
1460
+ }
1461
+ function resolveConfiguredVaultPassphrase(definition, vault = "default", processEnv = process.env) {
1462
+ if (definition?.provider !== "local") {
1463
+ return void 0;
1464
+ }
1465
+ const configuredSources = definition.auth?.passphrase?.from ?? [];
1466
+ for (const source of configuredSources) {
1467
+ if (source.startsWith("env:")) {
1468
+ const value = processEnv[source.slice(4)];
1469
+ if (value) {
1470
+ return value;
1471
+ }
1472
+ }
1473
+ }
1474
+ return resolveSecretPassphrase(vault, processEnv);
1475
+ }
1476
+ async function resolveVaultAccessKey(storeRoot, definition, vault = "default", processEnv = process.env) {
1477
+ if (definition?.provider !== "local") {
1478
+ return definition?.provider === "github-secrets" ? {
1479
+ method: definition.auth?.method ?? "environment",
1480
+ ...definition?.auth?.config ? { config: definition.auth.config } : {}
1481
+ } : void 0;
1482
+ }
1483
+ const sessionKey = await resolveVaultSessionKey(vault, processEnv);
1484
+ if (sessionKey) {
1485
+ return {
1486
+ derivedKey: sessionKey,
1487
+ method: "keychain",
1488
+ ...definition.auth?.config ? { config: definition.auth.config } : {}
1489
+ };
1490
+ }
1491
+ const passphrase = resolveConfiguredVaultPassphrase(definition, vault, processEnv);
1492
+ if (passphrase) {
1493
+ return {
1494
+ passphrase,
1495
+ method: "passphrase",
1496
+ ...definition.auth?.config ? { config: definition.auth.config } : {}
1497
+ };
1498
+ }
1499
+ const metadata = await readVaultMetadata(storeRoot, vault);
1500
+ if (!metadata) {
1501
+ return void 0;
1502
+ }
1503
+ throw new CnosAuthenticationError(
1504
+ `Cannot authenticate to vault "${vault}". Set ${getVaultPassphraseEnvVar(vault)} or run cnos vault auth ${vault}.`
1505
+ );
1506
+ }
1507
+ async function loadVaultPayload(storeRoot, vault, auth) {
1508
+ const meta = await readVaultMetadata(storeRoot, vault);
1509
+ if (!meta) {
1510
+ throw new CnosManifestError(`Missing CNOS vault metadata for "${vault}"`);
1511
+ }
1512
+ const salt = Buffer.from(meta.salt, "base64");
1513
+ const key = auth.derivedKey ?? (auth.passphrase ? deriveVaultKey(auth.passphrase, salt, meta.iterations) : void 0);
1514
+ if (!key) {
1515
+ throw new CnosAuthenticationError(`Vault "${vault}" requires authentication before access.`);
1516
+ }
1517
+ const buffer = await (0, import_promises7.readFile)(buildKeystorePath(storeRoot, vault));
1518
+ return {
1519
+ meta,
1520
+ payload: decryptPayload(buffer, key),
1521
+ key
1522
+ };
1523
+ }
1524
+ async function writeLocalSecret(storeRoot, ref, value, authOrPassphrase, vault = "default") {
1525
+ const auth = typeof authOrPassphrase === "string" ? {
1526
+ passphrase: authOrPassphrase,
1527
+ method: "passphrase"
1528
+ } : authOrPassphrase;
1529
+ if (auth.passphrase) {
1530
+ await ensureSecretVault(storeRoot, vault, auth.passphrase);
1531
+ } else {
1532
+ const meta2 = await readVaultMetadata(storeRoot, vault);
1533
+ if (!meta2) {
1534
+ throw new CnosAuthenticationError(`Vault "${vault}" requires passphrase-based authentication for initial creation.`);
1535
+ }
1536
+ }
1537
+ const { meta, payload, key } = await loadVaultPayload(storeRoot, vault, auth);
1538
+ const now = (/* @__PURE__ */ new Date()).toISOString();
1539
+ const existing = payload.metadata[ref];
1540
+ payload.secrets[ref] = value;
1541
+ payload.metadata[ref] = {
1542
+ createdAt: existing?.createdAt ?? now,
1543
+ updatedAt: now
1544
+ };
1545
+ const nextMeta = {
1546
+ ...meta,
1547
+ secretCount: Object.keys(payload.secrets).length
1548
+ };
1549
+ await writeVaultFiles(storeRoot, vault, nextMeta, payload, key);
1550
+ return buildKeystorePath(storeRoot, vault);
1551
+ }
1552
+ async function deleteLocalSecret(storeRoot, ref, auth, vault = "default") {
1553
+ const { meta, payload, key } = await loadVaultPayload(storeRoot, vault, auth);
1554
+ if (!(ref in payload.secrets)) {
1555
+ return false;
1556
+ }
1557
+ delete payload.secrets[ref];
1558
+ delete payload.metadata[ref];
1559
+ const nextMeta = {
1560
+ ...meta,
1561
+ secretCount: Object.keys(payload.secrets).length
1562
+ };
1563
+ await writeVaultFiles(storeRoot, vault, nextMeta, payload, key);
1564
+ return true;
1565
+ }
1566
+ async function readLocalSecret(storeRoot, ref, auth, vault = "default") {
1567
+ const { payload } = await loadVaultPayload(storeRoot, vault, auth);
1568
+ const value = payload.secrets[ref];
1569
+ if (value === void 0) {
1570
+ throw new CnosManifestError(`Missing local secret ref "${ref}" in vault "${vault}"`);
1571
+ }
1572
+ return value;
1573
+ }
1574
+ async function listLocalSecrets(storeRoot, auth, vault = "default") {
1575
+ const { payload } = await loadVaultPayload(storeRoot, vault, auth);
1576
+ return Object.keys(payload.secrets).sort((left, right) => left.localeCompare(right));
1577
+ }
1578
+ function resolveVaultDefinition(vaults, vault = "default") {
1579
+ const definition = vaults?.[vault];
1580
+ const provider = definition?.provider ?? "local";
1581
+ return {
1582
+ name: vault,
1583
+ provider,
1584
+ ...definition?.auth ? { auth: definition.auth } : {},
1585
+ ...definition?.mapping ? { mapping: definition.mapping } : {},
1586
+ requiresAuthentication: provider === "local"
1587
+ };
1588
+ }
1589
+
1590
+ // ../core/src/secrets/auditLog.ts
1591
+ async function appendAuditEvent(event, processEnv = process.env) {
1592
+ const auditFile = processEnv.CNOS_AUDIT_FILE ?? import_node_path8.default.join(resolveSecretStoreRoot(processEnv), "audit", "access.log");
1593
+ await (0, import_promises8.mkdir)(import_node_path8.default.dirname(auditFile), { recursive: true });
1594
+ await (0, import_promises8.appendFile)(
1595
+ auditFile,
1596
+ `${JSON.stringify({
1597
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
1598
+ ...event
1599
+ })}
1600
+ `,
1601
+ "utf8"
1602
+ );
1603
+ }
1604
+
1605
+ // ../core/src/secrets/secretCache.ts
1606
+ var SecretCache = class {
1607
+ cache = /* @__PURE__ */ new Map();
1608
+ authenticated = /* @__PURE__ */ new Set();
1609
+ load(vaultId, secrets) {
1610
+ this.authenticated.add(vaultId);
1611
+ for (const [ref, value] of secrets) {
1612
+ this.cache.set(`${vaultId}:${ref}`, value);
1613
+ }
1614
+ }
1615
+ isVaultAuthenticated(vaultId) {
1616
+ return this.authenticated.has(vaultId);
1617
+ }
1618
+ get(vaultId, ref) {
1619
+ return this.cache.get(`${vaultId}:${ref}`);
1620
+ }
1621
+ clear(vaultId) {
1622
+ if (!vaultId) {
1623
+ this.cache.clear();
1624
+ this.authenticated.clear();
1625
+ return;
1626
+ }
1627
+ this.authenticated.delete(vaultId);
1628
+ for (const key of Array.from(this.cache.keys())) {
1629
+ if (key.startsWith(`${vaultId}:`)) {
1630
+ this.cache.delete(key);
1631
+ }
1632
+ }
1633
+ }
1634
+ };
1635
+
1636
+ // ../core/src/secrets/providers/github.ts
1637
+ var GithubSecretsVaultProvider = class {
1638
+ constructor(vaultId, definition, processEnv = process.env) {
1639
+ this.vaultId = vaultId;
1640
+ this.definition = definition;
1641
+ this.processEnv = processEnv;
1642
+ }
1643
+ vaultId;
1644
+ definition;
1645
+ processEnv;
1646
+ authenticated = false;
1647
+ async authenticate(_authConfig) {
1648
+ void _authConfig;
1649
+ this.authenticated = true;
1650
+ }
1651
+ isAuthenticated() {
1652
+ return this.authenticated;
1653
+ }
1654
+ resolveEnvVar(ref) {
1655
+ if (this.processEnv[ref] !== void 0) {
1656
+ return ref;
1657
+ }
1658
+ return Object.entries(this.definition.mapping ?? {}).find(([, logicalRef]) => logicalRef === ref)?.[0];
1659
+ }
1660
+ async batchGet(refs) {
1661
+ this.authenticated = true;
1662
+ const resolved = /* @__PURE__ */ new Map();
1663
+ for (const ref of Array.from(new Set(refs)).sort((left, right) => left.localeCompare(right))) {
1664
+ const envVar = this.resolveEnvVar(ref);
1665
+ const value = envVar ? this.processEnv[envVar] : void 0;
1666
+ if (value !== void 0) {
1667
+ resolved.set(ref, value);
1668
+ }
1669
+ }
1670
+ return resolved;
1671
+ }
1672
+ async get(ref) {
1673
+ const envVar = this.resolveEnvVar(ref);
1674
+ this.authenticated = true;
1675
+ return envVar ? this.processEnv[envVar] : void 0;
1676
+ }
1677
+ async set(ref, value) {
1678
+ void ref;
1679
+ void value;
1680
+ throw new Error(`Vault "${this.vaultId}" is environment-backed and cannot be written by CNOS.`);
1681
+ }
1682
+ async delete(ref) {
1683
+ void ref;
1684
+ throw new Error(`Vault "${this.vaultId}" is environment-backed and cannot be mutated by CNOS.`);
1685
+ }
1686
+ async list() {
1687
+ return Object.values(this.definition.mapping ?? {}).sort((left, right) => left.localeCompare(right));
1688
+ }
1689
+ };
1690
+
1691
+ // ../core/src/secrets/providers/local.ts
1692
+ var LocalSecretVaultProvider = class _LocalSecretVaultProvider {
1693
+ constructor(vaultId, definition, processEnv = process.env, storeRoot = resolveSecretStoreRoot(processEnv)) {
1694
+ this.vaultId = vaultId;
1695
+ this.processEnv = processEnv;
1696
+ this.storeRoot = storeRoot;
1697
+ this.definition = definition;
1698
+ }
1699
+ vaultId;
1700
+ processEnv;
1701
+ storeRoot;
1702
+ authConfig;
1703
+ definition;
1704
+ static fromVaults(vaults, vaultId, processEnv) {
1705
+ const definition = resolveVaultDefinition(vaults, vaultId);
1706
+ return new _LocalSecretVaultProvider(vaultId, definition, processEnv);
1707
+ }
1708
+ async authenticate(authConfig) {
1709
+ this.authConfig = authConfig;
1710
+ await this.list();
1711
+ }
1712
+ isAuthenticated() {
1713
+ return Boolean(this.authConfig);
1714
+ }
1715
+ async requireAuth() {
1716
+ if (this.authConfig) {
1717
+ return this.authConfig;
1718
+ }
1719
+ const resolved = await resolveVaultAccessKey(this.storeRoot, this.definition, this.vaultId, this.processEnv);
1720
+ if (!resolved) {
1721
+ throw new CnosAuthenticationError(
1722
+ `Cannot authenticate to vault "${this.vaultId}". Set the configured passphrase env var or run cnos vault auth ${this.vaultId}.`
1723
+ );
1724
+ }
1725
+ this.authConfig = resolved;
1726
+ return resolved;
1727
+ }
1728
+ async batchGet(refs) {
1729
+ const auth = await this.requireAuth();
1730
+ const entries = await Promise.all(
1731
+ Array.from(new Set(refs)).sort((left, right) => left.localeCompare(right)).map(async (ref) => [ref, await readLocalSecret(this.storeRoot, ref, auth, this.vaultId)])
1732
+ );
1733
+ return new Map(entries);
1734
+ }
1735
+ async get(ref) {
1736
+ const auth = await this.requireAuth();
1737
+ try {
1738
+ return await readLocalSecret(this.storeRoot, ref, auth, this.vaultId);
1739
+ } catch {
1740
+ return void 0;
1741
+ }
1742
+ }
1743
+ async set(ref, value) {
1744
+ const auth = await this.requireAuth();
1745
+ await writeLocalSecret(this.storeRoot, ref, value, auth, this.vaultId);
1746
+ await appendAuditEvent(
1747
+ {
1748
+ action: "write",
1749
+ vault: this.vaultId,
1750
+ ref,
1751
+ caller: "cli"
1752
+ },
1753
+ this.processEnv
1754
+ );
1755
+ }
1756
+ async delete(ref) {
1757
+ const auth = await this.requireAuth();
1758
+ await deleteLocalSecret(this.storeRoot, ref, auth, this.vaultId);
1759
+ await appendAuditEvent(
1760
+ {
1761
+ action: "delete",
1762
+ vault: this.vaultId,
1763
+ ref,
1764
+ caller: "cli"
1765
+ },
1766
+ this.processEnv
1767
+ );
1768
+ }
1769
+ async list() {
1770
+ const auth = this.authConfig ?? await resolveVaultAccessKey(this.storeRoot, this.definition, this.vaultId, this.processEnv);
1771
+ if (!auth) {
1772
+ throw new CnosAuthenticationError(
1773
+ `Cannot authenticate to vault "${this.vaultId}". Set the configured passphrase env var or run cnos vault auth ${this.vaultId}.`
1774
+ );
1775
+ }
1776
+ this.authConfig = auth;
1777
+ return listLocalSecrets(this.storeRoot, auth, this.vaultId);
1778
+ }
1779
+ };
1780
+
1781
+ // ../core/src/secrets/providers/registry.ts
1782
+ function createSecretVaultProvider(vaultId, definition, processEnv) {
1783
+ if (definition.provider === "local") {
1784
+ return new LocalSecretVaultProvider(vaultId, definition, processEnv);
1785
+ }
1786
+ if (definition.provider === "github-secrets") {
1787
+ return new GithubSecretsVaultProvider(vaultId, definition, processEnv);
1788
+ }
1789
+ throw new CnosManifestError(`Unsupported vault provider: ${definition.provider}`);
1790
+ }
1791
+
1792
+ // ../core/src/secrets/prompt.ts
1793
+ var import_node_readline = __toESM(require("readline"), 1);
1794
+ var import_node_stream = require("stream");
1795
+ async function promptHidden(message) {
1796
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
1797
+ return void 0;
1798
+ }
1799
+ const mutableStdout = new WritableMask();
1800
+ const rl = import_node_readline.default.createInterface({
1801
+ input: process.stdin,
1802
+ output: mutableStdout,
1803
+ terminal: true
1804
+ });
1805
+ try {
1806
+ mutableStdout.muted = true;
1807
+ const value = await new Promise((resolve) => {
1808
+ rl.question(message, resolve);
1809
+ });
1810
+ process.stdout.write("\n");
1811
+ return value;
1812
+ } finally {
1813
+ rl.close();
1814
+ }
1815
+ }
1816
+ var WritableMask = class extends import_node_stream.Writable {
1817
+ muted = false;
1818
+ _write(chunk, _encoding, callback) {
1819
+ if (!this.muted) {
1820
+ process.stdout.write(chunk);
1821
+ }
1822
+ callback();
1823
+ }
1824
+ };
1825
+
1826
+ // ../core/src/secrets/resolveAuth.ts
1827
+ function toAuthError(vaultId, sources) {
1828
+ return new CnosAuthenticationError(
1829
+ `Cannot authenticate to vault "${vaultId}". Tried: ${sources.join(", ")}. Set ${getVaultPassphraseEnvVar(vaultId)} or run cnos vault auth ${vaultId}.`
1830
+ );
1831
+ }
1832
+ async function resolveVaultAuth(vaultId, definition, processEnv = process.env) {
1833
+ const sessionKey = await resolveVaultSessionKey(vaultId, processEnv);
1834
+ if (sessionKey) {
1835
+ return {
1836
+ derivedKey: sessionKey,
1837
+ method: "keychain",
1838
+ ...definition.auth?.config ? { config: definition.auth.config } : {}
1839
+ };
1840
+ }
1841
+ if (definition.provider === "github-secrets") {
1842
+ return {
1843
+ method: definition.auth?.method ?? "environment",
1844
+ ...definition.auth?.config ? { config: definition.auth.config } : {}
1845
+ };
1846
+ }
1847
+ const sources = definition.auth?.passphrase?.from ?? [getVaultPassphraseEnvVar(vaultId)];
1848
+ for (const source of sources) {
1849
+ if (source.startsWith("env:")) {
1850
+ const value = processEnv[source.slice(4)];
1851
+ if (value) {
1852
+ return {
1853
+ passphrase: value,
1854
+ method: "passphrase",
1855
+ ...definition.auth?.config ? { config: definition.auth.config } : {}
1856
+ };
1857
+ }
1858
+ }
1859
+ if (source.startsWith("keychain:")) {
1860
+ const value = await readKeychain(source.slice("keychain:".length));
1861
+ if (value) {
1862
+ return {
1863
+ derivedKey: Buffer.from(value, "hex"),
1864
+ method: "keychain",
1865
+ ...definition.auth?.config ? { config: definition.auth.config } : {}
1866
+ };
1867
+ }
1868
+ }
1869
+ if (source === "prompt") {
1870
+ const value = await promptHidden(`Enter passphrase for vault "${vaultId}": `);
1871
+ if (value) {
1872
+ return {
1873
+ passphrase: value,
1874
+ method: "passphrase",
1875
+ ...definition.auth?.config ? { config: definition.auth.config } : {}
1876
+ };
1877
+ }
1878
+ }
1879
+ }
1880
+ const fallback = resolveSecretPassphrase(vaultId, processEnv);
1881
+ if (fallback) {
1882
+ return {
1883
+ passphrase: fallback,
1884
+ method: "passphrase",
1885
+ ...definition.auth?.config ? { config: definition.auth.config } : {}
1886
+ };
1887
+ }
1888
+ throw toAuthError(vaultId, [getVaultSessionKeyEnvVar(vaultId), ...sources]);
1889
+ }
1890
+
1891
+ // ../core/src/secrets/batchResolve.ts
1892
+ function collectSecretDescriptors(graph) {
1893
+ return Array.from(graph.entries.values()).filter((entry) => entry.namespace === "secret" && isSecretReference(entry.value)).map((entry) => ({
1894
+ logicalKey: entry.key,
1895
+ ref: entry.value
1896
+ }));
1897
+ }
1898
+ async function batchResolveSecrets(graph, manifest, processEnv = process.env) {
1899
+ const cache = new SecretCache();
1900
+ const descriptors = collectSecretDescriptors(graph);
1901
+ const grouped = descriptors.reduce((accumulator, descriptor) => {
1902
+ const vaultId = descriptor.ref.vault ?? "default";
1903
+ const bucket = accumulator.get(vaultId) ?? [];
1904
+ bucket.push(descriptor);
1905
+ accumulator.set(vaultId, bucket);
1906
+ return accumulator;
1907
+ }, /* @__PURE__ */ new Map());
1908
+ for (const [vaultId, refs] of grouped) {
1909
+ const definition = manifest.vaults[vaultId] ?? { provider: "local", auth: { passphrase: { from: [] } } };
1910
+ const provider = createSecretVaultProvider(vaultId, definition, processEnv);
1911
+ const auth = await resolveVaultAuth(vaultId, definition, processEnv);
1912
+ await provider.authenticate(auth);
1913
+ const resolved = await provider.batchGet(refs.map((entry) => entry.ref.ref));
1914
+ cache.load(vaultId, resolved);
1915
+ await appendAuditEvent(
1916
+ {
1917
+ action: "batch_read",
1918
+ vault: vaultId,
1919
+ refs: Array.from(resolved.keys()).sort((left, right) => left.localeCompare(right)),
1920
+ caller: "runtime",
1921
+ workspace: graph.workspace.workspaceId,
1922
+ profile: graph.profile
1923
+ },
1924
+ processEnv
1925
+ );
1926
+ }
1927
+ return cache;
1928
+ }
1929
+ function resolveSecretEntryValue(key, value, cache) {
1930
+ if (!key.startsWith("secret.") || !isSecretReference(value)) {
1931
+ return value;
1932
+ }
1933
+ const vaultId = value.vault ?? "default";
1934
+ return cache.get(vaultId, value.ref) ?? value;
1935
+ }
1936
+
1109
1937
  // ../core/src/runtime/projection.ts
1110
1938
  function setNestedValue(target, pathSegments, value) {
1111
1939
  const [head, ...tail] = pathSegments;
@@ -1156,55 +1984,6 @@ function requireValue(graph, key) {
1156
1984
  return value;
1157
1985
  }
1158
1986
 
1159
- // ../core/src/utils/secretStore.ts
1160
- var import_node_crypto = require("crypto");
1161
- var import_promises6 = require("fs/promises");
1162
- var import_node_path6 = __toESM(require("path"), 1);
1163
- function isObject(value) {
1164
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
1165
- }
1166
- function isSecretReference(value) {
1167
- 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));
1168
- }
1169
- function resolveSecretStoreRoot(processEnv = process.env) {
1170
- return import_node_path6.default.resolve(expandHomePath(processEnv.CNOS_SECRET_HOME ?? "~/.cnos/secrets"));
1171
- }
1172
- function resolveSecretStoreFile(storeRoot, ref, vault = "default") {
1173
- return import_node_path6.default.join(storeRoot, "vaults", vault, "store", ...ref.split("/")).concat(".json");
1174
- }
1175
- function deriveKey(passphrase, salt) {
1176
- return (0, import_node_crypto.scryptSync)(passphrase, salt, 32);
1177
- }
1178
- function resolveSecretPassphrase(vault = "default", processEnv = process.env) {
1179
- const vaultToken = vault.replace(/[^A-Za-z0-9]+/g, "_").replace(/^_+|_+$/g, "").toUpperCase();
1180
- return processEnv[`CNOS_SECRET_PASSPHRASE_${vaultToken}`] ?? processEnv.CNOS_SECRET_PASSPHRASE;
1181
- }
1182
- function decryptDocument(document, passphrase) {
1183
- const salt = Buffer.from(document.salt, "base64");
1184
- const iv = Buffer.from(document.iv, "base64");
1185
- const tag = Buffer.from(document.tag, "base64");
1186
- const ciphertext = Buffer.from(document.ciphertext, "base64");
1187
- const key = deriveKey(passphrase, salt);
1188
- const decipher = (0, import_node_crypto.createDecipheriv)("aes-256-gcm", key, iv);
1189
- decipher.setAuthTag(tag);
1190
- const plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]);
1191
- return plaintext.toString("utf8");
1192
- }
1193
- async function readLocalSecret(storeRoot, ref, passphrase, vault = "default") {
1194
- if (!passphrase) {
1195
- throw new CnosManifestError(
1196
- `Missing CNOS secret passphrase for local secret ref "${ref}". Set CNOS_SECRET_PASSPHRASE or pass processEnv explicitly.`
1197
- );
1198
- }
1199
- const filePath = resolveSecretStoreFile(storeRoot, ref, vault);
1200
- const source = await (0, import_promises6.readFile)(filePath, "utf8");
1201
- const document = JSON.parse(source);
1202
- if (document.version !== 1 || document.algorithm !== "aes-256-gcm" || typeof document.salt !== "string" || typeof document.iv !== "string" || typeof document.tag !== "string" || typeof document.ciphertext !== "string") {
1203
- throw new CnosManifestError("Invalid local secret document", filePath);
1204
- }
1205
- return decryptDocument(document, passphrase);
1206
- }
1207
-
1208
1987
  // ../core/src/runtime/toEnv.ts
1209
1988
  function normalizeEnvValue(value) {
1210
1989
  if (value === void 0 || value === null) {
@@ -1286,28 +2065,42 @@ function toPublicEnv(graph, manifest, options = {}) {
1286
2065
  }
1287
2066
 
1288
2067
  // ../core/src/orchestrator/runtime.ts
1289
- function createRuntime(manifest, graph, plugins = []) {
2068
+ function createRuntime(manifest, graph, plugins = [], secretCache) {
2069
+ function readLogicalKey(key) {
2070
+ const entry = graph.entries.get(key);
2071
+ if (!entry) {
2072
+ return void 0;
2073
+ }
2074
+ if (!secretCache) {
2075
+ return entry.value;
2076
+ }
2077
+ return resolveSecretEntryValue(key, entry.value, secretCache);
2078
+ }
1290
2079
  return {
1291
2080
  manifest,
1292
2081
  plugins,
1293
2082
  graph,
1294
2083
  read(key) {
1295
- return readValue(graph, key);
2084
+ return readLogicalKey(key);
1296
2085
  },
1297
2086
  require(key) {
1298
- return requireValue(graph, key);
2087
+ const value = readLogicalKey(key);
2088
+ if (value === void 0) {
2089
+ return requireValue(graph, key);
2090
+ }
2091
+ return value;
1299
2092
  },
1300
2093
  readOr(key, fallback) {
1301
2094
  return readOrValue(graph, key, fallback);
1302
2095
  },
1303
- value(path10) {
1304
- return readValue(graph, toLogicalKey("value", path10));
2096
+ value(path12) {
2097
+ return readLogicalKey(toLogicalKey("value", path12));
1305
2098
  },
1306
- secret(path10) {
1307
- return readValue(graph, toLogicalKey("secret", path10));
2099
+ secret(path12) {
2100
+ return readLogicalKey(toLogicalKey("secret", path12));
1308
2101
  },
1309
- meta(path10) {
1310
- return readValue(graph, toLogicalKey("meta", path10));
2102
+ meta(path12) {
2103
+ return readLogicalKey(toLogicalKey("meta", path12));
1311
2104
  },
1312
2105
  inspect(key) {
1313
2106
  return inspectValue(graph, key);
@@ -1465,61 +2258,21 @@ async function createCnos(options = {}) {
1465
2258
  });
1466
2259
  const schemaApplied = applySchemaRules(graph, loadedManifest.manifest.schema);
1467
2260
  const promotedGraph = promoteToPublic(schemaApplied.graph, loadedManifest.manifest);
2261
+ const secretCache = options.secretResolution === "lazy" ? void 0 : await batchResolveSecrets(promotedGraph, loadedManifest.manifest, options.processEnv);
1468
2262
  return createRuntime(
1469
2263
  loadedManifest.manifest,
1470
2264
  appendMetaEntries({
1471
2265
  ...promotedGraph,
1472
2266
  profileSource: activeProfile.source
1473
2267
  }, options.cnosVersion),
1474
- plugins
2268
+ plugins,
2269
+ secretCache
1475
2270
  );
1476
2271
  }
1477
2272
 
1478
2273
  // ../core/src/runtime/dump.ts
1479
- var import_promises7 = require("fs/promises");
1480
- var import_node_path7 = __toESM(require("path"), 1);
1481
- function buildDumpFiles(graph, options = {}) {
1482
- const basePath = options.flatten ? "" : import_node_path7.default.posix.join("workspaces", graph.workspace.workspaceId);
1483
- const values = toNamespaceObject(graph, "value");
1484
- const secrets = toNamespaceObject(graph, "secret");
1485
- const files = [];
1486
- if (Object.keys(values).length > 0) {
1487
- files.push({
1488
- path: import_node_path7.default.posix.join(basePath, "values", graph.profile, "app.yml"),
1489
- namespace: "value",
1490
- content: stringifyYaml(values)
1491
- });
1492
- }
1493
- if (Object.keys(secrets).length > 0) {
1494
- files.push({
1495
- path: import_node_path7.default.posix.join(basePath, "secrets", graph.profile, "app.yml"),
1496
- namespace: "secret",
1497
- content: stringifyYaml(secrets)
1498
- });
1499
- }
1500
- return files.sort((left, right) => left.path.localeCompare(right.path));
1501
- }
1502
- function planDump(graph, options = {}) {
1503
- return {
1504
- workspaceId: graph.workspace.workspaceId,
1505
- profile: graph.profile,
1506
- flatten: options.flatten ?? false,
1507
- files: buildDumpFiles(graph, options)
1508
- };
1509
- }
1510
- async function writeDump(graph, options) {
1511
- const root = import_node_path7.default.resolve(options.to);
1512
- const plan = planDump(graph, options);
1513
- for (const file of plan.files) {
1514
- const destination = import_node_path7.default.join(root, file.path);
1515
- await (0, import_promises7.mkdir)(import_node_path7.default.dirname(destination), { recursive: true });
1516
- await (0, import_promises7.writeFile)(destination, file.content, "utf8");
1517
- }
1518
- return {
1519
- ...plan,
1520
- root
1521
- };
1522
- }
2274
+ var import_promises9 = require("fs/promises");
2275
+ var import_node_path9 = __toESM(require("path"), 1);
1523
2276
 
1524
2277
  // ../core/src/utils/envNaming.ts
1525
2278
  function normalizeMappingConfig(config = {}) {
@@ -1528,8 +2281,8 @@ function normalizeMappingConfig(config = {}) {
1528
2281
  explicit: config.explicit ?? {}
1529
2282
  };
1530
2283
  }
1531
- function fromScreamingSnake(path10) {
1532
- return path10.split("_").map((segment) => segment.trim().toLowerCase()).filter(Boolean).join(".");
2284
+ function fromScreamingSnake(path12) {
2285
+ return path12.split("_").map((segment) => segment.trim().toLowerCase()).filter(Boolean).join(".");
1533
2286
  }
1534
2287
  function envVarToLogicalKey(envVar, config = {}) {
1535
2288
  const normalized = normalizeMappingConfig(config);
@@ -1556,7 +2309,7 @@ function envVarToLogicalKey(envVar, config = {}) {
1556
2309
  // package.json
1557
2310
  var package_default = {
1558
2311
  name: "@kitsy/cnos",
1559
- version: "1.2.0",
2312
+ version: "1.3.0",
1560
2313
  description: "Batteries-included CNOS runtime package wired with the official plugins.",
1561
2314
  type: "module",
1562
2315
  main: "./dist/index.cjs",
@@ -1568,6 +2321,16 @@ var package_default = {
1568
2321
  import: "./dist/index.js",
1569
2322
  require: "./dist/index.cjs"
1570
2323
  },
2324
+ "./configure": {
2325
+ types: "./dist/configure/index.d.ts",
2326
+ import: "./dist/configure/index.js",
2327
+ require: "./dist/configure/index.cjs"
2328
+ },
2329
+ "./create": {
2330
+ types: "./dist/configure/index.d.ts",
2331
+ import: "./dist/configure/index.js",
2332
+ require: "./dist/configure/index.cjs"
2333
+ },
1571
2334
  "./internal": {
1572
2335
  types: "./dist/internal.d.ts",
1573
2336
  import: "./dist/internal.js",
@@ -1745,8 +2508,8 @@ function createCliArgsPlugin() {
1745
2508
  }
1746
2509
 
1747
2510
  // ../../plugins/dotenv/src/index.ts
1748
- var import_promises8 = require("fs/promises");
1749
- var import_node_path8 = __toESM(require("path"), 1);
2511
+ var import_promises10 = require("fs/promises");
2512
+ var import_node_path10 = __toESM(require("path"), 1);
1750
2513
  var DOTENV_PLUGIN_ID = "@kitsy/cnos/plugins/dotenv";
1751
2514
  function parseDoubleQuoted(value) {
1752
2515
  return value.replace(/\\n/g, "\n").replace(/\\r/g, "\r").replace(/\\t/g, " ").replace(/\\"/g, '"').replace(/\\\\/g, "\\");
@@ -1803,7 +2566,7 @@ function dotenvEntriesFromObject(values, mapping = {}, originFile, workspaceId =
1803
2566
  }
1804
2567
  async function readIfPresent(filePath) {
1805
2568
  try {
1806
- return await (0, import_promises8.readFile)(filePath, "utf8");
2569
+ return await (0, import_promises10.readFile)(filePath, "utf8");
1807
2570
  } catch {
1808
2571
  return void 0;
1809
2572
  }
@@ -1822,7 +2585,7 @@ function createDotenvPlugin() {
1822
2585
  workspace: workspaceRoot.workspaceId
1823
2586
  });
1824
2587
  for (const fileName of fileNames) {
1825
- const absolutePath = import_node_path8.default.join(envRoot, fileName);
2588
+ const absolutePath = import_node_path10.default.join(envRoot, fileName);
1826
2589
  const document = await readIfPresent(absolutePath);
1827
2590
  if (!document) {
1828
2591
  continue;
@@ -1831,7 +2594,7 @@ function createDotenvPlugin() {
1831
2594
  ...dotenvEntriesFromObject(
1832
2595
  parseDotenv(document),
1833
2596
  config.envMapping,
1834
- toPortablePath(import_node_path8.default.relative(import_node_path8.default.dirname(context.manifestRoot), absolutePath)),
2597
+ toPortablePath(import_node_path10.default.relative(import_node_path10.default.dirname(context.manifestRoot), absolutePath)),
1835
2598
  workspaceRoot.workspaceId
1836
2599
  )
1837
2600
  );
@@ -1869,32 +2632,32 @@ function createPublicEnvExportPlugin() {
1869
2632
  }
1870
2633
 
1871
2634
  // ../../plugins/filesystem/src/filesystemSecretsReader.ts
1872
- var import_promises10 = require("fs/promises");
2635
+ var import_promises12 = require("fs/promises");
1873
2636
 
1874
2637
  // ../../plugins/filesystem/src/helpers.ts
1875
- var import_promises9 = require("fs/promises");
1876
- var import_node_path9 = __toESM(require("path"), 1);
2638
+ var import_promises11 = require("fs/promises");
2639
+ var import_node_path11 = __toESM(require("path"), 1);
1877
2640
  var YAML_EXTENSIONS = /* @__PURE__ */ new Set([".yml", ".yaml"]);
1878
2641
  var FILESYSTEM_PLUGIN_ID = "@kitsy/cnos/plugins/filesystem";
1879
2642
  async function existsDirectory(targetPath) {
1880
2643
  try {
1881
- const stat = await (0, import_promises9.readdir)(targetPath);
1882
- void stat;
2644
+ const stat2 = await (0, import_promises11.readdir)(targetPath);
2645
+ void stat2;
1883
2646
  return true;
1884
2647
  } catch {
1885
2648
  return false;
1886
2649
  }
1887
2650
  }
1888
2651
  async function collectYamlFiles(root) {
1889
- const entries = await (0, import_promises9.readdir)(root, { withFileTypes: true });
2652
+ const entries = await (0, import_promises11.readdir)(root, { withFileTypes: true });
1890
2653
  const results = [];
1891
2654
  for (const entry of entries.sort((left, right) => left.name.localeCompare(right.name))) {
1892
- const absolutePath = import_node_path9.default.join(root, entry.name);
2655
+ const absolutePath = import_node_path11.default.join(root, entry.name);
1893
2656
  if (entry.isDirectory()) {
1894
2657
  results.push(...await collectYamlFiles(absolutePath));
1895
2658
  continue;
1896
2659
  }
1897
- if (entry.isFile() && YAML_EXTENSIONS.has(import_node_path9.default.extname(entry.name).toLowerCase())) {
2660
+ if (entry.isFile() && YAML_EXTENSIONS.has(import_node_path11.default.extname(entry.name).toLowerCase())) {
1898
2661
  results.push(absolutePath);
1899
2662
  }
1900
2663
  }
@@ -1902,16 +2665,16 @@ async function collectYamlFiles(root) {
1902
2665
  }
1903
2666
  async function collectFilesystemLayerFiles(manifestRoot, workspaceRoots, sourceRoot, activeLayers) {
1904
2667
  const files = [];
1905
- const repoRoot = import_node_path9.default.dirname(manifestRoot);
2668
+ const repoRoot = import_node_path11.default.dirname(manifestRoot);
1906
2669
  for (const workspaceRoot of workspaceRoots) {
1907
- const resolvedRoot = import_node_path9.default.resolve(workspaceRoot.path, sourceRoot);
2670
+ const resolvedRoot = import_node_path11.default.resolve(workspaceRoot.path, sourceRoot);
1908
2671
  for (const layer of activeLayers) {
1909
- const layerRoot = import_node_path9.default.join(resolvedRoot, layer);
2672
+ const layerRoot = import_node_path11.default.join(resolvedRoot, layer);
1910
2673
  if (!await existsDirectory(layerRoot)) {
1911
2674
  continue;
1912
2675
  }
1913
2676
  for (const absolutePath of await collectYamlFiles(layerRoot)) {
1914
- const relativePath = import_node_path9.default.relative(repoRoot, absolutePath);
2677
+ const relativePath = import_node_path11.default.relative(repoRoot, absolutePath);
1915
2678
  files.push({
1916
2679
  absolutePath,
1917
2680
  relativePath: toPortablePath(relativePath.startsWith("..") ? absolutePath : relativePath),
@@ -1961,31 +2724,6 @@ function yamlObjectToEntries(document, filePath, namespace, sourceId, workspaceI
1961
2724
  }
1962
2725
  }));
1963
2726
  }
1964
- async function resolveSecretValue(value, processEnv) {
1965
- if (!isSecretReference(value)) {
1966
- return value;
1967
- }
1968
- if (value.provider === "local") {
1969
- const passphrase = resolveSecretPassphrase(value.vault, processEnv);
1970
- if (!passphrase) {
1971
- return value;
1972
- }
1973
- return readLocalSecret(
1974
- resolveSecretStoreRoot(processEnv),
1975
- value.ref,
1976
- passphrase,
1977
- value.vault
1978
- );
1979
- }
1980
- if (value.provider === "env" || value.provider === "github-secrets") {
1981
- const resolved = processEnv?.[value.ref];
1982
- if (resolved === void 0) {
1983
- return value;
1984
- }
1985
- return resolved;
1986
- }
1987
- return value;
1988
- }
1989
2727
  function toSecretReferenceMetadata(value) {
1990
2728
  if (!isSecretReference(value)) {
1991
2729
  return void 0;
@@ -2013,14 +2751,12 @@ function createFilesystemSecretsPlugin() {
2013
2751
  );
2014
2752
  const entries = [];
2015
2753
  for (const file of files) {
2016
- const document = await (0, import_promises10.readFile)(file.absolutePath, "utf8");
2754
+ const document = await (0, import_promises12.readFile)(file.absolutePath, "utf8");
2017
2755
  const fileEntries = filesystemSecretsReader(file.relativePath, document, file.workspaceId);
2018
2756
  for (const entry of fileEntries) {
2019
2757
  const metadata = toSecretReferenceMetadata(entry.value);
2020
- const resolvedValue = await resolveSecretValue(entry.value, context.processEnv);
2021
2758
  entries.push({
2022
2759
  ...entry,
2023
- value: resolvedValue,
2024
2760
  ...metadata ? { metadata } : {}
2025
2761
  });
2026
2762
  }
@@ -2031,7 +2767,7 @@ function createFilesystemSecretsPlugin() {
2031
2767
  }
2032
2768
 
2033
2769
  // ../../plugins/filesystem/src/filesystemValuesReader.ts
2034
- var import_promises11 = require("fs/promises");
2770
+ var import_promises13 = require("fs/promises");
2035
2771
  function filesystemValuesReader(filePath, document, workspaceId = "default") {
2036
2772
  return yamlObjectToEntries(document, filePath, "value", "filesystem-values", workspaceId);
2037
2773
  }
@@ -2049,7 +2785,7 @@ function createFilesystemValuesPlugin() {
2049
2785
  );
2050
2786
  const entries = [];
2051
2787
  for (const file of files) {
2052
- const document = await (0, import_promises11.readFile)(file.absolutePath, "utf8");
2788
+ const document = await (0, import_promises13.readFile)(file.absolutePath, "utf8");
2053
2789
  entries.push(...filesystemValuesReader(file.relativePath, document, file.workspaceId));
2054
2790
  }
2055
2791
  return entries;
@@ -2116,16 +2852,35 @@ function defaultPlugins() {
2116
2852
  // src/runtime/state.ts
2117
2853
  var singletonRuntime;
2118
2854
  var singletonReady;
2855
+ var bootstrappedSecretHydrationRequired = false;
2856
+ function getSingletonRuntime() {
2857
+ return singletonRuntime;
2858
+ }
2119
2859
  function setSingletonRuntime(runtime) {
2120
2860
  singletonRuntime = runtime;
2121
2861
  singletonReady = Promise.resolve(runtime);
2862
+ bootstrappedSecretHydrationRequired = false;
2122
2863
  return runtime;
2123
2864
  }
2865
+ function getSingletonReady() {
2866
+ return singletonReady;
2867
+ }
2868
+ function setSingletonReady(promise) {
2869
+ singletonReady = promise;
2870
+ return promise;
2871
+ }
2872
+ function getBootstrappedSecretHydrationRequired() {
2873
+ return bootstrappedSecretHydrationRequired;
2874
+ }
2875
+ function setBootstrappedSecretHydrationRequired(value) {
2876
+ bootstrappedSecretHydrationRequired = value;
2877
+ }
2124
2878
 
2125
2879
  // src/createCnos.ts
2126
2880
  async function createCnos2(options = {}) {
2127
2881
  const runtime = await createCnos({
2128
2882
  ...options,
2883
+ processEnv: options.processEnv ?? process.env,
2129
2884
  cnosVersion: package_default.version,
2130
2885
  plugins: [...defaultPlugins(), ...options.plugins ?? []]
2131
2886
  });
@@ -2133,25 +2888,234 @@ async function createCnos2(options = {}) {
2133
2888
  return runtime;
2134
2889
  }
2135
2890
 
2136
- // src/build/index.ts
2137
- async function resolveBrowserData(options = {}) {
2138
- const runtime = await createCnos2(options);
2139
- const browserData = {};
2140
- for (const [key, entry] of runtime.graph.entries) {
2141
- if (!key.startsWith("public.")) {
2142
- continue;
2891
+ // src/runtime/bootstrap.ts
2892
+ var import_node_crypto2 = require("crypto");
2893
+ var CNOS_GRAPH_ENV_VAR = "__CNOS_GRAPH__";
2894
+ var CNOS_SECRET_PAYLOAD_ENV_VAR = "__CNOS_SECRET_PAYLOAD__";
2895
+ var CNOS_SESSION_KEY_ENV_VAR = "__CNOS_SESSION_KEY__";
2896
+ function deserializeRuntimeGraph(source) {
2897
+ const payload = JSON.parse(source);
2898
+ if (!payload || !Array.isArray(payload.entries) || typeof payload.profile !== "string" || typeof payload.resolvedAt !== "string" || !payload.profileSource || !payload.workspace || typeof payload.workspace.workspaceId !== "string" || !Array.isArray(payload.workspace.workspaceChain) || !Array.isArray(payload.workspace.workspaceRoots)) {
2899
+ throw new Error("Invalid CNOS runtime bootstrap payload");
2900
+ }
2901
+ return {
2902
+ entries: new Map(
2903
+ payload.entries.map((entry) => [
2904
+ entry.key,
2905
+ {
2906
+ key: entry.key,
2907
+ value: entry.value,
2908
+ namespace: entry.namespace,
2909
+ winner: entry.winner,
2910
+ overridden: entry.overridden ?? []
2911
+ }
2912
+ ])
2913
+ ),
2914
+ profile: payload.profile,
2915
+ resolvedAt: payload.resolvedAt,
2916
+ profileSource: payload.profileSource,
2917
+ workspace: payload.workspace
2918
+ };
2919
+ }
2920
+ function decryptSecretPayload(serialized, sessionKey) {
2921
+ const payload = JSON.parse(serialized);
2922
+ if (!payload || typeof payload.iv !== "string" || typeof payload.tag !== "string" || typeof payload.ciphertext !== "string") {
2923
+ throw new Error("Invalid CNOS secret payload");
2924
+ }
2925
+ const key = Buffer.from(sessionKey, "hex");
2926
+ const iv = Buffer.from(payload.iv, "base64");
2927
+ const tag = Buffer.from(payload.tag, "base64");
2928
+ const ciphertext = Buffer.from(payload.ciphertext, "base64");
2929
+ const decipher = (0, import_node_crypto2.createDecipheriv)("aes-256-gcm", key, iv);
2930
+ decipher.setAuthTag(tag);
2931
+ const plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]).toString("utf8");
2932
+ return JSON.parse(plaintext);
2933
+ }
2934
+ function readRuntimeGraphFromEnv(processEnv = process.env) {
2935
+ const serialized = processEnv[CNOS_GRAPH_ENV_VAR];
2936
+ if (!serialized) {
2937
+ return void 0;
2938
+ }
2939
+ const graph = deserializeRuntimeGraph(serialized);
2940
+ const secretPayload = processEnv[CNOS_SECRET_PAYLOAD_ENV_VAR];
2941
+ const sessionKey = processEnv[CNOS_SESSION_KEY_ENV_VAR];
2942
+ if (secretPayload && sessionKey) {
2943
+ const decrypted = decryptSecretPayload(secretPayload, sessionKey);
2944
+ for (const [key, value] of Object.entries(decrypted)) {
2945
+ const entry = graph.entries.get(key);
2946
+ if (entry) {
2947
+ entry.value = value;
2948
+ }
2949
+ }
2950
+ }
2951
+ return graph;
2952
+ }
2953
+ function graphRequiresSecretHydration(graph) {
2954
+ return Array.from(graph.entries.values()).some((entry) => entry.namespace === "secret" && isSecretReference(entry.value));
2955
+ }
2956
+
2957
+ // src/runtime/index.ts
2958
+ var NOT_READY_MESSAGE = "CNOS not initialized. Call await cnos.ready() or use cnos run.";
2959
+ function getRuntimeOrThrow() {
2960
+ const runtime = getSingletonRuntime();
2961
+ if (!runtime) {
2962
+ throw new Error(NOT_READY_MESSAGE);
2963
+ }
2964
+ return runtime;
2965
+ }
2966
+ function attachBootstrappedGraph(graph) {
2967
+ if (getSingletonRuntime()) {
2968
+ return;
2969
+ }
2970
+ const bootstrappedManifest = {
2971
+ version: 1,
2972
+ project: {
2973
+ name: "bootstrapped"
2974
+ },
2975
+ workspaces: {
2976
+ global: {
2977
+ enabled: Boolean(graph.workspace.globalRoot),
2978
+ ...graph.workspace.globalRoot ? {
2979
+ root: graph.workspace.globalRoot
2980
+ } : {},
2981
+ allowWrite: false
2982
+ },
2983
+ items: {},
2984
+ ...graph.workspace.workspaceSource === "implicit" ? {} : {
2985
+ default: graph.workspace.workspaceId
2986
+ }
2987
+ },
2988
+ profiles: {
2989
+ default: graph.profile,
2990
+ resolveFrom: ["default"]
2991
+ },
2992
+ plugins: {
2993
+ loaders: [],
2994
+ resolver: "profile-aware",
2995
+ validators: [],
2996
+ exporters: [],
2997
+ inspectors: []
2998
+ },
2999
+ sources: {},
3000
+ resolution: {
3001
+ precedence: [],
3002
+ arrayPolicy: "replace"
3003
+ },
3004
+ envMapping: {
3005
+ explicit: {}
3006
+ },
3007
+ public: {
3008
+ promote: [],
3009
+ frameworks: {}
3010
+ },
3011
+ namespaces: {},
3012
+ vaults: {},
3013
+ writePolicy: {
3014
+ define: {
3015
+ defaultProfile: graph.profile,
3016
+ targets: {
3017
+ value: "./values/app.yml",
3018
+ secret: "./secrets/app.yml"
3019
+ }
3020
+ }
3021
+ },
3022
+ schema: {}
3023
+ };
3024
+ const runtime = {
3025
+ manifest: bootstrappedManifest,
3026
+ plugins: [],
3027
+ graph,
3028
+ read(key) {
3029
+ return readValue(graph, key);
3030
+ },
3031
+ require(key) {
3032
+ return requireValue(graph, key);
3033
+ },
3034
+ readOr(key, fallback) {
3035
+ return readOrValue(graph, key, fallback);
3036
+ },
3037
+ value(path12) {
3038
+ return readValue(graph, toLogicalKey("value", path12));
3039
+ },
3040
+ secret(path12) {
3041
+ return readValue(graph, toLogicalKey("secret", path12));
3042
+ },
3043
+ meta(path12) {
3044
+ return readValue(graph, toLogicalKey("meta", path12));
3045
+ },
3046
+ inspect(key) {
3047
+ return inspectValue(graph, key);
3048
+ },
3049
+ toObject() {
3050
+ return toNamespaceObject(graph);
3051
+ },
3052
+ toNamespace(namespace) {
3053
+ return toNamespaceObject(graph, namespace);
3054
+ },
3055
+ toEnv(options) {
3056
+ return toEnv(graph, bootstrappedManifest, options);
3057
+ },
3058
+ toPublicEnv(options) {
3059
+ return toPublicEnv(graph, bootstrappedManifest, options);
3060
+ }
3061
+ };
3062
+ setSingletonRuntime(runtime);
3063
+ setBootstrappedSecretHydrationRequired(graphRequiresSecretHydration(graph));
3064
+ }
3065
+ function bootstrapFromProcessEnv() {
3066
+ if (typeof process === "undefined") {
3067
+ return;
3068
+ }
3069
+ try {
3070
+ const graph = readRuntimeGraphFromEnv(process.env);
3071
+ if (graph) {
3072
+ attachBootstrappedGraph(graph);
2143
3073
  }
2144
- browserData[key] = entry.value;
3074
+ } catch {
2145
3075
  }
2146
- return browserData;
2147
3076
  }
3077
+ bootstrapFromProcessEnv();
3078
+ var cnos = Object.assign(
3079
+ ((key) => readValue(getRuntimeOrThrow().graph, key)),
3080
+ {
3081
+ read(key) {
3082
+ return readValue(getRuntimeOrThrow().graph, key);
3083
+ },
3084
+ require(key) {
3085
+ return requireValue(getRuntimeOrThrow().graph, key);
3086
+ },
3087
+ readOr(key, fallback) {
3088
+ return readOrValue(getRuntimeOrThrow().graph, key, fallback);
3089
+ },
3090
+ value(path12) {
3091
+ return readValue(getRuntimeOrThrow().graph, toLogicalKey("value", path12));
3092
+ },
3093
+ secret(path12) {
3094
+ return readValue(getRuntimeOrThrow().graph, toLogicalKey("secret", path12));
3095
+ },
3096
+ meta(path12) {
3097
+ return readValue(getRuntimeOrThrow().graph, toLogicalKey("meta", path12));
3098
+ },
3099
+ async ready() {
3100
+ if (getSingletonRuntime() && !getBootstrappedSecretHydrationRequired()) {
3101
+ return;
3102
+ }
3103
+ const existing = getSingletonReady();
3104
+ if (existing && !getBootstrappedSecretHydrationRequired()) {
3105
+ await existing;
3106
+ return;
3107
+ }
3108
+ const readyPromise = createCnos2().then((runtime) => {
3109
+ setSingletonRuntime(runtime);
3110
+ return runtime;
3111
+ });
3112
+ setSingletonReady(readyPromise);
3113
+ await readyPromise;
3114
+ }
3115
+ }
3116
+ );
3117
+ var runtime_default = cnos;
2148
3118
  // Annotate the CommonJS export names for ESM import in node:
2149
3119
  0 && (module.exports = {
2150
- createCnos,
2151
- defaultPlugins,
2152
- planDump,
2153
- resolveBrowserData,
2154
- toEnv,
2155
- toPublicEnv,
2156
- writeDump
3120
+ cnos
2157
3121
  });