@nathapp/nax 0.58.3 → 0.58.5

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/nax.js +163 -120
  2. package/package.json +1 -1
package/dist/nax.js CHANGED
@@ -3483,8 +3483,8 @@ function parseAgentError(stderr) {
3483
3483
  }
3484
3484
 
3485
3485
  // src/agents/acp/prompt-audit.ts
3486
- import { mkdirSync as mkdirSync2 } from "fs";
3487
- import { isAbsolute, join, sep } from "path";
3486
+ import { existsSync as fsExistsSync, mkdirSync as mkdirSync2 } from "fs";
3487
+ import { dirname, isAbsolute, join, resolve, sep } from "path";
3488
3488
  function buildAuditFilename(entry, epochMs) {
3489
3489
  const stage = entry.pipelineStage ?? entry.callType;
3490
3490
  if (entry.callType === "run" && entry.turn !== undefined) {
@@ -3509,6 +3509,19 @@ function buildAuditContent(entry, epochMs) {
3509
3509
  return lines.join(`
3510
3510
  `);
3511
3511
  }
3512
+ function findNaxProjectRoot(startDir) {
3513
+ let dir = resolve(startDir);
3514
+ for (let depth = 0;depth < MAX_NAX_WALK_DEPTH; depth++) {
3515
+ if (_promptAuditDeps.existsSync(join(dir, ".nax", "config.json"))) {
3516
+ return dir;
3517
+ }
3518
+ const parent = dirname(dir);
3519
+ if (parent === dir)
3520
+ break;
3521
+ dir = parent;
3522
+ }
3523
+ return startDir;
3524
+ }
3512
3525
  async function writePromptAudit(entry) {
3513
3526
  try {
3514
3527
  let baseDir;
@@ -3517,7 +3530,8 @@ async function writePromptAudit(entry) {
3517
3530
  } else {
3518
3531
  const wtMarker = `${sep}.nax-wt${sep}`;
3519
3532
  const wtIdx = entry.workdir.indexOf(wtMarker);
3520
- const projectRoot = wtIdx !== -1 ? entry.workdir.substring(0, wtIdx) : entry.workdir;
3533
+ const strippedWorkdir = wtIdx !== -1 ? entry.workdir.substring(0, wtIdx) : entry.workdir;
3534
+ const projectRoot = findNaxProjectRoot(strippedWorkdir);
3521
3535
  baseDir = join(projectRoot, ".nax", "prompt-audit");
3522
3536
  }
3523
3537
  const resolvedDir = join(baseDir, entry.featureName ?? "_unknown");
@@ -3533,13 +3547,16 @@ async function writePromptAudit(entry) {
3533
3547
  });
3534
3548
  }
3535
3549
  }
3536
- var _promptAuditDeps;
3550
+ var _promptAuditDeps, MAX_NAX_WALK_DEPTH = 10;
3537
3551
  var init_prompt_audit = __esm(() => {
3538
3552
  init_logger2();
3539
3553
  _promptAuditDeps = {
3540
3554
  mkdirSync(path) {
3541
3555
  mkdirSync2(path, { recursive: true });
3542
3556
  },
3557
+ existsSync(path) {
3558
+ return fsExistsSync(path);
3559
+ },
3543
3560
  async writeFile(path, content) {
3544
3561
  await Bun.write(path, content);
3545
3562
  },
@@ -3769,8 +3786,8 @@ class SpawnAcpSession {
3769
3786
  const exitCode = await proc.exited;
3770
3787
  const makeDrain = (ms) => {
3771
3788
  let id;
3772
- const promise = new Promise((resolve) => {
3773
- id = setTimeout(() => resolve(""), ms);
3789
+ const promise = new Promise((resolve2) => {
3790
+ id = setTimeout(() => resolve2(""), ms);
3774
3791
  });
3775
3792
  return { promise, cancel: () => clearTimeout(id) };
3776
3793
  };
@@ -18802,8 +18819,8 @@ async function ensureAcpSession(client, sessionName, agentName, permissionMode)
18802
18819
  async function runSessionPrompt(session, prompt, timeoutMs) {
18803
18820
  const promptPromise = session.prompt(prompt);
18804
18821
  let timeoutId;
18805
- const timeoutPromise = new Promise((resolve) => {
18806
- timeoutId = setTimeout(() => resolve("timeout"), timeoutMs);
18822
+ const timeoutPromise = new Promise((resolve2) => {
18823
+ timeoutId = setTimeout(() => resolve2("timeout"), timeoutMs);
18807
18824
  });
18808
18825
  let winner;
18809
18826
  try {
@@ -19163,7 +19180,7 @@ class AcpAgentAdapter {
19163
19180
  while (turnCount < MAX_TURNS) {
19164
19181
  turnCount++;
19165
19182
  getSafeLogger()?.debug("acp-adapter", `Session turn ${turnCount}/${MAX_TURNS}`, { sessionName });
19166
- const _runAuditConfig = options.config ?? this.naxConfig;
19183
+ const _runAuditConfig = options.config;
19167
19184
  if (_runAuditConfig?.agent?.promptAudit?.enabled) {
19168
19185
  writePromptAudit({
19169
19186
  prompt: currentPrompt,
@@ -19456,9 +19473,9 @@ class AcpAgentAdapter {
19456
19473
  modelTier: options.modelTier ?? "balanced",
19457
19474
  modelDef,
19458
19475
  timeoutSeconds,
19459
- dangerouslySkipPermissions: resolvePermissions(options.config, "plan").skipPermissions,
19476
+ dangerouslySkipPermissions: resolvePermissions(this.naxConfig, "plan").skipPermissions,
19460
19477
  pipelineStage: "plan",
19461
- config: options.config,
19478
+ config: this.naxConfig,
19462
19479
  interactionBridge: options.interactionBridge,
19463
19480
  maxInteractionTurns: options.maxInteractionTurns,
19464
19481
  featureName: options.featureName,
@@ -19485,7 +19502,7 @@ class AcpAgentAdapter {
19485
19502
  const completeResult = await this.complete(prompt, {
19486
19503
  model,
19487
19504
  jsonMode: true,
19488
- config: options.config,
19505
+ config: this.naxConfig,
19489
19506
  workdir: options.workdir,
19490
19507
  featureName: options.featureName,
19491
19508
  storyId: options.storyId,
@@ -19859,8 +19876,8 @@ async function withProcessTimeout(proc, timeoutMs, opts) {
19859
19876
  try {
19860
19877
  const hardDeadlineMs = timeoutMs + graceMs + hardDeadlineBufferMs;
19861
19878
  let hardDeadlineId;
19862
- const hardDeadlinePromise = new Promise((resolve) => {
19863
- hardDeadlineId = setTimeout(() => resolve(-1), hardDeadlineMs);
19879
+ const hardDeadlinePromise = new Promise((resolve2) => {
19880
+ hardDeadlineId = setTimeout(() => resolve2(-1), hardDeadlineMs);
19864
19881
  });
19865
19882
  exitCode = await Promise.race([proc.exited, hardDeadlinePromise]);
19866
19883
  clearTimeout(hardDeadlineId);
@@ -19971,8 +19988,8 @@ async function executeOnce(binary, options, pidRegistry) {
19971
19988
  let stdoutTimeoutId;
19972
19989
  const stdout = await Promise.race([
19973
19990
  new Response(proc.stdout).text(),
19974
- new Promise((resolve) => {
19975
- stdoutTimeoutId = setTimeout(() => resolve(""), 5000);
19991
+ new Promise((resolve2) => {
19992
+ stdoutTimeoutId = setTimeout(() => resolve2(""), 5000);
19976
19993
  })
19977
19994
  ]);
19978
19995
  clearTimeout(stdoutTimeoutId);
@@ -20136,7 +20153,7 @@ ${inputContent}`;
20136
20153
  }
20137
20154
  return cmd;
20138
20155
  }
20139
- async function runPlan(binary, options, pidRegistry, buildAllowedEnv2) {
20156
+ async function runPlan(binary, options, pidRegistry) {
20140
20157
  const { resolveBalancedModelDef: resolveBalancedModelDef2 } = await Promise.resolve().then(() => (init_model_resolution(), exports_model_resolution));
20141
20158
  const cmd = buildPlanCommand(binary, options);
20142
20159
  let modelDef = options.modelDef;
@@ -20146,13 +20163,6 @@ async function runPlan(binary, options, pidRegistry, buildAllowedEnv2) {
20146
20163
  }
20147
20164
  modelDef = resolveBalancedModelDef2(options.config);
20148
20165
  }
20149
- const envOptions = {
20150
- workdir: options.workdir,
20151
- modelDef,
20152
- prompt: "",
20153
- modelTier: options.modelTier || "balanced",
20154
- timeoutSeconds: options.timeoutSeconds ?? 600
20155
- };
20156
20166
  const planTimeoutMs = (options.timeoutSeconds ?? 600) * 1000;
20157
20167
  if (options.interactive) {
20158
20168
  const proc = Bun.spawn(cmd, {
@@ -20160,7 +20170,7 @@ async function runPlan(binary, options, pidRegistry, buildAllowedEnv2) {
20160
20170
  stdin: "inherit",
20161
20171
  stdout: "inherit",
20162
20172
  stderr: "inherit",
20163
- env: buildAllowedEnv2(envOptions)
20173
+ env: buildAllowedEnv()
20164
20174
  });
20165
20175
  await pidRegistry.register(proc.pid);
20166
20176
  let exitCode;
@@ -20186,7 +20196,7 @@ async function runPlan(binary, options, pidRegistry, buildAllowedEnv2) {
20186
20196
  stdin: "ignore",
20187
20197
  stdout: Bun.file(outFile),
20188
20198
  stderr: Bun.file(errFile),
20189
- env: buildAllowedEnv2(envOptions)
20199
+ env: buildAllowedEnv()
20190
20200
  });
20191
20201
  await pidRegistry.register(proc.pid);
20192
20202
  let exitCode;
@@ -20216,6 +20226,7 @@ async function runPlan(binary, options, pidRegistry, buildAllowedEnv2) {
20216
20226
  var init_plan = __esm(() => {
20217
20227
  init_timeout_handler();
20218
20228
  init_logger2();
20229
+ init_env();
20219
20230
  init_model_resolution();
20220
20231
  });
20221
20232
 
@@ -20310,7 +20321,7 @@ class ClaudeCodeAdapter {
20310
20321
  }
20311
20322
  async plan(options) {
20312
20323
  const pidRegistry = this.getPidRegistry(options.workdir);
20313
- return runPlan(this.binary, options, pidRegistry, this.buildAllowedEnv.bind(this));
20324
+ return runPlan(this.binary, options, pidRegistry);
20314
20325
  }
20315
20326
  async decompose(options) {
20316
20327
  const { resolveBalancedModelDef: resolveBalancedModelDef2 } = await Promise.resolve().then(() => (init_model_resolution(), exports_model_resolution));
@@ -20328,13 +20339,7 @@ class ClaudeCodeAdapter {
20328
20339
  cmd.splice(cmd.length - 2, 0, "--dangerously-skip-permissions");
20329
20340
  }
20330
20341
  const pidRegistry = this.getPidRegistry(options.workdir);
20331
- const env2 = this.buildAllowedEnv({
20332
- workdir: options.workdir,
20333
- modelDef,
20334
- prompt: "",
20335
- modelTier: options.modelTier || "balanced",
20336
- timeoutSeconds: 600
20337
- });
20342
+ const env2 = buildAllowedEnv();
20338
20343
  if (options.featureName) {
20339
20344
  env2.NAX_FEATURE_NAME = options.featureName;
20340
20345
  }
@@ -20371,8 +20376,8 @@ class ClaudeCodeAdapter {
20371
20376
  let stdoutTimeoutId;
20372
20377
  const stdout = await Promise.race([
20373
20378
  new Response(proc.stdout).text(),
20374
- new Promise((resolve) => {
20375
- stdoutTimeoutId = setTimeout(() => resolve(""), 5000);
20379
+ new Promise((resolve2) => {
20380
+ stdoutTimeoutId = setTimeout(() => resolve2(""), 5000);
20376
20381
  })
20377
20382
  ]);
20378
20383
  clearTimeout(stdoutTimeoutId);
@@ -20742,9 +20747,9 @@ var init_registry = __esm(() => {
20742
20747
 
20743
20748
  // src/config/path-security.ts
20744
20749
  import { existsSync as existsSync3, lstatSync, realpathSync } from "fs";
20745
- import { basename, isAbsolute as isAbsolute3, normalize, resolve } from "path";
20750
+ import { basename, isAbsolute as isAbsolute3, normalize, resolve as resolve2 } from "path";
20746
20751
  function validateDirectory(dirPath, baseDir) {
20747
- const resolved = resolve(dirPath);
20752
+ const resolved = resolve2(dirPath);
20748
20753
  if (!existsSync3(resolved)) {
20749
20754
  throw new Error(`Directory does not exist: ${dirPath}`);
20750
20755
  }
@@ -20763,7 +20768,7 @@ function validateDirectory(dirPath, baseDir) {
20763
20768
  throw new Error(`Failed to stat path: ${dirPath} (${error48.message})`);
20764
20769
  }
20765
20770
  if (baseDir) {
20766
- const resolvedBase = resolve(baseDir);
20771
+ const resolvedBase = resolve2(baseDir);
20767
20772
  const realBase = existsSync3(resolvedBase) ? realpathSync(resolvedBase) : resolvedBase;
20768
20773
  if (!isWithinDirectory(realPath, realBase)) {
20769
20774
  throw new Error(`Path is outside allowed directory: ${dirPath} (resolved to ${realPath}, base: ${realBase})`);
@@ -20782,14 +20787,14 @@ function isWithinDirectory(targetPath, basePath) {
20782
20787
  return targetWithSlash.startsWith(baseWithSlash) || normalizedTarget === normalizedBase;
20783
20788
  }
20784
20789
  function validateFilePath(filePath, baseDir) {
20785
- const resolved = resolve(filePath);
20790
+ const resolved = resolve2(filePath);
20786
20791
  let realPath;
20787
20792
  try {
20788
20793
  if (!existsSync3(resolved)) {
20789
- const parent = resolve(resolved, "..");
20794
+ const parent = resolve2(resolved, "..");
20790
20795
  if (existsSync3(parent)) {
20791
20796
  const realParent = realpathSync(parent);
20792
- realPath = resolve(realParent, basename(resolved));
20797
+ realPath = resolve2(realParent, basename(resolved));
20793
20798
  } else {
20794
20799
  realPath = resolved;
20795
20800
  }
@@ -20799,7 +20804,7 @@ function validateFilePath(filePath, baseDir) {
20799
20804
  } catch (error48) {
20800
20805
  throw new Error(`Failed to resolve path: ${filePath} (${error48.message})`);
20801
20806
  }
20802
- const resolvedBase = resolve(baseDir);
20807
+ const resolvedBase = resolve2(baseDir);
20803
20808
  const realBase = existsSync3(resolvedBase) ? realpathSync(resolvedBase) : resolvedBase;
20804
20809
  if (!isWithinDirectory(realPath, realBase)) {
20805
20810
  throw new Error(`Path is outside allowed directory: ${filePath} (resolved to ${realPath}, base: ${realBase})`);
@@ -20846,12 +20851,22 @@ var init_json_file = __esm(() => {
20846
20851
 
20847
20852
  // src/config/merge.ts
20848
20853
  function mergePackageConfig(root, packageOverride) {
20849
- const hasAnyMergeableField = packageOverride.execution !== undefined || packageOverride.review !== undefined || packageOverride.acceptance !== undefined || packageOverride.quality !== undefined || packageOverride.context !== undefined || packageOverride.project !== undefined;
20854
+ const hasAnyMergeableField = packageOverride.agent !== undefined || packageOverride.models !== undefined || packageOverride.routing !== undefined || packageOverride.execution !== undefined || packageOverride.review !== undefined || packageOverride.acceptance !== undefined || packageOverride.quality !== undefined || packageOverride.context !== undefined || packageOverride.project !== undefined;
20850
20855
  if (!hasAnyMergeableField) {
20851
20856
  return root;
20852
20857
  }
20853
20858
  return {
20854
20859
  ...root,
20860
+ agent: packageOverride.agent !== undefined ? {
20861
+ ...root.agent,
20862
+ ...packageOverride.agent,
20863
+ promptAudit: {
20864
+ enabled: packageOverride.agent.promptAudit?.enabled ?? root.agent?.promptAudit?.enabled ?? false,
20865
+ ...packageOverride.agent.promptAudit?.dir !== undefined ? { dir: packageOverride.agent.promptAudit.dir } : root.agent?.promptAudit?.dir !== undefined ? { dir: root.agent.promptAudit.dir } : {}
20866
+ }
20867
+ } : root.agent,
20868
+ models: packageOverride.models !== undefined ? { ...root.models, ...packageOverride.models } : root.models,
20869
+ routing: packageOverride.routing !== undefined ? { ...root.routing, ...packageOverride.routing, llm: { ...root.routing?.llm, ...packageOverride.routing.llm } } : root.routing,
20855
20870
  execution: {
20856
20871
  ...root.execution,
20857
20872
  ...packageOverride.execution,
@@ -20993,7 +21008,7 @@ function isPlainObject2(value) {
20993
21008
 
20994
21009
  // src/config/paths.ts
20995
21010
  import { homedir as homedir2 } from "os";
20996
- import { join as join7, resolve as resolve2 } from "path";
21011
+ import { join as join7, resolve as resolve3 } from "path";
20997
21012
  function globalConfigDir() {
20998
21013
  const override = process.env[GLOBAL_CONFIG_DIR_ENV];
20999
21014
  if (override)
@@ -21001,7 +21016,7 @@ function globalConfigDir() {
21001
21016
  return join7(homedir2(), ".nax");
21002
21017
  }
21003
21018
  function projectConfigDir(projectRoot) {
21004
- return join7(resolve2(projectRoot), PROJECT_NAX_DIR);
21019
+ return join7(resolve3(projectRoot), PROJECT_NAX_DIR);
21005
21020
  }
21006
21021
  var GLOBAL_CONFIG_DIR_ENV = "NAX_GLOBAL_CONFIG_DIR", PROJECT_NAX_DIR = ".nax";
21007
21022
  var init_paths = () => {};
@@ -21155,12 +21170,12 @@ var init_profile = __esm(() => {
21155
21170
 
21156
21171
  // src/config/loader.ts
21157
21172
  import { existsSync as existsSync7 } from "fs";
21158
- import { basename as basename2, dirname as dirname2, join as join9, resolve as resolve3 } from "path";
21173
+ import { basename as basename2, dirname as dirname3, join as join9, resolve as resolve4 } from "path";
21159
21174
  function globalConfigPath() {
21160
21175
  return join9(globalConfigDir(), "config.json");
21161
21176
  }
21162
21177
  function findProjectDir(startDir = process.cwd()) {
21163
- let dir = resolve3(startDir);
21178
+ let dir = resolve4(startDir);
21164
21179
  let depth = 0;
21165
21180
  while (depth < MAX_DIRECTORY_DEPTH) {
21166
21181
  const candidate = join9(dir, PROJECT_NAX_DIR);
@@ -21211,7 +21226,7 @@ function applyBatchModeCompat(conf) {
21211
21226
  async function loadConfig(startDir, cliOverrides) {
21212
21227
  let rawConfig = structuredClone(DEFAULT_CONFIG);
21213
21228
  const projDir = startDir ? basename2(startDir) === PROJECT_NAX_DIR ? startDir : findProjectDir(startDir) : findProjectDir();
21214
- const projectRoot = startDir ? basename2(startDir) === PROJECT_NAX_DIR ? dirname2(startDir) : startDir : process.cwd();
21229
+ const projectRoot = startDir ? basename2(startDir) === PROJECT_NAX_DIR ? dirname3(startDir) : startDir : process.cwd();
21215
21230
  const profileName = await resolveProfileName(cliOverrides ?? {}, process.env, projectRoot);
21216
21231
  const globalConfRaw = await loadJsonFile(globalConfigPath(), "config");
21217
21232
  if (globalConfRaw) {
@@ -21254,13 +21269,19 @@ ${errors3.join(`
21254
21269
  }
21255
21270
  async function loadConfigForWorkdir(rootConfigPath, packageDir) {
21256
21271
  const logger = getLogger();
21257
- const rootNaxDir = dirname2(rootConfigPath);
21258
- const rootConfig = await loadConfig(rootNaxDir);
21272
+ const resolvedRootConfigPath = resolve4(rootConfigPath);
21273
+ const rootNaxDir = dirname3(resolvedRootConfigPath);
21274
+ let rootConfigPromise = _rootConfigCache.get(resolvedRootConfigPath);
21275
+ if (!rootConfigPromise) {
21276
+ rootConfigPromise = loadConfig(rootNaxDir);
21277
+ _rootConfigCache.set(resolvedRootConfigPath, rootConfigPromise);
21278
+ }
21279
+ const rootConfig = await rootConfigPromise;
21259
21280
  if (!packageDir) {
21260
21281
  logger.debug("config", "No packageDir \u2014 using root config");
21261
21282
  return rootConfig;
21262
21283
  }
21263
- const repoRoot = dirname2(rootNaxDir);
21284
+ const repoRoot = dirname3(rootNaxDir);
21264
21285
  const packageConfigPath = join9(repoRoot, PROJECT_NAX_DIR, "mono", packageDir, "config.json");
21265
21286
  const packageOverride = await loadJsonFile(packageConfigPath, "config");
21266
21287
  if (!packageOverride) {
@@ -21271,8 +21292,26 @@ async function loadConfigForWorkdir(rootConfigPath, packageDir) {
21271
21292
  return rootConfig;
21272
21293
  }
21273
21294
  logger.debug("config", "Per-package config loaded", { packageConfigPath, packageDir });
21274
- return mergePackageConfig(rootConfig, packageOverride);
21295
+ const { profile: packageProfile, ...packageFields } = packageOverride;
21296
+ let merged = mergePackageConfig(rootConfig, packageFields);
21297
+ if (packageProfile && packageProfile !== "default") {
21298
+ const packageRoot = join9(repoRoot, packageDir);
21299
+ const profileData = await loadProfile(packageProfile, packageRoot);
21300
+ const rawMerged = deepMergeConfig(merged, profileData);
21301
+ rawMerged.profile = packageProfile;
21302
+ const result = NaxConfigSchema.safeParse(rawMerged);
21303
+ if (result.success) {
21304
+ merged = result.data;
21305
+ } else {
21306
+ logger.warn("config", "Per-package profile failed validation \u2014 using merged config without profile", {
21307
+ packageDir,
21308
+ packageProfile
21309
+ });
21310
+ }
21311
+ }
21312
+ return merged;
21275
21313
  }
21314
+ var _rootConfigCache;
21276
21315
  var init_loader = __esm(() => {
21277
21316
  init_logger2();
21278
21317
  init_json_file();
@@ -21280,6 +21319,7 @@ var init_loader = __esm(() => {
21280
21319
  init_paths();
21281
21320
  init_profile();
21282
21321
  init_schema();
21322
+ _rootConfigCache = new Map;
21283
21323
  });
21284
21324
  // src/config/index.ts
21285
21325
  var init_config = __esm(() => {
@@ -22138,7 +22178,8 @@ Do NOT output the JSON to the conversation. Write the file, then reply with a br
22138
22178
  };
22139
22179
  }
22140
22180
  const proposalOutputs = successful.map((p) => p.output);
22141
- const outcome = await resolveOutcome(proposalOutputs, [], ctx.stageConfig, ctx.config, ctx.storyId, 0);
22181
+ const resolverTimeoutMs = (ctx.stageConfig.timeoutSeconds ?? 600) * 1000;
22182
+ const outcome = await resolveOutcome(proposalOutputs, [], ctx.stageConfig, ctx.config, ctx.storyId, resolverTimeoutMs);
22142
22183
  const winningOutput = successful[0].output;
22143
22184
  const proposals = successful.map((p) => ({ debater: p.debater, output: p.output }));
22144
22185
  logger?.info("debate", "debate:result", {
@@ -22432,22 +22473,21 @@ class AutoInteractionPlugin {
22432
22473
  if (!adapter) {
22433
22474
  throw new Error("Auto plugin requires adapter to be injected via _autoPluginDeps.adapter");
22434
22475
  }
22435
- let modelArg;
22436
- if (this.config.naxConfig) {
22476
+ const naxConfig = this.config.naxConfig ?? DEFAULT_CONFIG;
22477
+ let resolvedModel;
22478
+ try {
22437
22479
  const modelTier = this.config.model ?? "fast";
22438
- const naxConfig = this.config.naxConfig;
22439
- const modelDef = resolveModelForAgent(naxConfig.models, naxConfig.autoMode.defaultAgent, modelTier, naxConfig.autoMode.defaultAgent);
22440
- modelArg = modelDef.model;
22441
- }
22442
- const timeoutMs = this.config.naxConfig ? (this.config.naxConfig.execution?.sessionTimeoutSeconds ?? 600) * 1000 : undefined;
22480
+ resolvedModel = resolveModelForAgent(naxConfig.models, naxConfig.autoMode.defaultAgent, modelTier, naxConfig.autoMode.defaultAgent).model;
22481
+ } catch {}
22482
+ const timeoutMs = (naxConfig.execution?.sessionTimeoutSeconds ?? 600) * 1000;
22443
22483
  const result = await adapter.complete(prompt, {
22444
- ...modelArg && { model: modelArg },
22484
+ ...resolvedModel !== undefined && { model: resolvedModel },
22445
22485
  jsonMode: true,
22446
- ...this.config.naxConfig && { config: this.config.naxConfig },
22486
+ config: naxConfig,
22447
22487
  featureName: request.featureName,
22448
22488
  storyId: request.storyId,
22449
22489
  sessionRole: "auto",
22450
- ...timeoutMs !== undefined && { timeoutMs }
22490
+ timeoutMs
22451
22491
  });
22452
22492
  const output = typeof result === "string" ? result : result.output;
22453
22493
  return this.parseResponse(output);
@@ -22605,9 +22645,9 @@ ${request.summary}
22605
22645
  if (!this.rl) {
22606
22646
  throw new Error("CLI plugin not initialized");
22607
22647
  }
22608
- const timeoutPromise = new Promise((resolve4) => {
22648
+ const timeoutPromise = new Promise((resolve5) => {
22609
22649
  setTimeout(() => {
22610
- resolve4({
22650
+ resolve5({
22611
22651
  requestId: request.id,
22612
22652
  action: "skip",
22613
22653
  respondedBy: "timeout",
@@ -22759,9 +22799,9 @@ ${request.summary}
22759
22799
  if (!this.rl) {
22760
22800
  throw new Error("CLI plugin not initialized");
22761
22801
  }
22762
- return new Promise((resolve4) => {
22802
+ return new Promise((resolve5) => {
22763
22803
  this.rl?.question(prompt, (answer) => {
22764
- resolve4(answer);
22804
+ resolve5(answer);
22765
22805
  });
22766
22806
  });
22767
22807
  }
@@ -23193,7 +23233,7 @@ class WebhookInteractionPlugin {
23193
23233
  this.pendingResponses.delete(requestId);
23194
23234
  return early;
23195
23235
  }
23196
- return new Promise((resolve4) => {
23236
+ return new Promise((resolve5) => {
23197
23237
  const existingCallback = this.receiveCallbacks.get(requestId);
23198
23238
  if (existingCallback) {
23199
23239
  this.clearReceiveTimer(requestId);
@@ -23207,7 +23247,7 @@ class WebhookInteractionPlugin {
23207
23247
  const timer = setTimeout(() => {
23208
23248
  this.clearReceiveTimer(requestId);
23209
23249
  this.receiveCallbacks.delete(requestId);
23210
- resolve4({
23250
+ resolve5({
23211
23251
  requestId,
23212
23252
  action: "skip",
23213
23253
  respondedBy: "timeout",
@@ -23218,7 +23258,7 @@ class WebhookInteractionPlugin {
23218
23258
  this.receiveCallbacks.set(requestId, (response) => {
23219
23259
  this.clearReceiveTimer(requestId);
23220
23260
  this.receiveCallbacks.delete(requestId);
23221
- resolve4(response);
23261
+ resolve5(response);
23222
23262
  });
23223
23263
  });
23224
23264
  }
@@ -24585,8 +24625,9 @@ function getNextStory(prd, currentStoryId, maxRetries) {
24585
24625
  return currentStory;
24586
24626
  }
24587
24627
  }
24628
+ const storyIds = new Set(prd.userStories.map((s) => s.id));
24588
24629
  const completedIds = new Set(prd.userStories.filter((s) => s.passes || s.status === "passed" || s.status === "skipped").map((s) => s.id));
24589
- return prd.userStories.find((s) => !s.passes && s.status !== "passed" && s.status !== "skipped" && s.status !== "blocked" && s.status !== "failed" && s.status !== "paused" && s.status !== "decomposed" && s.dependencies.every((dep) => completedIds.has(dep))) ?? null;
24630
+ return prd.userStories.find((s) => !s.passes && s.status !== "passed" && s.status !== "skipped" && s.status !== "blocked" && s.status !== "failed" && s.status !== "paused" && s.status !== "decomposed" && s.dependencies.every((dep) => !storyIds.has(dep) || completedIds.has(dep))) ?? null;
24590
24631
  }
24591
24632
  function isComplete(prd) {
24592
24633
  return prd.userStories.every((s) => s.passes || s.status === "passed" || s.status === "skipped");
@@ -27386,7 +27427,7 @@ async function runSemanticReview(workdir, storyGitRef, story, semanticConfig, mo
27386
27427
  storyId: story.id,
27387
27428
  stage: "review",
27388
27429
  stageConfig: reviewStageConfig,
27389
- config: naxConfig,
27430
+ config: naxConfig ?? DEFAULT_CONFIG,
27390
27431
  workdir,
27391
27432
  featureName,
27392
27433
  timeoutSeconds: naxConfig?.execution?.sessionTimeoutSeconds
@@ -27489,7 +27530,7 @@ ${formatFindings(debateBlocking)}`,
27489
27530
  timeoutSeconds: semanticConfig.timeoutMs ? Math.ceil(semanticConfig.timeoutMs / 1000) : 3600,
27490
27531
  modelTier: semanticConfig.modelTier,
27491
27532
  modelDef: resolvedModelDef,
27492
- config: naxConfig
27533
+ config: naxConfig ?? DEFAULT_CONFIG
27493
27534
  });
27494
27535
  runOutput = runResult.output;
27495
27536
  runSucceeded = true;
@@ -27504,7 +27545,7 @@ ${formatFindings(debateBlocking)}`,
27504
27545
  workdir,
27505
27546
  timeoutMs: semanticConfig.timeoutMs,
27506
27547
  modelTier: semanticConfig.modelTier,
27507
- config: naxConfig
27548
+ config: naxConfig ?? DEFAULT_CONFIG
27508
27549
  });
27509
27550
  rawResponse = typeof completeResult === "string" ? completeResult : completeResult.output;
27510
27551
  }
@@ -27610,6 +27651,7 @@ ${formatFindings(blockingFindings)}`;
27610
27651
  var _semanticDeps, DIFF_CAP_BYTES = 51200;
27611
27652
  var init_semantic = __esm(() => {
27612
27653
  init_adapter();
27654
+ init_config();
27613
27655
  init_debate();
27614
27656
  init_logger2();
27615
27657
  init_git();
@@ -28633,7 +28675,7 @@ var init_constitution = __esm(() => {
28633
28675
  });
28634
28676
 
28635
28677
  // src/pipeline/stages/constitution.ts
28636
- import { dirname as dirname3 } from "path";
28678
+ import { dirname as dirname4 } from "path";
28637
28679
  var constitutionStage;
28638
28680
  var init_constitution2 = __esm(() => {
28639
28681
  init_constitution();
@@ -28643,7 +28685,7 @@ var init_constitution2 = __esm(() => {
28643
28685
  enabled: (ctx) => ctx.config.constitution.enabled,
28644
28686
  async execute(ctx) {
28645
28687
  const logger = getLogger();
28646
- const ngentDir = ctx.featureDir ? dirname3(dirname3(ctx.featureDir)) : `${ctx.workdir}/nax`;
28688
+ const ngentDir = ctx.featureDir ? dirname4(dirname4(ctx.featureDir)) : `${ctx.workdir}/nax`;
28647
28689
  const result = await loadConstitution(ngentDir, ctx.config.constitution);
28648
28690
  if (result) {
28649
28691
  ctx.constitution = result;
@@ -29505,13 +29547,14 @@ ${pkgContent.trim()}`;
29505
29547
  }
29506
29548
  }
29507
29549
  function getAllReadyStories(prd) {
29550
+ const storyIds = new Set(prd.userStories.map((s) => s.id));
29508
29551
  const completedIds = new Set(prd.userStories.filter((s) => s.passes || s.status === "skipped").map((s) => s.id));
29509
29552
  const logger = getSafeLogger2();
29510
29553
  logger?.debug("routing", "getAllReadyStories: completed set", {
29511
29554
  completedIds: [...completedIds],
29512
29555
  totalStories: prd.userStories.length
29513
29556
  });
29514
- return prd.userStories.filter((s) => !s.passes && s.status !== "skipped" && s.status !== "failed" && s.status !== "paused" && s.status !== "blocked" && s.dependencies.every((dep) => completedIds.has(dep)));
29557
+ return prd.userStories.filter((s) => !s.passes && s.status !== "skipped" && s.status !== "failed" && s.status !== "paused" && s.status !== "blocked" && s.dependencies.every((dep) => !storyIds.has(dep) || completedIds.has(dep)));
29515
29558
  }
29516
29559
  var CONTEXT_MAX_TOKENS = 1e5, CONTEXT_RESERVED_TOKENS = 1e4;
29517
29560
  var init_story_context = __esm(() => {
@@ -29830,10 +29873,10 @@ async function executeWithTimeout(command, timeoutSeconds, env2, options) {
29830
29873
  const timeoutMs = timeoutSeconds * 1000;
29831
29874
  let timedOut = false;
29832
29875
  const timer = { id: undefined };
29833
- const timeoutPromise = new Promise((resolve6) => {
29876
+ const timeoutPromise = new Promise((resolve7) => {
29834
29877
  timer.id = setTimeout(() => {
29835
29878
  timedOut = true;
29836
- resolve6();
29879
+ resolve7();
29837
29880
  }, timeoutMs);
29838
29881
  });
29839
29882
  const processPromise = proc.exited;
@@ -32651,7 +32694,7 @@ async function _defaultRunDebate(storyId, stageConfig, prompt, config2) {
32651
32694
  if (resolved.length === 0) {
32652
32695
  return { output: null, totalCostUsd: 0 };
32653
32696
  }
32654
- const timeoutMs = (config2?.execution?.sessionTimeoutSeconds ?? 600) * 1000;
32697
+ const timeoutMs = (config2.execution?.sessionTimeoutSeconds ?? 600) * 1000;
32655
32698
  const startMs = Date.now();
32656
32699
  const proposalSettled = await Promise.allSettled(resolved.map(({ debater, adapter }) => adapter.complete(prompt, {
32657
32700
  model: debater.model,
@@ -33129,16 +33172,16 @@ class AcceptanceStrategy {
33129
33172
  }, timeoutMs);
33130
33173
  const exitCode = await Promise.race([
33131
33174
  proc.exited,
33132
- new Promise((resolve6) => setTimeout(() => resolve6(124), timeoutMs + 6000))
33175
+ new Promise((resolve7) => setTimeout(() => resolve7(124), timeoutMs + 6000))
33133
33176
  ]);
33134
33177
  clearTimeout(timeoutId);
33135
33178
  const stdout = await Promise.race([
33136
33179
  new Response(proc.stdout).text(),
33137
- new Promise((resolve6) => setTimeout(() => resolve6(""), 3000))
33180
+ new Promise((resolve7) => setTimeout(() => resolve7(""), 3000))
33138
33181
  ]);
33139
33182
  const stderr = await Promise.race([
33140
33183
  new Response(proc.stderr).text(),
33141
- new Promise((resolve6) => setTimeout(() => resolve6(""), 3000))
33184
+ new Promise((resolve7) => setTimeout(() => resolve7(""), 3000))
33142
33185
  ]);
33143
33186
  const durationMs = Date.now() - start;
33144
33187
  if (timedOut || exitCode === 124) {
@@ -34834,12 +34877,12 @@ var init_init_context = __esm(() => {
34834
34877
 
34835
34878
  // src/utils/path-security.ts
34836
34879
  import { realpathSync as realpathSync3 } from "fs";
34837
- import { dirname as dirname4, isAbsolute as isAbsolute5, join as join32, normalize as normalize2, resolve as resolve6 } from "path";
34880
+ import { dirname as dirname5, isAbsolute as isAbsolute5, join as join32, normalize as normalize2, resolve as resolve7 } from "path";
34838
34881
  function safeRealpathForComparison(p) {
34839
34882
  try {
34840
34883
  return realpathSync3(p);
34841
34884
  } catch {
34842
- const parent = dirname4(p);
34885
+ const parent = dirname5(p);
34843
34886
  if (parent === p)
34844
34887
  return normalize2(p);
34845
34888
  const resolvedParent = safeRealpathForComparison(parent);
@@ -34850,7 +34893,7 @@ function validateModulePath(modulePath, allowedRoots) {
34850
34893
  if (!modulePath) {
34851
34894
  return { valid: false, error: "Module path is empty" };
34852
34895
  }
34853
- const resolvedRoots = allowedRoots.map((r) => safeRealpathForComparison(resolve6(r)));
34896
+ const resolvedRoots = allowedRoots.map((r) => safeRealpathForComparison(resolve7(r)));
34854
34897
  if (isAbsolute5(modulePath)) {
34855
34898
  const normalized = normalize2(modulePath);
34856
34899
  const resolved = safeRealpathForComparison(normalized);
@@ -34860,8 +34903,8 @@ function validateModulePath(modulePath, allowedRoots) {
34860
34903
  }
34861
34904
  } else {
34862
34905
  for (let i = 0;i < allowedRoots.length; i++) {
34863
- const originalRoot = resolve6(allowedRoots[i]);
34864
- const absoluteInput = resolve6(join32(originalRoot, modulePath));
34906
+ const originalRoot = resolve7(allowedRoots[i]);
34907
+ const absoluteInput = resolve7(join32(originalRoot, modulePath));
34865
34908
  const resolved = safeRealpathForComparison(absoluteInput);
34866
34909
  const resolvedRoot = resolvedRoots[i];
34867
34910
  if (resolved.startsWith(`${resolvedRoot}/`) || resolved === resolvedRoot) {
@@ -35609,7 +35652,7 @@ var package_default;
35609
35652
  var init_package = __esm(() => {
35610
35653
  package_default = {
35611
35654
  name: "@nathapp/nax",
35612
- version: "0.58.3",
35655
+ version: "0.58.5",
35613
35656
  description: "AI Coding Agent Orchestrator \u2014 loops until done",
35614
35657
  type: "module",
35615
35658
  bin: {
@@ -35689,8 +35732,8 @@ var init_version = __esm(() => {
35689
35732
  NAX_VERSION = package_default.version;
35690
35733
  NAX_COMMIT = (() => {
35691
35734
  try {
35692
- if (/^[0-9a-f]{6,10}$/.test("1cf117ef"))
35693
- return "1cf117ef";
35735
+ if (/^[0-9a-f]{6,10}$/.test("374b714e"))
35736
+ return "374b714e";
35694
35737
  } catch {}
35695
35738
  try {
35696
35739
  const result = Bun.spawnSync(["git", "rev-parse", "--short", "HEAD"], {
@@ -39864,7 +39907,7 @@ var init_project = __esm(() => {
39864
39907
 
39865
39908
  // src/execution/status-file.ts
39866
39909
  import { rename, unlink as unlink3 } from "fs/promises";
39867
- import { resolve as resolve8 } from "path";
39910
+ import { resolve as resolve9 } from "path";
39868
39911
  function countProgress(prd) {
39869
39912
  const stories = prd.userStories;
39870
39913
  const passed = stories.filter((s) => s.status === "passed").length;
@@ -39909,7 +39952,7 @@ function buildStatusSnapshot(state) {
39909
39952
  return snapshot;
39910
39953
  }
39911
39954
  async function writeStatusFile(filePath, status) {
39912
- const resolvedPath = resolve8(filePath);
39955
+ const resolvedPath = resolve9(filePath);
39913
39956
  if (filePath.includes("../") || filePath.includes("..\\")) {
39914
39957
  throw new Error("Invalid status file path: path traversal detected");
39915
39958
  }
@@ -40992,14 +41035,14 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
40992
41035
  prevActScopeDepth !== actScopeDepth - 1 && console.error("You seem to have overlapping act() calls, this is not supported. Be sure to await previous act() calls before making a new one. ");
40993
41036
  actScopeDepth = prevActScopeDepth;
40994
41037
  }
40995
- function recursivelyFlushAsyncActWork(returnValue, resolve9, reject) {
41038
+ function recursivelyFlushAsyncActWork(returnValue, resolve10, reject) {
40996
41039
  var queue = ReactSharedInternals.actQueue;
40997
41040
  if (queue !== null)
40998
41041
  if (queue.length !== 0)
40999
41042
  try {
41000
41043
  flushActQueue(queue);
41001
41044
  enqueueTask(function() {
41002
- return recursivelyFlushAsyncActWork(returnValue, resolve9, reject);
41045
+ return recursivelyFlushAsyncActWork(returnValue, resolve10, reject);
41003
41046
  });
41004
41047
  return;
41005
41048
  } catch (error48) {
@@ -41007,7 +41050,7 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
41007
41050
  }
41008
41051
  else
41009
41052
  ReactSharedInternals.actQueue = null;
41010
- 0 < ReactSharedInternals.thrownErrors.length ? (queue = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, reject(queue)) : resolve9(returnValue);
41053
+ 0 < ReactSharedInternals.thrownErrors.length ? (queue = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, reject(queue)) : resolve10(returnValue);
41011
41054
  }
41012
41055
  function flushActQueue(queue) {
41013
41056
  if (!isFlushing) {
@@ -41183,14 +41226,14 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
41183
41226
  didAwaitActCall || didWarnNoAwaitAct || (didWarnNoAwaitAct = true, console.error("You called act(async () => ...) without await. This could lead to unexpected testing behaviour, interleaving multiple act calls and mixing their scopes. You should - await act(async () => ...);"));
41184
41227
  });
41185
41228
  return {
41186
- then: function(resolve9, reject) {
41229
+ then: function(resolve10, reject) {
41187
41230
  didAwaitActCall = true;
41188
41231
  thenable.then(function(returnValue) {
41189
41232
  popActScope(prevActQueue, prevActScopeDepth);
41190
41233
  if (prevActScopeDepth === 0) {
41191
41234
  try {
41192
41235
  flushActQueue(queue), enqueueTask(function() {
41193
- return recursivelyFlushAsyncActWork(returnValue, resolve9, reject);
41236
+ return recursivelyFlushAsyncActWork(returnValue, resolve10, reject);
41194
41237
  });
41195
41238
  } catch (error$0) {
41196
41239
  ReactSharedInternals.thrownErrors.push(error$0);
@@ -41201,7 +41244,7 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
41201
41244
  reject(_thrownError);
41202
41245
  }
41203
41246
  } else
41204
- resolve9(returnValue);
41247
+ resolve10(returnValue);
41205
41248
  }, function(error48) {
41206
41249
  popActScope(prevActQueue, prevActScopeDepth);
41207
41250
  0 < ReactSharedInternals.thrownErrors.length ? (error48 = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, reject(error48)) : reject(error48);
@@ -41217,11 +41260,11 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
41217
41260
  if (0 < ReactSharedInternals.thrownErrors.length)
41218
41261
  throw callback = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, callback;
41219
41262
  return {
41220
- then: function(resolve9, reject) {
41263
+ then: function(resolve10, reject) {
41221
41264
  didAwaitActCall = true;
41222
41265
  prevActScopeDepth === 0 ? (ReactSharedInternals.actQueue = queue, enqueueTask(function() {
41223
- return recursivelyFlushAsyncActWork(returnValue$jscomp$0, resolve9, reject);
41224
- })) : resolve9(returnValue$jscomp$0);
41266
+ return recursivelyFlushAsyncActWork(returnValue$jscomp$0, resolve10, reject);
41267
+ })) : resolve10(returnValue$jscomp$0);
41225
41268
  }
41226
41269
  };
41227
41270
  };
@@ -44063,8 +44106,8 @@ It can also happen if the client has a browser extension installed which messes
44063
44106
  currentEntangledActionThenable = {
44064
44107
  status: "pending",
44065
44108
  value: undefined,
44066
- then: function(resolve9) {
44067
- entangledListeners.push(resolve9);
44109
+ then: function(resolve10) {
44110
+ entangledListeners.push(resolve10);
44068
44111
  }
44069
44112
  };
44070
44113
  }
@@ -44088,8 +44131,8 @@ It can also happen if the client has a browser extension installed which messes
44088
44131
  status: "pending",
44089
44132
  value: null,
44090
44133
  reason: null,
44091
- then: function(resolve9) {
44092
- listeners.push(resolve9);
44134
+ then: function(resolve10) {
44135
+ listeners.push(resolve10);
44093
44136
  }
44094
44137
  };
44095
44138
  thenable.then(function() {
@@ -72614,13 +72657,13 @@ function createCliInteractionBridge() {
72614
72657
  process.stdout.write(`
72615
72658
  \uD83E\uDD16 Agent: ${text}
72616
72659
  You: `);
72617
- return new Promise((resolve4) => {
72660
+ return new Promise((resolve5) => {
72618
72661
  const rl = createInterface2({ input: process.stdin, terminal: false });
72619
72662
  rl.once("line", (line) => {
72620
72663
  rl.close();
72621
- resolve4(line.trim());
72664
+ resolve5(line.trim());
72622
72665
  });
72623
- rl.once("close", () => resolve4(""));
72666
+ rl.once("close", () => resolve5(""));
72624
72667
  });
72625
72668
  }
72626
72669
  };
@@ -73125,20 +73168,20 @@ async function displayModelEfficiency(workdir) {
73125
73168
  // src/cli/status-features.ts
73126
73169
  init_source();
73127
73170
  import { existsSync as existsSync15, readdirSync as readdirSync4 } from "fs";
73128
- import { join as join14, resolve as resolve5 } from "path";
73171
+ import { join as join14, resolve as resolve6 } from "path";
73129
73172
 
73130
73173
  // src/commands/common.ts
73131
73174
  init_path_security();
73132
73175
  init_errors();
73133
73176
  import { existsSync as existsSync14, readdirSync as readdirSync3, realpathSync as realpathSync2 } from "fs";
73134
- import { join as join12, resolve as resolve4 } from "path";
73177
+ import { join as join12, resolve as resolve5 } from "path";
73135
73178
  function resolveProject(options = {}) {
73136
73179
  const { dir, feature } = options;
73137
73180
  let projectRoot;
73138
73181
  let naxDir;
73139
73182
  let configPath;
73140
73183
  if (dir) {
73141
- projectRoot = realpathSync2(resolve4(dir));
73184
+ projectRoot = realpathSync2(resolve5(dir));
73142
73185
  naxDir = join12(projectRoot, ".nax");
73143
73186
  if (!existsSync14(naxDir)) {
73144
73187
  throw new NaxError(`Directory does not contain a nax project: ${projectRoot}
@@ -73191,7 +73234,7 @@ No features found in this project.`;
73191
73234
  };
73192
73235
  }
73193
73236
  function findProjectRoot(startDir) {
73194
- let current = resolve4(startDir);
73237
+ let current = resolve5(startDir);
73195
73238
  let depth = 0;
73196
73239
  while (depth < MAX_DIRECTORY_DEPTH) {
73197
73240
  const naxDir = join12(current, ".nax");
@@ -73508,7 +73551,7 @@ async function displayFeatureStatus(options = {}) {
73508
73551
  if (options.feature) {
73509
73552
  let featureDir;
73510
73553
  if (options.dir) {
73511
- featureDir = join14(resolve5(options.dir), ".nax", "features", options.feature);
73554
+ featureDir = join14(resolve6(options.dir), ".nax", "features", options.feature);
73512
73555
  } else {
73513
73556
  const resolved = resolveProject({ feature: options.feature });
73514
73557
  if (!resolved.featureDir) {
@@ -81634,8 +81677,8 @@ class Ink {
81634
81677
  }
81635
81678
  }
81636
81679
  async waitUntilExit() {
81637
- this.exitPromise ||= new Promise((resolve9, reject2) => {
81638
- this.resolveExitPromise = resolve9;
81680
+ this.exitPromise ||= new Promise((resolve10, reject2) => {
81681
+ this.resolveExitPromise = resolve10;
81639
81682
  this.rejectExitPromise = reject2;
81640
81683
  });
81641
81684
  if (!this.beforeExitHandler) {
@@ -83448,7 +83491,7 @@ async function promptForConfirmation(question) {
83448
83491
  if (!process.stdin.isTTY) {
83449
83492
  return true;
83450
83493
  }
83451
- return new Promise((resolve9) => {
83494
+ return new Promise((resolve10) => {
83452
83495
  process.stdout.write(source_default.bold(`${question} [Y/n] `));
83453
83496
  process.stdin.setRawMode(true);
83454
83497
  process.stdin.resume();
@@ -83461,9 +83504,9 @@ async function promptForConfirmation(question) {
83461
83504
  process.stdout.write(`
83462
83505
  `);
83463
83506
  if (answer === "n") {
83464
- resolve9(false);
83507
+ resolve10(false);
83465
83508
  } else {
83466
- resolve9(true);
83509
+ resolve10(true);
83467
83510
  }
83468
83511
  };
83469
83512
  process.stdin.on("data", handler);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nathapp/nax",
3
- "version": "0.58.3",
3
+ "version": "0.58.5",
4
4
  "description": "AI Coding Agent Orchestrator — loops until done",
5
5
  "type": "module",
6
6
  "bin": {