envpkt 0.14.0 → 0.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -728,12 +728,13 @@ const formatError = (error) => {
728
728
  case "IdentityNotFound": return `${RED}Error:${RESET} Identity file not found: ${error.path}`;
729
729
  case "SealKeyUnavailable": {
730
730
  const e = error;
731
+ const restoreLine = e.configuredKeyFile ? ` • Restore the configured key to ${e.configuredKeyFile} (or set ENVPKT_AGE_KEY_FILE / ENVPKT_AGE_KEY)` : ` • Restore your key to ~/.envpkt/age-key.txt (or set ENVPKT_AGE_KEY_FILE / ENVPKT_AGE_KEY)`;
731
732
  return [
732
733
  `${RED}Error:${RESET} ${e.sealedKeys.length} sealed secret(s) can't be decrypted — no age key found.`,
733
734
  `${DIM}Searched (in order):${RESET}`,
734
735
  e.searched.map((l) => ` • ${l}`).join("\n"),
735
736
  `${DIM}Fix one:${RESET}`,
736
- ` • Restore your key to ~/.envpkt/age-key.txt (or set ENVPKT_AGE_KEY_FILE / ENVPKT_AGE_KEY)`,
737
+ restoreLine,
737
738
  ` • Re-provision from source: envpkt seal --edit <KEY>`
738
739
  ].join("\n");
739
740
  }
@@ -1404,11 +1405,13 @@ const resolveSealIdentity = (config, configDir) => {
1404
1405
  });
1405
1406
  const inlineKey = resolveInlineKey().orUndefined();
1406
1407
  if (inlineKey) return Option(materializeInlineKey(inlineKey));
1407
- const defaultPath = join(homedir(), ".envpkt", "age-key.txt");
1408
- if (existsSync(defaultPath)) return Option({
1409
- path: defaultPath,
1410
- dispose: noop
1411
- });
1408
+ if (!config.identity?.key_file) {
1409
+ const defaultPath = join(homedir(), ".envpkt", "age-key.txt");
1410
+ if (existsSync(defaultPath)) return Option({
1411
+ path: defaultPath,
1412
+ dispose: noop
1413
+ });
1414
+ }
1412
1415
  return Option(void 0);
1413
1416
  };
1414
1417
  /** Describe the seal-identity precedence chain with per-entry status, for a clear no-key error. */
@@ -1423,7 +1426,7 @@ const describeSealKeySearch = (config, configDir) => {
1423
1426
  keyFileLine,
1424
1427
  envFileLine,
1425
1428
  inlineLine,
1426
- `${defaultPath} (${existsSync(defaultPath) ? "found" : "missing"})`
1429
+ keyFile ? `${defaultPath} (skipped — identity.key_file is set)` : `${defaultPath} (${existsSync(defaultPath) ? "found" : "missing"})`
1427
1430
  ];
1428
1431
  };
