envpkt 0.6.8 → 0.6.10

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 (2) hide show
  1. package/dist/cli.js +52 -2
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -3059,6 +3059,52 @@ const runSeal = async (options) => {
3059
3059
  const msg = err._tag === "IdentityNotFound" ? `not found: ${err.path}` : err.message;
3060
3060
  console.error(`${YELLOW}Warning:${RESET} Could not unwrap agent key: ${msg}`);
3061
3061
  }, (k) => k) : void 0;
3062
+ const editKeys = options.edit ? options.edit.split(",").map((k) => k.trim()).filter((k) => k.length > 0) : [];
3063
+ if (editKeys.length > 0) {
3064
+ const allSecretEntries = config.secret ?? {};
3065
+ const unknownKeys = editKeys.filter((k) => !(k in allSecretEntries));
3066
+ if (unknownKeys.length > 0) {
3067
+ console.error(`${RED}Error:${RESET} Unknown secret key(s): ${unknownKeys.join(", ")}`);
3068
+ console.error(`${DIM}Available keys: ${Object.keys(allSecretEntries).join(", ")}${RESET}`);
3069
+ process.exit(2);
3070
+ }
3071
+ if (!process.stdin.isTTY) {
3072
+ console.error(`${RED}Error:${RESET} --edit requires an interactive terminal`);
3073
+ process.exit(2);
3074
+ }
3075
+ const secretEntries = Object.fromEntries(editKeys.map((k) => [k, allSecretEntries[k]]));
3076
+ console.log(`${BOLD}Editing ${editKeys.length} secret(s)${RESET} with recipient ${CYAN}${recipient.slice(0, 20)}...${RESET}`);
3077
+ console.log("");
3078
+ const rl = await import("node:readline").then((m) => m.createInterface({
3079
+ input: process.stdin,
3080
+ output: process.stderr
3081
+ }));
3082
+ const prompt = (question) => new Promise((resolve) => {
3083
+ rl.question(question, (answer) => resolve(answer));
3084
+ });
3085
+ const values = {};
3086
+ for (const key of editKeys) {
3087
+ const value = await prompt(`Enter new value for ${key}: `);
3088
+ if (value === "") {
3089
+ console.error(`${YELLOW}Skipped${RESET} ${key} (empty value)`);
3090
+ continue;
3091
+ }
3092
+ values[key] = value;
3093
+ }
3094
+ rl.close();
3095
+ if (Object.keys(values).length === 0) {
3096
+ console.error(`${RED}Error:${RESET} No values provided`);
3097
+ process.exit(2);
3098
+ }
3099
+ sealSecrets(secretEntries, values, recipient).fold((err) => {
3100
+ console.error(`${RED}Error:${RESET} Seal failed: ${err.message}`);
3101
+ process.exit(2);
3102
+ }, (sealedMeta) => {
3103
+ writeSealedToml(configPath, sealedMeta);
3104
+ console.log(`${GREEN}Sealed${RESET} ${Object.keys(values).length} secret(s) into ${DIM}${configPath}${RESET}`);
3105
+ });
3106
+ return;
3107
+ }
3062
3108
  const allSecretEntries = config.secret ?? {};
3063
3109
  const allKeys = Object.keys(allSecretEntries);
3064
3110
  const alreadySealed = allKeys.filter((k) => allSecretEntries[k]?.encrypted_value);
@@ -3141,8 +3187,12 @@ else
3141
3187
  fi
3142
3188
  `;
3143
3189
  const BASH_HOOK = `# envpkt shell hook — add to your .bashrc
3190
+ _envpkt_last_dir=""
3144
3191
  _envpkt_prompt() {
3145
- envpkt audit --format minimal 2>/dev/null
3192
+ if [[ "$PWD" != "$_envpkt_last_dir" ]]; then
3193
+ _envpkt_last_dir="$PWD"
3194
+ envpkt audit --format minimal 2>/dev/null
3195
+ fi
3146
3196
  }
3147
3197
 
3148
3198
  if [[ ! "$PROMPT_COMMAND" == *"_envpkt_prompt"* ]]; then
@@ -3202,7 +3252,7 @@ program.command("exec").description("Run pre-flight audit then execute a command
3202
3252
  program.command("resolve").description("Resolve catalog references and output a flat, self-contained config").option("-c, --config <path>", "Path to envpkt.toml").option("-o, --output <path>", "Write resolved config to file (default: stdout)").option("--format <format>", "Output format: toml | json", "toml").option("--dry-run", "Show what would be resolved without writing").action((options) => {
3203
3253
  runResolve(options);
3204
3254
  });
3205
- program.command("seal").description("Encrypt secret values into envpkt.toml using age — sealed packets are safe to commit to git").option("-c, --config <path>", "Path to envpkt.toml").option("--profile <profile>", "fnox profile to use for value resolution").option("--reseal", "Re-encrypt all secrets, including already sealed (for key rotation)").action(async (options) => {
3255
+ program.command("seal").description("Encrypt secret values into envpkt.toml using age — sealed packets are safe to commit to git").option("-c, --config <path>", "Path to envpkt.toml").option("--profile <profile>", "fnox profile to use for value resolution").option("--reseal", "Re-encrypt all secrets, including already sealed (for key rotation)").option("--edit <keys>", "Re-seal specific keys with new values (comma-separated), always prompts interactively").action(async (options) => {
3206
3256
  await runSeal(options);
3207
3257
  });
3208
3258
  program.command("mcp").description("Start the envpkt MCP server (stdio transport)").option("-c, --config <path>", "Path to envpkt.toml").action((options) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "envpkt",
3
- "version": "0.6.8",
3
+ "version": "0.6.10",
4
4
  "description": "Credential lifecycle and fleet management for AI agents",
5
5
  "keywords": [
6
6
  "credentials",