@nathapp/nax 0.40.1 → 0.42.0
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/README.md +1 -0
- package/bin/nax.ts +130 -11
- package/dist/nax.js +1520 -424
- package/package.json +8 -7
- package/src/acceptance/fix-generator.ts +4 -35
- package/src/acceptance/generator.ts +4 -27
- package/src/agents/acp/adapter.ts +642 -0
- package/src/agents/acp/cost.ts +79 -0
- package/src/agents/acp/index.ts +9 -0
- package/src/agents/acp/interaction-bridge.ts +126 -0
- package/src/agents/acp/parser.ts +166 -0
- package/src/agents/acp/spawn-client.ts +309 -0
- package/src/agents/acp/types.ts +22 -0
- package/src/agents/claude-complete.ts +3 -3
- package/src/agents/claude.ts +12 -2
- package/src/agents/registry.ts +83 -0
- package/src/agents/types-extended.ts +23 -0
- package/src/agents/types.ts +17 -0
- package/src/analyze/scanner.ts +16 -20
- package/src/cli/analyze.ts +6 -2
- package/src/cli/plan.ts +218 -129
- package/src/commands/precheck.ts +1 -1
- package/src/config/defaults.ts +1 -0
- package/src/config/runtime-types.ts +10 -0
- package/src/config/schema.ts +1 -0
- package/src/config/schemas.ts +6 -0
- package/src/config/types.ts +1 -0
- package/src/execution/executor-types.ts +6 -0
- package/src/execution/iteration-runner.ts +2 -0
- package/src/execution/lifecycle/acceptance-loop.ts +5 -2
- package/src/execution/lifecycle/run-initialization.ts +16 -4
- package/src/execution/lifecycle/run-setup.ts +4 -0
- package/src/execution/runner-completion.ts +11 -1
- package/src/execution/runner-execution.ts +8 -0
- package/src/execution/runner-setup.ts +4 -0
- package/src/execution/runner.ts +10 -0
- package/src/interaction/plugins/webhook.ts +10 -1
- package/src/pipeline/stages/execution.ts +33 -1
- package/src/pipeline/stages/routing.ts +18 -7
- package/src/pipeline/types.ts +10 -0
- package/src/prd/schema.ts +249 -0
- package/src/tdd/orchestrator.ts +7 -0
- package/src/tdd/rectification-gate.ts +6 -0
- package/src/tdd/session-runner.ts +15 -2
- package/src/utils/git.ts +30 -0
- package/src/verification/runners.ts +10 -1
|
@@ -10,8 +10,17 @@ import { resolveModel } from "../config";
|
|
|
10
10
|
import { getLogger } from "../logger";
|
|
11
11
|
import type { UserStory } from "../prd";
|
|
12
12
|
import { PromptBuilder } from "../prompts";
|
|
13
|
-
import { autoCommitIfDirty } from "../utils/git";
|
|
13
|
+
import { autoCommitIfDirty as _autoCommitIfDirtyFn } from "../utils/git";
|
|
14
14
|
import { cleanupProcessTree } from "./cleanup";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Injectable dependencies for session-runner — allows tests to mock
|
|
18
|
+
* autoCommitIfDirty without going through internal git deps.
|
|
19
|
+
* @internal
|
|
20
|
+
*/
|
|
21
|
+
export const _sessionRunnerDeps = {
|
|
22
|
+
autoCommitIfDirty: _autoCommitIfDirtyFn,
|
|
23
|
+
};
|
|
15
24
|
import { getChangedFiles, verifyImplementerIsolation, verifyTestWriterIsolation } from "./isolation";
|
|
16
25
|
import type { IsolationCheck } from "./types";
|
|
17
26
|
import type { TddSessionResult, TddSessionRole } from "./types";
|
|
@@ -84,6 +93,7 @@ export async function runTddSession(
|
|
|
84
93
|
lite = false,
|
|
85
94
|
skipIsolation = false,
|
|
86
95
|
constitution?: string,
|
|
96
|
+
featureName?: string,
|
|
87
97
|
): Promise<TddSessionResult> {
|
|
88
98
|
const startTime = Date.now();
|
|
89
99
|
|
|
@@ -130,6 +140,9 @@ export async function runTddSession(
|
|
|
130
140
|
modelDef: resolveModel(config.models[modelTier]),
|
|
131
141
|
timeoutSeconds: config.execution.sessionTimeoutSeconds,
|
|
132
142
|
dangerouslySkipPermissions: config.execution.dangerouslySkipPermissions,
|
|
143
|
+
featureName,
|
|
144
|
+
storyId: story.id,
|
|
145
|
+
sessionRole: role,
|
|
133
146
|
});
|
|
134
147
|
|
|
135
148
|
// BUG-21 Fix: Clean up orphaned child processes if agent failed
|
|
@@ -154,7 +167,7 @@ export async function runTddSession(
|
|
|
154
167
|
}
|
|
155
168
|
|
|
156
169
|
// BUG-058: Auto-commit if agent left uncommitted changes
|
|
157
|
-
await autoCommitIfDirty(workdir, "tdd", role, story.id);
|
|
170
|
+
await _sessionRunnerDeps.autoCommitIfDirty(workdir, "tdd", role, story.id);
|
|
158
171
|
|
|
159
172
|
// Check isolation based on role and skipIsolation flag.
|
|
160
173
|
let isolation: IsolationCheck | undefined;
|
package/src/utils/git.ts
CHANGED
|
@@ -153,6 +153,36 @@ export function detectMergeConflict(output: string): boolean {
|
|
|
153
153
|
export async function autoCommitIfDirty(workdir: string, stage: string, role: string, storyId: string): Promise<void> {
|
|
154
154
|
const logger = getSafeLogger();
|
|
155
155
|
try {
|
|
156
|
+
// Guard: only auto-commit if workdir IS the git repository root.
|
|
157
|
+
// Without this, a workdir nested inside another git repo (e.g. a temp dir
|
|
158
|
+
// created inside the nax repo during tests) would cause git to walk up and
|
|
159
|
+
// commit files from the parent repo instead.
|
|
160
|
+
const topLevelProc = _gitDeps.spawn(["git", "rev-parse", "--show-toplevel"], {
|
|
161
|
+
cwd: workdir,
|
|
162
|
+
stdout: "pipe",
|
|
163
|
+
stderr: "pipe",
|
|
164
|
+
});
|
|
165
|
+
const gitRoot = (await new Response(topLevelProc.stdout).text()).trim();
|
|
166
|
+
await topLevelProc.exited;
|
|
167
|
+
|
|
168
|
+
// Normalize paths to handle symlinks (e.g. /tmp → /private/tmp on macOS)
|
|
169
|
+
const { realpathSync } = await import("node:fs");
|
|
170
|
+
const realWorkdir = (() => {
|
|
171
|
+
try {
|
|
172
|
+
return realpathSync(workdir);
|
|
173
|
+
} catch {
|
|
174
|
+
return workdir;
|
|
175
|
+
}
|
|
176
|
+
})();
|
|
177
|
+
const realGitRoot = (() => {
|
|
178
|
+
try {
|
|
179
|
+
return realpathSync(gitRoot);
|
|
180
|
+
} catch {
|
|
181
|
+
return gitRoot;
|
|
182
|
+
}
|
|
183
|
+
})();
|
|
184
|
+
if (realWorkdir !== realGitRoot) return;
|
|
185
|
+
|
|
156
186
|
const statusProc = _gitDeps.spawn(["git", "status", "--porcelain"], {
|
|
157
187
|
cwd: workdir,
|
|
158
188
|
stdout: "pipe",
|
|
@@ -113,8 +113,17 @@ export async function scoped(options: VerificationGateOptions): Promise<Verifica
|
|
|
113
113
|
return runVerificationCore({ ...options, command: scopedCommand });
|
|
114
114
|
}
|
|
115
115
|
|
|
116
|
+
/**
|
|
117
|
+
* Injectable dependencies for regression() — allows tests to replace
|
|
118
|
+
* the 2s agent-cleanup sleep with a no-op without touching production behaviour.
|
|
119
|
+
* @internal
|
|
120
|
+
*/
|
|
121
|
+
export const _regressionRunnerDeps = {
|
|
122
|
+
sleep: (ms: number): Promise<void> => Bun.sleep(ms),
|
|
123
|
+
};
|
|
124
|
+
|
|
116
125
|
/** Quick smoke test — no asset verification, 2s delay to let agent processes terminate. */
|
|
117
126
|
export async function regression(options: VerificationGateOptions): Promise<VerificationResult> {
|
|
118
|
-
await
|
|
127
|
+
await _regressionRunnerDeps.sleep(2000);
|
|
119
128
|
return runVerificationCore({ ...options, expectedFiles: undefined });
|
|
120
129
|
}
|