vibeman 0.0.12 → 0.0.13

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 (29) hide show
  1. package/dist/api.js +205 -105
  2. package/dist/commit.txt +1 -1
  3. package/dist/index.js +29 -6
  4. package/dist/ui/assets/{index-ByZHh-PW.js → index-AacKgcwz.js} +1 -1
  5. package/dist/ui/assets/{index-B7jXVZvp.js → index-B-SoOQ3F.js} +1 -1
  6. package/dist/ui/assets/{index-DLpjBSMu.js → index-BCRvuZjU.js} +1 -1
  7. package/dist/ui/assets/{index-BunmAvtt.js → index-BK62XAzY.js} +1 -1
  8. package/dist/ui/assets/{index-DLmnpfog.js → index-B_lr0R8Z.js} +1 -1
  9. package/dist/ui/assets/{index-BSBd0iNJ.js → index-BnaWildZ.js} +1 -1
  10. package/dist/ui/assets/{index-D_jkO9O-.js → index-BrOS5hPg.js} +1 -1
  11. package/dist/ui/assets/{index-CKMfCp4z.js → index-Btdv65e_.js} +1 -1
  12. package/dist/ui/assets/{index-C_fbobmw.js → index-BvHGNf4Y.js} +1 -1
  13. package/dist/ui/assets/{index-CGuNU-ZD.js → index-C-AZWfRD.js} +1 -1
  14. package/dist/ui/assets/{index-C11szUfi.js → index-C8FDQRxy.js} +188 -188
  15. package/dist/ui/assets/{index-BjdJVJkF.js → index-CBQN5qXY.js} +1 -1
  16. package/dist/ui/assets/{index-CjUsp5je.js → index-CWcSlUCR.js} +1 -1
  17. package/dist/ui/assets/{index-B8A4iBxI.js → index-CXV7fZxu.js} +1 -1
  18. package/dist/ui/assets/{index-BaXVaxHx.js → index-CuieGJbi.js} +1 -1
  19. package/dist/ui/assets/{index-BRRYaPwU.js → index-D1F9nIOz.js} +1 -1
  20. package/dist/ui/assets/{index-BuwohDsu.js → index-D3gXfrX-.js} +1 -1
  21. package/dist/ui/assets/{index-DlmuGNPY.js → index-DWT6BjYW.js} +1 -1
  22. package/dist/ui/assets/{index-F9P0dYhi.css → index-D_uhpUwJ.css} +1 -1
  23. package/dist/ui/assets/{index-BmtnQPpD.js → index-Dhu8BZu7.js} +1 -1
  24. package/dist/ui/assets/{index-DPowuqxK.js → index-DkFfIHJr.js} +1 -1
  25. package/dist/ui/assets/{index-DRxfqe2a.js → index-cS068OSU.js} +1 -1
  26. package/dist/ui/assets/{index-CTP1vZJL.js → index-o8f2ilDp.js} +1 -1
  27. package/dist/ui/assets/{index-BAQhZ7Ry.js → index-q7X3WW0-.js} +1 -1
  28. package/dist/ui/index.html +2 -2
  29. package/package.json +1 -1
package/dist/api.js CHANGED
@@ -15677,6 +15677,51 @@ var init_zod = __esm(() => {
15677
15677
  init_external();
15678
15678
  });
15679
15679
 
15680
+ // ../shared/runtime/vibeman-env.ts
15681
+ function readVibemanEnv(env, key) {
15682
+ const value = env[key];
15683
+ if (typeof value === "string" && value.trim().length > 0) {
15684
+ return value.trim();
15685
+ }
15686
+ return;
15687
+ }
15688
+ var VIBEMAN_ENV_PREFIX = "VIBEMAN_", VIBEMAN_ENV_KEYS;
15689
+ var init_vibeman_env = __esm(() => {
15690
+ VIBEMAN_ENV_KEYS = {
15691
+ ROOT: "VIBEMAN_ROOT",
15692
+ PORT: "VIBEMAN_PORT",
15693
+ DATABASE_URL: "VIBEMAN_DATABASE_URL",
15694
+ VERBOSE: "VIBEMAN_VERBOSE",
15695
+ LOG_FORMAT: "VIBEMAN_LOG_FORMAT",
15696
+ UI_DIST: "VIBEMAN_UI_DIST",
15697
+ CODEX_PATH: "VIBEMAN_CODEX_PATH",
15698
+ GEMINI_PATH: "VIBEMAN_GEMINI_PATH",
15699
+ CLAUDE_CODE_PATH: "VIBEMAN_CLAUDE_CODE_PATH",
15700
+ TRACE: "VIBEMAN_TRACE",
15701
+ DIST_ROOT: "VIBEMAN_DIST_ROOT",
15702
+ DB_AUTORECOVER: "VIBEMAN_DB_AUTORECOVER"
15703
+ };
15704
+ });
15705
+
15706
+ // ../api/src/services/env-policy.ts
15707
+ function isVibemanPrefixedEnvKey(key) {
15708
+ return key.startsWith(VIBEMAN_ENV_PREFIX);
15709
+ }
15710
+ function shouldFilterForExternalAppLaunch(input) {
15711
+ if (isVibemanPrefixedEnvKey(input.key))
15712
+ return true;
15713
+ return false;
15714
+ }
15715
+ function shouldFilterForWorktreeShellInheritance(input) {
15716
+ if (isVibemanPrefixedEnvKey(input.key))
15717
+ return true;
15718
+ return false;
15719
+ }
15720
+ var init_env_policy = __esm(() => {
15721
+ init_vibeman_env();
15722
+ init_vibeman_env();
15723
+ });
15724
+
15680
15725
  // ../../node_modules/pino-std-serializers/lib/err-helpers.js
