@nathapp/nax 0.58.2 → 0.58.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/nax.js +177 -128
- 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 } 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,13 +3509,30 @@ 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;
|
|
3515
3528
|
if (entry.auditDir) {
|
|
3516
3529
|
baseDir = isAbsolute(entry.auditDir) ? entry.auditDir : join(entry.workdir, entry.auditDir);
|
|
3517
3530
|
} else {
|
|
3518
|
-
|
|
3531
|
+
const wtMarker = `${sep}.nax-wt${sep}`;
|
|
3532
|
+
const wtIdx = entry.workdir.indexOf(wtMarker);
|
|
3533
|
+
const strippedWorkdir = wtIdx !== -1 ? entry.workdir.substring(0, wtIdx) : entry.workdir;
|
|
3534
|
+
const projectRoot = findNaxProjectRoot(strippedWorkdir);
|
|
3535
|
+
baseDir = join(projectRoot, ".nax", "prompt-audit");
|
|
3519
3536
|
}
|
|
3520
3537
|
const resolvedDir = join(baseDir, entry.featureName ?? "_unknown");
|
|
3521
3538
|
_promptAuditDeps.mkdirSync(resolvedDir);
|
|
@@ -3530,13 +3547,16 @@ async function writePromptAudit(entry) {
|
|
|
3530
3547
|
});
|
|
3531
3548
|
}
|
|
3532
3549
|
}
|
|
3533
|
-
var _promptAuditDeps;
|
|
3550
|
+
var _promptAuditDeps, MAX_NAX_WALK_DEPTH = 10;
|
|
3534
3551
|
var init_prompt_audit = __esm(() => {
|
|
3535
3552
|
init_logger2();
|
|
3536
3553
|
_promptAuditDeps = {
|
|
3537
3554
|
mkdirSync(path) {
|
|
3538
3555
|
mkdirSync2(path, { recursive: true });
|
|
3539
3556
|
},
|
|
3557
|
+
existsSync(path) {
|
|
3558
|
+
return fsExistsSync(path);
|
|
3559
|
+
},
|
|
3540
3560
|
async writeFile(path, content) {
|
|
3541
3561
|
await Bun.write(path, content);
|
|
3542
3562
|
},
|
|
@@ -3766,8 +3786,8 @@ class SpawnAcpSession {
|
|
|
3766
3786
|
const exitCode = await proc.exited;
|
|
3767
3787
|
const makeDrain = (ms) => {
|
|
3768
3788
|
let id;
|
|
3769
|
-
const promise = new Promise((
|
|
3770
|
-
id = setTimeout(() =>
|
|
3789
|
+
const promise = new Promise((resolve2) => {
|
|
3790
|
+
id = setTimeout(() => resolve2(""), ms);
|
|
3771
3791
|
});
|
|
3772
3792
|
return { promise, cancel: () => clearTimeout(id) };
|
|
3773
3793
|
};
|
|
@@ -18799,8 +18819,8 @@ async function ensureAcpSession(client, sessionName, agentName, permissionMode)
|
|
|
18799
18819
|
async function runSessionPrompt(session, prompt, timeoutMs) {
|
|
18800
18820
|
const promptPromise = session.prompt(prompt);
|
|
18801
18821
|
let timeoutId;
|
|
18802
|
-
const timeoutPromise = new Promise((
|
|
18803
|
-
timeoutId = setTimeout(() =>
|
|
18822
|
+
const timeoutPromise = new Promise((resolve2) => {
|
|
18823
|
+
timeoutId = setTimeout(() => resolve2("timeout"), timeoutMs);
|
|
18804
18824
|
});
|
|
18805
18825
|
let winner;
|
|
18806
18826
|
try {
|
|
@@ -18976,12 +18996,14 @@ function extractQuestion(output) {
|
|
|
18976
18996
|
}
|
|
18977
18997
|
|
|
18978
18998
|
class AcpAgentAdapter {
|
|
18999
|
+
naxConfig;
|
|
18979
19000
|
name;
|
|
18980
19001
|
displayName;
|
|
18981
19002
|
binary;
|
|
18982
19003
|
capabilities;
|
|
18983
19004
|
_unavailableAgents;
|
|
18984
|
-
constructor(agentName) {
|
|
19005
|
+
constructor(agentName, naxConfig) {
|
|
19006
|
+
this.naxConfig = naxConfig;
|
|
18985
19007
|
const entry = resolveRegistryEntry(agentName);
|
|
18986
19008
|
this.name = agentName;
|
|
18987
19009
|
this.displayName = entry.displayName;
|
|
@@ -19158,12 +19180,13 @@ class AcpAgentAdapter {
|
|
|
19158
19180
|
while (turnCount < MAX_TURNS) {
|
|
19159
19181
|
turnCount++;
|
|
19160
19182
|
getSafeLogger()?.debug("acp-adapter", `Session turn ${turnCount}/${MAX_TURNS}`, { sessionName });
|
|
19161
|
-
|
|
19183
|
+
const _runAuditConfig = options.config;
|
|
19184
|
+
if (_runAuditConfig?.agent?.promptAudit?.enabled) {
|
|
19162
19185
|
writePromptAudit({
|
|
19163
19186
|
prompt: currentPrompt,
|
|
19164
19187
|
sessionName,
|
|
19165
19188
|
workdir: options.workdir,
|
|
19166
|
-
auditDir:
|
|
19189
|
+
auditDir: _runAuditConfig.agent.promptAudit.dir,
|
|
19167
19190
|
storyId: options.storyId,
|
|
19168
19191
|
featureName: options.featureName,
|
|
19169
19192
|
pipelineStage: options.pipelineStage ?? "run",
|
|
@@ -19265,7 +19288,7 @@ class AcpAgentAdapter {
|
|
|
19265
19288
|
};
|
|
19266
19289
|
}
|
|
19267
19290
|
async complete(prompt, _options) {
|
|
19268
|
-
const timeoutMs = _options?.timeoutMs
|
|
19291
|
+
const timeoutMs = _options?.timeoutMs || 120000;
|
|
19269
19292
|
const permissionMode = resolvePermissions(_options?.config, "complete").mode;
|
|
19270
19293
|
const workdir = _options?.workdir;
|
|
19271
19294
|
const config2 = _options?.config;
|
|
@@ -19291,15 +19314,16 @@ class AcpAgentAdapter {
|
|
|
19291
19314
|
try {
|
|
19292
19315
|
const completeSessionName = _options?.sessionName ?? buildSessionName(workdir ?? process.cwd(), _options?.featureName, _options?.storyId, _options?.sessionRole);
|
|
19293
19316
|
session = await client.createSession({ agentName, permissionMode, sessionName: completeSessionName });
|
|
19294
|
-
|
|
19317
|
+
const _completeAuditConfig = config2 ?? this.naxConfig;
|
|
19318
|
+
if (_completeAuditConfig?.agent?.promptAudit?.enabled) {
|
|
19295
19319
|
writePromptAudit({
|
|
19296
19320
|
prompt,
|
|
19297
19321
|
sessionName: completeSessionName,
|
|
19298
19322
|
workdir: workdir ?? process.cwd(),
|
|
19299
|
-
auditDir:
|
|
19323
|
+
auditDir: _completeAuditConfig.agent.promptAudit.dir,
|
|
19300
19324
|
storyId: _options?.storyId,
|
|
19301
19325
|
featureName: _options?.featureName,
|
|
19302
|
-
pipelineStage: "complete",
|
|
19326
|
+
pipelineStage: _options?.pipelineStage ?? "complete",
|
|
19303
19327
|
callType: "complete"
|
|
19304
19328
|
});
|
|
19305
19329
|
}
|
|
@@ -19449,9 +19473,9 @@ class AcpAgentAdapter {
|
|
|
19449
19473
|
modelTier: options.modelTier ?? "balanced",
|
|
19450
19474
|
modelDef,
|
|
19451
19475
|
timeoutSeconds,
|
|
19452
|
-
dangerouslySkipPermissions: resolvePermissions(
|
|
19476
|
+
dangerouslySkipPermissions: resolvePermissions(this.naxConfig, "plan").skipPermissions,
|
|
19453
19477
|
pipelineStage: "plan",
|
|
19454
|
-
config:
|
|
19478
|
+
config: this.naxConfig,
|
|
19455
19479
|
interactionBridge: options.interactionBridge,
|
|
19456
19480
|
maxInteractionTurns: options.maxInteractionTurns,
|
|
19457
19481
|
featureName: options.featureName,
|
|
@@ -19478,7 +19502,7 @@ class AcpAgentAdapter {
|
|
|
19478
19502
|
const completeResult = await this.complete(prompt, {
|
|
19479
19503
|
model,
|
|
19480
19504
|
jsonMode: true,
|
|
19481
|
-
config:
|
|
19505
|
+
config: this.naxConfig,
|
|
19482
19506
|
workdir: options.workdir,
|
|
19483
19507
|
featureName: options.featureName,
|
|
19484
19508
|
storyId: options.storyId,
|
|
@@ -19852,8 +19876,8 @@ async function withProcessTimeout(proc, timeoutMs, opts) {
|
|
|
19852
19876
|
try {
|
|
19853
19877
|
const hardDeadlineMs = timeoutMs + graceMs + hardDeadlineBufferMs;
|
|
19854
19878
|
let hardDeadlineId;
|
|
19855
|
-
const hardDeadlinePromise = new Promise((
|
|
19856
|
-
hardDeadlineId = setTimeout(() =>
|
|
19879
|
+
const hardDeadlinePromise = new Promise((resolve2) => {
|
|
19880
|
+
hardDeadlineId = setTimeout(() => resolve2(-1), hardDeadlineMs);
|
|
19857
19881
|
});
|
|
19858
19882
|
exitCode = await Promise.race([proc.exited, hardDeadlinePromise]);
|
|
19859
19883
|
clearTimeout(hardDeadlineId);
|
|
@@ -19964,8 +19988,8 @@ async function executeOnce(binary, options, pidRegistry) {
|
|
|
19964
19988
|
let stdoutTimeoutId;
|
|
19965
19989
|
const stdout = await Promise.race([
|
|
19966
19990
|
new Response(proc.stdout).text(),
|
|
19967
|
-
new Promise((
|
|
19968
|
-
stdoutTimeoutId = setTimeout(() =>
|
|
19991
|
+
new Promise((resolve2) => {
|
|
19992
|
+
stdoutTimeoutId = setTimeout(() => resolve2(""), 5000);
|
|
19969
19993
|
})
|
|
19970
19994
|
]);
|
|
19971
19995
|
clearTimeout(stdoutTimeoutId);
|
|
@@ -20129,7 +20153,7 @@ ${inputContent}`;
|
|
|
20129
20153
|
}
|
|
20130
20154
|
return cmd;
|
|
20131
20155
|
}
|
|
20132
|
-
async function runPlan(binary, options, pidRegistry
|
|
20156
|
+
async function runPlan(binary, options, pidRegistry) {
|
|
20133
20157
|
const { resolveBalancedModelDef: resolveBalancedModelDef2 } = await Promise.resolve().then(() => (init_model_resolution(), exports_model_resolution));
|
|
20134
20158
|
const cmd = buildPlanCommand(binary, options);
|
|
20135
20159
|
let modelDef = options.modelDef;
|
|
@@ -20139,13 +20163,6 @@ async function runPlan(binary, options, pidRegistry, buildAllowedEnv2) {
|
|
|
20139
20163
|
}
|
|
20140
20164
|
modelDef = resolveBalancedModelDef2(options.config);
|
|
20141
20165
|
}
|
|
20142
|
-
const envOptions = {
|
|
20143
|
-
workdir: options.workdir,
|
|
20144
|
-
modelDef,
|
|
20145
|
-
prompt: "",
|
|
20146
|
-
modelTier: options.modelTier || "balanced",
|
|
20147
|
-
timeoutSeconds: options.timeoutSeconds ?? 600
|
|
20148
|
-
};
|
|
20149
20166
|
const planTimeoutMs = (options.timeoutSeconds ?? 600) * 1000;
|
|
20150
20167
|
if (options.interactive) {
|
|
20151
20168
|
const proc = Bun.spawn(cmd, {
|
|
@@ -20153,7 +20170,7 @@ async function runPlan(binary, options, pidRegistry, buildAllowedEnv2) {
|
|
|
20153
20170
|
stdin: "inherit",
|
|
20154
20171
|
stdout: "inherit",
|
|
20155
20172
|
stderr: "inherit",
|
|
20156
|
-
env:
|
|
20173
|
+
env: buildAllowedEnv()
|
|
20157
20174
|
});
|
|
20158
20175
|
await pidRegistry.register(proc.pid);
|
|
20159
20176
|
let exitCode;
|
|
@@ -20179,7 +20196,7 @@ async function runPlan(binary, options, pidRegistry, buildAllowedEnv2) {
|
|
|
20179
20196
|
stdin: "ignore",
|
|
20180
20197
|
stdout: Bun.file(outFile),
|
|
20181
20198
|
stderr: Bun.file(errFile),
|
|
20182
|
-
env:
|
|
20199
|
+
env: buildAllowedEnv()
|
|
20183
20200
|
});
|
|
20184
20201
|
await pidRegistry.register(proc.pid);
|
|
20185
20202
|
let exitCode;
|
|
@@ -20209,6 +20226,7 @@ async function runPlan(binary, options, pidRegistry, buildAllowedEnv2) {
|
|
|
20209
20226
|
var init_plan = __esm(() => {
|
|
20210
20227
|
init_timeout_handler();
|
|
20211
20228
|
init_logger2();
|
|
20229
|
+
init_env();
|
|
20212
20230
|
init_model_resolution();
|
|
20213
20231
|
});
|
|
20214
20232
|
|
|
@@ -20303,7 +20321,7 @@ class ClaudeCodeAdapter {
|
|
|
20303
20321
|
}
|
|
20304
20322
|
async plan(options) {
|
|
20305
20323
|
const pidRegistry = this.getPidRegistry(options.workdir);
|
|
20306
|
-
return runPlan(this.binary, options, pidRegistry
|
|
20324
|
+
return runPlan(this.binary, options, pidRegistry);
|
|
20307
20325
|
}
|
|
20308
20326
|
async decompose(options) {
|
|
20309
20327
|
const { resolveBalancedModelDef: resolveBalancedModelDef2 } = await Promise.resolve().then(() => (init_model_resolution(), exports_model_resolution));
|
|
@@ -20321,13 +20339,7 @@ class ClaudeCodeAdapter {
|
|
|
20321
20339
|
cmd.splice(cmd.length - 2, 0, "--dangerously-skip-permissions");
|
|
20322
20340
|
}
|
|
20323
20341
|
const pidRegistry = this.getPidRegistry(options.workdir);
|
|
20324
|
-
const env2 =
|
|
20325
|
-
workdir: options.workdir,
|
|
20326
|
-
modelDef,
|
|
20327
|
-
prompt: "",
|
|
20328
|
-
modelTier: options.modelTier || "balanced",
|
|
20329
|
-
timeoutSeconds: 600
|
|
20330
|
-
});
|
|
20342
|
+
const env2 = buildAllowedEnv();
|
|
20331
20343
|
if (options.featureName) {
|
|
20332
20344
|
env2.NAX_FEATURE_NAME = options.featureName;
|
|
20333
20345
|
}
|
|
@@ -20364,8 +20376,8 @@ class ClaudeCodeAdapter {
|
|
|
20364
20376
|
let stdoutTimeoutId;
|
|
20365
20377
|
const stdout = await Promise.race([
|
|
20366
20378
|
new Response(proc.stdout).text(),
|
|
20367
|
-
new Promise((
|
|
20368
|
-
stdoutTimeoutId = setTimeout(() =>
|
|
20379
|
+
new Promise((resolve2) => {
|
|
20380
|
+
stdoutTimeoutId = setTimeout(() => resolve2(""), 5000);
|
|
20369
20381
|
})
|
|
20370
20382
|
]);
|
|
20371
20383
|
clearTimeout(stdoutTimeoutId);
|
|
@@ -20679,7 +20691,7 @@ function createAgentRegistry(config2) {
|
|
|
20679
20691
|
if (!known)
|
|
20680
20692
|
return;
|
|
20681
20693
|
if (!acpCache.has(name)) {
|
|
20682
|
-
acpCache.set(name, new AcpAgentAdapter(name));
|
|
20694
|
+
acpCache.set(name, new AcpAgentAdapter(name, config2));
|
|
20683
20695
|
logger?.debug("agents", `Created AcpAgentAdapter for ${name}`, { name, protocol });
|
|
20684
20696
|
}
|
|
20685
20697
|
return acpCache.get(name);
|
|
@@ -20693,7 +20705,7 @@ function createAgentRegistry(config2) {
|
|
|
20693
20705
|
async function getInstalledAgents2() {
|
|
20694
20706
|
const agents = protocol === "acp" ? ALL_AGENTS.map((a) => {
|
|
20695
20707
|
if (!acpCache.has(a.name)) {
|
|
20696
|
-
acpCache.set(a.name, new AcpAgentAdapter(a.name));
|
|
20708
|
+
acpCache.set(a.name, new AcpAgentAdapter(a.name, config2));
|
|
20697
20709
|
}
|
|
20698
20710
|
return acpCache.get(a.name);
|
|
20699
20711
|
}) : ALL_AGENTS;
|
|
@@ -20703,7 +20715,7 @@ function createAgentRegistry(config2) {
|
|
|
20703
20715
|
async function checkAgentHealth2() {
|
|
20704
20716
|
const agents = protocol === "acp" ? ALL_AGENTS.map((a) => {
|
|
20705
20717
|
if (!acpCache.has(a.name)) {
|
|
20706
|
-
acpCache.set(a.name, new AcpAgentAdapter(a.name));
|
|
20718
|
+
acpCache.set(a.name, new AcpAgentAdapter(a.name, config2));
|
|
20707
20719
|
}
|
|
20708
20720
|
return acpCache.get(a.name);
|
|
20709
20721
|
}) : ALL_AGENTS;
|
|
@@ -20735,9 +20747,9 @@ var init_registry = __esm(() => {
|
|
|
20735
20747
|
|
|
20736
20748
|
// src/config/path-security.ts
|
|
20737
20749
|
import { existsSync as existsSync3, lstatSync, realpathSync } from "fs";
|
|
20738
|
-
import { basename, isAbsolute as isAbsolute3, normalize, resolve } from "path";
|
|
20750
|
+
import { basename, isAbsolute as isAbsolute3, normalize, resolve as resolve2 } from "path";
|
|
20739
20751
|
function validateDirectory(dirPath, baseDir) {
|
|
20740
|
-
const resolved =
|
|
20752
|
+
const resolved = resolve2(dirPath);
|
|
20741
20753
|
if (!existsSync3(resolved)) {
|
|
20742
20754
|
throw new Error(`Directory does not exist: ${dirPath}`);
|
|
20743
20755
|
}
|
|
@@ -20756,7 +20768,7 @@ function validateDirectory(dirPath, baseDir) {
|
|
|
20756
20768
|
throw new Error(`Failed to stat path: ${dirPath} (${error48.message})`);
|
|
20757
20769
|
}
|
|
20758
20770
|
if (baseDir) {
|
|
20759
|
-
const resolvedBase =
|
|
20771
|
+
const resolvedBase = resolve2(baseDir);
|
|
20760
20772
|
const realBase = existsSync3(resolvedBase) ? realpathSync(resolvedBase) : resolvedBase;
|
|
20761
20773
|
if (!isWithinDirectory(realPath, realBase)) {
|
|
20762
20774
|
throw new Error(`Path is outside allowed directory: ${dirPath} (resolved to ${realPath}, base: ${realBase})`);
|
|
@@ -20775,14 +20787,14 @@ function isWithinDirectory(targetPath, basePath) {
|
|
|
20775
20787
|
return targetWithSlash.startsWith(baseWithSlash) || normalizedTarget === normalizedBase;
|
|
20776
20788
|
}
|
|
20777
20789
|
function validateFilePath(filePath, baseDir) {
|
|
20778
|
-
const resolved =
|
|
20790
|
+
const resolved = resolve2(filePath);
|
|
20779
20791
|
let realPath;
|
|
20780
20792
|
try {
|
|
20781
20793
|
if (!existsSync3(resolved)) {
|
|
20782
|
-
const parent =
|
|
20794
|
+
const parent = resolve2(resolved, "..");
|
|
20783
20795
|
if (existsSync3(parent)) {
|
|
20784
20796
|
const realParent = realpathSync(parent);
|
|
20785
|
-
realPath =
|
|
20797
|
+
realPath = resolve2(realParent, basename(resolved));
|
|
20786
20798
|
} else {
|
|
20787
20799
|
realPath = resolved;
|
|
20788
20800
|
}
|
|
@@ -20792,7 +20804,7 @@ function validateFilePath(filePath, baseDir) {
|
|
|
20792
20804
|
} catch (error48) {
|
|
20793
20805
|
throw new Error(`Failed to resolve path: ${filePath} (${error48.message})`);
|
|
20794
20806
|
}
|
|
20795
|
-
const resolvedBase =
|
|
20807
|
+
const resolvedBase = resolve2(baseDir);
|
|
20796
20808
|
const realBase = existsSync3(resolvedBase) ? realpathSync(resolvedBase) : resolvedBase;
|
|
20797
20809
|
if (!isWithinDirectory(realPath, realBase)) {
|
|
20798
20810
|
throw new Error(`Path is outside allowed directory: ${filePath} (resolved to ${realPath}, base: ${realBase})`);
|
|
@@ -20839,12 +20851,22 @@ var init_json_file = __esm(() => {
|
|
|
20839
20851
|
|
|
20840
20852
|
// src/config/merge.ts
|
|
20841
20853
|
function mergePackageConfig(root, packageOverride) {
|
|
20842
|
-
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;
|
|
20843
20855
|
if (!hasAnyMergeableField) {
|
|
20844
20856
|
return root;
|
|
20845
20857
|
}
|
|
20846
20858
|
return {
|
|
20847
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,
|
|
20848
20870
|
execution: {
|
|
20849
20871
|
...root.execution,
|
|
20850
20872
|
...packageOverride.execution,
|
|
@@ -20986,7 +21008,7 @@ function isPlainObject2(value) {
|
|
|
20986
21008
|
|
|
20987
21009
|
// src/config/paths.ts
|
|
20988
21010
|
import { homedir as homedir2 } from "os";
|
|
20989
|
-
import { join as join7, resolve as
|
|
21011
|
+
import { join as join7, resolve as resolve3 } from "path";
|
|
20990
21012
|
function globalConfigDir() {
|
|
20991
21013
|
const override = process.env[GLOBAL_CONFIG_DIR_ENV];
|
|
20992
21014
|
if (override)
|
|
@@ -20994,7 +21016,7 @@ function globalConfigDir() {
|
|
|
20994
21016
|
return join7(homedir2(), ".nax");
|
|
20995
21017
|
}
|
|
20996
21018
|
function projectConfigDir(projectRoot) {
|
|
20997
|
-
return join7(
|
|
21019
|
+
return join7(resolve3(projectRoot), PROJECT_NAX_DIR);
|
|
20998
21020
|
}
|
|
20999
21021
|
var GLOBAL_CONFIG_DIR_ENV = "NAX_GLOBAL_CONFIG_DIR", PROJECT_NAX_DIR = ".nax";
|
|
21000
21022
|
var init_paths = () => {};
|
|
@@ -21148,12 +21170,12 @@ var init_profile = __esm(() => {
|
|
|
21148
21170
|
|
|
21149
21171
|
// src/config/loader.ts
|
|
21150
21172
|
import { existsSync as existsSync7 } from "fs";
|
|
21151
|
-
import { basename as basename2, dirname as
|
|
21173
|
+
import { basename as basename2, dirname as dirname3, join as join9, resolve as resolve4 } from "path";
|
|
21152
21174
|
function globalConfigPath() {
|
|
21153
21175
|
return join9(globalConfigDir(), "config.json");
|
|
21154
21176
|
}
|
|
21155
21177
|
function findProjectDir(startDir = process.cwd()) {
|
|
21156
|
-
let dir =
|
|
21178
|
+
let dir = resolve4(startDir);
|
|
21157
21179
|
let depth = 0;
|
|
21158
21180
|
while (depth < MAX_DIRECTORY_DEPTH) {
|
|
21159
21181
|
const candidate = join9(dir, PROJECT_NAX_DIR);
|
|
@@ -21204,7 +21226,7 @@ function applyBatchModeCompat(conf) {
|
|
|
21204
21226
|
async function loadConfig(startDir, cliOverrides) {
|
|
21205
21227
|
let rawConfig = structuredClone(DEFAULT_CONFIG);
|
|
21206
21228
|
const projDir = startDir ? basename2(startDir) === PROJECT_NAX_DIR ? startDir : findProjectDir(startDir) : findProjectDir();
|
|
21207
|
-
const projectRoot = startDir ? basename2(startDir) === PROJECT_NAX_DIR ?
|
|
21229
|
+
const projectRoot = startDir ? basename2(startDir) === PROJECT_NAX_DIR ? dirname3(startDir) : startDir : process.cwd();
|
|
21208
21230
|
const profileName = await resolveProfileName(cliOverrides ?? {}, process.env, projectRoot);
|
|
21209
21231
|
const globalConfRaw = await loadJsonFile(globalConfigPath(), "config");
|
|
21210
21232
|
if (globalConfRaw) {
|
|
@@ -21247,13 +21269,19 @@ ${errors3.join(`
|
|
|
21247
21269
|
}
|
|
21248
21270
|
async function loadConfigForWorkdir(rootConfigPath, packageDir) {
|
|
21249
21271
|
const logger = getLogger();
|
|
21250
|
-
const
|
|
21251
|
-
const
|
|
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;
|
|
21252
21280
|
if (!packageDir) {
|
|
21253
21281
|
logger.debug("config", "No packageDir \u2014 using root config");
|
|
21254
21282
|
return rootConfig;
|
|
21255
21283
|
}
|
|
21256
|
-
const repoRoot =
|
|
21284
|
+
const repoRoot = dirname3(rootNaxDir);
|
|
21257
21285
|
const packageConfigPath = join9(repoRoot, PROJECT_NAX_DIR, "mono", packageDir, "config.json");
|
|
21258
21286
|
const packageOverride = await loadJsonFile(packageConfigPath, "config");
|
|
21259
21287
|
if (!packageOverride) {
|
|
@@ -21264,8 +21292,26 @@ async function loadConfigForWorkdir(rootConfigPath, packageDir) {
|
|
|
21264
21292
|
return rootConfig;
|
|
21265
21293
|
}
|
|
21266
21294
|
logger.debug("config", "Per-package config loaded", { packageConfigPath, packageDir });
|
|
21267
|
-
|
|
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;
|
|
21268
21313
|
}
|
|
21314
|
+
var _rootConfigCache;
|
|
21269
21315
|
var init_loader = __esm(() => {
|
|
21270
21316
|
init_logger2();
|
|
21271
21317
|
init_json_file();
|
|
@@ -21273,6 +21319,7 @@ var init_loader = __esm(() => {
|
|
|
21273
21319
|
init_paths();
|
|
21274
21320
|
init_profile();
|
|
21275
21321
|
init_schema();
|
|
21322
|
+
_rootConfigCache = new Map;
|
|
21276
21323
|
});
|
|
21277
21324
|
// src/config/index.ts
|
|
21278
21325
|
var init_config = __esm(() => {
|
|
@@ -22425,22 +22472,21 @@ class AutoInteractionPlugin {
|
|
|
22425
22472
|
if (!adapter) {
|
|
22426
22473
|
throw new Error("Auto plugin requires adapter to be injected via _autoPluginDeps.adapter");
|
|
22427
22474
|
}
|
|
22428
|
-
|
|
22429
|
-
|
|
22475
|
+
const naxConfig = this.config.naxConfig ?? DEFAULT_CONFIG;
|
|
22476
|
+
let resolvedModel;
|
|
22477
|
+
try {
|
|
22430
22478
|
const modelTier = this.config.model ?? "fast";
|
|
22431
|
-
|
|
22432
|
-
|
|
22433
|
-
|
|
22434
|
-
}
|
|
22435
|
-
const timeoutMs = this.config.naxConfig ? (this.config.naxConfig.execution?.sessionTimeoutSeconds ?? 600) * 1000 : undefined;
|
|
22479
|
+
resolvedModel = resolveModelForAgent(naxConfig.models, naxConfig.autoMode.defaultAgent, modelTier, naxConfig.autoMode.defaultAgent).model;
|
|
22480
|
+
} catch {}
|
|
22481
|
+
const timeoutMs = (naxConfig.execution?.sessionTimeoutSeconds ?? 600) * 1000;
|
|
22436
22482
|
const result = await adapter.complete(prompt, {
|
|
22437
|
-
...
|
|
22483
|
+
...resolvedModel !== undefined && { model: resolvedModel },
|
|
22438
22484
|
jsonMode: true,
|
|
22439
|
-
|
|
22485
|
+
config: naxConfig,
|
|
22440
22486
|
featureName: request.featureName,
|
|
22441
22487
|
storyId: request.storyId,
|
|
22442
22488
|
sessionRole: "auto",
|
|
22443
|
-
|
|
22489
|
+
timeoutMs
|
|
22444
22490
|
});
|
|
22445
22491
|
const output = typeof result === "string" ? result : result.output;
|
|
22446
22492
|
return this.parseResponse(output);
|
|
@@ -22598,9 +22644,9 @@ ${request.summary}
|
|
|
22598
22644
|
if (!this.rl) {
|
|
22599
22645
|
throw new Error("CLI plugin not initialized");
|
|
22600
22646
|
}
|
|
22601
|
-
const timeoutPromise = new Promise((
|
|
22647
|
+
const timeoutPromise = new Promise((resolve5) => {
|
|
22602
22648
|
setTimeout(() => {
|
|
22603
|
-
|
|
22649
|
+
resolve5({
|
|
22604
22650
|
requestId: request.id,
|
|
22605
22651
|
action: "skip",
|
|
22606
22652
|
respondedBy: "timeout",
|
|
@@ -22752,9 +22798,9 @@ ${request.summary}
|
|
|
22752
22798
|
if (!this.rl) {
|
|
22753
22799
|
throw new Error("CLI plugin not initialized");
|
|
22754
22800
|
}
|
|
22755
|
-
return new Promise((
|
|
22801
|
+
return new Promise((resolve5) => {
|
|
22756
22802
|
this.rl?.question(prompt, (answer) => {
|
|
22757
|
-
|
|
22803
|
+
resolve5(answer);
|
|
22758
22804
|
});
|
|
22759
22805
|
});
|
|
22760
22806
|
}
|
|
@@ -23186,7 +23232,7 @@ class WebhookInteractionPlugin {
|
|
|
23186
23232
|
this.pendingResponses.delete(requestId);
|
|
23187
23233
|
return early;
|
|
23188
23234
|
}
|
|
23189
|
-
return new Promise((
|
|
23235
|
+
return new Promise((resolve5) => {
|
|
23190
23236
|
const existingCallback = this.receiveCallbacks.get(requestId);
|
|
23191
23237
|
if (existingCallback) {
|
|
23192
23238
|
this.clearReceiveTimer(requestId);
|
|
@@ -23200,7 +23246,7 @@ class WebhookInteractionPlugin {
|
|
|
23200
23246
|
const timer = setTimeout(() => {
|
|
23201
23247
|
this.clearReceiveTimer(requestId);
|
|
23202
23248
|
this.receiveCallbacks.delete(requestId);
|
|
23203
|
-
|
|
23249
|
+
resolve5({
|
|
23204
23250
|
requestId,
|
|
23205
23251
|
action: "skip",
|
|
23206
23252
|
respondedBy: "timeout",
|
|
@@ -23211,7 +23257,7 @@ class WebhookInteractionPlugin {
|
|
|
23211
23257
|
this.receiveCallbacks.set(requestId, (response) => {
|
|
23212
23258
|
this.clearReceiveTimer(requestId);
|
|
23213
23259
|
this.receiveCallbacks.delete(requestId);
|
|
23214
|
-
|
|
23260
|
+
resolve5(response);
|
|
23215
23261
|
});
|
|
23216
23262
|
});
|
|
23217
23263
|
}
|
|
@@ -24578,8 +24624,9 @@ function getNextStory(prd, currentStoryId, maxRetries) {
|
|
|
24578
24624
|
return currentStory;
|
|
24579
24625
|
}
|
|
24580
24626
|
}
|
|
24627
|
+
const storyIds = new Set(prd.userStories.map((s) => s.id));
|
|
24581
24628
|
const completedIds = new Set(prd.userStories.filter((s) => s.passes || s.status === "passed" || s.status === "skipped").map((s) => s.id));
|
|
24582
|
-
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;
|
|
24629
|
+
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;
|
|
24583
24630
|
}
|
|
24584
24631
|
function isComplete(prd) {
|
|
24585
24632
|
return prd.userStories.every((s) => s.passes || s.status === "passed" || s.status === "skipped");
|
|
@@ -27379,7 +27426,7 @@ async function runSemanticReview(workdir, storyGitRef, story, semanticConfig, mo
|
|
|
27379
27426
|
storyId: story.id,
|
|
27380
27427
|
stage: "review",
|
|
27381
27428
|
stageConfig: reviewStageConfig,
|
|
27382
|
-
config: naxConfig,
|
|
27429
|
+
config: naxConfig ?? DEFAULT_CONFIG,
|
|
27383
27430
|
workdir,
|
|
27384
27431
|
featureName,
|
|
27385
27432
|
timeoutSeconds: naxConfig?.execution?.sessionTimeoutSeconds
|
|
@@ -27482,7 +27529,7 @@ ${formatFindings(debateBlocking)}`,
|
|
|
27482
27529
|
timeoutSeconds: semanticConfig.timeoutMs ? Math.ceil(semanticConfig.timeoutMs / 1000) : 3600,
|
|
27483
27530
|
modelTier: semanticConfig.modelTier,
|
|
27484
27531
|
modelDef: resolvedModelDef,
|
|
27485
|
-
config: naxConfig
|
|
27532
|
+
config: naxConfig ?? DEFAULT_CONFIG
|
|
27486
27533
|
});
|
|
27487
27534
|
runOutput = runResult.output;
|
|
27488
27535
|
runSucceeded = true;
|
|
@@ -27497,7 +27544,7 @@ ${formatFindings(debateBlocking)}`,
|
|
|
27497
27544
|
workdir,
|
|
27498
27545
|
timeoutMs: semanticConfig.timeoutMs,
|
|
27499
27546
|
modelTier: semanticConfig.modelTier,
|
|
27500
|
-
config: naxConfig
|
|
27547
|
+
config: naxConfig ?? DEFAULT_CONFIG
|
|
27501
27548
|
});
|
|
27502
27549
|
rawResponse = typeof completeResult === "string" ? completeResult : completeResult.output;
|
|
27503
27550
|
}
|
|
@@ -27603,6 +27650,7 @@ ${formatFindings(blockingFindings)}`;
|
|
|
27603
27650
|
var _semanticDeps, DIFF_CAP_BYTES = 51200;
|
|
27604
27651
|
var init_semantic = __esm(() => {
|
|
27605
27652
|
init_adapter();
|
|
27653
|
+
init_config();
|
|
27606
27654
|
init_debate();
|
|
27607
27655
|
init_logger2();
|
|
27608
27656
|
init_git();
|
|
@@ -28626,7 +28674,7 @@ var init_constitution = __esm(() => {
|
|
|
28626
28674
|
});
|
|
28627
28675
|
|
|
28628
28676
|
// src/pipeline/stages/constitution.ts
|
|
28629
|
-
import { dirname as
|
|
28677
|
+
import { dirname as dirname4 } from "path";
|
|
28630
28678
|
var constitutionStage;
|
|
28631
28679
|
var init_constitution2 = __esm(() => {
|
|
28632
28680
|
init_constitution();
|
|
@@ -28636,7 +28684,7 @@ var init_constitution2 = __esm(() => {
|
|
|
28636
28684
|
enabled: (ctx) => ctx.config.constitution.enabled,
|
|
28637
28685
|
async execute(ctx) {
|
|
28638
28686
|
const logger = getLogger();
|
|
28639
|
-
const ngentDir = ctx.featureDir ?
|
|
28687
|
+
const ngentDir = ctx.featureDir ? dirname4(dirname4(ctx.featureDir)) : `${ctx.workdir}/nax`;
|
|
28640
28688
|
const result = await loadConstitution(ngentDir, ctx.config.constitution);
|
|
28641
28689
|
if (result) {
|
|
28642
28690
|
ctx.constitution = result;
|
|
@@ -29498,13 +29546,14 @@ ${pkgContent.trim()}`;
|
|
|
29498
29546
|
}
|
|
29499
29547
|
}
|
|
29500
29548
|
function getAllReadyStories(prd) {
|
|
29549
|
+
const storyIds = new Set(prd.userStories.map((s) => s.id));
|
|
29501
29550
|
const completedIds = new Set(prd.userStories.filter((s) => s.passes || s.status === "skipped").map((s) => s.id));
|
|
29502
29551
|
const logger = getSafeLogger2();
|
|
29503
29552
|
logger?.debug("routing", "getAllReadyStories: completed set", {
|
|
29504
29553
|
completedIds: [...completedIds],
|
|
29505
29554
|
totalStories: prd.userStories.length
|
|
29506
29555
|
});
|
|
29507
|
-
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)));
|
|
29556
|
+
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)));
|
|
29508
29557
|
}
|
|
29509
29558
|
var CONTEXT_MAX_TOKENS = 1e5, CONTEXT_RESERVED_TOKENS = 1e4;
|
|
29510
29559
|
var init_story_context = __esm(() => {
|
|
@@ -29823,10 +29872,10 @@ async function executeWithTimeout(command, timeoutSeconds, env2, options) {
|
|
|
29823
29872
|
const timeoutMs = timeoutSeconds * 1000;
|
|
29824
29873
|
let timedOut = false;
|
|
29825
29874
|
const timer = { id: undefined };
|
|
29826
|
-
const timeoutPromise = new Promise((
|
|
29875
|
+
const timeoutPromise = new Promise((resolve7) => {
|
|
29827
29876
|
timer.id = setTimeout(() => {
|
|
29828
29877
|
timedOut = true;
|
|
29829
|
-
|
|
29878
|
+
resolve7();
|
|
29830
29879
|
}, timeoutMs);
|
|
29831
29880
|
});
|
|
29832
29881
|
const processPromise = proc.exited;
|
|
@@ -32644,7 +32693,7 @@ async function _defaultRunDebate(storyId, stageConfig, prompt, config2) {
|
|
|
32644
32693
|
if (resolved.length === 0) {
|
|
32645
32694
|
return { output: null, totalCostUsd: 0 };
|
|
32646
32695
|
}
|
|
32647
|
-
const timeoutMs = (config2
|
|
32696
|
+
const timeoutMs = (config2.execution?.sessionTimeoutSeconds ?? 600) * 1000;
|
|
32648
32697
|
const startMs = Date.now();
|
|
32649
32698
|
const proposalSettled = await Promise.allSettled(resolved.map(({ debater, adapter }) => adapter.complete(prompt, {
|
|
32650
32699
|
model: debater.model,
|
|
@@ -33122,16 +33171,16 @@ class AcceptanceStrategy {
|
|
|
33122
33171
|
}, timeoutMs);
|
|
33123
33172
|
const exitCode = await Promise.race([
|
|
33124
33173
|
proc.exited,
|
|
33125
|
-
new Promise((
|
|
33174
|
+
new Promise((resolve7) => setTimeout(() => resolve7(124), timeoutMs + 6000))
|
|
33126
33175
|
]);
|
|
33127
33176
|
clearTimeout(timeoutId);
|
|
33128
33177
|
const stdout = await Promise.race([
|
|
33129
33178
|
new Response(proc.stdout).text(),
|
|
33130
|
-
new Promise((
|
|
33179
|
+
new Promise((resolve7) => setTimeout(() => resolve7(""), 3000))
|
|
33131
33180
|
]);
|
|
33132
33181
|
const stderr = await Promise.race([
|
|
33133
33182
|
new Response(proc.stderr).text(),
|
|
33134
|
-
new Promise((
|
|
33183
|
+
new Promise((resolve7) => setTimeout(() => resolve7(""), 3000))
|
|
33135
33184
|
]);
|
|
33136
33185
|
const durationMs = Date.now() - start;
|
|
33137
33186
|
if (timedOut || exitCode === 124) {
|
|
@@ -34827,12 +34876,12 @@ var init_init_context = __esm(() => {
|
|
|
34827
34876
|
|
|
34828
34877
|
// src/utils/path-security.ts
|
|
34829
34878
|
import { realpathSync as realpathSync3 } from "fs";
|
|
34830
|
-
import { dirname as
|
|
34879
|
+
import { dirname as dirname5, isAbsolute as isAbsolute5, join as join32, normalize as normalize2, resolve as resolve7 } from "path";
|
|
34831
34880
|
function safeRealpathForComparison(p) {
|
|
34832
34881
|
try {
|
|
34833
34882
|
return realpathSync3(p);
|
|
34834
34883
|
} catch {
|
|
34835
|
-
const parent =
|
|
34884
|
+
const parent = dirname5(p);
|
|
34836
34885
|
if (parent === p)
|
|
34837
34886
|
return normalize2(p);
|
|
34838
34887
|
const resolvedParent = safeRealpathForComparison(parent);
|
|
@@ -34843,7 +34892,7 @@ function validateModulePath(modulePath, allowedRoots) {
|
|
|
34843
34892
|
if (!modulePath) {
|
|
34844
34893
|
return { valid: false, error: "Module path is empty" };
|
|
34845
34894
|
}
|
|
34846
|
-
const resolvedRoots = allowedRoots.map((r) => safeRealpathForComparison(
|
|
34895
|
+
const resolvedRoots = allowedRoots.map((r) => safeRealpathForComparison(resolve7(r)));
|
|
34847
34896
|
if (isAbsolute5(modulePath)) {
|
|
34848
34897
|
const normalized = normalize2(modulePath);
|
|
34849
34898
|
const resolved = safeRealpathForComparison(normalized);
|
|
@@ -34853,8 +34902,8 @@ function validateModulePath(modulePath, allowedRoots) {
|
|
|
34853
34902
|
}
|
|
34854
34903
|
} else {
|
|
34855
34904
|
for (let i = 0;i < allowedRoots.length; i++) {
|
|
34856
|
-
const originalRoot =
|
|
34857
|
-
const absoluteInput =
|
|
34905
|
+
const originalRoot = resolve7(allowedRoots[i]);
|
|
34906
|
+
const absoluteInput = resolve7(join32(originalRoot, modulePath));
|
|
34858
34907
|
const resolved = safeRealpathForComparison(absoluteInput);
|
|
34859
34908
|
const resolvedRoot = resolvedRoots[i];
|
|
34860
34909
|
if (resolved.startsWith(`${resolvedRoot}/`) || resolved === resolvedRoot) {
|
|
@@ -35602,7 +35651,7 @@ var package_default;
|
|
|
35602
35651
|
var init_package = __esm(() => {
|
|
35603
35652
|
package_default = {
|
|
35604
35653
|
name: "@nathapp/nax",
|
|
35605
|
-
version: "0.58.
|
|
35654
|
+
version: "0.58.4",
|
|
35606
35655
|
description: "AI Coding Agent Orchestrator \u2014 loops until done",
|
|
35607
35656
|
type: "module",
|
|
35608
35657
|
bin: {
|
|
@@ -35682,8 +35731,8 @@ var init_version = __esm(() => {
|
|
|
35682
35731
|
NAX_VERSION = package_default.version;
|
|
35683
35732
|
NAX_COMMIT = (() => {
|
|
35684
35733
|
try {
|
|
35685
|
-
if (/^[0-9a-f]{6,10}$/.test("
|
|
35686
|
-
return "
|
|
35734
|
+
if (/^[0-9a-f]{6,10}$/.test("05836706"))
|
|
35735
|
+
return "05836706";
|
|
35687
35736
|
} catch {}
|
|
35688
35737
|
try {
|
|
35689
35738
|
const result = Bun.spawnSync(["git", "rev-parse", "--short", "HEAD"], {
|
|
@@ -39857,7 +39906,7 @@ var init_project = __esm(() => {
|
|
|
39857
39906
|
|
|
39858
39907
|
// src/execution/status-file.ts
|
|
39859
39908
|
import { rename, unlink as unlink3 } from "fs/promises";
|
|
39860
|
-
import { resolve as
|
|
39909
|
+
import { resolve as resolve9 } from "path";
|
|
39861
39910
|
function countProgress(prd) {
|
|
39862
39911
|
const stories = prd.userStories;
|
|
39863
39912
|
const passed = stories.filter((s) => s.status === "passed").length;
|
|
@@ -39902,7 +39951,7 @@ function buildStatusSnapshot(state) {
|
|
|
39902
39951
|
return snapshot;
|
|
39903
39952
|
}
|
|
39904
39953
|
async function writeStatusFile(filePath, status) {
|
|
39905
|
-
const resolvedPath =
|
|
39954
|
+
const resolvedPath = resolve9(filePath);
|
|
39906
39955
|
if (filePath.includes("../") || filePath.includes("..\\")) {
|
|
39907
39956
|
throw new Error("Invalid status file path: path traversal detected");
|
|
39908
39957
|
}
|
|
@@ -40985,14 +41034,14 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
40985
41034
|
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. ");
|
|
40986
41035
|
actScopeDepth = prevActScopeDepth;
|
|
40987
41036
|
}
|
|
40988
|
-
function recursivelyFlushAsyncActWork(returnValue,
|
|
41037
|
+
function recursivelyFlushAsyncActWork(returnValue, resolve10, reject) {
|
|
40989
41038
|
var queue = ReactSharedInternals.actQueue;
|
|
40990
41039
|
if (queue !== null)
|
|
40991
41040
|
if (queue.length !== 0)
|
|
40992
41041
|
try {
|
|
40993
41042
|
flushActQueue(queue);
|
|
40994
41043
|
enqueueTask(function() {
|
|
40995
|
-
return recursivelyFlushAsyncActWork(returnValue,
|
|
41044
|
+
return recursivelyFlushAsyncActWork(returnValue, resolve10, reject);
|
|
40996
41045
|
});
|
|
40997
41046
|
return;
|
|
40998
41047
|
} catch (error48) {
|
|
@@ -41000,7 +41049,7 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
41000
41049
|
}
|
|
41001
41050
|
else
|
|
41002
41051
|
ReactSharedInternals.actQueue = null;
|
|
41003
|
-
0 < ReactSharedInternals.thrownErrors.length ? (queue = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, reject(queue)) :
|
|
41052
|
+
0 < ReactSharedInternals.thrownErrors.length ? (queue = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, reject(queue)) : resolve10(returnValue);
|
|
41004
41053
|
}
|
|
41005
41054
|
function flushActQueue(queue) {
|
|
41006
41055
|
if (!isFlushing) {
|
|
@@ -41176,14 +41225,14 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
41176
41225
|
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 () => ...);"));
|
|
41177
41226
|
});
|
|
41178
41227
|
return {
|
|
41179
|
-
then: function(
|
|
41228
|
+
then: function(resolve10, reject) {
|
|
41180
41229
|
didAwaitActCall = true;
|
|
41181
41230
|
thenable.then(function(returnValue) {
|
|
41182
41231
|
popActScope(prevActQueue, prevActScopeDepth);
|
|
41183
41232
|
if (prevActScopeDepth === 0) {
|
|
41184
41233
|
try {
|
|
41185
41234
|
flushActQueue(queue), enqueueTask(function() {
|
|
41186
|
-
return recursivelyFlushAsyncActWork(returnValue,
|
|
41235
|
+
return recursivelyFlushAsyncActWork(returnValue, resolve10, reject);
|
|
41187
41236
|
});
|
|
41188
41237
|
} catch (error$0) {
|
|
41189
41238
|
ReactSharedInternals.thrownErrors.push(error$0);
|
|
@@ -41194,7 +41243,7 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
41194
41243
|
reject(_thrownError);
|
|
41195
41244
|
}
|
|
41196
41245
|
} else
|
|
41197
|
-
|
|
41246
|
+
resolve10(returnValue);
|
|
41198
41247
|
}, function(error48) {
|
|
41199
41248
|
popActScope(prevActQueue, prevActScopeDepth);
|
|
41200
41249
|
0 < ReactSharedInternals.thrownErrors.length ? (error48 = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, reject(error48)) : reject(error48);
|
|
@@ -41210,11 +41259,11 @@ See https://react.dev/link/invalid-hook-call for tips about how to debug and fix
|
|
|
41210
41259
|
if (0 < ReactSharedInternals.thrownErrors.length)
|
|
41211
41260
|
throw callback = aggregateErrors(ReactSharedInternals.thrownErrors), ReactSharedInternals.thrownErrors.length = 0, callback;
|
|
41212
41261
|
return {
|
|
41213
|
-
then: function(
|
|
41262
|
+
then: function(resolve10, reject) {
|
|
41214
41263
|
didAwaitActCall = true;
|
|
41215
41264
|
prevActScopeDepth === 0 ? (ReactSharedInternals.actQueue = queue, enqueueTask(function() {
|
|
41216
|
-
return recursivelyFlushAsyncActWork(returnValue$jscomp$0,
|
|
41217
|
-
})) :
|
|
41265
|
+
return recursivelyFlushAsyncActWork(returnValue$jscomp$0, resolve10, reject);
|
|
41266
|
+
})) : resolve10(returnValue$jscomp$0);
|
|
41218
41267
|
}
|
|
41219
41268
|
};
|
|
41220
41269
|
};
|
|
@@ -44056,8 +44105,8 @@ It can also happen if the client has a browser extension installed which messes
|
|
|
44056
44105
|
currentEntangledActionThenable = {
|
|
44057
44106
|
status: "pending",
|
|
44058
44107
|
value: undefined,
|
|
44059
|
-
then: function(
|
|
44060
|
-
entangledListeners.push(
|
|
44108
|
+
then: function(resolve10) {
|
|
44109
|
+
entangledListeners.push(resolve10);
|
|
44061
44110
|
}
|
|
44062
44111
|
};
|
|
44063
44112
|
}
|
|
@@ -44081,8 +44130,8 @@ It can also happen if the client has a browser extension installed which messes
|
|
|
44081
44130
|
status: "pending",
|
|
44082
44131
|
value: null,
|
|
44083
44132
|
reason: null,
|
|
44084
|
-
then: function(
|
|
44085
|
-
listeners.push(
|
|
44133
|
+
then: function(resolve10) {
|
|
44134
|
+
listeners.push(resolve10);
|
|
44086
44135
|
}
|
|
44087
44136
|
};
|
|
44088
44137
|
thenable.then(function() {
|
|
@@ -72607,13 +72656,13 @@ function createCliInteractionBridge() {
|
|
|
72607
72656
|
process.stdout.write(`
|
|
72608
72657
|
\uD83E\uDD16 Agent: ${text}
|
|
72609
72658
|
You: `);
|
|
72610
|
-
return new Promise((
|
|
72659
|
+
return new Promise((resolve5) => {
|
|
72611
72660
|
const rl = createInterface2({ input: process.stdin, terminal: false });
|
|
72612
72661
|
rl.once("line", (line) => {
|
|
72613
72662
|
rl.close();
|
|
72614
|
-
|
|
72663
|
+
resolve5(line.trim());
|
|
72615
72664
|
});
|
|
72616
|
-
rl.once("close", () =>
|
|
72665
|
+
rl.once("close", () => resolve5(""));
|
|
72617
72666
|
});
|
|
72618
72667
|
}
|
|
72619
72668
|
};
|
|
@@ -73118,20 +73167,20 @@ async function displayModelEfficiency(workdir) {
|
|
|
73118
73167
|
// src/cli/status-features.ts
|
|
73119
73168
|
init_source();
|
|
73120
73169
|
import { existsSync as existsSync15, readdirSync as readdirSync4 } from "fs";
|
|
73121
|
-
import { join as join14, resolve as
|
|
73170
|
+
import { join as join14, resolve as resolve6 } from "path";
|
|
73122
73171
|
|
|
73123
73172
|
// src/commands/common.ts
|
|
73124
73173
|
init_path_security();
|
|
73125
73174
|
init_errors();
|
|
73126
73175
|
import { existsSync as existsSync14, readdirSync as readdirSync3, realpathSync as realpathSync2 } from "fs";
|
|
73127
|
-
import { join as join12, resolve as
|
|
73176
|
+
import { join as join12, resolve as resolve5 } from "path";
|
|
73128
73177
|
function resolveProject(options = {}) {
|
|
73129
73178
|
const { dir, feature } = options;
|
|
73130
73179
|
let projectRoot;
|
|
73131
73180
|
let naxDir;
|
|
73132
73181
|
let configPath;
|
|
73133
73182
|
if (dir) {
|
|
73134
|
-
projectRoot = realpathSync2(
|
|
73183
|
+
projectRoot = realpathSync2(resolve5(dir));
|
|
73135
73184
|
naxDir = join12(projectRoot, ".nax");
|
|
73136
73185
|
if (!existsSync14(naxDir)) {
|
|
73137
73186
|
throw new NaxError(`Directory does not contain a nax project: ${projectRoot}
|
|
@@ -73184,7 +73233,7 @@ No features found in this project.`;
|
|
|
73184
73233
|
};
|
|
73185
73234
|
}
|
|
73186
73235
|
function findProjectRoot(startDir) {
|
|
73187
|
-
let current =
|
|
73236
|
+
let current = resolve5(startDir);
|
|
73188
73237
|
let depth = 0;
|
|
73189
73238
|
while (depth < MAX_DIRECTORY_DEPTH) {
|
|
73190
73239
|
const naxDir = join12(current, ".nax");
|
|
@@ -73501,7 +73550,7 @@ async function displayFeatureStatus(options = {}) {
|
|
|
73501
73550
|
if (options.feature) {
|
|
73502
73551
|
let featureDir;
|
|
73503
73552
|
if (options.dir) {
|
|
73504
|
-
featureDir = join14(
|
|
73553
|
+
featureDir = join14(resolve6(options.dir), ".nax", "features", options.feature);
|
|
73505
73554
|
} else {
|
|
73506
73555
|
const resolved = resolveProject({ feature: options.feature });
|
|
73507
73556
|
if (!resolved.featureDir) {
|
|
@@ -81627,8 +81676,8 @@ class Ink {
|
|
|
81627
81676
|
}
|
|
81628
81677
|
}
|
|
81629
81678
|
async waitUntilExit() {
|
|
81630
|
-
this.exitPromise ||= new Promise((
|
|
81631
|
-
this.resolveExitPromise =
|
|
81679
|
+
this.exitPromise ||= new Promise((resolve10, reject2) => {
|
|
81680
|
+
this.resolveExitPromise = resolve10;
|
|
81632
81681
|
this.rejectExitPromise = reject2;
|
|
81633
81682
|
});
|
|
81634
81683
|
if (!this.beforeExitHandler) {
|
|
@@ -83441,7 +83490,7 @@ async function promptForConfirmation(question) {
|
|
|
83441
83490
|
if (!process.stdin.isTTY) {
|
|
83442
83491
|
return true;
|
|
83443
83492
|
}
|
|
83444
|
-
return new Promise((
|
|
83493
|
+
return new Promise((resolve10) => {
|
|
83445
83494
|
process.stdout.write(source_default.bold(`${question} [Y/n] `));
|
|
83446
83495
|
process.stdin.setRawMode(true);
|
|
83447
83496
|
process.stdin.resume();
|
|
@@ -83454,9 +83503,9 @@ async function promptForConfirmation(question) {
|
|
|
83454
83503
|
process.stdout.write(`
|
|
83455
83504
|
`);
|
|
83456
83505
|
if (answer === "n") {
|
|
83457
|
-
|
|
83506
|
+
resolve10(false);
|
|
83458
83507
|
} else {
|
|
83459
|
-
|
|
83508
|
+
resolve10(true);
|
|
83460
83509
|
}
|
|
83461
83510
|
};
|
|
83462
83511
|
process.stdin.on("data", handler);
|