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.
Files changed (212) hide show
  1. package/README.md +53 -9
  2. package/dist/agents/core/designer.md +131 -0
  3. package/dist/agents/core/refiner.md +61 -0
  4. package/dist/agents/core/researcher.md +78 -0
  5. package/dist/agents/core/specifier.md +16 -0
  6. package/dist/agents/researchers/academic.md +27 -0
  7. package/dist/agents/researchers/competitive.md +28 -0
  8. package/dist/agents/researchers/context.md +46 -0
  9. package/dist/agents/researchers/ecosystem.md +28 -0
  10. package/dist/agents/researchers/gaps.md +67 -0
  11. package/dist/agents/specifiers/visual-coherence.md +55 -0
  12. package/dist/cli.js +83 -1
  13. package/dist/cli.js.map +1 -1
  14. package/dist/commands/create.js +20 -2
  15. package/dist/commands/create.js.map +1 -1
  16. package/dist/commands/design.d.ts +8 -0
  17. package/dist/commands/design.js +130 -0
  18. package/dist/commands/design.js.map +1 -0
  19. package/dist/commands/index.d.ts +1 -0
  20. package/dist/commands/index.js +3 -1
  21. package/dist/commands/index.js.map +1 -1
  22. package/dist/commands/plan.js +3 -3
  23. package/dist/commands/plan.js.map +1 -1
  24. package/dist/commands/qa-workflow.d.ts +33 -0
  25. package/dist/commands/qa-workflow.js +139 -0
  26. package/dist/commands/qa-workflow.js.map +1 -0
  27. package/dist/commands/refine.d.ts +8 -0
  28. package/dist/commands/refine.js +105 -0
  29. package/dist/commands/refine.js.map +1 -0
  30. package/dist/commands/research.d.ts +10 -0
  31. package/dist/commands/research.js +146 -0
  32. package/dist/commands/research.js.map +1 -0
  33. package/dist/commands/rewind.js +5 -3
  34. package/dist/commands/rewind.js.map +1 -1
  35. package/dist/commands/shape.js +36 -121
  36. package/dist/commands/shape.js.map +1 -1
  37. package/dist/commands/spec.js +1 -0
  38. package/dist/commands/spec.js.map +1 -1
  39. package/dist/engine/claude/stream.display.js +0 -1
  40. package/dist/engine/claude/stream.display.js.map +1 -1
  41. package/dist/engine/claude/stream.parse.d.ts +1 -15
  42. package/dist/engine/claude/stream.parse.js +3 -21
  43. package/dist/engine/claude/stream.parse.js.map +1 -1
  44. package/dist/engine/claude/stream.result.js +2 -2
  45. package/dist/engine/claude/stream.types.d.ts +15 -0
  46. package/dist/engine/claude/stream.types.js +23 -0
  47. package/dist/engine/claude/stream.types.js.map +1 -0
  48. package/dist/engine/discovery/agent.registry.d.ts +4 -0
  49. package/dist/engine/discovery/agent.registry.js +46 -18
  50. package/dist/engine/discovery/agent.registry.js.map +1 -1
  51. package/dist/engine/discovery/flavour.config.d.ts +9 -0
  52. package/dist/engine/discovery/flavour.config.js +61 -0
  53. package/dist/engine/discovery/flavour.config.js.map +1 -0
  54. package/dist/engine/discovery/plugin.scan.d.ts +1 -0
  55. package/dist/engine/discovery/plugin.scan.js +29 -1
  56. package/dist/engine/discovery/plugin.scan.js.map +1 -1
  57. package/dist/engine/discovery/skill.check.d.ts +19 -0
  58. package/dist/engine/discovery/skill.check.js +145 -0
  59. package/dist/engine/discovery/skill.check.js.map +1 -0
  60. package/dist/engine/pipeline/build.exec.js +1 -0
  61. package/dist/engine/pipeline/build.exec.js.map +1 -1
  62. package/dist/engine/pipeline/ensemble.exec.d.ts +12 -1
  63. package/dist/engine/pipeline/ensemble.exec.js +20 -10
  64. package/dist/engine/pipeline/ensemble.exec.js.map +1 -1
  65. package/dist/engine/pipeline/phase.sequence.js +10 -10
  66. package/dist/engine/pipeline/phase.sequence.js.map +1 -1
  67. package/dist/engine/pipeline/pipeline.shared.d.ts +6 -0
  68. package/dist/engine/pipeline/pipeline.shared.js +24 -1
  69. package/dist/engine/pipeline/pipeline.shared.js.map +1 -1
  70. package/dist/engine/pipeline/plan.exec.js +1 -0
  71. package/dist/engine/pipeline/plan.exec.js.map +1 -1
  72. package/dist/engine/pipeline/refine.exec.d.ts +10 -0
  73. package/dist/engine/pipeline/refine.exec.js +91 -0
  74. package/dist/engine/pipeline/refine.exec.js.map +1 -0
  75. package/dist/engine/pipeline/research.exec.d.ts +17 -0
  76. package/dist/engine/pipeline/research.exec.js +196 -0
  77. package/dist/engine/pipeline/research.exec.js.map +1 -0
  78. package/dist/engine/pipeline/review.exec.js +23 -0
  79. package/dist/engine/pipeline/review.exec.js.map +1 -1
  80. package/dist/engine/pipeline/specify.exec.d.ts +1 -0
  81. package/dist/engine/pipeline/specify.exec.js +114 -44
  82. package/dist/engine/pipeline/specify.exec.js.map +1 -1
  83. package/dist/flavours/data-analysis/core/refiner.md +65 -0
  84. package/dist/flavours/data-analysis/core/researcher.md +81 -0
  85. package/dist/flavours/data-analysis/researchers/academic.md +29 -0
  86. package/dist/flavours/data-analysis/researchers/competitive.md +29 -0
  87. package/dist/flavours/data-analysis/researchers/ecosystem.md +29 -0
  88. package/dist/flavours/data-analysis/researchers/gaps.md +59 -0
  89. package/dist/flavours/game-dev/core/refiner.md +65 -0
  90. package/dist/flavours/game-dev/core/researcher.md +81 -0
  91. package/dist/flavours/game-dev/researchers/academic.md +31 -0
  92. package/dist/flavours/game-dev/researchers/competitive.md +30 -0
  93. package/dist/flavours/game-dev/researchers/ecosystem.md +29 -0
  94. package/dist/flavours/game-dev/researchers/gaps.md +59 -0
  95. package/dist/flavours/legal-drafting/core/refiner.md +65 -0
  96. package/dist/flavours/legal-drafting/core/researcher.md +81 -0
  97. package/dist/flavours/legal-drafting/researchers/academic.md +31 -0
  98. package/dist/flavours/legal-drafting/researchers/competitive.md +31 -0
  99. package/dist/flavours/legal-drafting/researchers/ecosystem.md +30 -0
  100. package/dist/flavours/legal-drafting/researchers/gaps.md +59 -0
  101. package/dist/flavours/machine-learning/core/refiner.md +65 -0
  102. package/dist/flavours/machine-learning/core/researcher.md +81 -0
  103. package/dist/flavours/machine-learning/researchers/academic.md +32 -0
  104. package/dist/flavours/machine-learning/researchers/competitive.md +32 -0
  105. package/dist/flavours/machine-learning/researchers/ecosystem.md +31 -0
  106. package/dist/flavours/machine-learning/researchers/gaps.md +59 -0
  107. package/dist/flavours/mobile-app/core/refiner.md +65 -0
  108. package/dist/flavours/mobile-app/core/researcher.md +81 -0
  109. package/dist/flavours/mobile-app/researchers/academic.md +31 -0
  110. package/dist/flavours/mobile-app/researchers/competitive.md +32 -0
  111. package/dist/flavours/mobile-app/researchers/ecosystem.md +31 -0
  112. package/dist/flavours/mobile-app/researchers/gaps.md +59 -0
  113. package/dist/flavours/music-composition/core/refiner.md +65 -0
  114. package/dist/flavours/music-composition/core/researcher.md +81 -0
  115. package/dist/flavours/music-composition/researchers/academic.md +32 -0
  116. package/dist/flavours/music-composition/researchers/competitive.md +32 -0
  117. package/dist/flavours/music-composition/researchers/ecosystem.md +32 -0
  118. package/dist/flavours/music-composition/researchers/gaps.md +59 -0
  119. package/dist/flavours/novel-writing/core/refiner.md +65 -0
  120. package/dist/flavours/novel-writing/core/researcher.md +81 -0
  121. package/dist/flavours/novel-writing/researchers/academic.md +32 -0
  122. package/dist/flavours/novel-writing/researchers/competitive.md +32 -0
  123. package/dist/flavours/novel-writing/researchers/ecosystem.md +32 -0
  124. package/dist/flavours/novel-writing/researchers/gaps.md +59 -0
  125. package/dist/flavours/screenwriting/core/refiner.md +65 -0
  126. package/dist/flavours/screenwriting/core/researcher.md +81 -0
  127. package/dist/flavours/screenwriting/researchers/academic.md +32 -0
  128. package/dist/flavours/screenwriting/researchers/competitive.md +32 -0
  129. package/dist/flavours/screenwriting/researchers/ecosystem.md +32 -0
  130. package/dist/flavours/screenwriting/researchers/gaps.md +59 -0
  131. package/dist/flavours/security-audit/core/refiner.md +65 -0
  132. package/dist/flavours/security-audit/core/researcher.md +81 -0
  133. package/dist/flavours/security-audit/researchers/academic.md +32 -0
  134. package/dist/flavours/security-audit/researchers/competitive.md +32 -0
  135. package/dist/flavours/security-audit/researchers/ecosystem.md +32 -0
  136. package/dist/flavours/security-audit/researchers/gaps.md +59 -0
  137. package/dist/flavours/software-engineering/core/builder.md +2 -0
  138. package/dist/flavours/software-engineering/core/refiner.md +65 -0
  139. package/dist/flavours/software-engineering/core/researcher.md +81 -0
  140. package/dist/flavours/software-engineering/core/reviewer.md +2 -0
  141. package/dist/flavours/software-engineering/flavour.json +7 -0
  142. package/dist/flavours/software-engineering/researchers/academic.md +32 -0
  143. package/dist/flavours/software-engineering/researchers/competitive.md +32 -0
  144. package/dist/flavours/software-engineering/researchers/ecosystem.md +32 -0
  145. package/dist/flavours/software-engineering/researchers/gaps.md +59 -0
  146. package/dist/flavours/technical-writing/core/refiner.md +65 -0
  147. package/dist/flavours/technical-writing/core/researcher.md +81 -0
  148. package/dist/flavours/technical-writing/researchers/academic.md +32 -0
  149. package/dist/flavours/technical-writing/researchers/competitive.md +32 -0
  150. package/dist/flavours/technical-writing/researchers/ecosystem.md +32 -0
  151. package/dist/flavours/technical-writing/researchers/gaps.md +59 -0
  152. package/dist/flavours/test-suite/core/refiner.md +65 -0
  153. package/dist/flavours/test-suite/core/researcher.md +81 -0
  154. package/dist/flavours/test-suite/researchers/academic.md +32 -0
  155. package/dist/flavours/test-suite/researchers/competitive.md +32 -0
  156. package/dist/flavours/test-suite/researchers/ecosystem.md +32 -0
  157. package/dist/flavours/test-suite/researchers/gaps.md +59 -0
  158. package/dist/flavours/translation/core/refiner.md +65 -0
  159. package/dist/flavours/translation/core/researcher.md +81 -0
  160. package/dist/flavours/translation/researchers/academic.md +32 -0
  161. package/dist/flavours/translation/researchers/competitive.md +32 -0
  162. package/dist/flavours/translation/researchers/ecosystem.md +32 -0
  163. package/dist/flavours/translation/researchers/gaps.md +59 -0
  164. package/dist/flavours/web-game/core/builder.md +123 -0
  165. package/dist/flavours/web-game/core/reviewer.md +159 -0
  166. package/dist/flavours/web-game/flavour.json +9 -0
  167. package/dist/flavours/web-ui/core/builder.md +117 -0
  168. package/dist/flavours/web-ui/core/reviewer.md +155 -0
  169. package/dist/flavours/web-ui/flavour.json +10 -0
  170. package/dist/plugin/visual-tools/plugin.json +4 -0
  171. package/dist/plugin/visual-tools/skills/a11y-audit/SKILL.md +57 -0
  172. package/dist/plugin/visual-tools/skills/agent-browser/SKILL.md +56 -0
  173. package/dist/plugin/visual-tools/skills/agent-browser/references/viewports.md +17 -0
  174. package/dist/plugin/visual-tools/skills/canvas-screenshot/SKILL.md +84 -0
  175. package/dist/plugin/visual-tools/skills/css-audit/SKILL.md +50 -0
  176. package/dist/plugin/visual-tools/skills/lighthouse/SKILL.md +58 -0
  177. package/dist/plugin/visual-tools/skills/shader-validate/SKILL.md +77 -0
  178. package/dist/plugin/visual-tools/skills/visual-diff/SKILL.md +68 -0
  179. package/dist/shapes/detect.d.ts +8 -0
  180. package/dist/shapes/detect.js +87 -0
  181. package/dist/shapes/detect.js.map +1 -0
  182. package/dist/shapes/game-visual.json +8 -0
  183. package/dist/shapes/print-layout.json +8 -0
  184. package/dist/shapes/web-visual.json +9 -0
  185. package/dist/stores/budget.js +2 -1
  186. package/dist/stores/budget.js.map +1 -1
  187. package/dist/stores/feedback.format.d.ts +3 -0
  188. package/dist/stores/feedback.format.js +62 -0
  189. package/dist/stores/feedback.format.js.map +1 -0
  190. package/dist/stores/feedback.parse.d.ts +2 -0
  191. package/dist/stores/feedback.parse.js +121 -0
  192. package/dist/stores/feedback.parse.js.map +1 -0
  193. package/dist/stores/feedback.verdict.d.ts +2 -4
  194. package/dist/stores/feedback.verdict.js +7 -175
  195. package/dist/stores/feedback.verdict.js.map +1 -1
  196. package/dist/stores/index.d.ts +1 -1
  197. package/dist/stores/index.js +1 -2
  198. package/dist/stores/index.js.map +1 -1
  199. package/dist/stores/settings.d.ts +2 -0
  200. package/dist/stores/settings.js +24 -1
  201. package/dist/stores/settings.js.map +1 -1
  202. package/dist/stores/state.d.ts +4 -0
  203. package/dist/stores/state.js +75 -12
  204. package/dist/stores/state.js.map +1 -1
  205. package/dist/stores/trajectory.d.ts +2 -3
  206. package/dist/stores/trajectory.js +6 -7
  207. package/dist/stores/trajectory.js.map +1 -1
  208. package/dist/types.d.ts +15 -3
  209. package/dist/utils/atomic-write.d.ts +6 -0
  210. package/dist/utils/atomic-write.js +62 -0
  211. package/dist/utils/atomic-write.js.map +1 -0
  212. 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