15681
15726
  var require_err_helpers = __commonJS((exports, module) => {
15682
15727
  var isErrorLike = (err) => {
@@ -19959,7 +20004,7 @@ function formatExtraPayloadWithMode(payload, verboseDetails) {
19959
20004
  kvParts.push(`${key}=${summarizeSuppressedValue(value)}`);
19960
20005
  }
19961
20006
  if (hiddenDetailCount > 0 && !verboseDetails) {
19962
- kvParts.push("detail=hidden(use VERBOSE=debug|trace)");
20007
+ kvParts.push(`detail=hidden(use ${VIBEMAN_ENV_KEYS.VERBOSE}=debug|trace)`);
19963
20008
  }
19964
20009
  return kvParts.join(" ");
19965
20010
  }
@@ -20109,15 +20154,16 @@ function parseBooleanEnv(raw2) {
20109
20154
  }
20110
20155
  var import_pino, levelEnv, allowedLevels, level, logFormatEnv, logFormat, usePrettyLogs, useColor, includeVerboseDetails, homeDir, cwd, levelLabels, colors, hiddenDetailKeyMatchers, sensitiveKeySegments, sensitiveSegmentPairs, bannerPrinted = false, stream, logger;
20111
20156
  var init_log = __esm(() => {
20157
+ init_env_policy();
20112
20158
  import_pino = __toESM(require_pino(), 1);
20113
- levelEnv = process.env.VERBOSE?.toLowerCase();
20159
+ levelEnv = readVibemanEnv(process.env, VIBEMAN_ENV_KEYS.VERBOSE)?.toLowerCase();
20114
20160
  allowedLevels = new Set(["error", "warn", "info", "debug", "trace"]);
20115
20161
  level = allowedLevels.has(levelEnv ?? "") ? levelEnv : "info";
20116
- logFormatEnv = process.env.LOG_FORMAT?.toLowerCase();
20162
+ logFormatEnv = readVibemanEnv(process.env, VIBEMAN_ENV_KEYS.LOG_FORMAT)?.toLowerCase();
20117
20163
  logFormat = logFormatEnv === "json" || logFormatEnv === "pretty" ? logFormatEnv : "pretty";
20118
20164
  usePrettyLogs = logFormat === "pretty";
20119
20165
  useColor = Boolean(process.stdout.isTTY) && !process.env.NO_COLOR;
20120
- includeVerboseDetails = level === "debug" || level === "trace" || parseBooleanEnv(process.env.VIBEMAN_TRACE);
20166
+ includeVerboseDetails = level === "debug" || level === "trace" || parseBooleanEnv(process.env[VIBEMAN_ENV_KEYS.TRACE]);
20121
20167
  homeDir = homedir();
20122
20168
  cwd = process.cwd();
20123
20169
  levelLabels = {
@@ -42319,23 +42365,29 @@ var init_log_sanitizer = __esm(() => {
42319
42365
  import { execFile, spawn } from "node:child_process";
42320
42366
  import { existsSync as existsSync3 } from "node:fs";
42321
42367
  import { delimiter, resolve as resolve3 } from "node:path";
42368
+ function safeLog(method, ...args) {
42369
+ const fn = logger[method];
42370
+ if (typeof fn === "function") {
42371
+ fn.call(logger, ...args);
42372
+ }
42373
+ }
42322
42374
  function resolveClaudeCodeCliPath(env, logContext) {
42323
- const envOverride = env?.CLAUDE_CODE_PATH ?? process.env.CLAUDE_CODE_PATH;
42375
+ const envOverride = env?.[VIBEMAN_ENV_KEYS.CLAUDE_CODE_PATH] ?? process.env[VIBEMAN_ENV_KEYS.CLAUDE_CODE_PATH];
42324
42376
  if (envOverride) {
42325
42377
  const resolved = envOverride.trim();
42326
42378
  if (resolved && existsSync3(resolved)) {
42327
42379
  if (logContext) {
42328
- logger.debug({ ...logContext, executable: resolved, source: "env" }, "Claude CLI resolved.");
42380
+ safeLog("debug", { ...logContext, executable: resolved, source: "env" }, "Claude CLI resolved.");
42329
42381
  }
42330
42382
  return resolved;
42331
42383
  }
42332
42384
  if (logContext) {
42333
- logger.warn({ ...logContext, executable: resolved }, "Claude CLI path override not found.");
42385
+ safeLog("warn", { ...logContext, executable: resolved }, "Claude CLI path override not found.");
42334
42386
  }
42335
42387
  }
42336
42388
  const fromPath = findClaudeExecutableOnPath();
42337
42389
  if (fromPath && logContext) {
42338
- logger.debug({ ...logContext, executable: fromPath }, "Claude CLI resolved.");
42390
+ safeLog("debug", { ...logContext, executable: fromPath }, "Claude CLI resolved.");
42339
42391
  }
42340
42392
  return fromPath || undefined;
42341
42393
  }
@@ -42758,7 +42810,7 @@ function formatParamsForLog(params) {
42758
42810
  agentTurnOptionsKeys: params.agentTurnOptions ? Object.keys(params.agentTurnOptions).sort() : undefined,
42759
42811
  signal: params.signal ? { aborted: params.signal.aborted } : undefined,
42760
42812
  logContext: params.logContext,
42761
- detail: "hidden (set VERBOSE=debug|trace for full prompt/env/context)"
42813
+ detail: `hidden (set ${VIBEMAN_ENV_KEYS.VERBOSE}=debug|trace for full prompt/env/context)`
42762
42814
  });
42763
42815
  try {
42764
42816
  return JSON.stringify(summarized, null, 2);
@@ -42768,6 +42820,7 @@ function formatParamsForLog(params) {
42768
42820
  }
42769
42821
  var CLAUDE_EXECUTABLE_CANDIDATES, ClaudeRunError, ClaudeCodeCliProvider;
42770
42822
  var init_claude_code_cli_provider = __esm(() => {
42823
+ init_env_policy();
42771
42824
  init_log();
42772
42825
  init_log_sanitizer();
42773
42826
  CLAUDE_EXECUTABLE_CANDIDATES = process.platform === "win32" ? ["claude.exe", "claude.cmd", "claude.bat"] : ["claude"];
@@ -42865,10 +42918,10 @@ ${formatParamsForLog(params)}`);
42865
42918
  resolveExecutable() {
42866
42919
  const resolved = findClaudeExecutableOnPath();
42867
42920
  if (resolved) {
42868
- logger.debug({ ...this.logContext, executable: resolved }, "Claude CLI resolved.");
42921
+ safeLog("debug", { ...this.logContext, executable: resolved }, "Claude CLI resolved.");
42869
42922
  return resolved;
42870
42923
  }
42871
- logger.warn(this.logContext, "Claude CLI not found on PATH.");
42924
+ safeLog("warn", this.logContext, "Claude CLI not found on PATH.");
42872
42925
  return "";
42873
42926
  }
42874
42927
  async validateSetup() {
@@ -42881,7 +42934,7 @@ ${formatParamsForLog(params)}`);
42881
42934
  };
42882
42935
  }
42883
42936
  const version3 = await this.getVersion(executable);
42884
- logger.info({ ...this.logContext, executable, version: version3 }, "Claude CLI validated.");
42937
+ safeLog("info", { ...this.logContext, executable, version: version3 }, "Claude CLI validated.");
42885
42938
  return { success: true, message: "Claude CLI available.", version: version3 };
42886
42939
  }
42887
42940
  async getVersion(executable) {
@@ -43324,23 +43377,29 @@ function buildCodexTurnOptions(params) {
43324
43377
  import { execFile as execFile2 } from "node:child_process";
43325
43378
  import { existsSync as existsSync4 } from "node:fs";
43326
43379
  import { delimiter as delimiter2, dirname as dirname2, resolve as resolve4 } from "node:path";
43380
+ function safeLog2(method, ...args) {
43381
+ const fn = logger[method];
43382
+ if (typeof fn === "function") {
43383
+ fn.call(logger, ...args);
43384
+ }
43385
+ }
43327
43386
  function resolveCodexCliPath(env, logContext) {
43328
- const envOverride = env?.CODEX_PATH ?? process.env.CODEX_PATH;
43387
+ const envOverride = env?.[VIBEMAN_ENV_KEYS.CODEX_PATH] ?? process.env[VIBEMAN_ENV_KEYS.CODEX_PATH];
43329
43388
  if (envOverride) {
43330
43389
  const resolved = envOverride.trim();
43331
43390
  if (resolved && existsSync4(resolved)) {
43332
43391
  if (logContext) {
43333
- logger.debug({ ...logContext, executable: resolved, source: "env" }, "Codex CLI resolved.");
43392
+ safeLog2("debug", { ...logContext, executable: resolved, source: "env" }, "Codex CLI resolved.");
43334
43393
  }
43335
43394
  return resolved;
43336
43395
  }
43337
43396
  if (logContext) {
43338
- logger.warn({ ...logContext, executable: resolved }, "Codex CLI path override not found.");
43397
+ safeLog2("warn", { ...logContext, executable: resolved }, "Codex CLI path override not found.");
43339
43398
  }
43340
43399
  }
43341
43400
  const fromPath = findCodexExecutableOnPath();
43342
43401
  if (fromPath && logContext) {
43343
- logger.debug({ ...logContext, executable: fromPath }, "Codex CLI resolved.");
43402
+ safeLog2("debug", { ...logContext, executable: fromPath }, "Codex CLI resolved.");
43344
43403
  }
43345
43404
  return fromPath || undefined;
43346
43405
  }
@@ -43495,7 +43554,7 @@ function summarizeRunParamsForLog(params) {
43495
43554
  agentThreadOptionsKeys: params.agentThreadOptions ? Object.keys(params.agentThreadOptions).sort() : undefined,
43496
43555
  agentTurnOptionsKeys: params.agentTurnOptions ? Object.keys(params.agentTurnOptions).sort() : undefined,
43497
43556
  logContext: params.logContext,
43498
- detail: "hidden (set VERBOSE=debug|trace for full prompt/env/context)"
43557
+ detail: `hidden (set ${VIBEMAN_ENV_KEYS.VERBOSE}=debug|trace for full prompt/env/context)`
43499
43558
  });
43500
43559
  }
43501
43560
  return sanitizeForLog({
@@ -43541,6 +43600,7 @@ function emitRunEvent(onEvent, event, log) {
43541
43600
  var CodexRunError, CodexCliProvider;
43542
43601
  var init_codex_cli_provider = __esm(() => {
43543
43602
  init_dist3();
43603
+ init_env_policy();
43544
43604
  init_log_sanitizer();
43545
43605
  init_log();
43546
43606
  CodexRunError = class CodexRunError extends Error {
@@ -43674,10 +43734,10 @@ ${formatParamsForLog2(summarizeRunParamsForLog(params))}`);
43674
43734
  resolveExecutable() {
43675
43735
  const resolved = findCodexExecutableOnPath();
43676
43736
  if (resolved) {
43677
- logger.debug({ ...this.logContext, executable: resolved }, "Codex CLI resolved.");
43737
+ safeLog2("debug", { ...this.logContext, executable: resolved }, "Codex CLI resolved.");
43678
43738
  return resolved;
43679
43739
  }
43680
- logger.warn(this.logContext, "Codex CLI not found on PATH.");
43740
+ safeLog2("warn", this.logContext, "Codex CLI not found on PATH.");
43681
43741
  return "";
43682
43742
  }
43683
43743
  async validateSetup() {
@@ -43697,7 +43757,7 @@ ${formatParamsForLog2(summarizeRunParamsForLog(params))}`);
43697
43757
  details: "Ensure the CLI can execute (for example, `node` is available on PATH)."
43698
43758
  };
43699
43759
  }
43700
- logger.info({ ...this.logContext, executable, version: version3 }, "Codex CLI validated.");
43760
+ safeLog2("info", { ...this.logContext, executable, version: version3 }, "Codex CLI validated.");
43701
43761
  return { success: true, message: "Codex CLI available.", version: version3 };
43702
43762
  }
43703
43763
  async getVersion(executable) {
@@ -43718,23 +43778,29 @@ ${formatParamsForLog2(summarizeRunParamsForLog(params))}`);
43718
43778
  import { execFile as execFile3, spawn as spawn3 } from "node:child_process";
43719
43779
  import { existsSync as existsSync5 } from "node:fs";
43720
43780
  import { delimiter as delimiter3, resolve as resolve5 } from "node:path";
43781
+ function safeLog3(method, ...args) {
43782
+ const fn = logger[method];
43783
+ if (typeof fn === "function") {
43784
+ fn.call(logger, ...args);
43785
+ }
43786
+ }
43721
43787
  function resolveGeminiCliPath(env, logContext) {
43722
- const envOverride = env?.GEMINI_PATH ?? process.env.GEMINI_PATH;
43788
+ const envOverride = env?.[VIBEMAN_ENV_KEYS.GEMINI_PATH] ?? process.env[VIBEMAN_ENV_KEYS.GEMINI_PATH];
43723
43789
  if (envOverride) {
43724
43790
  const resolved = envOverride.trim();
43725
43791
  if (resolved && existsSync5(resolved)) {
43726
43792
  if (logContext) {
43727
- logger.debug({ ...logContext, executable: resolved, source: "env" }, "Gemini CLI resolved.");
43793
+ safeLog3("debug", { ...logContext, executable: resolved, source: "env" }, "Gemini CLI resolved.");
43728
43794
  }
43729
43795
  return resolved;
43730
43796
  }
43731
43797
  if (logContext) {
43732
- logger.warn({ ...logContext, executable: resolved }, "Gemini CLI path override not found.");
43798
+ safeLog3("warn", { ...logContext, executable: resolved }, "Gemini CLI path override not found.");
43733
43799
  }
43734
43800
  }
43735
43801
  const fromPath = findGeminiExecutableOnPath();
43736
43802
  if (fromPath && logContext) {
43737
- logger.debug({ ...logContext, executable: fromPath }, "Gemini CLI resolved.");
43803
+ safeLog3("debug", { ...logContext, executable: fromPath }, "Gemini CLI resolved.");
43738
43804
  }
43739
43805
  return fromPath || undefined;
43740
43806
  }
@@ -44082,7 +44148,7 @@ function formatParamsForLog3(params) {
44082
44148
  agentTurnOptionsKeys: params.agentTurnOptions ? Object.keys(params.agentTurnOptions).sort() : undefined,
44083
44149
  signal: params.signal ? { aborted: params.signal.aborted } : undefined,
44084
44150
  logContext: params.logContext,
44085
- detail: "hidden (set VERBOSE=debug|trace for full prompt/env/context)"
44151
+ detail: `hidden (set ${VIBEMAN_ENV_KEYS.VERBOSE}=debug|trace for full prompt/env/context)`
44086
44152
  });
44087
44153
  try {
44088
44154
  return JSON.stringify(summarized, null, 2);
@@ -44092,6 +44158,7 @@ function formatParamsForLog3(params) {
44092
44158
  }
44093
44159
  var GEMINI_EXECUTABLE_CANDIDATES, GeminiRunError, GeminiCliProvider;
44094
44160
  var init_gemini_cli_provider = __esm(() => {
44161
+ init_env_policy();
44095
44162
  init_log();
44096
44163
  init_log_sanitizer();
44097
44164
  GEMINI_EXECUTABLE_CANDIDATES = process.platform === "win32" ? ["gemini.exe", "gemini.cmd", "gemini.bat"] : ["gemini"];
@@ -44189,10 +44256,10 @@ ${formatParamsForLog3(params)}`);
44189
44256
  resolveExecutable() {
44190
44257
  const resolved = findGeminiExecutableOnPath();
44191
44258
  if (resolved) {
44192
- logger.debug({ ...this.logContext, executable: resolved }, "Gemini CLI resolved.");
44259
+ safeLog3("debug", { ...this.logContext, executable: resolved }, "Gemini CLI resolved.");
44193
44260
  return resolved;
44194
44261
  }
44195
- logger.warn(this.logContext, "Gemini CLI not found on PATH.");
44262
+ safeLog3("warn", this.logContext, "Gemini CLI not found on PATH.");
44196
44263
  return "";
44197
44264
  }
44198
44265
  async validateSetup() {
@@ -44205,7 +44272,7 @@ ${formatParamsForLog3(params)}`);
44205
44272
  };
44206
44273
  }
44207
44274
  const version3 = await this.getVersion(executable);
44208
- logger.info({ ...this.logContext, executable, version: version3 }, "Gemini CLI validated.");
44275
+ safeLog3("info", { ...this.logContext, executable, version: version3 }, "Gemini CLI validated.");
44209
44276
  return { success: true, message: "Gemini CLI available.", version: version3 };
44210
44277
  }
44211
44278
  async getVersion(executable) {
@@ -44249,8 +44316,9 @@ import { fileURLToPath as fileURLToPath3 } from "node:url";
44249
44316
  var currentDir, distRoot, packagedSchema, isPackaged, packagedDistRoot, apiRoot, schemaPath, prismaConfigPath, migrationsDir;
44250
44317
  var init_paths = __esm(() => {
44251
44318
  init_dist_layout();
44319
+ init_vibeman_env();
44252
44320
  currentDir = dirname3(fileURLToPath3(import.meta.url));
44253
- distRoot = process.env.VIBEMAN_DIST_ROOT;
44321
+ distRoot = process.env[VIBEMAN_ENV_KEYS.DIST_ROOT];
44254
44322
  packagedSchema = distRoot ? resolve6(distRoot, DIST_LAYOUT.prismaSchema) : "";
44255
44323
  isPackaged = Boolean(packagedSchema) && existsSync6(packagedSchema);
44256
44324
  packagedDistRoot = isPackaged && distRoot ? distRoot : "";
@@ -45339,7 +45407,7 @@ async function initializeDatabase(root) {
45339
45407
  const localDbPath = dbPath;
45340
45408
  await ensureGitignoreHasDbFile(root);
45341
45409
  const databaseUrl = `file:${dbPath}`;
45342
- process.env.DATABASE_URL = databaseUrl;
45410
+ process.env[VIBEMAN_ENV_KEYS.DATABASE_URL] = databaseUrl;
45343
45411
  const databaseTarget = { kind: "local", path: localDbPath };
45344
45412
  startupStatus = { state: "initializing", database: databaseTarget };
45345
45413
  const migrationError = await runMigrations(databaseUrl, databaseTarget, localDbPath);
@@ -45416,7 +45484,7 @@ async function runMigrations(databaseUrl, databaseTarget, localDbPath) {
45416
45484
  } catch (error48) {
45417
45485
  const kind = classifyMigrationError(error48);
45418
45486
  const details = formatMigrationDetails(error48);
45419
- const canAutoRecover = databaseTarget.kind === "local" && localDbPath && (kind === "failed-migrations" || kind === "schema-mismatch") && process.env.VIBEMAN_DB_AUTORECOVER === "1";
45487
+ const canAutoRecover = databaseTarget.kind === "local" && localDbPath && (kind === "failed-migrations" || kind === "schema-mismatch") && process.env[VIBEMAN_ENV_KEYS.DB_AUTORECOVER] === "1";
45420
45488
  if (canAutoRecover) {
45421
45489
  console.warn(`[db] Migration failed (${kind}). Attempting auto-recovery by backing up and recreating the local database.`);
45422
45490
  try {
@@ -45689,18 +45757,18 @@ function logStartupError(error48) {
45689
45757
  `));
45690
45758
  }
45691
45759
  async function ensureCodexCliPath(db) {
45692
- const envPath = process.env.CODEX_PATH?.trim();
45760
+ const envPath = readVibemanEnv(process.env, VIBEMAN_ENV_KEYS.CODEX_PATH);
45693
45761
  if (envPath) {
45694
45762
  if (existsSync10(envPath)) {
45695
45763
  await setCodexCliPathSetting(db, envPath);
45696
45764
  return "env";
45697
45765
  }
45698
- console.warn(`[config] CODEX_PATH is invalid and will be ignored: ${envPath}`);
45766
+ console.warn(`[config] ${VIBEMAN_ENV_KEYS.CODEX_PATH} is invalid and will be ignored: ${envPath}`);
45699
45767
  }
45700
45768
  const storedPath = await getCodexCliPathSetting(db);
45701
45769
  if (storedPath) {
45702
45770
  if (existsSync10(storedPath)) {
45703
- process.env.CODEX_PATH = storedPath;
45771
+ process.env[VIBEMAN_ENV_KEYS.CODEX_PATH] = storedPath;
45704
45772
  return "db";
45705
45773
  }
45706
45774
  await clearCodexCliPathSetting(db);
@@ -45709,24 +45777,24 @@ async function ensureCodexCliPath(db) {
45709
45777
  const detectedPath = resolveCodexCliPath();
45710
45778
  if (detectedPath && existsSync10(detectedPath)) {
45711
45779
  await setCodexCliPathSetting(db, detectedPath);
45712
- process.env.CODEX_PATH = detectedPath;
45780
+ process.env[VIBEMAN_ENV_KEYS.CODEX_PATH] = detectedPath;
45713
45781
  return "auto-detected";
45714
45782
  }
45715
45783
  return "none";
45716
45784
  }
45717
45785
  async function ensureGeminiCliPath(db) {
45718
- const envPath = process.env.GEMINI_PATH?.trim();
45786
+ const envPath = readVibemanEnv(process.env, VIBEMAN_ENV_KEYS.GEMINI_PATH);
45719
45787
  if (envPath) {
45720
45788
  if (existsSync10(envPath)) {
45721
45789
  await setGeminiCliPathSetting(db, envPath);
45722
45790
  return "env";
45723
45791
  }
45724
- console.warn(`[config] GEMINI_PATH is invalid and will be ignored: ${envPath}`);
45792
+ console.warn(`[config] ${VIBEMAN_ENV_KEYS.GEMINI_PATH} is invalid and will be ignored: ${envPath}`);
45725
45793
  }
45726
45794
  const storedPath = await getGeminiCliPathSetting(db);
45727
45795
  if (storedPath) {
45728
45796
  if (existsSync10(storedPath)) {
45729
- process.env.GEMINI_PATH = storedPath;
45797
+ process.env[VIBEMAN_ENV_KEYS.GEMINI_PATH] = storedPath;
45730
45798
  return "db";
45731
45799
  }
45732
45800
  await clearGeminiCliPathSetting(db);
@@ -45735,24 +45803,24 @@ async function ensureGeminiCliPath(db) {
45735
45803
  const detectedPath = resolveGeminiCliPath();
45736
45804
  if (detectedPath && existsSync10(detectedPath)) {
45737
45805
  await setGeminiCliPathSetting(db, detectedPath);
45738
- process.env.GEMINI_PATH = detectedPath;
45806
+ process.env[VIBEMAN_ENV_KEYS.GEMINI_PATH] = detectedPath;
45739
45807
  return "auto-detected";
45740
45808
  }
45741
45809
  return "none";
45742
45810
  }
45743
45811
  async function ensureClaudeCodeCliPath(db) {
45744
- const envPath = process.env.CLAUDE_CODE_PATH?.trim();
45812
+ const envPath = readVibemanEnv(process.env, VIBEMAN_ENV_KEYS.CLAUDE_CODE_PATH);
45745
45813
  if (envPath) {
45746
45814
  if (existsSync10(envPath)) {
45747
45815
  await setClaudeCodeCliPathSetting(db, envPath);
45748
45816
  return "env";
45749
45817
  }
45750
- console.warn(`[config] CLAUDE_CODE_PATH is invalid and will be ignored: ${envPath}`);
45818
+ console.warn(`[config] ${VIBEMAN_ENV_KEYS.CLAUDE_CODE_PATH} is invalid and will be ignored: ${envPath}`);
45751
45819
  }
45752
45820
  const storedPath = await getClaudeCodeCliPathSetting(db);
45753
45821
  if (storedPath) {
45754
45822
  if (existsSync10(storedPath)) {
45755
- process.env.CLAUDE_CODE_PATH = storedPath;
45823
+ process.env[VIBEMAN_ENV_KEYS.CLAUDE_CODE_PATH] = storedPath;
45756
45824
  return "db";
45757
45825
  }
45758
45826
  await clearClaudeCodeCliPathSetting(db);
@@ -45761,7 +45829,7 @@ async function ensureClaudeCodeCliPath(db) {
45761
45829
  const detectedPath = resolveClaudeCodeCliPath();
45762
45830
  if (detectedPath && existsSync10(detectedPath)) {
45763
45831
  await setClaudeCodeCliPathSetting(db, detectedPath);
45764
- process.env.CLAUDE_CODE_PATH = detectedPath;
45832
+ process.env[VIBEMAN_ENV_KEYS.CLAUDE_CODE_PATH] = detectedPath;
45765
45833
  return "auto-detected";
45766
45834
  }
45767
45835
  return "none";
@@ -45772,6 +45840,7 @@ var init_db = __esm(() => {
45772
45840
  init_claude_code_cli_provider();
45773
45841
  init_codex_cli_provider();
45774
45842
  init_gemini_cli_provider();
45843
+ init_env_policy();
45775
45844
  init_paths();
45776
45845
  init_migrate();
45777
45846
  init_storage();
@@ -101110,6 +101179,12 @@ var init_dist8 = __esm(() => {
101110
101179
  });
101111
101180
 
101112
101181
  // ../api/src/services/workflows/logs.ts
101182
+ function safeLog4(method, ...args) {
101183
+ const fn = logger[method];
101184
+ if (typeof fn === "function") {
101185
+ fn.call(logger, ...args);
101186
+ }
101187
+ }
101113
101188
  async function appendRunLog(db, runId, entry) {
101114
101189
  maybeCleanupWorkflowLogs(db);
101115
101190
  await db.workflowRunLog.create({
@@ -101211,7 +101286,7 @@ async function cleanupWorkflowLogs(db, now = Date.now()) {
101211
101286
  }
101212
101287
  });
101213
101288
  if (result.count > 0) {
101214
- logger.info({
101289
+ safeLog4("info", {
101215
101290
  module: "workflow",
101216
101291
  retentionDays: workflowLogRetentionDays,
101217
101292
  deletedCount: result.count
@@ -101220,7 +101295,7 @@ async function cleanupWorkflowLogs(db, now = Date.now()) {
101220
101295
  return { deletedCount: result.count, skipped: false };
101221
101296
  } catch (error48) {
101222
101297
  const message = error48 instanceof Error ? error48.message : String(error48);
101223
- logger.warn({ module: "workflow", errorMessage: message }, `Workflow log cleanup failed: ${message}`);
101298
+ safeLog4("warn", { module: "workflow", errorMessage: message }, `Workflow log cleanup failed: ${message}`);
101224
101299
  return { deletedCount: 0, skipped: false, error: message };
101225
101300
  }
101226
101301
  }
@@ -101911,6 +101986,7 @@ var init_prompt_builder = __esm(() => {
101911
101986
  // ../api/src/services/workflows/executor.ts
101912
101987
  import { spawn as spawn5 } from "node:child_process";
101913
101988
  import { readFileSync as readFileSync4 } from "node:fs";
101989
+ import { resolve as resolvePath4 } from "node:path";
101914
101990
  function createExecutorControl() {
101915
101991
  const abortController = new AbortController;
101916
101992
  let child = null;
@@ -102757,9 +102833,13 @@ function hasBunScript(cwd2, scriptName) {
102757
102833
  }
102758
102834
  }
102759
102835
  function buildShellEnv(input) {
102836
+ const isolateWorktreeInheritedEnv = shouldIsolateWorktreeInheritedEnv(input);
102760
102837
  const baseEnv = {};
102761
102838
  for (const [key, value] of Object.entries(process.env)) {
102762
102839
  if (typeof value === "string") {
102840
+ if (isolateWorktreeInheritedEnv && shouldFilterForWorktreeShellInheritance({ env: process.env, key, value })) {
102841
+ continue;
102842
+ }
102763
102843
  baseEnv[key] = value;
102764
102844
  }
102765
102845
  }
@@ -102788,6 +102868,26 @@ function buildShellEnv(input) {
102788
102868
  }
102789
102869
  return baseEnv;
102790
102870
  }
102871
+ function shouldIsolateWorktreeInheritedEnv(input) {
102872
+ const payload = input.runPayload ?? {};
102873
+ const worktreePath = normalizeEnvPath(payload.worktreePath);
102874
+ if (!worktreePath) {
102875
+ return false;
102876
+ }
102877
+ const repoRoot = normalizeEnvPath(payload.repoRoot ?? payload.root ?? input.root);
102878
+ if (!repoRoot) {
102879
+ return true;
102880
+ }
102881
+ return worktreePath !== repoRoot;
102882
+ }
102883
+ function normalizeEnvPath(raw2) {
102884
+ if (typeof raw2 !== "string")
102885
+ return null;
102886
+ const trimmed2 = raw2.trim();
102887
+ if (trimmed2.length === 0)
102888
+ return null;
102889
+ return resolvePath4(trimmed2);
102890
+ }
102791
102891
  function summarizeShellFailure(command, result) {
102792
102892
  const SNIPPET_LINES = 30;
102793
102893
  const statusLine = [
@@ -102878,6 +102978,7 @@ var init_executor = __esm(() => {
102878
102978
  init_codex_cli_provider();
102879
102979
  init_gemini_cli_provider();
102880
102980
  init_runtime_backend();
102981
+ init_env_policy();
102881
102982
  init_provider_factory();
102882
102983
  init_provider_registry();
102883
102984
  init_model_aliases();
@@ -102891,6 +102992,12 @@ var init_executor = __esm(() => {
102891
102992
  // ../api/src/services/workflows/runner.ts
102892
102993
  import { readFile as readFile3, writeFile as writeFile2 } from "node:fs/promises";
102893
102994
  import { normalize as normalize7, resolve as resolve13 } from "node:path";
102995
+ function safeLog5(method, ...args) {
102996
+ const fn = logger[method];
102997
+ if (typeof fn === "function") {
102998
+ fn.call(logger, ...args);
102999
+ }
103000
+ }
102894
103001
  function isTerminalRunStatus(status) {
102895
103002
  return TERMINAL_RUN_STATUSES.has(status);
102896
103003
  }
@@ -103178,7 +103285,7 @@ function queueWorkflowExecution(db, input) {
103178
103285
  executorType: "coding_agent",
103179
103286
  error: error48
103180
103287
  });
103181
- logger.error({ module: "workflow", runId: input.runId, error: classified.message }, "safeExecuteWorkflow wrapper failed. Marking workflow run failed.");
103288
+ safeLog5("error", { module: "workflow", runId: input.runId, error: classified.message }, "safeExecuteWorkflow wrapper failed. Marking workflow run failed.");
103182
103289
  markRunFailedFromUnhandledError(db, input.runId, {
103183
103290
  message: classified.message,
103184
103291
  failureReason: input.failureReason ?? classified.failureReason,
@@ -103186,7 +103293,7 @@ function queueWorkflowExecution(db, input) {
103186
103293
  currentNodeKey: input.currentNodeKey
103187
103294
  }).catch((persistError) => {
103188
103295
  const persistMessage = persistError instanceof Error ? persistError.message : String(persistError);
103189
- logger.error({ module: "workflow", runId: input.runId, error: persistMessage }, "Unable to persist failed status after safeExecuteWorkflow wrapper failure.");
103296
+ safeLog5("error", { module: "workflow", runId: input.runId, error: persistMessage }, "Unable to persist failed status after safeExecuteWorkflow wrapper failure.");
103190
103297
  });
103191
103298
  });
103192
103299
  }
@@ -103198,7 +103305,7 @@ async function safeExecuteWorkflow(db, input) {
103198
103305
  executorType: "coding_agent",
103199
103306
  error: error48
103200
103307
  });
103201
- logger.error({ module: "workflow", runId: input.runId, error: classified.message }, "Workflow failed.");
103308
+ safeLog5("error", { module: "workflow", runId: input.runId, error: classified.message }, "Workflow failed.");
103202
103309
  await markRunFailedFromUnhandledError(db, input.runId, {
103203
103310
  message: classified.message,
103204
103311
  failureReason: input.failureReason ?? classified.failureReason,
@@ -103261,7 +103368,7 @@ async function markRunFailedFromUnhandledError(db, runId, input) {
103261
103368
  });
103262
103369
  } catch (error48) {
103263
103370
  const message = error48 instanceof Error ? error48.message : String(error48);
103264
- logger.error({ module: "workflow", runId, error: message }, "Failed to persist workflow state via read/persist path. Trying fallback update.");
103371
+ safeLog5("error", { module: "workflow", runId, error: message }, "Failed to persist workflow state via read/persist path. Trying fallback update.");
103265
103372
  await updateRunFailureFallback(db, {
103266
103373
  runId,
103267
103374
  message: input.message,
@@ -103709,7 +103816,7 @@ function createNode(db, node) {
103709
103816
  }));
103710
103817
  if (result.paused) {
103711
103818
  const detail = formatExecutorFailureForLog(result);
103712
- logger.warn({ module: "workflow", runId: state.runId, nodeKey: node.nodeKey, attempt }, `Node paused: ${node.nodeKey} (attempt ${attempt})${detail ? `
103819
+ safeLog5("warn", { module: "workflow", runId: state.runId, nodeKey: node.nodeKey, attempt }, `Node paused: ${node.nodeKey} (attempt ${attempt})${detail ? `
103713
103820
  ${detail}` : ""}`);
103714
103821
  } else if (result.success) {
103715
103822
  logWorkflow(state.runId, `Node completed: ${node.nodeKey} (attempt ${attempt})`, {
@@ -103718,7 +103825,7 @@ ${detail}` : ""}`);
103718
103825
  });
103719
103826
  } else {
103720
103827
  const detail = formatExecutorFailureForLog(result);
103721
- logger.error({ module: "workflow", runId: state.runId, nodeKey: node.nodeKey, attempt }, `Node failed: ${node.nodeKey} (attempt ${attempt})${detail ? `
103828
+ safeLog5("error", { module: "workflow", runId: state.runId, nodeKey: node.nodeKey, attempt }, `Node failed: ${node.nodeKey} (attempt ${attempt})${detail ? `
103722
103829
  ${detail}` : ""}`);
103723
103830
  }
103724
103831
  const basePayload = buildRunPayloadAfterNodeResult({
@@ -103930,13 +104037,13 @@ async function updateRunStatus(db, runId, status, nodeKey, message, options2) {
103930
104037
  if (status === "failed") {
103931
104038
  const detail = typeof message === "string" && message.trim().length > 0 ? `
103932
104039
  ${tailText(message, 8000)}` : "";
103933
- logger.error(logData, `Run status: failed${nodeSuffix}${detail}`);
104040
+ safeLog5("error", logData, `Run status: failed${nodeSuffix}${detail}`);
103934
104041
  } else if (status === "paused") {
103935
104042
  const detail = typeof message === "string" && message.trim().length > 0 ? `
103936
104043
  ${tailText(message, 8000)}` : "";
103937
- logger.warn(logData, `Run status: paused${nodeSuffix}${detail}`);
104044
+ safeLog5("warn", logData, `Run status: paused${nodeSuffix}${detail}`);
103938
104045
  } else {
103939
- logger.info(logData, `Run status: ${status}${nodeSuffix}`);
104046
+ safeLog5("info", logData, `Run status: ${status}${nodeSuffix}`);
103940
104047
  }
103941
104048
  const current = await readRunState(db, runId);
103942
104049
  if (isTerminalRunStatus(current.status)) {
@@ -104750,7 +104857,7 @@ async function updateTaskStatusForRunPayload(input) {
104750
104857
  }
104751
104858
  } catch (error48) {
104752
104859
  const message = error48 instanceof Error ? error48.message : String(error48);
104753
- logger.warn({
104860
+ safeLog5("warn", {
104754
104861
  module: "workflow",
104755
104862
  runId: input.runId,
104756
104863
  nodeKey: input.nodeKey,
@@ -104785,7 +104892,7 @@ async function autoCommitTaskStatusUpdate(input) {
104785
104892
  if (isNothingToCommitError(message)) {
104786
104893
  return;
104787
104894
  }
104788
- logger.warn({
104895
+ safeLog5("warn", {
104789
104896
  module: "workflow",
104790
104897
  runId: input.runId,
104791
104898
  nodeKey: input.nodeKey,
@@ -104798,7 +104905,7 @@ function createLog2(event, data) {
104798
104905
  return { ts: new Date().toISOString(), level: "info", event, data };
104799
104906
  }
104800
104907
  function logWorkflow(runId, message, data) {
104801
- logger.info({ module: "workflow", runId, ...data }, message);
104908
+ safeLog5("info", { module: "workflow", runId, ...data }, message);
104802
104909
  }
104803
104910
  function tailText(text, maxChars) {
104804
104911
  const normalized = text.replace(/\r\n/g, `
@@ -107486,6 +107593,17 @@ function isWithin2(rootPath, targetPath) {
107486
107593
  const relativePath = relative6(rootPath, targetPath);
107487
107594
  return relativePath === "" || !relativePath.startsWith("..") && !relativePath.startsWith(`..${sep3}`);
107488
107595
  }
107596
+ function buildAppLaunchEnv(env) {
107597
+ const next = {};
107598
+ for (const [key, value] of Object.entries(env)) {
107599
+ if (typeof value !== "string")
107600
+ continue;
107601
+ if (shouldFilterForExternalAppLaunch({ env, key, value }))
107602
+ continue;
107603
+ next[key] = value;
107604
+ }
107605
+ return next;
107606
+ }
107489
107607
  function resolveDetectionPath(rawPath) {
107490
107608
  if (rawPath.startsWith("~/")) {
107491
107609
  return resolve16(homedir2(), rawPath.slice(2));
@@ -107543,7 +107661,10 @@ function resolveAppDefinition(category, appId) {
107543
107661
  return app;
107544
107662
  }
107545
107663
  async function openInApp(appName, targetPath) {
107546
- const child = spawn7("open", ["-a", appName, targetPath], { stdio: "ignore" });
107664
+ const child = spawn7("open", ["-a", appName, targetPath], {
107665
+ stdio: "ignore",
107666
+ env: buildAppLaunchEnv(process.env)
107667
+ });
107547
107668
  await new Promise((resolvePromise, rejectPromise) => {
107548
107669
  child.once("error", (error48) => rejectPromise(error48));
107549
107670
  child.once("close", (code) => {
@@ -107560,6 +107681,7 @@ var init_system2 = __esm(() => {
107560
107681
  init_dist4();
107561
107682
  init_zod();
107562
107683
  init_trpc();
107684
+ init_env_policy();
107563
107685
  init_remote_access();
107564
107686
  appCategories = ["terminal", "editor"];
107565
107687
  appCatalog = [
@@ -108307,6 +108429,7 @@ var init_cli_settings = __esm(() => {
108307
108429
  init_model_catalog();
108308
108430
  init_model_aliases();
108309
108431
  init_settings();
108432
+ init_env_policy();
108310
108433
  cliIdSchema = exports_external.enum(AGENT_PROVIDER_IDS);
108311
108434
  updatePathSchema = exports_external.object({
108312
108435
  id: cliIdSchema,
@@ -108357,9 +108480,9 @@ var init_cli_settings = __esm(() => {
108357
108480
  id: exports_external.string().trim().min(1)
108358
108481
  });
108359
108482
  CLI_ENV_BY_PROVIDER = {
108360
- "codex-cli": "CODEX_PATH",
108361
- "gemini-cli": "GEMINI_PATH",
108362
- "claude-code": "CLAUDE_CODE_PATH"
108483
+ "codex-cli": VIBEMAN_ENV_KEYS.CODEX_PATH,
108484
+ "gemini-cli": VIBEMAN_ENV_KEYS.GEMINI_PATH,
108485
+ "claude-code": VIBEMAN_ENV_KEYS.CLAUDE_CODE_PATH
108363
108486
  };
108364
108487
  BASE_PROVIDER_BY_RUNTIME_ADAPTER = new Map(AGENT_PROVIDER_IDS.map((providerId) => {
108365
108488
  const definition = getAgentProviderDefinition(providerId);
@@ -123404,35 +123527,12 @@ function isNodeVersionCompatible(currentNodeVersion, requiredRange) {
123404
123527
 
123405
123528
  // ../api/src/services/config.ts
123406
123529
  init_zod();
123530
+ init_env_policy();
123407
123531
  import { existsSync as existsSync2, statSync } from "node:fs";
123408
123532
  import { isAbsolute, resolve as resolvePath } from "node:path";
123409
123533
  var LOG_LEVELS = ["error", "warn", "info", "debug", "trace"];
123410
123534
  var LOG_FORMATS = ["pretty", "json"];
123411
- var startupEnvSchema = exports_external.object({
123412
- PORT: exports_external.string().optional(),
123413
- VIBEMAN_ROOT: exports_external.string().optional(),
123414
- UI_DIST: exports_external.string().optional(),
123415
- VERBOSE: exports_external.string().optional(),
123416
- LOG_FORMAT: exports_external.string().optional(),
123417
- CODEX_PATH: exports_external.string().optional(),
123418
- GEMINI_PATH: exports_external.string().optional(),
123419
- CLAUDE_CODE_PATH: exports_external.string().optional(),
123420
- DEBUG: exports_external.string().optional(),
123421
- ENABLE_VIBEMAN_CA_TESTS: exports_external.string().optional(),
123422
- ENABLE_VIBEMAN_CA_TESTS_CODEX: exports_external.string().optional(),
123423
- ENABLE_VIBEMAN_CA_TESTS_GEMINI: exports_external.string().optional(),
123424
- ENABLE_VIBEMAN_CA_TESTS_CLAUDE: exports_external.string().optional(),
123425
- VIBEMAN_WORKFLOW_RUN_ID: exports_external.string().optional(),
123426
- VIBEMAN_WORKFLOW_STEP_ID: exports_external.string().optional(),
123427
- VIBEMAN_WORKFLOW_ROOT: exports_external.string().optional(),
123428
- VIBEMAN_TASK_PATH: exports_external.string().optional(),
123429
- VIBEMAN_TASK_NAME: exports_external.string().optional(),
123430
- VIBEMAN_TASK_BRANCH: exports_external.string().optional(),
123431
- VIBEMAN_TASK_WORKTREE: exports_external.string().optional(),
123432
- VIBEMAN_REPO_ROOT: exports_external.string().optional(),
123433
- VIBEMAN_DEFAULT_BRANCH: exports_external.string().optional(),
123434
- NODE_ENV: exports_external.string().optional()
123435
- }).passthrough();
123535
+ var startupEnvSchema = exports_external.object({}).catchall(exports_external.string().optional());
123436
123536
 
123437
123537
  class StartupConfigError extends Error {
123438
123538
  details;
@@ -123446,7 +123546,7 @@ function loadStartupConfig(input) {
123446
123546
  const cwd = input.cwd ?? process.cwd();
123447
123547
  const parsed = startupEnvSchema.parse(input.env);
123448
123548
  const warnings = [];
123449
- const rootRaw = parsed.VIBEMAN_ROOT?.trim();
123549
+ const rootRaw = parsed[VIBEMAN_ENV_KEYS.ROOT]?.trim();
123450
123550
  if (!rootRaw) {
123451
123551
  throw new StartupConfigError("Missing required environment variable VIBEMAN_ROOT.", [
123452
123552
  "Set VIBEMAN_ROOT to the target project directory before starting the API."
@@ -123458,13 +123558,13 @@ function loadStartupConfig(input) {
123458
123558
  `Resolved path does not exist or is not a directory: ${root}`
123459
123559
  ]);
123460
123560
  }
123461
- const port = parsePort(parsed.PORT, warnings);
123462
- const uiDist = parseOptionalDirectory(parsed.UI_DIST, "UI_DIST", cwd, warnings);
123463
- const verbose = parseLogLevel(parsed.VERBOSE, warnings);
123464
- const logFormat = parseLogFormat(parsed.LOG_FORMAT, parsed.NODE_ENV, warnings);
123465
- const codexPath = parseOptionalCliPath(parsed.CODEX_PATH, "CODEX_PATH", warnings);
123466
- const geminiPath = parseOptionalCliPath(parsed.GEMINI_PATH, "GEMINI_PATH", warnings);
123467
- const claudeCodePath = parseOptionalCliPath(parsed.CLAUDE_CODE_PATH, "CLAUDE_CODE_PATH", warnings);
123561
+ const port = parsePort(readVibemanEnv(parsed, VIBEMAN_ENV_KEYS.PORT), warnings);
123562
+ const uiDist = parseOptionalDirectory(readVibemanEnv(parsed, VIBEMAN_ENV_KEYS.UI_DIST), VIBEMAN_ENV_KEYS.UI_DIST, cwd, warnings);
123563
+ const verbose = parseLogLevel(readVibemanEnv(parsed, VIBEMAN_ENV_KEYS.VERBOSE), warnings);
123564
+ const logFormat = parseLogFormat(readVibemanEnv(parsed, VIBEMAN_ENV_KEYS.LOG_FORMAT), parsed.NODE_ENV, warnings);
123565
+ const codexPath = parseOptionalCliPath(readVibemanEnv(parsed, VIBEMAN_ENV_KEYS.CODEX_PATH), VIBEMAN_ENV_KEYS.CODEX_PATH, warnings);
123566
+ const geminiPath = parseOptionalCliPath(readVibemanEnv(parsed, VIBEMAN_ENV_KEYS.GEMINI_PATH), VIBEMAN_ENV_KEYS.GEMINI_PATH, warnings);
123567
+ const claudeCodePath = parseOptionalCliPath(readVibemanEnv(parsed, VIBEMAN_ENV_KEYS.CLAUDE_CODE_PATH), VIBEMAN_ENV_KEYS.CLAUDE_CODE_PATH, warnings);
123468
123568
  const debug = parseBoolean(parsed.DEBUG).value;
123469
123569
  const caAll = parseBoolean(parsed.ENABLE_VIBEMAN_CA_TESTS).value;
123470
123570
  const caCodex = parseBoolean(parsed.ENABLE_VIBEMAN_CA_TESTS_CODEX);
@@ -123522,7 +123622,7 @@ function parsePort(raw2, warnings) {
123522
123622
  }
123523
123623
  const value = Number(raw2);
123524
123624
  if (!Number.isInteger(value) || value < 1 || value > 65535) {
123525
- warnings.push(`PORT="${raw2}" is invalid; using default 6969.`);
123625
+ warnings.push(`${VIBEMAN_ENV_KEYS.PORT}="${raw2}" is invalid; using default 6969.`);
123526
123626
  return 6969;
123527
123627
  }
123528
123628
  return value;
@@ -123549,7 +123649,7 @@ function parseLogLevel(raw2, warnings) {
123549
123649
  }
123550
123650
  const parsed = exports_external.enum(LOG_LEVELS).safeParse(normalized);
123551
123651
  if (!parsed.success) {
123552
- warnings.push(`VERBOSE="${raw2}" is invalid; using "info".`);
123652
+ warnings.push(`${VIBEMAN_ENV_KEYS.VERBOSE}="${raw2}" is invalid; using "info".`);
123553
123653
  return "info";
123554
123654
  }
123555
123655
  return parsed.data;
@@ -123562,7 +123662,7 @@ function parseLogFormat(raw2, nodeEnv, warnings) {
123562
123662
  }
123563
123663
  const parsed = exports_external.enum(LOG_FORMATS).safeParse(normalized);
123564
123664
  if (!parsed.success) {
123565
- warnings.push(`LOG_FORMAT="${raw2}" is invalid; using "${defaultValue}".`);
123665
+ warnings.push(`${VIBEMAN_ENV_KEYS.LOG_FORMAT}="${raw2}" is invalid; using "${defaultValue}".`);
123566
123666
  return defaultValue;
123567
123667
  }
123568
123668
  return parsed.data;
@@ -123609,14 +123709,14 @@ function warnInvalidBoolean(key, raw2, parsed, warnings) {
123609
123709
  warnings.push(`${key}="${raw2}" is invalid; treating it as false.`);
123610
123710
  }
123611
123711
  function applyConfigToEnv(config2, env) {
123612
- env.VIBEMAN_ROOT = config2.root;
123613
- env.PORT = String(config2.port);
123614
- env.VERBOSE = config2.verbose;
123615
- env.LOG_FORMAT = config2.logFormat;
123616
- setOptionalEnv(env, "UI_DIST", config2.uiDist);
123617
- setOptionalEnv(env, "CODEX_PATH", config2.codexPath);
123618
- setOptionalEnv(env, "GEMINI_PATH", config2.geminiPath);
123619
- setOptionalEnv(env, "CLAUDE_CODE_PATH", config2.claudeCodePath);
123712
+ env[VIBEMAN_ENV_KEYS.ROOT] = config2.root;
123713
+ env[VIBEMAN_ENV_KEYS.PORT] = String(config2.port);
123714
+ env[VIBEMAN_ENV_KEYS.VERBOSE] = config2.verbose;
123715
+ env[VIBEMAN_ENV_KEYS.LOG_FORMAT] = config2.logFormat;
123716
+ setOptionalEnv(env, VIBEMAN_ENV_KEYS.UI_DIST, config2.uiDist);
123717
+ setOptionalEnv(env, VIBEMAN_ENV_KEYS.CODEX_PATH, config2.codexPath);
123718
+ setOptionalEnv(env, VIBEMAN_ENV_KEYS.GEMINI_PATH, config2.geminiPath);
123719
+ setOptionalEnv(env, VIBEMAN_ENV_KEYS.CLAUDE_CODE_PATH, config2.claudeCodePath);
123620
123720
  }
123621
123721
  function setOptionalEnv(env, key, value) {
123622
123722
  if (value === undefined) {