@nathapp/nax 0.32.2 → 0.34.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 +191 -6
- package/dist/nax.js +1150 -382
- package/package.json +1 -1
- package/src/cli/analyze.ts +145 -0
- package/src/cli/config.ts +9 -0
- package/src/config/defaults.ts +8 -0
- package/src/config/schema.ts +1 -0
- package/src/config/schemas.ts +10 -0
- package/src/config/types.ts +18 -0
- package/src/context/elements.ts +13 -0
- package/src/context/greenfield.ts +1 -1
- package/src/decompose/apply.ts +44 -0
- package/src/decompose/builder.ts +181 -0
- package/src/decompose/index.ts +8 -0
- package/src/decompose/sections/codebase.ts +26 -0
- package/src/decompose/sections/constraints.ts +32 -0
- package/src/decompose/sections/index.ts +4 -0
- package/src/decompose/sections/sibling-stories.ts +25 -0
- package/src/decompose/sections/target-story.ts +31 -0
- package/src/decompose/types.ts +55 -0
- package/src/decompose/validators/complexity.ts +45 -0
- package/src/decompose/validators/coverage.ts +134 -0
- package/src/decompose/validators/dependency.ts +91 -0
- package/src/decompose/validators/index.ts +35 -0
- package/src/decompose/validators/overlap.ts +128 -0
- package/src/execution/crash-recovery.ts +8 -0
- package/src/execution/escalation/tier-escalation.ts +9 -2
- package/src/execution/iteration-runner.ts +2 -0
- package/src/execution/lifecycle/run-completion.ts +100 -15
- package/src/execution/parallel-executor.ts +20 -1
- package/src/execution/pipeline-result-handler.ts +5 -1
- package/src/execution/runner.ts +20 -0
- package/src/execution/sequential-executor.ts +2 -11
- package/src/hooks/types.ts +20 -10
- package/src/interaction/index.ts +1 -0
- package/src/interaction/triggers.ts +21 -0
- package/src/interaction/types.ts +7 -0
- package/src/metrics/tracker.ts +7 -0
- package/src/metrics/types.ts +2 -0
- package/src/pipeline/stages/review.ts +6 -0
- package/src/pipeline/stages/routing.ts +89 -0
- package/src/pipeline/types.ts +2 -0
- package/src/plugins/types.ts +33 -0
- package/src/prd/index.ts +7 -2
- package/src/prd/types.ts +17 -2
- package/src/review/orchestrator.ts +1 -0
- package/src/review/types.ts +2 -0
- package/src/tdd/isolation.ts +1 -1
package/src/prd/index.ts
CHANGED
|
@@ -107,6 +107,7 @@ export function getNextStory(prd: PRD, currentStoryId?: string | null, maxRetrie
|
|
|
107
107
|
s.status !== "blocked" &&
|
|
108
108
|
s.status !== "failed" &&
|
|
109
109
|
s.status !== "paused" &&
|
|
110
|
+
s.status !== "decomposed" &&
|
|
110
111
|
s.dependencies.every((dep) => completedIds.has(dep)),
|
|
111
112
|
) ?? null
|
|
112
113
|
);
|
|
@@ -132,11 +133,12 @@ export function countStories(prd: PRD): {
|
|
|
132
133
|
skipped: number;
|
|
133
134
|
blocked: number;
|
|
134
135
|
paused: number;
|
|
136
|
+
decomposed: number;
|
|
135
137
|
} {
|
|
136
138
|
return {
|
|
137
139
|
total: prd.userStories.length,
|
|
138
140
|
passed: prd.userStories.filter((s) => s.passes || s.status === "passed").length,
|
|
139
|
-
failed: prd.userStories.filter((s) => s.status === "failed").length,
|
|
141
|
+
failed: prd.userStories.filter((s) => s.status === "failed" || s.status === "regression-failed").length,
|
|
140
142
|
pending: prd.userStories.filter(
|
|
141
143
|
(s) =>
|
|
142
144
|
!s.passes &&
|
|
@@ -144,11 +146,14 @@ export function countStories(prd: PRD): {
|
|
|
144
146
|
s.status !== "failed" &&
|
|
145
147
|
s.status !== "skipped" &&
|
|
146
148
|
s.status !== "blocked" &&
|
|
147
|
-
s.status !== "paused"
|
|
149
|
+
s.status !== "paused" &&
|
|
150
|
+
s.status !== "regression-failed" &&
|
|
151
|
+
s.status !== "decomposed",
|
|
148
152
|
).length,
|
|
149
153
|
skipped: prd.userStories.filter((s) => s.status === "skipped").length,
|
|
150
154
|
blocked: prd.userStories.filter((s) => s.status === "blocked").length,
|
|
151
155
|
paused: prd.userStories.filter((s) => s.status === "paused").length,
|
|
156
|
+
decomposed: prd.userStories.filter((s) => s.status === "decomposed").length,
|
|
152
157
|
};
|
|
153
158
|
}
|
|
154
159
|
|
package/src/prd/types.ts
CHANGED
|
@@ -9,7 +9,16 @@ import type { ModelTier } from "../config";
|
|
|
9
9
|
import type { FailureCategory } from "../tdd/types";
|
|
10
10
|
|
|
11
11
|
/** User story status */
|
|
12
|
-
export type StoryStatus =
|
|
12
|
+
export type StoryStatus =
|
|
13
|
+
| "pending"
|
|
14
|
+
| "in-progress"
|
|
15
|
+
| "passed"
|
|
16
|
+
| "failed"
|
|
17
|
+
| "skipped"
|
|
18
|
+
| "blocked"
|
|
19
|
+
| "paused"
|
|
20
|
+
| "regression-failed"
|
|
21
|
+
| "decomposed";
|
|
13
22
|
|
|
14
23
|
/** Verification stage where failure occurred */
|
|
15
24
|
export type VerificationStage = "verify" | "review" | "regression" | "rectification" | "agent-session" | "escalation";
|
|
@@ -38,6 +47,8 @@ export interface StructuredFailure {
|
|
|
38
47
|
summary: string;
|
|
39
48
|
/** Parsed test failures (if applicable) */
|
|
40
49
|
testFailures?: TestFailureContext[];
|
|
50
|
+
/** Structured review findings from plugin reviewers (e.g., semgrep, eslint) */
|
|
51
|
+
reviewFindings?: import("../plugins/types").ReviewFinding[];
|
|
41
52
|
/** ISO timestamp when failure was recorded */
|
|
42
53
|
timestamp: string;
|
|
43
54
|
}
|
|
@@ -150,7 +161,10 @@ export function isStalled(prd: PRD): boolean {
|
|
|
150
161
|
|
|
151
162
|
const blockedIds = new Set(
|
|
152
163
|
prd.userStories
|
|
153
|
-
.filter(
|
|
164
|
+
.filter(
|
|
165
|
+
(s) =>
|
|
166
|
+
s.status === "blocked" || s.status === "failed" || s.status === "paused" || s.status === "regression-failed",
|
|
167
|
+
)
|
|
154
168
|
.map((s) => s.id),
|
|
155
169
|
);
|
|
156
170
|
|
|
@@ -159,6 +173,7 @@ export function isStalled(prd: PRD): boolean {
|
|
|
159
173
|
s.status === "blocked" ||
|
|
160
174
|
s.status === "failed" ||
|
|
161
175
|
s.status === "paused" ||
|
|
176
|
+
s.status === "regression-failed" ||
|
|
162
177
|
s.dependencies.some((dep) => blockedIds.has(dep)),
|
|
163
178
|
);
|
|
164
179
|
}
|
package/src/review/types.ts
CHANGED
|
@@ -35,6 +35,8 @@ export interface PluginReviewerResult {
|
|
|
35
35
|
exitCode?: number;
|
|
36
36
|
/** Error message if reviewer threw an exception */
|
|
37
37
|
error?: string;
|
|
38
|
+
/** Structured findings from the reviewer (optional) */
|
|
39
|
+
findings?: import("../plugins/types").ReviewFinding[];
|
|
38
40
|
}
|
|
39
41
|
|
|
40
42
|
/** Review phase result */
|
package/src/tdd/isolation.ts
CHANGED
|
@@ -55,7 +55,7 @@ function matchesAllowedPath(filePath: string, allowedPaths: string[]): boolean {
|
|
|
55
55
|
return allowedPaths.some((pattern) => {
|
|
56
56
|
// Simple glob matching: ** = any directory, * = any filename segment
|
|
57
57
|
const regexPattern = pattern.replace(/\*\*/g, ".*").replace(/\*/g, "[^/]*").replace(/\//g, "\\/");
|
|
58
|
-
const regex = new RegExp(`^${regexPattern}$`);
|
|
58
|
+
const regex = new RegExp(`^${regexPattern}$`); // nosemgrep: detect-non-literal-regexp — pattern from PRD scope config, not user input
|
|
59
59
|
return regex.test(filePath);
|
|
60
60
|
});
|
|
61
61
|
}
|