@nathapp/nax 0.56.2 → 0.56.3
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 +63 -45
- package/package.json +1 -1
package/dist/nax.js
CHANGED
|
@@ -3663,7 +3663,18 @@ var init_env = __esm(() => {
|
|
|
3663
3663
|
init_logger2();
|
|
3664
3664
|
ESSENTIAL_VARS = ["PATH", "TMPDIR", "NODE_ENV", "USER", "LOGNAME"];
|
|
3665
3665
|
API_KEY_VARS = ["ANTHROPIC_API_KEY", "OPENAI_API_KEY", "GEMINI_API_KEY", "GOOGLE_API_KEY", "CLAUDE_API_KEY"];
|
|
3666
|
-
ALLOWED_PREFIXES = [
|
|
3666
|
+
ALLOWED_PREFIXES = [
|
|
3667
|
+
"CLAUDE_",
|
|
3668
|
+
"NAX_",
|
|
3669
|
+
"CLAW_",
|
|
3670
|
+
"TURBO_",
|
|
3671
|
+
"ACPX_",
|
|
3672
|
+
"CODEX_",
|
|
3673
|
+
"GEMINI_",
|
|
3674
|
+
"ANTHROPIC_",
|
|
3675
|
+
"OPENCODE_",
|
|
3676
|
+
"MINIMAX_"
|
|
3677
|
+
];
|
|
3667
3678
|
});
|
|
3668
3679
|
|
|
3669
3680
|
// src/agents/cost/pricing.ts
|
|
@@ -22056,7 +22067,7 @@ var package_default;
|
|
|
22056
22067
|
var init_package = __esm(() => {
|
|
22057
22068
|
package_default = {
|
|
22058
22069
|
name: "@nathapp/nax",
|
|
22059
|
-
version: "0.56.
|
|
22070
|
+
version: "0.56.3",
|
|
22060
22071
|
description: "AI Coding Agent Orchestrator \u2014 loops until done",
|
|
22061
22072
|
type: "module",
|
|
22062
22073
|
bin: {
|
|
@@ -22135,8 +22146,8 @@ var init_version = __esm(() => {
|
|
|
22135
22146
|
NAX_VERSION = package_default.version;
|
|
22136
22147
|
NAX_COMMIT = (() => {
|
|
22137
22148
|
try {
|
|
22138
|
-
if (/^[0-9a-f]{6,10}$/.test("
|
|
22139
|
-
return "
|
|
22149
|
+
if (/^[0-9a-f]{6,10}$/.test("52dcc35f"))
|
|
22150
|
+
return "52dcc35f";
|
|
22140
22151
|
} catch {}
|
|
22141
22152
|
try {
|
|
22142
22153
|
const result = Bun.spawnSync(["git", "rev-parse", "--short", "HEAD"], {
|
|
@@ -27127,17 +27138,15 @@ var init_autofix = __esm(() => {
|
|
|
27127
27138
|
});
|
|
27128
27139
|
|
|
27129
27140
|
// src/execution/progress.ts
|
|
27130
|
-
import {
|
|
27141
|
+
import { appendFile as appendFile2, mkdir } from "fs/promises";
|
|
27131
27142
|
import { join as join18 } from "path";
|
|
27132
27143
|
async function appendProgress(featureDir, storyId, status, message) {
|
|
27133
|
-
|
|
27144
|
+
await mkdir(featureDir, { recursive: true });
|
|
27134
27145
|
const progressPath = join18(featureDir, "progress.txt");
|
|
27135
27146
|
const timestamp = new Date().toISOString();
|
|
27136
27147
|
const entry = `[${timestamp}] ${storyId} \u2014 ${status.toUpperCase()} \u2014 ${message}
|
|
27137
27148
|
`;
|
|
27138
|
-
|
|
27139
|
-
const existing = await file3.exists() ? await file3.text() : "";
|
|
27140
|
-
await Bun.write(progressPath, existing + entry);
|
|
27149
|
+
await appendFile2(progressPath, entry);
|
|
27141
27150
|
}
|
|
27142
27151
|
var init_progress = () => {};
|
|
27143
27152
|
|
|
@@ -32481,7 +32490,7 @@ __export(exports_init_context, {
|
|
|
32481
32490
|
_initContextDeps: () => _initContextDeps
|
|
32482
32491
|
});
|
|
32483
32492
|
import { existsSync as existsSync24 } from "fs";
|
|
32484
|
-
import { mkdir } from "fs/promises";
|
|
32493
|
+
import { mkdir as mkdir2 } from "fs/promises";
|
|
32485
32494
|
import { basename as basename3, join as join30 } from "path";
|
|
32486
32495
|
async function findFiles(dir, maxFiles = 200) {
|
|
32487
32496
|
try {
|
|
@@ -32725,7 +32734,7 @@ async function initPackage(repoRoot, packagePath, force = false) {
|
|
|
32725
32734
|
return;
|
|
32726
32735
|
}
|
|
32727
32736
|
if (!existsSync24(naxDir)) {
|
|
32728
|
-
await
|
|
32737
|
+
await mkdir2(naxDir, { recursive: true });
|
|
32729
32738
|
}
|
|
32730
32739
|
const content = generatePackageContextTemplate(packagePath);
|
|
32731
32740
|
await Bun.write(contextPath, content);
|
|
@@ -32740,7 +32749,7 @@ async function initContext(projectRoot, options = {}) {
|
|
|
32740
32749
|
return;
|
|
32741
32750
|
}
|
|
32742
32751
|
if (!existsSync24(naxDir)) {
|
|
32743
|
-
await
|
|
32752
|
+
await mkdir2(naxDir, { recursive: true });
|
|
32744
32753
|
}
|
|
32745
32754
|
const scan = await scanProject(projectRoot);
|
|
32746
32755
|
let content;
|
|
@@ -34443,7 +34452,7 @@ var init_headless_formatter = __esm(() => {
|
|
|
34443
34452
|
});
|
|
34444
34453
|
|
|
34445
34454
|
// src/pipeline/subscribers/events-writer.ts
|
|
34446
|
-
import { appendFile as
|
|
34455
|
+
import { appendFile as appendFile3, mkdir as mkdir3 } from "fs/promises";
|
|
34447
34456
|
import { homedir as homedir5 } from "os";
|
|
34448
34457
|
import { basename as basename6, join as join47 } from "path";
|
|
34449
34458
|
function wireEventsWriter(bus, feature, runId, workdir) {
|
|
@@ -34456,10 +34465,10 @@ function wireEventsWriter(bus, feature, runId, workdir) {
|
|
|
34456
34465
|
return (async () => {
|
|
34457
34466
|
try {
|
|
34458
34467
|
if (!dirReady) {
|
|
34459
|
-
await
|
|
34468
|
+
await mkdir3(eventsDir, { recursive: true });
|
|
34460
34469
|
dirReady = true;
|
|
34461
34470
|
}
|
|
34462
|
-
await
|
|
34471
|
+
await appendFile3(eventsFile, `${JSON.stringify(line)}
|
|
34463
34472
|
`);
|
|
34464
34473
|
} catch (err) {
|
|
34465
34474
|
logger?.warn("events-writer", "Failed to write event line (non-fatal)", {
|
|
@@ -34629,7 +34638,7 @@ var init_interaction2 = __esm(() => {
|
|
|
34629
34638
|
});
|
|
34630
34639
|
|
|
34631
34640
|
// src/pipeline/subscribers/registry.ts
|
|
34632
|
-
import { mkdir as
|
|
34641
|
+
import { mkdir as mkdir4, writeFile } from "fs/promises";
|
|
34633
34642
|
import { homedir as homedir6 } from "os";
|
|
34634
34643
|
import { basename as basename7, join as join48 } from "path";
|
|
34635
34644
|
function wireRegistry(bus, feature, runId, workdir) {
|
|
@@ -34640,7 +34649,7 @@ function wireRegistry(bus, feature, runId, workdir) {
|
|
|
34640
34649
|
const unsub = bus.on("run:started", (_ev) => {
|
|
34641
34650
|
return (async () => {
|
|
34642
34651
|
try {
|
|
34643
|
-
await
|
|
34652
|
+
await mkdir4(runDir, { recursive: true });
|
|
34644
34653
|
const meta3 = {
|
|
34645
34654
|
runId,
|
|
34646
34655
|
project,
|
|
@@ -35592,7 +35601,7 @@ __export(exports_manager, {
|
|
|
35592
35601
|
WorktreeManager: () => WorktreeManager
|
|
35593
35602
|
});
|
|
35594
35603
|
import { existsSync as existsSync32, symlinkSync } from "fs";
|
|
35595
|
-
import { mkdir as
|
|
35604
|
+
import { mkdir as mkdir5 } from "fs/promises";
|
|
35596
35605
|
import { join as join50 } from "path";
|
|
35597
35606
|
|
|
35598
35607
|
class WorktreeManager {
|
|
@@ -35601,7 +35610,7 @@ class WorktreeManager {
|
|
|
35601
35610
|
const infoDir = join50(projectRoot, ".git", "info");
|
|
35602
35611
|
const excludePath = join50(infoDir, "exclude");
|
|
35603
35612
|
try {
|
|
35604
|
-
await
|
|
35613
|
+
await mkdir5(infoDir, { recursive: true });
|
|
35605
35614
|
let existing = "";
|
|
35606
35615
|
if (existsSync32(excludePath)) {
|
|
35607
35616
|
existing = await Bun.file(excludePath).text();
|
|
@@ -36782,6 +36791,7 @@ class StatusWriter {
|
|
|
36782
36791
|
_prd = null;
|
|
36783
36792
|
_currentStory = null;
|
|
36784
36793
|
_consecutiveWriteFailures = 0;
|
|
36794
|
+
_mutex = Promise.resolve();
|
|
36785
36795
|
constructor(statusFile, config2, ctx) {
|
|
36786
36796
|
this.statusFile = statusFile;
|
|
36787
36797
|
this.costLimit = config2.execution.costLimit === Number.POSITIVE_INFINITY ? null : config2.execution.costLimit;
|
|
@@ -36817,6 +36827,11 @@ class StatusWriter {
|
|
|
36817
36827
|
async update(totalCost, iterations, overrides = {}) {
|
|
36818
36828
|
if (!this._prd)
|
|
36819
36829
|
return;
|
|
36830
|
+
const write = this._doUpdate(totalCost, iterations, overrides);
|
|
36831
|
+
this._mutex = this._mutex.then(() => write).catch(() => write);
|
|
36832
|
+
return this._mutex;
|
|
36833
|
+
}
|
|
36834
|
+
async _doUpdate(totalCost, iterations, overrides) {
|
|
36820
36835
|
const safeLogger = getSafeLogger();
|
|
36821
36836
|
try {
|
|
36822
36837
|
const base = this.getSnapshot(totalCost, iterations);
|
|
@@ -36841,20 +36856,23 @@ class StatusWriter {
|
|
|
36841
36856
|
return;
|
|
36842
36857
|
const safeLogger = getSafeLogger();
|
|
36843
36858
|
const featureStatusPath = join52(featureDir, "status.json");
|
|
36844
|
-
|
|
36845
|
-
|
|
36846
|
-
|
|
36847
|
-
|
|
36859
|
+
const write = async () => {
|
|
36860
|
+
try {
|
|
36861
|
+
const base = this.getSnapshot(totalCost, iterations);
|
|
36862
|
+
if (!base)
|
|
36863
|
+
throw new Error("Failed to get snapshot");
|
|
36864
|
+
const state = { ...base, ...overrides };
|
|
36865
|
+
await writeStatusFile(featureStatusPath, buildStatusSnapshot(state));
|
|
36866
|
+
safeLogger?.debug("status-file", "Feature status written", { path: featureStatusPath });
|
|
36867
|
+
} catch (err) {
|
|
36868
|
+
safeLogger?.warn("status-file", "Failed to write feature status file (non-fatal)", {
|
|
36869
|
+
path: featureStatusPath,
|
|
36870
|
+
error: err.message
|
|
36871
|
+
});
|
|
36848
36872
|
}
|
|
36849
|
-
|
|
36850
|
-
|
|
36851
|
-
|
|
36852
|
-
} catch (err) {
|
|
36853
|
-
safeLogger?.warn("status-file", "Failed to write feature status file (non-fatal)", {
|
|
36854
|
-
path: featureStatusPath,
|
|
36855
|
-
error: err.message
|
|
36856
|
-
});
|
|
36857
|
-
}
|
|
36873
|
+
};
|
|
36874
|
+
this._mutex = this._mutex.then(write).catch(() => write());
|
|
36875
|
+
return this._mutex;
|
|
36858
36876
|
}
|
|
36859
36877
|
}
|
|
36860
36878
|
var init_status_writer = __esm(() => {
|
|
@@ -36953,7 +36971,7 @@ var exports_precheck_runner = {};
|
|
|
36953
36971
|
__export(exports_precheck_runner, {
|
|
36954
36972
|
runPrecheckValidation: () => runPrecheckValidation
|
|
36955
36973
|
});
|
|
36956
|
-
import { mkdirSync as
|
|
36974
|
+
import { mkdirSync as mkdirSync4 } from "fs";
|
|
36957
36975
|
import path17 from "path";
|
|
36958
36976
|
async function runPrecheckValidation(ctx) {
|
|
36959
36977
|
const logger = getSafeLogger();
|
|
@@ -36968,7 +36986,7 @@ async function runPrecheckValidation(ctx) {
|
|
|
36968
36986
|
format: "human"
|
|
36969
36987
|
});
|
|
36970
36988
|
if (ctx.logFilePath) {
|
|
36971
|
-
|
|
36989
|
+
mkdirSync4(path17.dirname(ctx.logFilePath), { recursive: true });
|
|
36972
36990
|
const precheckLog = {
|
|
36973
36991
|
type: "precheck",
|
|
36974
36992
|
timestamp: new Date().toISOString(),
|
|
@@ -68274,7 +68292,7 @@ var require_jsx_dev_runtime = __commonJS((exports, module) => {
|
|
|
68274
68292
|
|
|
68275
68293
|
// bin/nax.ts
|
|
68276
68294
|
init_source();
|
|
68277
|
-
import { existsSync as existsSync34, mkdirSync as
|
|
68295
|
+
import { existsSync as existsSync34, mkdirSync as mkdirSync5 } from "fs";
|
|
68278
68296
|
import { homedir as homedir8 } from "os";
|
|
68279
68297
|
import { join as join55 } from "path";
|
|
68280
68298
|
|
|
@@ -70683,7 +70701,7 @@ async function runsShowCommand(options) {
|
|
|
70683
70701
|
}
|
|
70684
70702
|
// src/cli/prompts-main.ts
|
|
70685
70703
|
init_logger2();
|
|
70686
|
-
import { existsSync as existsSync22, mkdirSync as
|
|
70704
|
+
import { existsSync as existsSync22, mkdirSync as mkdirSync2 } from "fs";
|
|
70687
70705
|
import { join as join28 } from "path";
|
|
70688
70706
|
|
|
70689
70707
|
// src/pipeline/index.ts
|
|
@@ -70823,7 +70841,7 @@ async function promptsCommand(options) {
|
|
|
70823
70841
|
throw new Error(storyId ? `Story "${storyId}" not found in feature "${feature}"` : `No stories found in feature "${feature}"`);
|
|
70824
70842
|
}
|
|
70825
70843
|
if (outputDir) {
|
|
70826
|
-
|
|
70844
|
+
mkdirSync2(outputDir, { recursive: true });
|
|
70827
70845
|
}
|
|
70828
70846
|
logger.info("cli", "Assembling prompts", {
|
|
70829
70847
|
feature,
|
|
@@ -70903,7 +70921,7 @@ ${"=".repeat(80)}`);
|
|
|
70903
70921
|
return processedStories;
|
|
70904
70922
|
}
|
|
70905
70923
|
// src/cli/prompts-init.ts
|
|
70906
|
-
import { existsSync as existsSync23, mkdirSync as
|
|
70924
|
+
import { existsSync as existsSync23, mkdirSync as mkdirSync3 } from "fs";
|
|
70907
70925
|
import { join as join29 } from "path";
|
|
70908
70926
|
var TEMPLATE_ROLES = [
|
|
70909
70927
|
{ file: "test-writer.md", role: "test-writer" },
|
|
@@ -70929,7 +70947,7 @@ var TEMPLATE_HEADER = `<!--
|
|
|
70929
70947
|
async function promptsInitCommand(options) {
|
|
70930
70948
|
const { workdir, force = false, autoWireConfig = true } = options;
|
|
70931
70949
|
const templatesDir = join29(workdir, ".nax", "templates");
|
|
70932
|
-
|
|
70950
|
+
mkdirSync3(templatesDir, { recursive: true });
|
|
70933
70951
|
const existingFiles = TEMPLATE_ROLES.map((t) => t.file).filter((f) => existsSync23(join29(templatesDir, f)));
|
|
70934
70952
|
if (existingFiles.length > 0 && !force) {
|
|
70935
70953
|
console.warn(`[WARN] nax/templates/ already contains files: ${existingFiles.join(", ")}. No files overwritten.
|
|
@@ -80398,8 +80416,8 @@ Next: nax generate --package ${options.package}`));
|
|
|
80398
80416
|
console.log(source_default.yellow("nax already initialized. Use --force to overwrite."));
|
|
80399
80417
|
return;
|
|
80400
80418
|
}
|
|
80401
|
-
|
|
80402
|
-
|
|
80419
|
+
mkdirSync5(join55(naxDir, "features"), { recursive: true });
|
|
80420
|
+
mkdirSync5(join55(naxDir, "hooks"), { recursive: true });
|
|
80403
80421
|
await Bun.write(join55(naxDir, "config.json"), JSON.stringify(DEFAULT_CONFIG, null, 2));
|
|
80404
80422
|
await Bun.write(join55(naxDir, "hooks.json"), JSON.stringify({
|
|
80405
80423
|
hooks: {
|
|
@@ -80564,7 +80582,7 @@ program2.command("run").description("Run the orchestration loop for a feature").
|
|
|
80564
80582
|
}
|
|
80565
80583
|
try {
|
|
80566
80584
|
const planLogDir = join55(featureDir, "plan");
|
|
80567
|
-
|
|
80585
|
+
mkdirSync5(planLogDir, { recursive: true });
|
|
80568
80586
|
const planLogId = new Date().toISOString().replace(/:/g, "-").replace(/\..+/, "");
|
|
80569
80587
|
const planLogPath = join55(planLogDir, `${planLogId}.jsonl`);
|
|
80570
80588
|
initLogger({ level: "info", filePath: planLogPath, useChalk: false, headless: true });
|
|
@@ -80611,7 +80629,7 @@ program2.command("run").description("Run the orchestration loop for a feature").
|
|
|
80611
80629
|
}
|
|
80612
80630
|
resetLogger();
|
|
80613
80631
|
const runsDir = join55(featureDir, "runs");
|
|
80614
|
-
|
|
80632
|
+
mkdirSync5(runsDir, { recursive: true });
|
|
80615
80633
|
const runId = new Date().toISOString().replace(/:/g, "-").replace(/\..+/, "");
|
|
80616
80634
|
const logFilePath = join55(runsDir, `${runId}.jsonl`);
|
|
80617
80635
|
const isTTY = process.stdout.isTTY ?? false;
|
|
@@ -80717,7 +80735,7 @@ features.command("create <name>").description("Create a new feature").option("-d
|
|
|
80717
80735
|
process.exit(1);
|
|
80718
80736
|
}
|
|
80719
80737
|
const featureDir = join55(naxDir, "features", name);
|
|
80720
|
-
|
|
80738
|
+
mkdirSync5(featureDir, { recursive: true });
|
|
80721
80739
|
await Bun.write(join55(featureDir, "spec.md"), `# Feature: ${name}
|
|
80722
80740
|
|
|
80723
80741
|
## Overview
|
|
@@ -80824,7 +80842,7 @@ Use: nax plan -f <feature> --from <spec>`));
|
|
|
80824
80842
|
}
|
|
80825
80843
|
const config2 = await loadConfig(workdir);
|
|
80826
80844
|
const featureLogDir = join55(naxDir, "features", options.feature, "plan");
|
|
80827
|
-
|
|
80845
|
+
mkdirSync5(featureLogDir, { recursive: true });
|
|
80828
80846
|
const planLogId = new Date().toISOString().replace(/:/g, "-").replace(/\..+/, "");
|
|
80829
80847
|
const planLogPath = join55(featureLogDir, `${planLogId}.jsonl`);
|
|
80830
80848
|
initLogger({ level: "info", filePath: planLogPath, useChalk: false, headless: true });
|