- import { ReviewIssue, ReviewVerdict } from "../types";
2
- export declare const parseVerdict: (text: string) => ReviewVerdict;
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
- // Normalize an issue entryaccept 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
- // 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 compatibilityimplementations 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":"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"}
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"}
@@ -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, makeTrajectoryEntry, readTrajectory } from './trajectory';
9
+ export { logTrajectory, readTrajectory } from './trajectory';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.readTrajectory = exports.makeTrajectoryEntry = 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;
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
@@ -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,2CAAiF;AAAxE,2GAAA,aAAa,OAAA;AAAE,iHAAA,mBAAmB,OAAA;AAAE,4GAAA,cAAc,OAAA"}
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 {};
@@ -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"}
@@ -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[];
@@ -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
- fs.writeFileSync(statePath(buildDir), JSON.stringify(state, null, 2) + "\n");
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
- const PIPELINE_STAGES = ["shape", "spec", "plan", "build"];
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 PIPELINE_STAGES) {
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, resetStages) => {
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 = PIPELINE_STAGES.indexOf(targetStage);
234
- for (const stage of PIPELINE_STAGES) {
235
- if (PIPELINE_STAGES.indexOf(stage) > targetIndex) {
236
- state.pipeline[stage] = "pending";
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 (resetStages.includes("plan") || resetStages.includes("build")) {
287
+ if (_resetStages.includes("plan") || _resetStages.includes("build")) {
246
288
  state.phases = [];
247
289
  }
248
- if (resetStages.includes("build")) {
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 = PIPELINE_STAGES.slice(PIPELINE_STAGES.indexOf(targetStage) + 1);
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