1429
1432
  const resolveIdentityKey = (config, configDir) => {
@@ -1499,7 +1502,8 @@ const bootSafe = (options) => {
1499
1502
  if (hasSealedValues && sealIdentity.isEmpty) return Left({
1500
1503
  _tag: "SealKeyUnavailable",
1501
1504
  sealedKeys: nonAliasMetaKeys.filter((k) => !!nonAliasSecretEntries[k]?.encrypted_value),
1502
- searched: describeSealKeySearch(config, configDir)
1505
+ searched: describeSealKeySearch(config, configDir),
1506
+ configuredKeyFile: config.identity?.key_file ? resolve(configDir, expandPath(config.identity.key_file)) : void 0
1503
1507
  });
1504
1508
  return checkExpiration(audit, failOnExpired, warnOnly).map((warnings) => {
1505
1509
  const secrets = {};
package/dist/index.d.ts CHANGED
@@ -339,6 +339,7 @@ type BootError = ConfigError | FnoxError | CatalogError | AliasError | {
339
339
  readonly _tag: "SealKeyUnavailable";
340
340
  readonly sealedKeys: ReadonlyArray<string>;
341
341
  readonly searched: ReadonlyArray<string>;
342
+ readonly configuredKeyFile?: string;
342
343
  } | IdentityError;
343
344
  type IdentityError = {
344
345
  readonly _tag: "AgeNotFound";
package/dist/index.js CHANGED
@@ -1983,11 +1983,13 @@ const resolveSealIdentity = (config, configDir) => {
1983
1983
  });
1984
1984
  const inlineKey = resolveInlineKey().orUndefined();
1985
1985
  if (inlineKey) return Option(materializeInlineKey(inlineKey));
1986
- const defaultPath = join(homedir(), ".envpkt", "age-key.txt");
1987
- if (existsSync(defaultPath)) return Option({
1988
- path: defaultPath,
1989
- dispose: noop
1990
- });
1986
+ if (!config.identity?.key_file) {
1987
+ const defaultPath = join(homedir(), ".envpkt", "age-key.txt");
1988
+ if (existsSync(defaultPath)) return Option({
1989
+ path: defaultPath,
1990
+ dispose: noop
1991
+ });
1992
+ }
1991
1993
  return Option(void 0);
1992
1994
  };
1993
1995
  /** Describe the seal-identity precedence chain with per-entry status, for a clear no-key error. */
@@ -2002,7 +2004,7 @@ const describeSealKeySearch = (config, configDir) => {
2002
2004
  keyFileLine,
2003
2005
  envFileLine,
2004
2006
  inlineLine,
2005
- `${defaultPath} (${existsSync(defaultPath) ? "found" : "missing"})`
2007
+ keyFile ? `${defaultPath} (skipped — identity.key_file is set)` : `${defaultPath} (${existsSync(defaultPath) ? "found" : "missing"})`
2006
2008
  ];
2007
2009
  };
2008
2010
  const resolveIdentityKey = (config, configDir) => {
@@ -2078,7 +2080,8 @@ const bootSafe = (options) => {
2078
2080
  if (hasSealedValues && sealIdentity.isEmpty) return Left({
2079
2081
  _tag: "SealKeyUnavailable",
2080
2082
  sealedKeys: nonAliasMetaKeys.filter((k) => !!nonAliasSecretEntries[k]?.encrypted_value),
2081
- searched: describeSealKeySearch(config, configDir)
2083
+ searched: describeSealKeySearch(config, configDir),
2084
+ configuredKeyFile: config.identity?.key_file ? resolve(configDir, expandPath(config.identity.key_file)) : void 0
2082
2085
  });
2083
2086
  return checkExpiration(audit, failOnExpired, warnOnly).map((warnings) => {
2084
2087
  const secrets = {};
@@ -2232,12 +2235,13 @@ const formatBootError = (error) => {
2232
2235
  case "SealKeyUnavailable": {
2233
2236
  const keys = error.sealedKeys.length;
2234
2237
  const searched = error.searched.map((line) => ` • ${line}`).join("\n");
2238
+ const restoreLine = error.configuredKeyFile ? ` • Restore the configured key to ${error.configuredKeyFile} (or set ENVPKT_AGE_KEY_FILE / ENVPKT_AGE_KEY)` : ` • Restore your key to ~/.envpkt/age-key.txt (or set ENVPKT_AGE_KEY_FILE / ENVPKT_AGE_KEY)`;
2235
2239
  return [
2236
2240
  `${keys} sealed secret(s) can't be decrypted — no age key found.`,
2237
2241
  `Searched (in order):`,
2238
2242
  searched,
2239
2243
  `Fix one:`,
2240
- ` • Restore your key to ~/.envpkt/age-key.txt (or set ENVPKT_AGE_KEY_FILE / ENVPKT_AGE_KEY)`,
2244
+ restoreLine,
2241
2245
  ` • Re-provision from source: envpkt seal --edit <KEY>`,
2242
2246
  `Refusing to inject empty values for sealed secrets.`
2243
2247
  ].join("\n");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "envpkt",
3
- "version": "0.14.0",
3
+ "version": "0.14.1",
4
4
  "description": "Credential lifecycle and fleet management for AI agents",
5
5
  "keywords": [
6
6
  "credentials",
@@ -39,18 +39,18 @@
39
39
  "prepublishOnly": "pnpm validate"
40
40
  },
41
41
  "dependencies": {
42
- "@modelcontextprotocol/sdk": "^1.29.0",
42
+ "@modelcontextprotocol/sdk": "^1.30.0",
43
43
  "@sinclair/typebox": "^0.34.52",
44
44
  "commander": "^15.0.0",
45
- "functype": "^1.6.3",
46
- "functype-log": "^1.6.3",
47
- "functype-os": "^1.6.3",
48
- "smol-toml": "^1.7.0"
45
+ "functype": "^1.8.0",
46
+ "functype-log": "^1.8.0",
47
+ "functype-os": "^1.8.0",
48
+ "smol-toml": "^1.7.1"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@types/node": "^24.13.3",
52
- "ts-builds": "^3.2.2",
53
- "tsdown": "^0.22.9",
52
+ "ts-builds": "^3.2.3",
53
+ "tsdown": "^0.22.14",
54
54
  "tsx": "^4.23.1"
55
55
  },
56
56
  "type": "module",
@@ -71,5 +71,5 @@
71
71
  "schemas"
72
72
  ],
73
73
  "prettier": "ts-builds/prettier",
74
- "packageManager": "pnpm@11.15.0+sha512.266f8957a30d2be6e9468e5e66bcdedd35a794175f71b067ba8504d686cce1d0c0f429b33c323c3c569ad4891e667574a49ff71d1b89a22cc66f13c65818c578"
74
+ "packageManager": "pnpm@11.18.0+sha512.33d83c77da82f49fba836925c6f1b841181ec3132b670639bd012f7075f5c7cf634c5f870147c19aae7478fac01df09d8892e880454896edd23ee9b33757563c"
75
75
  }