ridgeline 0.5.9 → 0.7.2
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 +53 -9
- package/dist/agents/core/designer.md +131 -0
- package/dist/agents/core/refiner.md +61 -0
- package/dist/agents/core/researcher.md +78 -0
- package/dist/agents/core/specifier.md +16 -0
- package/dist/agents/researchers/academic.md +27 -0
- package/dist/agents/researchers/competitive.md +28 -0
- package/dist/agents/researchers/context.md +46 -0
- package/dist/agents/researchers/ecosystem.md +28 -0
- package/dist/agents/researchers/gaps.md +67 -0
- package/dist/agents/specifiers/visual-coherence.md +55 -0
- package/dist/cli.js +83 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/create.js +20 -2
- package/dist/commands/create.js.map +1 -1
- package/dist/commands/design.d.ts +8 -0
- package/dist/commands/design.js +130 -0
- package/dist/commands/design.js.map +1 -0
- package/dist/commands/index.d.ts +1 -0
- package/dist/commands/index.js +3 -1
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/plan.js +3 -3
- package/dist/commands/plan.js.map +1 -1
- package/dist/commands/qa-workflow.d.ts +33 -0
- package/dist/commands/qa-workflow.js +139 -0
- package/dist/commands/qa-workflow.js.map +1 -0
- package/dist/commands/refine.d.ts +8 -0
- package/dist/commands/refine.js +105 -0
- package/dist/commands/refine.js.map +1 -0
- package/dist/commands/research.d.ts +10 -0
- package/dist/commands/research.js +146 -0
- package/dist/commands/research.js.map +1 -0
- package/dist/commands/rewind.js +5 -3
- package/dist/commands/rewind.js.map +1 -1
- package/dist/commands/shape.js +36 -121
- package/dist/commands/shape.js.map +1 -1
- package/dist/commands/spec.js +1 -0
- package/dist/commands/spec.js.map +1 -1
- package/dist/engine/claude/stream.display.js +0 -1
- package/dist/engine/claude/stream.display.js.map +1 -1
- package/dist/engine/claude/stream.parse.d.ts +1 -15
- package/dist/engine/claude/stream.parse.js +3 -21
- package/dist/engine/claude/stream.parse.js.map +1 -1
- package/dist/engine/claude/stream.result.js +2 -2
- package/dist/engine/claude/stream.types.d.ts +15 -0
- package/dist/engine/claude/stream.types.js +23 -0
- package/dist/engine/claude/stream.types.js.map +1 -0
- package/dist/engine/discovery/agent.registry.d.ts +4 -0
- package/dist/engine/discovery/agent.registry.js +46 -18
- package/dist/engine/discovery/agent.registry.js.map +1 -1
- package/dist/engine/discovery/flavour.config.d.ts +9 -0
- package/dist/engine/discovery/flavour.config.js +61 -0
- package/dist/engine/discovery/flavour.config.js.map +1 -0
- package/dist/engine/discovery/plugin.scan.d.ts +1 -0
- package/dist/engine/discovery/plugin.scan.js +29 -1
- package/dist/engine/discovery/plugin.scan.js.map +1 -1
- package/dist/engine/discovery/skill.check.d.ts +19 -0
- package/dist/engine/discovery/skill.check.js +145 -0
- package/dist/engine/discovery/skill.check.js.map +1 -0
- package/dist/engine/pipeline/build.exec.js +1 -0
- package/dist/engine/pipeline/build.exec.js.map +1 -1
- package/dist/engine/pipeline/ensemble.exec.d.ts +12 -1
- package/dist/engine/pipeline/ensemble.exec.js +20 -10
- package/dist/engine/pipeline/ensemble.exec.js.map +1 -1
- package/dist/engine/pipeline/phase.sequence.js +10 -10
- package/dist/engine/pipeline/phase.sequence.js.map +1 -1
- package/dist/engine/pipeline/pipeline.shared.d.ts +6 -0
- package/dist/engine/pipeline/pipeline.shared.js +24 -1
- package/dist/engine/pipeline/pipeline.shared.js.map +1 -1
- package/dist/engine/pipeline/plan.exec.js +1 -0
- package/dist/engine/pipeline/plan.exec.js.map +1 -1
- package/dist/engine/pipeline/refine.exec.d.ts +10 -0
- package/dist/engine/pipeline/refine.exec.js +91 -0
- package/dist/engine/pipeline/refine.exec.js.map +1 -0
- package/dist/engine/pipeline/research.exec.d.ts +17 -0
- package/dist/engine/pipeline/research.exec.js +196 -0
- package/dist/engine/pipeline/research.exec.js.map +1 -0
- package/dist/engine/pipeline/review.exec.js +23 -0
- package/dist/engine/pipeline/review.exec.js.map +1 -1
- package/dist/engine/pipeline/specify.exec.d.ts +1 -0
- package/dist/engine/pipeline/specify.exec.js +114 -44
- package/dist/engine/pipeline/specify.exec.js.map +1 -1
- package/dist/flavours/data-analysis/core/refiner.md +65 -0
- package/dist/flavours/data-analysis/core/researcher.md +81 -0
- package/dist/flavours/data-analysis/researchers/academic.md +29 -0
- package/dist/flavours/data-analysis/researchers/competitive.md +29 -0
- package/dist/flavours/data-analysis/researchers/ecosystem.md +29 -0
- package/dist/flavours/data-analysis/researchers/gaps.md +59 -0
- package/dist/flavours/game-dev/core/refiner.md +65 -0
- package/dist/flavours/game-dev/core/researcher.md +81 -0
- package/dist/flavours/game-dev/researchers/academic.md +31 -0
- package/dist/flavours/game-dev/researchers/competitive.md +30 -0
- package/dist/flavours/game-dev/researchers/ecosystem.md +29 -0
- package/dist/flavours/game-dev/researchers/gaps.md +59 -0
- package/dist/flavours/legal-drafting/core/refiner.md +65 -0
- package/dist/flavours/legal-drafting/core/researcher.md +81 -0
- package/dist/flavours/legal-drafting/researchers/academic.md +31 -0
- package/dist/flavours/legal-drafting/researchers/competitive.md +31 -0
- package/dist/flavours/legal-drafting/researchers/ecosystem.md +30 -0
- package/dist/flavours/legal-drafting/researchers/gaps.md +59 -0
- package/dist/flavours/machine-learning/core/refiner.md +65 -0
- package/dist/flavours/machine-learning/core/researcher.md +81 -0
- package/dist/flavours/machine-learning/researchers/academic.md +32 -0
- package/dist/flavours/machine-learning/researchers/competitive.md +32 -0
- package/dist/flavours/machine-learning/researchers/ecosystem.md +31 -0
- package/dist/flavours/machine-learning/researchers/gaps.md +59 -0
- package/dist/flavours/mobile-app/core/refiner.md +65 -0
- package/dist/flavours/mobile-app/core/researcher.md +81 -0
- package/dist/flavours/mobile-app/researchers/academic.md +31 -0
- package/dist/flavours/mobile-app/researchers/competitive.md +32 -0
- package/dist/flavours/mobile-app/researchers/ecosystem.md +31 -0
- package/dist/flavours/mobile-app/researchers/gaps.md +59 -0
- package/dist/flavours/music-composition/core/refiner.md +65 -0
- package/dist/flavours/music-composition/core/researcher.md +81 -0
- package/dist/flavours/music-composition/researchers/academic.md +32 -0
- package/dist/flavours/music-composition/researchers/competitive.md +32 -0
- package/dist/flavours/music-composition/researchers/ecosystem.md +32 -0
- package/dist/flavours/music-composition/researchers/gaps.md +59 -0
- package/dist/flavours/novel-writing/core/refiner.md +65 -0
- package/dist/flavours/novel-writing/core/researcher.md +81 -0
- package/dist/flavours/novel-writing/researchers/academic.md +32 -0
- package/dist/flavours/novel-writing/researchers/competitive.md +32 -0
- package/dist/flavours/novel-writing/researchers/ecosystem.md +32 -0
- package/dist/flavours/novel-writing/researchers/gaps.md +59 -0
- package/dist/flavours/screenwriting/core/refiner.md +65 -0
- package/dist/flavours/screenwriting/core/researcher.md +81 -0
- package/dist/flavours/screenwriting/researchers/academic.md +32 -0
- package/dist/flavours/screenwriting/researchers/competitive.md +32 -0
- package/dist/flavours/screenwriting/researchers/ecosystem.md +32 -0
- package/dist/flavours/screenwriting/researchers/gaps.md +59 -0
- package/dist/flavours/security-audit/core/refiner.md +65 -0
- package/dist/flavours/security-audit/core/researcher.md +81 -0
- package/dist/flavours/security-audit/researchers/academic.md +32 -0
- package/dist/flavours/security-audit/researchers/competitive.md +32 -0
- package/dist/flavours/security-audit/researchers/ecosystem.md +32 -0
- package/dist/flavours/security-audit/researchers/gaps.md +59 -0
- package/dist/flavours/software-engineering/core/builder.md +2 -0
- package/dist/flavours/software-engineering/core/refiner.md +65 -0
- package/dist/flavours/software-engineering/core/researcher.md +81 -0
- package/dist/flavours/software-engineering/core/reviewer.md +2 -0
- package/dist/flavours/software-engineering/flavour.json +7 -0
- package/dist/flavours/software-engineering/researchers/academic.md +32 -0
- package/dist/flavours/software-engineering/researchers/competitive.md +32 -0
- package/dist/flavours/software-engineering/researchers/ecosystem.md +32 -0
- package/dist/flavours/software-engineering/researchers/gaps.md +59 -0
- package/dist/flavours/technical-writing/core/refiner.md +65 -0
- package/dist/flavours/technical-writing/core/researcher.md +81 -0
- package/dist/flavours/technical-writing/researchers/academic.md +32 -0
- package/dist/flavours/technical-writing/researchers/competitive.md +32 -0
- package/dist/flavours/technical-writing/researchers/ecosystem.md +32 -0
- package/dist/flavours/technical-writing/researchers/gaps.md +59 -0
- package/dist/flavours/test-suite/core/refiner.md +65 -0
- package/dist/flavours/test-suite/core/researcher.md +81 -0
- package/dist/flavours/test-suite/researchers/academic.md +32 -0
- package/dist/flavours/test-suite/researchers/competitive.md +32 -0
- package/dist/flavours/test-suite/researchers/ecosystem.md +32 -0
- package/dist/flavours/test-suite/researchers/gaps.md +59 -0
- package/dist/flavours/translation/core/refiner.md +65 -0
- package/dist/flavours/translation/core/researcher.md +81 -0
- package/dist/flavours/translation/researchers/academic.md +32 -0
- package/dist/flavours/translation/researchers/competitive.md +32 -0
- package/dist/flavours/translation/researchers/ecosystem.md +32 -0
- package/dist/flavours/translation/researchers/gaps.md +59 -0
- package/dist/flavours/web-game/core/builder.md +123 -0
- package/dist/flavours/web-game/core/reviewer.md +159 -0
- package/dist/flavours/web-game/flavour.json +9 -0
- package/dist/flavours/web-ui/core/builder.md +117 -0
- package/dist/flavours/web-ui/core/reviewer.md +155 -0
- package/dist/flavours/web-ui/flavour.json +10 -0
- package/dist/plugin/visual-tools/plugin.json +4 -0
- package/dist/plugin/visual-tools/skills/a11y-audit/SKILL.md +57 -0
- package/dist/plugin/visual-tools/skills/agent-browser/SKILL.md +56 -0
- package/dist/plugin/visual-tools/skills/agent-browser/references/viewports.md +17 -0
- package/dist/plugin/visual-tools/skills/canvas-screenshot/SKILL.md +84 -0
- package/dist/plugin/visual-tools/skills/css-audit/SKILL.md +50 -0
- package/dist/plugin/visual-tools/skills/lighthouse/SKILL.md +58 -0
- package/dist/plugin/visual-tools/skills/shader-validate/SKILL.md +77 -0
- package/dist/plugin/visual-tools/skills/visual-diff/SKILL.md +68 -0
- package/dist/shapes/detect.d.ts +8 -0
- package/dist/shapes/detect.js +87 -0
- package/dist/shapes/detect.js.map +1 -0
- package/dist/shapes/game-visual.json +8 -0
- package/dist/shapes/print-layout.json +8 -0
- package/dist/shapes/web-visual.json +9 -0
- package/dist/stores/budget.js +2 -1
- package/dist/stores/budget.js.map +1 -1
- package/dist/stores/feedback.format.d.ts +3 -0
- package/dist/stores/feedback.format.js +62 -0
- package/dist/stores/feedback.format.js.map +1 -0
- package/dist/stores/feedback.parse.d.ts +2 -0
- package/dist/stores/feedback.parse.js +121 -0
- package/dist/stores/feedback.parse.js.map +1 -0
- package/dist/stores/feedback.verdict.d.ts +2 -4
- package/dist/stores/feedback.verdict.js +7 -175
- package/dist/stores/feedback.verdict.js.map +1 -1
- package/dist/stores/index.d.ts +1 -1
- package/dist/stores/index.js +1 -2
- package/dist/stores/index.js.map +1 -1
- package/dist/stores/settings.d.ts +2 -0
- package/dist/stores/settings.js +24 -1
- package/dist/stores/settings.js.map +1 -1
- package/dist/stores/state.d.ts +4 -0
- package/dist/stores/state.js +75 -12
- package/dist/stores/state.js.map +1 -1
- package/dist/stores/trajectory.d.ts +2 -3
- package/dist/stores/trajectory.js +6 -7
- package/dist/stores/trajectory.js.map +1 -1
- package/dist/types.d.ts +15 -3
- package/dist/utils/atomic-write.d.ts +6 -0
- package/dist/utils/atomic-write.js +62 -0
- package/dist/utils/atomic-write.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parseVerdict = void 0;
|
|
4
|
+
// Normalize an issue entry — accept both string and object forms
|
|
5
|
+
const normalizeIssue = (item, severity) => {
|
|
6
|
+
if (typeof item === "string") {
|
|
7
|
+
return { description: item, severity };
|
|
8
|
+
}
|
|
9
|
+
if (typeof item === "object" && item !== null) {
|
|
10
|
+
const obj = item;
|
|
11
|
+
return {
|
|
12
|
+
criterion: typeof obj.criterion === "number" ? obj.criterion : undefined,
|
|
13
|
+
description: typeof obj.description === "string" ? obj.description : String(obj.description ?? ""),
|
|
14
|
+
file: typeof obj.file === "string" ? obj.file : undefined,
|
|
15
|
+
severity,
|
|
16
|
+
requiredState: typeof obj.requiredState === "string" ? obj.requiredState : undefined,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
return { description: String(item), severity };
|
|
20
|
+
};
|
|
21
|
+
// Try to parse a raw object as a ReviewVerdict
|
|
22
|
+
const tryParseVerdict = (raw) => {
|
|
23
|
+
if (typeof raw !== "object" || raw === null)
|
|
24
|
+
return null;
|
|
25
|
+
const obj = raw;
|
|
26
|
+
if (typeof obj.passed !== "boolean")
|
|
27
|
+
return null;
|
|
28
|
+
return {
|
|
29
|
+
passed: obj.passed,
|
|
30
|
+
summary: typeof obj.summary === "string" ? obj.summary : "",
|
|
31
|
+
criteriaResults: Array.isArray(obj.criteriaResults)
|
|
32
|
+
? obj.criteriaResults.map((cr) => ({
|
|
33
|
+
criterion: typeof cr.criterion === "number" ? cr.criterion : 0,
|
|
34
|
+
passed: typeof cr.passed === "boolean" ? cr.passed : false,
|
|
35
|
+
notes: typeof cr.notes === "string" ? cr.notes : "",
|
|
36
|
+
}))
|
|
37
|
+
: [],
|
|
38
|
+
issues: Array.isArray(obj.issues)
|
|
39
|
+
? obj.issues.map((i) => normalizeIssue(i, "blocking"))
|
|
40
|
+
: [],
|
|
41
|
+
suggestions: Array.isArray(obj.suggestions)
|
|
42
|
+
? obj.suggestions.map((s) => normalizeIssue(s, "suggestion"))
|
|
43
|
+
: [],
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
// Find the end index of a balanced JSON object starting at position 0 in `text`.
|
|
47
|
+
// Returns the index of the closing brace, or -1 if no balanced pair is found.
|
|
48
|
+
const findBalancedBrace = (text) => {
|
|
49
|
+
let depth = 0;
|
|
50
|
+
let inString = false;
|
|
51
|
+
let escape = false;
|
|
52
|
+
for (let j = 0; j < text.length; j++) {
|
|
53
|
+
const ch = text[j];
|
|
54
|
+
if (escape) {
|
|
55
|
+
escape = false;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (ch === "\\") {
|
|
59
|
+
escape = true;
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
if (ch === '"') {
|
|
63
|
+
inString = !inString;
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
if (inString)
|
|
67
|
+
continue;
|
|
68
|
+
if (ch === "{")
|
|
69
|
+
depth++;
|
|
70
|
+
if (ch === "}") {
|
|
71
|
+
depth--;
|
|
72
|
+
if (depth === 0)
|
|
73
|
+
return j;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return -1;
|
|
77
|
+
};
|
|
78
|
+
// Try to parse a JSON object starting at `text` as a ReviewVerdict.
|
|
79
|
+
// First tries the full slice, then tries balanced brace extraction.
|
|
80
|
+
const tryExtractVerdictAt = (text) => {
|
|
81
|
+
try {
|
|
82
|
+
return tryParseVerdict(JSON.parse(text));
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
const end = findBalancedBrace(text);
|
|
86
|
+
if (end === -1)
|
|
87
|
+
return null;
|
|
88
|
+
try {
|
|
89
|
+
return tryParseVerdict(JSON.parse(text.slice(0, end + 1)));
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
const UNPARSEABLE_VERDICT = {
|
|
97
|
+
passed: false,
|
|
98
|
+
summary: "Could not parse reviewer verdict from output",
|
|
99
|
+
criteriaResults: [],
|
|
100
|
+
issues: [{ description: "Reviewer output did not contain a valid JSON verdict", severity: "blocking" }],
|
|
101
|
+
suggestions: [],
|
|
102
|
+
};
|
|
103
|
+
// Extract the JSON verdict block from reviewer's text output
|
|
104
|
+
const parseVerdict = (text) => {
|
|
105
|
+
// Try extracting from fenced code block first
|
|
106
|
+
const fencedMatch = text.match(/```(?:json)?\s*\n?([\s\S]*?)\n?```/);
|
|
107
|
+
if (fencedMatch) {
|
|
108
|
+
const result = tryExtractVerdictAt(fencedMatch[1]);
|
|
109
|
+
if (result)
|
|
110
|
+
return result;
|
|
111
|
+
}
|
|
112
|
+
// Scan every { and try to parse a verdict from that position
|
|
113
|
+
for (let i = text.indexOf("{"); i !== -1; i = text.indexOf("{", i + 1)) {
|
|
114
|
+
const result = tryExtractVerdictAt(text.slice(i));
|
|
115
|
+
if (result)
|
|
116
|
+
return result;
|
|
117
|
+
}
|
|
118
|
+
return UNPARSEABLE_VERDICT;
|
|
119
|
+
};
|
|
120
|
+
exports.parseVerdict = parseVerdict;
|
|
121
|
+
//# sourceMappingURL=feedback.parse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback.parse.js","sourceRoot":"","sources":["../../src/stores/feedback.parse.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export
|
|
3
|
-
export declare const formatIssue: (issue: ReviewIssue) => string;
|
|
4
|
-
export declare const generateFeedback: (phaseId: string, verdict: ReviewVerdict) => string;
|
|
1
|
+
export { parseVerdict } from "./feedback.parse";
|
|
2
|
+
export { formatIssue, generateFeedback } from "./feedback.format";
|
|
@@ -1,179 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.generateFeedback = exports.formatIssue = exports.parseVerdict = void 0;
|
|
4
|
-
//
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
return {
|
|
12
|
-
criterion: typeof obj.criterion === "number" ? obj.criterion : undefined,
|
|
13
|
-
description: typeof obj.description === "string" ? obj.description : String(obj.description ?? ""),
|
|
14
|
-
file: typeof obj.file === "string" ? obj.file : undefined,
|
|
15
|
-
severity,
|
|
16
|
-
requiredState: typeof obj.requiredState === "string" ? obj.requiredState : undefined,
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
return { description: String(item), severity };
|
|
20
|
-
};
|
|
21
|
-
// Try to parse a raw object as a ReviewVerdict
|
|
22
|
-
const tryParseVerdict = (raw) => {
|
|
23
|
-
if (typeof raw !== "object" || raw === null)
|
|
24
|
-
return null;
|
|
25
|
-
const obj = raw;
|
|
26
|
-
if (typeof obj.passed !== "boolean")
|
|
27
|
-
return null;
|
|
28
|
-
return {
|
|
29
|
-
passed: obj.passed,
|
|
30
|
-
summary: typeof obj.summary === "string" ? obj.summary : "",
|
|
31
|
-
criteriaResults: Array.isArray(obj.criteriaResults)
|
|
32
|
-
? obj.criteriaResults.map((cr) => ({
|
|
33
|
-
criterion: typeof cr.criterion === "number" ? cr.criterion : 0,
|
|
34
|
-
passed: typeof cr.passed === "boolean" ? cr.passed : false,
|
|
35
|
-
notes: typeof cr.notes === "string" ? cr.notes : "",
|
|
36
|
-
}))
|
|
37
|
-
: [],
|
|
38
|
-
issues: Array.isArray(obj.issues)
|
|
39
|
-
? obj.issues.map((i) => normalizeIssue(i, "blocking"))
|
|
40
|
-
: [],
|
|
41
|
-
suggestions: Array.isArray(obj.suggestions)
|
|
42
|
-
? obj.suggestions.map((s) => normalizeIssue(s, "suggestion"))
|
|
43
|
-
: [],
|
|
44
|
-
};
|
|
45
|
-
};
|
|
46
|
-
// Find the end index of a balanced JSON object starting at position 0 in `text`.
|
|
47
|
-
// Returns the index of the closing brace, or -1 if no balanced pair is found.
|
|
48
|
-
const findBalancedBrace = (text) => {
|
|
49
|
-
let depth = 0;
|
|
50
|
-
let inString = false;
|
|
51
|
-
let escape = false;
|
|
52
|
-
for (let j = 0; j < text.length; j++) {
|
|
53
|
-
const ch = text[j];
|
|
54
|
-
if (escape) {
|
|
55
|
-
escape = false;
|
|
56
|
-
continue;
|
|
57
|
-
}
|
|
58
|
-
if (ch === "\\") {
|
|
59
|
-
escape = true;
|
|
60
|
-
continue;
|
|
61
|
-
}
|
|
62
|
-
if (ch === '"') {
|
|
63
|
-
inString = !inString;
|
|
64
|
-
continue;
|
|
65
|
-
}
|
|
66
|
-
if (inString)
|
|
67
|
-
continue;
|
|
68
|
-
if (ch === "{")
|
|
69
|
-
depth++;
|
|
70
|
-
if (ch === "}") {
|
|
71
|
-
depth--;
|
|
72
|
-
if (depth === 0)
|
|
73
|
-
return j;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
return -1;
|
|
77
|
-
};
|
|
78
|
-
// Try to parse a JSON object starting at `text` as a ReviewVerdict.
|
|
79
|
-
// First tries the full slice, then tries balanced brace extraction.
|
|
80
|
-
const tryExtractVerdictAt = (text) => {
|
|
81
|
-
try {
|
|
82
|
-
return tryParseVerdict(JSON.parse(text));
|
|
83
|
-
}
|
|
84
|
-
catch {
|
|
85
|
-
const end = findBalancedBrace(text);
|
|
86
|
-
if (end === -1)
|
|
87
|
-
return null;
|
|
88
|
-
try {
|
|
89
|
-
return tryParseVerdict(JSON.parse(text.slice(0, end + 1)));
|
|
90
|
-
}
|
|
91
|
-
catch {
|
|
92
|
-
return null;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
const UNPARSEABLE_VERDICT = {
|
|
97
|
-
passed: false,
|
|
98
|
-
summary: "Could not parse reviewer verdict from output",
|
|
99
|
-
criteriaResults: [],
|
|
100
|
-
issues: [{ description: "Reviewer output did not contain a valid JSON verdict", severity: "blocking" }],
|
|
101
|
-
suggestions: [],
|
|
102
|
-
};
|
|
103
|
-
// Extract the JSON verdict block from reviewer's text output
|
|
104
|
-
const parseVerdict = (text) => {
|
|
105
|
-
// Try extracting from fenced code block first
|
|
106
|
-
const fencedMatch = text.match(/```(?:json)?\s*\n?([\s\S]*?)\n?```/);
|
|
107
|
-
if (fencedMatch) {
|
|
108
|
-
const result = tryExtractVerdictAt(fencedMatch[1]);
|
|
109
|
-
if (result)
|
|
110
|
-
return result;
|
|
111
|
-
}
|
|
112
|
-
// Scan every { and try to parse a verdict from that position
|
|
113
|
-
for (let i = text.indexOf("{"); i !== -1; i = text.indexOf("{", i + 1)) {
|
|
114
|
-
const result = tryExtractVerdictAt(text.slice(i));
|
|
115
|
-
if (result)
|
|
116
|
-
return result;
|
|
117
|
-
}
|
|
118
|
-
return UNPARSEABLE_VERDICT;
|
|
119
|
-
};
|
|
120
|
-
exports.parseVerdict = parseVerdict;
|
|
121
|
-
// Format a ReviewIssue for display
|
|
122
|
-
const formatIssue = (issue) => {
|
|
123
|
-
const parts = [];
|
|
124
|
-
if (issue.file)
|
|
125
|
-
parts.push(issue.file);
|
|
126
|
-
parts.push(issue.description);
|
|
127
|
-
return parts.join(": ");
|
|
128
|
-
};
|
|
129
|
-
exports.formatIssue = formatIssue;
|
|
130
|
-
// Generate feedback markdown from a structured verdict
|
|
131
|
-
const generateFeedback = (phaseId, verdict) => {
|
|
132
|
-
const lines = [];
|
|
133
|
-
lines.push(`# Reviewer Feedback: Phase ${phaseId}`);
|
|
134
|
-
lines.push("");
|
|
135
|
-
// Failed criteria
|
|
136
|
-
const failed = verdict.criteriaResults.filter((cr) => !cr.passed);
|
|
137
|
-
if (failed.length > 0) {
|
|
138
|
-
lines.push("## Failed Criteria");
|
|
139
|
-
lines.push("");
|
|
140
|
-
for (const cr of failed) {
|
|
141
|
-
lines.push(`### Criterion ${cr.criterion}`);
|
|
142
|
-
lines.push(`**Status:** FAIL`);
|
|
143
|
-
lines.push(`**Evidence:** ${cr.notes}`);
|
|
144
|
-
// Find matching issue with requiredState
|
|
145
|
-
const matchingIssue = verdict.issues.find((i) => i.criterion === cr.criterion);
|
|
146
|
-
if (matchingIssue?.requiredState) {
|
|
147
|
-
lines.push(`**Required state:** ${matchingIssue.requiredState}`);
|
|
148
|
-
}
|
|
149
|
-
lines.push("");
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
// Blocking issues
|
|
153
|
-
const blocking = verdict.issues.filter((i) => i.severity === "blocking");
|
|
154
|
-
if (blocking.length > 0) {
|
|
155
|
-
lines.push("## Issues");
|
|
156
|
-
lines.push("");
|
|
157
|
-
for (const issue of blocking) {
|
|
158
|
-
const filePart = issue.file ? ` (${issue.file})` : "";
|
|
159
|
-
lines.push(`- ${issue.description}${filePart}`);
|
|
160
|
-
if (issue.requiredState) {
|
|
161
|
-
lines.push(` - **Required:** ${issue.requiredState}`);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
lines.push("");
|
|
165
|
-
}
|
|
166
|
-
// What passed
|
|
167
|
-
const passed = verdict.criteriaResults.filter((cr) => cr.passed);
|
|
168
|
-
if (passed.length > 0) {
|
|
169
|
-
lines.push("## What Passed");
|
|
170
|
-
lines.push("");
|
|
171
|
-
for (const cr of passed) {
|
|
172
|
-
lines.push(`- Criterion ${cr.criterion}: ${cr.notes}`);
|
|
173
|
-
}
|
|
174
|
-
lines.push("");
|
|
175
|
-
}
|
|
176
|
-
return lines.join("\n");
|
|
177
|
-
};
|
|
178
|
-
exports.generateFeedback = generateFeedback;
|
|
4
|
+
// Re-exports for backward compatibility — implementations split into
|
|
5
|
+
// feedback.parse.ts (verdict parsing) and feedback.format.ts (formatting).
|
|
6
|
+
var feedback_parse_1 = require("./feedback.parse");
|
|
7
|
+
Object.defineProperty(exports, "parseVerdict", { enumerable: true, get: function () { return feedback_parse_1.parseVerdict; } });
|
|
8
|
+
var feedback_format_1 = require("./feedback.format");
|
|
9
|
+
Object.defineProperty(exports, "formatIssue", { enumerable: true, get: function () { return feedback_format_1.formatIssue; } });
|
|
10
|
+
Object.defineProperty(exports, "generateFeedback", { enumerable: true, get: function () { return feedback_format_1.generateFeedback; } });
|
|
179
11
|
//# sourceMappingURL=feedback.verdict.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"feedback.verdict.js","sourceRoot":"","sources":["../../src/stores/feedback.verdict.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"feedback.verdict.js","sourceRoot":"","sources":["../../src/stores/feedback.verdict.ts"],"names":[],"mappings":";;;AAAA,qEAAqE;AACrE,2EAA2E;AAC3E,mDAA+C;AAAtC,8GAAA,YAAY,OAAA;AACrB,qDAAiE;AAAxD,8GAAA,WAAW,OAAA;AAAE,mHAAA,gBAAgB,OAAA"}
|
package/dist/stores/index.d.ts
CHANGED
|
@@ -6,4 +6,4 @@ export { resolveFile, parseCheckCommand } from './inputs';
|
|
|
6
6
|
export { PHASE_FILENAME_PATTERN, isPhaseFile, parsePhaseFilename, parsePhaseContent, scanPhases, } from './phases';
|
|
7
7
|
export { loadState, saveState, initState, updatePhaseStatus, resetRetries, getNextIncompletePhase, } from './state';
|
|
8
8
|
export { checkpointTagName, completionTagName, createCheckpoint, createCompletionTag, verifyCompletionTag, cleanupBuildTags, } from './tags';
|
|
9
|
-
export { logTrajectory,
|
|
9
|
+
export { logTrajectory, readTrajectory } from './trajectory';
|
package/dist/stores/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.readTrajectory = exports.
|
|
3
|
+
exports.readTrajectory = exports.logTrajectory = exports.cleanupBuildTags = exports.verifyCompletionTag = exports.createCompletionTag = exports.createCheckpoint = exports.completionTagName = exports.checkpointTagName = exports.getNextIncompletePhase = exports.resetRetries = exports.updatePhaseStatus = exports.initState = exports.saveState = exports.loadState = exports.scanPhases = exports.parsePhaseContent = exports.parsePhaseFilename = exports.isPhaseFile = exports.PHASE_FILENAME_PATTERN = exports.parseCheckCommand = exports.resolveFile = exports.ensureHandoffExists = exports.readHandoff = exports.archiveFeedback = exports.writeFeedback = exports.readFeedback = exports.archiveFeedbackPath = exports.feedbackPath = exports.generateFeedback = exports.formatIssue = exports.parseVerdict = exports.getTotalCost = exports.recordCost = exports.saveBudget = exports.loadBudget = void 0;
|
|
4
4
|
var budget_1 = require("./budget");
|
|
5
5
|
Object.defineProperty(exports, "loadBudget", { enumerable: true, get: function () { return budget_1.loadBudget; } });
|
|
6
6
|
Object.defineProperty(exports, "saveBudget", { enumerable: true, get: function () { return budget_1.saveBudget; } });
|
|
@@ -44,6 +44,5 @@ Object.defineProperty(exports, "verifyCompletionTag", { enumerable: true, get: f
|
|
|
44
44
|
Object.defineProperty(exports, "cleanupBuildTags", { enumerable: true, get: function () { return tags_1.cleanupBuildTags; } });
|
|
45
45
|
var trajectory_1 = require("./trajectory");
|
|
46
46
|
Object.defineProperty(exports, "logTrajectory", { enumerable: true, get: function () { return trajectory_1.logTrajectory; } });
|
|
47
|
-
Object.defineProperty(exports, "makeTrajectoryEntry", { enumerable: true, get: function () { return trajectory_1.makeTrajectoryEntry; } });
|
|
48
47
|
Object.defineProperty(exports, "readTrajectory", { enumerable: true, get: function () { return trajectory_1.readTrajectory; } });
|
|
49
48
|
//# sourceMappingURL=index.js.map
|
package/dist/stores/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/stores/index.ts"],"names":[],"mappings":";;;AAAA,mCAA2E;AAAlE,oGAAA,UAAU,OAAA;AAAE,oGAAA,UAAU,OAAA;AAAE,oGAAA,UAAU,OAAA;AAAE,sGAAA,YAAY,OAAA;AACzD,uDAI2B;AAHzB,gHAAA,YAAY,OAAA;AACZ,+GAAA,WAAW,OAAA;AACX,oHAAA,gBAAgB,OAAA;AAElB,6CAMsB;AALpB,2GAAA,YAAY,OAAA;AACZ,kHAAA,mBAAmB,OAAA;AACnB,2GAAA,YAAY,OAAA;AACZ,4GAAA,aAAa,OAAA;AACb,8GAAA,eAAe,OAAA;AAEjB,qCAA4D;AAAnD,sGAAA,WAAW,OAAA;AAAE,8GAAA,mBAAmB,OAAA;AACzC,mCAAyD;AAAhD,qGAAA,WAAW,OAAA;AAAE,2GAAA,iBAAiB,OAAA;AACvC,mCAMiB;AALf,gHAAA,sBAAsB,OAAA;AACtB,qGAAA,WAAW,OAAA;AACX,4GAAA,kBAAkB,OAAA;AAClB,2GAAA,iBAAiB,OAAA;AACjB,oGAAA,UAAU,OAAA;AAEZ,iCAOgB;AANd,kGAAA,SAAS,OAAA;AACT,kGAAA,SAAS,OAAA;AACT,kGAAA,SAAS,OAAA;AACT,0GAAA,iBAAiB,OAAA;AACjB,qGAAA,YAAY,OAAA;AACZ,+GAAA,sBAAsB,OAAA;AAExB,+BAOe;AANb,yGAAA,iBAAiB,OAAA;AACjB,yGAAA,iBAAiB,OAAA;AACjB,wGAAA,gBAAgB,OAAA;AAChB,2GAAA,mBAAmB,OAAA;AACnB,2GAAA,mBAAmB,OAAA;AACnB,wGAAA,gBAAgB,OAAA;AAElB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/stores/index.ts"],"names":[],"mappings":";;;AAAA,mCAA2E;AAAlE,oGAAA,UAAU,OAAA;AAAE,oGAAA,UAAU,OAAA;AAAE,oGAAA,UAAU,OAAA;AAAE,sGAAA,YAAY,OAAA;AACzD,uDAI2B;AAHzB,gHAAA,YAAY,OAAA;AACZ,+GAAA,WAAW,OAAA;AACX,oHAAA,gBAAgB,OAAA;AAElB,6CAMsB;AALpB,2GAAA,YAAY,OAAA;AACZ,kHAAA,mBAAmB,OAAA;AACnB,2GAAA,YAAY,OAAA;AACZ,4GAAA,aAAa,OAAA;AACb,8GAAA,eAAe,OAAA;AAEjB,qCAA4D;AAAnD,sGAAA,WAAW,OAAA;AAAE,8GAAA,mBAAmB,OAAA;AACzC,mCAAyD;AAAhD,qGAAA,WAAW,OAAA;AAAE,2GAAA,iBAAiB,OAAA;AACvC,mCAMiB;AALf,gHAAA,sBAAsB,OAAA;AACtB,qGAAA,WAAW,OAAA;AACX,4GAAA,kBAAkB,OAAA;AAClB,2GAAA,iBAAiB,OAAA;AACjB,oGAAA,UAAU,OAAA;AAEZ,iCAOgB;AANd,kGAAA,SAAS,OAAA;AACT,kGAAA,SAAS,OAAA;AACT,kGAAA,SAAS,OAAA;AACT,0GAAA,iBAAiB,OAAA;AACjB,qGAAA,YAAY,OAAA;AACZ,+GAAA,sBAAsB,OAAA;AAExB,+BAOe;AANb,yGAAA,iBAAiB,OAAA;AACjB,yGAAA,iBAAiB,OAAA;AACjB,wGAAA,gBAAgB,OAAA;AAChB,2GAAA,mBAAmB,OAAA;AACnB,2GAAA,mBAAmB,OAAA;AACnB,wGAAA,gBAAgB,OAAA;AAElB,2CAA4D;AAAnD,2GAAA,aAAa,OAAA;AAAE,4GAAA,cAAc,OAAA"}
|
|
@@ -9,4 +9,6 @@ type RidgelineSettings = {
|
|
|
9
9
|
};
|
|
10
10
|
export declare const loadSettings: (ridgelineDir: string) => RidgelineSettings;
|
|
11
11
|
export declare const resolveNetworkAllowlist: (ridgelineDir: string) => string[];
|
|
12
|
+
/** Build the network allowlist for research agents: base allowlist + research domains. */
|
|
13
|
+
export declare const resolveResearchAllowlist: (ridgelineDir: string) => string[];
|
|
12
14
|
export {};
|
package/dist/stores/settings.js
CHANGED
|
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.resolveNetworkAllowlist = exports.loadSettings = exports.DEFAULT_NETWORK_ALLOWLIST = exports.CLAUDE_REQUIRED_DOMAINS = void 0;
|
|
36
|
+
exports.resolveResearchAllowlist = exports.resolveNetworkAllowlist = exports.loadSettings = exports.DEFAULT_NETWORK_ALLOWLIST = exports.CLAUDE_REQUIRED_DOMAINS = void 0;
|
|
37
37
|
const fs = __importStar(require("node:fs"));
|
|
38
38
|
const path = __importStar(require("node:path"));
|
|
39
39
|
/** Domains Claude needs for authentication and API access — always allowlisted. */
|
|
@@ -42,6 +42,19 @@ exports.CLAUDE_REQUIRED_DOMAINS = [
|
|
|
42
42
|
"downloads.claude.ai",
|
|
43
43
|
"http-intake.logs.us5.datadoghq.com",
|
|
44
44
|
];
|
|
45
|
+
/** Additional domains needed for research agents (web search, docs, academic). */
|
|
46
|
+
const RESEARCH_NETWORK_DOMAINS = [
|
|
47
|
+
"arxiv.org",
|
|
48
|
+
"export.arxiv.org",
|
|
49
|
+
"api.semanticscholar.org",
|
|
50
|
+
"scholar.google.com",
|
|
51
|
+
"docs.python.org",
|
|
52
|
+
"developer.mozilla.org",
|
|
53
|
+
"docs.rs",
|
|
54
|
+
"pkg.go.dev",
|
|
55
|
+
"learn.microsoft.com",
|
|
56
|
+
"devdocs.io",
|
|
57
|
+
];
|
|
45
58
|
exports.DEFAULT_NETWORK_ALLOWLIST = [
|
|
46
59
|
...exports.CLAUDE_REQUIRED_DOMAINS,
|
|
47
60
|
"registry.npmjs.org",
|
|
@@ -82,4 +95,14 @@ const resolveNetworkAllowlist = (ridgelineDir) => {
|
|
|
82
95
|
return [...merged];
|
|
83
96
|
};
|
|
84
97
|
exports.resolveNetworkAllowlist = resolveNetworkAllowlist;
|
|
98
|
+
/** Build the network allowlist for research agents: base allowlist + research domains. */
|
|
99
|
+
const resolveResearchAllowlist = (ridgelineDir) => {
|
|
100
|
+
const base = (0, exports.resolveNetworkAllowlist)(ridgelineDir);
|
|
101
|
+
// If base is empty, user set "*" (unrestricted) — keep it unrestricted
|
|
102
|
+
if (base.length === 0)
|
|
103
|
+
return [];
|
|
104
|
+
const merged = new Set([...base, ...RESEARCH_NETWORK_DOMAINS]);
|
|
105
|
+
return [...merged];
|
|
106
|
+
};
|
|
107
|
+
exports.resolveResearchAllowlist = resolveResearchAllowlist;
|
|
85
108
|
//# sourceMappingURL=settings.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../../src/stores/settings.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,4CAA6B;AAC7B,gDAAiC;AAEjC,mFAAmF;AACtE,QAAA,uBAAuB,GAAa;IAC/C,mBAAmB;IACnB,qBAAqB;IACrB,oCAAoC;CACrC,CAAA;AAEY,QAAA,yBAAyB,GAAa;IACjD,GAAG,+BAAuB;IAC1B,oBAAoB;IACpB,YAAY;IACZ,+BAA+B;IAC/B,2BAA2B;IAC3B,UAAU;IACV,wBAAwB;IACxB,WAAW;IACX,kBAAkB;IAClB,cAAc;IACd,kBAAkB;IAClB,YAAY;IACZ,YAAY;IACZ,eAAe;CAChB,CAAA;AASM,MAAM,YAAY,GAAG,CAAC,YAAoB,EAAqB,EAAE;IACtE,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,eAAe,CAAC,CAAA;IAC7D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAA;QAClD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAsB,CAAA;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAA;IACX,CAAC;AACH,CAAC,CAAA;AARY,QAAA,YAAY,gBAQxB;AAEM,MAAM,uBAAuB,GAAG,CAAC,YAAoB,EAAY,EAAE;IACxE,MAAM,QAAQ,GAAG,IAAA,oBAAY,EAAC,YAAY,CAAC,CAAA;IAC3C,MAAM,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,IAAI,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;QACjF,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS;QAC5B,CAAC,CAAC,CAAC,GAAG,iCAAyB,CAAC,CAAA;IAClC,iFAAiF;IACjF,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAA;IACjC,+EAA+E;IAC/E,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,+BAAuB,EAAE,GAAG,IAAI,CAAC,CAAC,CAAA;IAC7D,OAAO,CAAC,GAAG,MAAM,CAAC,CAAA;AACpB,CAAC,CAAA;AAVY,QAAA,uBAAuB,2BAUnC"}
|
|
1
|
+
{"version":3,"file":"settings.js","sourceRoot":"","sources":["../../src/stores/settings.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,4CAA6B;AAC7B,gDAAiC;AAEjC,mFAAmF;AACtE,QAAA,uBAAuB,GAAa;IAC/C,mBAAmB;IACnB,qBAAqB;IACrB,oCAAoC;CACrC,CAAA;AAED,kFAAkF;AAClF,MAAM,wBAAwB,GAAa;IACzC,WAAW;IACX,kBAAkB;IAClB,yBAAyB;IACzB,oBAAoB;IACpB,iBAAiB;IACjB,uBAAuB;IACvB,SAAS;IACT,YAAY;IACZ,qBAAqB;IACrB,YAAY;CACb,CAAA;AAEY,QAAA,yBAAyB,GAAa;IACjD,GAAG,+BAAuB;IAC1B,oBAAoB;IACpB,YAAY;IACZ,+BAA+B;IAC/B,2BAA2B;IAC3B,UAAU;IACV,wBAAwB;IACxB,WAAW;IACX,kBAAkB;IAClB,cAAc;IACd,kBAAkB;IAClB,YAAY;IACZ,YAAY;IACZ,eAAe;CAChB,CAAA;AASM,MAAM,YAAY,GAAG,CAAC,YAAoB,EAAqB,EAAE;IACtE,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,eAAe,CAAC,CAAA;IAC7D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAA;QAClD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAsB,CAAA;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAA;IACX,CAAC;AACH,CAAC,CAAA;AARY,QAAA,YAAY,gBAQxB;AAEM,MAAM,uBAAuB,GAAG,CAAC,YAAoB,EAAY,EAAE;IACxE,MAAM,QAAQ,GAAG,IAAA,oBAAY,EAAC,YAAY,CAAC,CAAA;IAC3C,MAAM,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,SAAS,IAAI,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;QACjF,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS;QAC5B,CAAC,CAAC,CAAC,GAAG,iCAAyB,CAAC,CAAA;IAClC,iFAAiF;IACjF,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAA;IACjC,+EAA+E;IAC/E,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,+BAAuB,EAAE,GAAG,IAAI,CAAC,CAAC,CAAA;IAC7D,OAAO,CAAC,GAAG,MAAM,CAAC,CAAA;AACpB,CAAC,CAAA;AAVY,QAAA,uBAAuB,2BAUnC;AAED,0FAA0F;AACnF,MAAM,wBAAwB,GAAG,CAAC,YAAoB,EAAY,EAAE;IACzE,MAAM,IAAI,GAAG,IAAA,+BAAuB,EAAC,YAAY,CAAC,CAAA;IAClD,uEAAuE;IACvE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAA;IAChC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,EAAE,GAAG,wBAAwB,CAAC,CAAC,CAAA;IAC9D,OAAO,CAAC,GAAG,MAAM,CAAC,CAAA;AACpB,CAAC,CAAA;AANY,QAAA,wBAAwB,4BAMpC"}
|
package/dist/stores/state.d.ts
CHANGED
|
@@ -18,3 +18,7 @@ export declare const getNextPipelineStage: (buildDir: string) => PipelineStage |
|
|
|
18
18
|
* return list of files/dirs to delete from disk.
|
|
19
19
|
*/
|
|
20
20
|
export declare const rewindTo: (buildDir: string, buildName: string, targetStage: PipelineStage) => string[];
|
|
21
|
+
/** Record matched shape names in build state. */
|
|
22
|
+
export declare const recordMatchedShapes: (buildDir: string, buildName: string, shapes: string[]) => void;
|
|
23
|
+
/** Read matched shapes from build state. Returns empty array if none recorded. */
|
|
24
|
+
export declare const getMatchedShapes: (buildDir: string) => string[];
|
package/dist/stores/state.js
CHANGED
|
@@ -33,14 +33,18 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.rewindTo = exports.getNextPipelineStage = exports.markBuildRunning = exports.advancePipeline = exports.getPipelineStatus = exports.getNextIncompletePhase = exports.resetRetries = exports.updatePhaseStatus = exports.initState = exports.saveState = exports.loadState = void 0;
|
|
36
|
+
exports.getMatchedShapes = exports.recordMatchedShapes = exports.rewindTo = exports.getNextPipelineStage = exports.markBuildRunning = exports.advancePipeline = exports.getPipelineStatus = exports.getNextIncompletePhase = exports.resetRetries = exports.updatePhaseStatus = exports.initState = exports.saveState = exports.loadState = void 0;
|
|
37
37
|
const fs = __importStar(require("node:fs"));
|
|
38
38
|
const path = __importStar(require("node:path"));
|
|
39
39
|
const tags_1 = require("./tags");
|
|
40
|
+
const atomic_write_1 = require("../utils/atomic-write");
|
|
40
41
|
const statePath = (buildDir) => path.join(buildDir, "state.json");
|
|
41
42
|
const DEFAULT_PIPELINE = {
|
|
42
43
|
shape: "pending",
|
|
44
|
+
design: "skipped",
|
|
43
45
|
spec: "pending",
|
|
46
|
+
research: "skipped",
|
|
47
|
+
refine: "skipped",
|
|
44
48
|
plan: "pending",
|
|
45
49
|
build: "pending",
|
|
46
50
|
};
|
|
@@ -58,7 +62,7 @@ const loadState = (buildDir) => {
|
|
|
58
62
|
};
|
|
59
63
|
exports.loadState = loadState;
|
|
60
64
|
const saveState = (buildDir, state) => {
|
|
61
|
-
|
|
65
|
+
(0, atomic_write_1.atomicWriteSync)(statePath(buildDir), JSON.stringify(state, null, 2) + "\n");
|
|
62
66
|
};
|
|
63
67
|
exports.saveState = saveState;
|
|
64
68
|
const initState = (buildName, phases) => ({
|
|
@@ -119,14 +123,19 @@ exports.getNextIncompletePhase = getNextIncompletePhase;
|
|
|
119
123
|
/** Derive pipeline state from existing artifacts on disk (for legacy state files). */
|
|
120
124
|
const derivePipelineFromArtifacts = (buildDir) => {
|
|
121
125
|
const hasShape = fs.existsSync(path.join(buildDir, "shape.md"));
|
|
126
|
+
const hasDesign = fs.existsSync(path.join(buildDir, "design.md"));
|
|
122
127
|
const hasSpec = fs.existsSync(path.join(buildDir, "spec.md"));
|
|
123
128
|
const hasConstraints = fs.existsSync(path.join(buildDir, "constraints.md"));
|
|
129
|
+
const hasResearch = fs.existsSync(path.join(buildDir, "research.md"));
|
|
124
130
|
const phasesDir = path.join(buildDir, "phases");
|
|
125
131
|
const hasPhases = fs.existsSync(phasesDir) &&
|
|
126
132
|
fs.readdirSync(phasesDir).some((f) => f.endsWith(".md") && /^\d+-.+\.md$/.test(f));
|
|
127
133
|
return {
|
|
128
134
|
shape: hasShape ? "complete" : "pending",
|
|
135
|
+
design: hasDesign ? "complete" : "skipped",
|
|
129
136
|
spec: hasSpec && hasConstraints ? "complete" : "pending",
|
|
137
|
+
research: hasResearch ? "complete" : "skipped",
|
|
138
|
+
refine: hasResearch ? "complete" : "skipped",
|
|
130
139
|
plan: hasPhases ? "complete" : "pending",
|
|
131
140
|
build: "pending",
|
|
132
141
|
};
|
|
@@ -139,7 +148,10 @@ const getPipelineStatus = (buildDir) => {
|
|
|
139
148
|
// Belt and suspenders: if state says complete but file is missing, trust disk
|
|
140
149
|
return {
|
|
141
150
|
shape: fromState.shape === "complete" && fromDisk.shape === "complete" ? "complete" : fromDisk.shape,
|
|
151
|
+
design: fromState.design ?? "skipped",
|
|
142
152
|
spec: fromState.spec === "complete" && fromDisk.spec === "complete" ? "complete" : fromDisk.spec,
|
|
153
|
+
research: fromState.research ?? "skipped",
|
|
154
|
+
refine: fromState.refine ?? "skipped",
|
|
143
155
|
plan: fromState.plan === "complete" && fromDisk.plan === "complete" ? "complete" : fromDisk.plan,
|
|
144
156
|
build: fromState.build === "pending" ? "pending" : fromState.build,
|
|
145
157
|
};
|
|
@@ -180,11 +192,15 @@ const markBuildRunning = (buildDir, buildName) => {
|
|
|
180
192
|
(0, exports.saveState)(buildDir, state);
|
|
181
193
|
};
|
|
182
194
|
exports.markBuildRunning = markBuildRunning;
|
|
183
|
-
|
|
195
|
+
// The ordered list of stages for auto-advance.
|
|
196
|
+
// Research and refine are excluded — they are opt-in only.
|
|
197
|
+
const REQUIRED_PIPELINE_STAGES = ["shape", "spec", "plan", "build"];
|
|
198
|
+
// All stages including optional ones, for rewind calculations.
|
|
199
|
+
const ALL_PIPELINE_STAGES = ["shape", "design", "spec", "research", "refine", "plan", "build"];
|
|
184
200
|
/** Determine the next incomplete pipeline stage. */
|
|
185
201
|
const getNextPipelineStage = (buildDir) => {
|
|
186
202
|
const status = (0, exports.getPipelineStatus)(buildDir);
|
|
187
|
-
for (const stage of
|
|
203
|
+
for (const stage of REQUIRED_PIPELINE_STAGES) {
|
|
188
204
|
const s = status[stage];
|
|
189
205
|
if (s === "pending" || s === "running")
|
|
190
206
|
return stage;
|
|
@@ -197,6 +213,23 @@ const collectStageFiles = (buildDir, stage) => {
|
|
|
197
213
|
const files = [];
|
|
198
214
|
const phasesDir = path.join(buildDir, "phases");
|
|
199
215
|
switch (stage) {
|
|
216
|
+
case "research": {
|
|
217
|
+
const fp = path.join(buildDir, "research.md");
|
|
218
|
+
if (fs.existsSync(fp))
|
|
219
|
+
files.push(fp);
|
|
220
|
+
break;
|
|
221
|
+
}
|
|
222
|
+
case "design": {
|
|
223
|
+
const fp = path.join(buildDir, "design.md");
|
|
224
|
+
if (fs.existsSync(fp))
|
|
225
|
+
files.push(fp);
|
|
226
|
+
break;
|
|
227
|
+
}
|
|
228
|
+
case "refine":
|
|
229
|
+
// Refine modifies spec.md in-place — no separate artifact to delete.
|
|
230
|
+
// Rewinding to refine means "undo the refinement" which requires
|
|
231
|
+
// rewinding spec too (the user should rewind to spec instead).
|
|
232
|
+
break;
|
|
200
233
|
case "spec":
|
|
201
234
|
for (const f of ["spec.md", "constraints.md", "taste.md"]) {
|
|
202
235
|
const fp = path.join(buildDir, f);
|
|
@@ -226,26 +259,35 @@ const collectStageFiles = (buildDir, stage) => {
|
|
|
226
259
|
return files;
|
|
227
260
|
};
|
|
228
261
|
/** Reset pipeline state for stages downstream of targetStage. */
|
|
229
|
-
const resetPipelineState = (buildDir, buildName, targetStage,
|
|
262
|
+
const resetPipelineState = (buildDir, buildName, targetStage, _resetStages) => {
|
|
230
263
|
const state = (0, exports.loadState)(buildDir);
|
|
231
264
|
if (!state)
|
|
232
265
|
return;
|
|
233
|
-
const targetIndex =
|
|
234
|
-
for (const stage of
|
|
235
|
-
if (
|
|
236
|
-
|
|
266
|
+
const targetIndex = ALL_PIPELINE_STAGES.indexOf(targetStage);
|
|
267
|
+
for (const stage of ALL_PIPELINE_STAGES) {
|
|
268
|
+
if (ALL_PIPELINE_STAGES.indexOf(stage) > targetIndex) {
|
|
269
|
+
// Optional stages reset to "skipped", required stages to "pending"
|
|
270
|
+
if (stage === "research" || stage === "refine" || stage === "design") {
|
|
271
|
+
state.pipeline[stage] = "skipped";
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
state.pipeline[stage] = "pending";
|
|
275
|
+
}
|
|
237
276
|
}
|
|
238
277
|
}
|
|
239
278
|
if (targetStage === "build") {
|
|
240
279
|
state.pipeline.build = "pending";
|
|
241
280
|
}
|
|
281
|
+
else if (targetStage === "research" || targetStage === "refine" || targetStage === "design") {
|
|
282
|
+
state.pipeline[targetStage] = "complete";
|
|
283
|
+
}
|
|
242
284
|
else {
|
|
243
285
|
state.pipeline[targetStage] = "complete";
|
|
244
286
|
}
|
|
245
|
-
if (
|
|
287
|
+
if (_resetStages.includes("plan") || _resetStages.includes("build")) {
|
|
246
288
|
state.phases = [];
|
|
247
289
|
}
|
|
248
|
-
if (
|
|
290
|
+
if (_resetStages.includes("build")) {
|
|
249
291
|
(0, tags_1.cleanupBuildTags)(buildName);
|
|
250
292
|
}
|
|
251
293
|
(0, exports.saveState)(buildDir, state);
|
|
@@ -255,10 +297,31 @@ const resetPipelineState = (buildDir, buildName, targetStage, resetStages) => {
|
|
|
255
297
|
* return list of files/dirs to delete from disk.
|
|
256
298
|
*/
|
|
257
299
|
const rewindTo = (buildDir, buildName, targetStage) => {
|
|
258
|
-
const resetStages =
|
|
300
|
+
const resetStages = ALL_PIPELINE_STAGES.slice(ALL_PIPELINE_STAGES.indexOf(targetStage) + 1);
|
|
259
301
|
const toDelete = resetStages.flatMap((stage) => collectStageFiles(buildDir, stage));
|
|
260
302
|
resetPipelineState(buildDir, buildName, targetStage, resetStages);
|
|
261
303
|
return toDelete;
|
|
262
304
|
};
|
|
263
305
|
exports.rewindTo = rewindTo;
|
|
306
|
+
/** Record matched shape names in build state. */
|
|
307
|
+
const recordMatchedShapes = (buildDir, buildName, shapes) => {
|
|
308
|
+
let state = (0, exports.loadState)(buildDir);
|
|
309
|
+
if (!state) {
|
|
310
|
+
state = {
|
|
311
|
+
buildName,
|
|
312
|
+
startedAt: new Date().toISOString(),
|
|
313
|
+
pipeline: { ...DEFAULT_PIPELINE },
|
|
314
|
+
phases: [],
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
state.matchedShapes = shapes;
|
|
318
|
+
(0, exports.saveState)(buildDir, state);
|
|
319
|
+
};
|
|
320
|
+
exports.recordMatchedShapes = recordMatchedShapes;
|
|
321
|
+
/** Read matched shapes from build state. Returns empty array if none recorded. */
|
|
322
|
+
const getMatchedShapes = (buildDir) => {
|
|
323
|
+
const state = (0, exports.loadState)(buildDir);
|
|
324
|
+
return state?.matchedShapes ?? [];
|
|
325
|
+
};
|
|
326
|
+
exports.getMatchedShapes = getMatchedShapes;
|
|
264
327
|
//# sourceMappingURL=state.js.map
|