stoa-mcp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/LICENSE +65 -0
  2. package/README.md +397 -0
  3. package/dist/cli/build.d.ts +39 -0
  4. package/dist/cli/build.d.ts.map +1 -0
  5. package/dist/cli/build.js +288 -0
  6. package/dist/cli/build.js.map +1 -0
  7. package/dist/cli/review-loop.d.ts +2 -0
  8. package/dist/cli/review-loop.d.ts.map +1 -0
  9. package/dist/cli/review-loop.js +97 -0
  10. package/dist/cli/review-loop.js.map +1 -0
  11. package/dist/cli/scenarios-runner.d.ts +12 -0
  12. package/dist/cli/scenarios-runner.d.ts.map +1 -0
  13. package/dist/cli/scenarios-runner.js +158 -0
  14. package/dist/cli/scenarios-runner.js.map +1 -0
  15. package/dist/cli/verify.d.ts +13 -0
  16. package/dist/cli/verify.d.ts.map +1 -0
  17. package/dist/cli/verify.js +149 -0
  18. package/dist/cli/verify.js.map +1 -0
  19. package/dist/cli.d.ts +3 -0
  20. package/dist/cli.d.ts.map +1 -0
  21. package/dist/cli.js +1135 -0
  22. package/dist/cli.js.map +1 -0
  23. package/dist/core/index.d.ts +3 -0
  24. package/dist/core/index.d.ts.map +1 -0
  25. package/dist/core/index.js +2 -0
  26. package/dist/core/index.js.map +1 -0
  27. package/dist/core/parsers.d.ts +29 -0
  28. package/dist/core/parsers.d.ts.map +1 -0
  29. package/dist/core/parsers.js +296 -0
  30. package/dist/core/parsers.js.map +1 -0
  31. package/dist/core/parsers.test.d.ts +2 -0
  32. package/dist/core/parsers.test.d.ts.map +1 -0
  33. package/dist/core/parsers.test.js +198 -0
  34. package/dist/core/parsers.test.js.map +1 -0
  35. package/dist/core/prompts.d.ts +30 -0
  36. package/dist/core/prompts.d.ts.map +1 -0
  37. package/dist/core/prompts.js +346 -0
  38. package/dist/core/prompts.js.map +1 -0
  39. package/dist/core/refine.d.ts +38 -0
  40. package/dist/core/refine.d.ts.map +1 -0
  41. package/dist/core/refine.js +233 -0
  42. package/dist/core/refine.js.map +1 -0
  43. package/dist/core/spec-score.d.ts +17 -0
  44. package/dist/core/spec-score.d.ts.map +1 -0
  45. package/dist/core/spec-score.js +59 -0
  46. package/dist/core/spec-score.js.map +1 -0
  47. package/dist/formatters/index.d.ts +2 -0
  48. package/dist/formatters/index.d.ts.map +1 -0
  49. package/dist/formatters/index.js +2 -0
  50. package/dist/formatters/index.js.map +1 -0
  51. package/dist/formatters/stage-formatters.d.ts +10 -0
  52. package/dist/formatters/stage-formatters.d.ts.map +1 -0
  53. package/dist/formatters/stage-formatters.js +100 -0
  54. package/dist/formatters/stage-formatters.js.map +1 -0
  55. package/dist/formatters/stage-formatters.test.d.ts +2 -0
  56. package/dist/formatters/stage-formatters.test.d.ts.map +1 -0
  57. package/dist/formatters/stage-formatters.test.js +107 -0
  58. package/dist/formatters/stage-formatters.test.js.map +1 -0
  59. package/dist/guardrails/index.d.ts +2 -0
  60. package/dist/guardrails/index.d.ts.map +1 -0
  61. package/dist/guardrails/index.js +2 -0
  62. package/dist/guardrails/index.js.map +1 -0
  63. package/dist/guardrails/loader.d.ts +9 -0
  64. package/dist/guardrails/loader.d.ts.map +1 -0
  65. package/dist/guardrails/loader.js +56 -0
  66. package/dist/guardrails/loader.js.map +1 -0
  67. package/dist/guardrails/refine.d.ts +53 -0
  68. package/dist/guardrails/refine.d.ts.map +1 -0
  69. package/dist/guardrails/refine.js +184 -0
  70. package/dist/guardrails/refine.js.map +1 -0
  71. package/dist/index.d.ts +6 -0
  72. package/dist/index.d.ts.map +1 -0
  73. package/dist/index.js +196 -0
  74. package/dist/index.js.map +1 -0
  75. package/dist/storage/change-detection.d.ts +2 -0
  76. package/dist/storage/change-detection.d.ts.map +1 -0
  77. package/dist/storage/change-detection.js +47 -0
  78. package/dist/storage/change-detection.js.map +1 -0
  79. package/dist/storage/change-detection.test.d.ts +2 -0
  80. package/dist/storage/change-detection.test.d.ts.map +1 -0
  81. package/dist/storage/change-detection.test.js +81 -0
  82. package/dist/storage/change-detection.test.js.map +1 -0
  83. package/dist/storage/index.d.ts +9 -0
  84. package/dist/storage/index.d.ts.map +1 -0
  85. package/dist/storage/index.js +6 -0
  86. package/dist/storage/index.js.map +1 -0
  87. package/dist/storage/moodboard-describe.d.ts +14 -0
  88. package/dist/storage/moodboard-describe.d.ts.map +1 -0
  89. package/dist/storage/moodboard-describe.js +185 -0
  90. package/dist/storage/moodboard-describe.js.map +1 -0
  91. package/dist/storage/moodboard-sync.d.ts +11 -0
  92. package/dist/storage/moodboard-sync.d.ts.map +1 -0
  93. package/dist/storage/moodboard-sync.js +205 -0
  94. package/dist/storage/moodboard-sync.js.map +1 -0
  95. package/dist/storage/moodboard.d.ts +4 -0
  96. package/dist/storage/moodboard.d.ts.map +1 -0
  97. package/dist/storage/moodboard.js +68 -0
  98. package/dist/storage/moodboard.js.map +1 -0
  99. package/dist/storage/moodboard.test.d.ts +2 -0
  100. package/dist/storage/moodboard.test.d.ts.map +1 -0
  101. package/dist/storage/moodboard.test.js +133 -0
  102. package/dist/storage/moodboard.test.js.map +1 -0
  103. package/dist/storage/project-scan.d.ts +12 -0
  104. package/dist/storage/project-scan.d.ts.map +1 -0
  105. package/dist/storage/project-scan.js +118 -0
  106. package/dist/storage/project-scan.js.map +1 -0
  107. package/dist/storage/project.d.ts +10 -0
  108. package/dist/storage/project.d.ts.map +1 -0
  109. package/dist/storage/project.js +101 -0
  110. package/dist/storage/project.js.map +1 -0
  111. package/dist/storage/roles-refine.d.ts +59 -0
  112. package/dist/storage/roles-refine.d.ts.map +1 -0
  113. package/dist/storage/roles-refine.js +223 -0
  114. package/dist/storage/roles-refine.js.map +1 -0
  115. package/dist/storage/roles.d.ts +6 -0
  116. package/dist/storage/roles.d.ts.map +1 -0
  117. package/dist/storage/roles.js +41 -0
  118. package/dist/storage/roles.js.map +1 -0
  119. package/dist/storage/scenarios-refine.d.ts +47 -0
  120. package/dist/storage/scenarios-refine.d.ts.map +1 -0
  121. package/dist/storage/scenarios-refine.js +311 -0
  122. package/dist/storage/scenarios-refine.js.map +1 -0
  123. package/dist/storage/scenarios.d.ts +12 -0
  124. package/dist/storage/scenarios.d.ts.map +1 -0
  125. package/dist/storage/scenarios.js +37 -0
  126. package/dist/storage/scenarios.js.map +1 -0
  127. package/dist/storage/specs.d.ts +17 -0
  128. package/dist/storage/specs.d.ts.map +1 -0
  129. package/dist/storage/specs.js +104 -0
  130. package/dist/storage/specs.js.map +1 -0
  131. package/dist/tools/index.d.ts +2 -0
  132. package/dist/tools/index.d.ts.map +1 -0
  133. package/dist/tools/index.js +2 -0
  134. package/dist/tools/index.js.map +1 -0
  135. package/dist/tools/rerefine.d.ts +8 -0
  136. package/dist/tools/rerefine.d.ts.map +1 -0
  137. package/dist/tools/rerefine.js +153 -0
  138. package/dist/tools/rerefine.js.map +1 -0
  139. package/dist/tools/rerefine.test.d.ts +2 -0
  140. package/dist/tools/rerefine.test.d.ts.map +1 -0
  141. package/dist/tools/rerefine.test.js +123 -0
  142. package/dist/tools/rerefine.test.js.map +1 -0
  143. package/dist/utils/index.d.ts +3 -0
  144. package/dist/utils/index.d.ts.map +1 -0
  145. package/dist/utils/index.js +3 -0
  146. package/dist/utils/index.js.map +1 -0
  147. package/dist/utils/slug.d.ts +3 -0
  148. package/dist/utils/slug.d.ts.map +1 -0
  149. package/dist/utils/slug.js +33 -0
  150. package/dist/utils/slug.js.map +1 -0
  151. package/dist/utils/spec-helpers.d.ts +12 -0
  152. package/dist/utils/spec-helpers.d.ts.map +1 -0
  153. package/dist/utils/spec-helpers.js +95 -0
  154. package/dist/utils/spec-helpers.js.map +1 -0
  155. package/dist/utils/spec-helpers.test.d.ts +2 -0
  156. package/dist/utils/spec-helpers.test.d.ts.map +1 -0
  157. package/dist/utils/spec-helpers.test.js +114 -0
  158. package/dist/utils/spec-helpers.test.js.map +1 -0
  159. package/package.json +53 -0
  160. package/templates/guardrails/ask-when-unclear.md +3 -0
  161. package/templates/guardrails/dont-delete-code.md +3 -0
  162. package/templates/guardrails/explain-changes.md +3 -0
  163. package/templates/guardrails/run-tests.md +3 -0
  164. package/templates/guardrails/small-changes.md +3 -0
  165. package/templates/roles/builder.md +3 -0
  166. package/templates/roles/fixer.md +3 -0
  167. package/templates/roles/planner.md +3 -0
@@ -0,0 +1,288 @@
1
+ import { existsSync, readFileSync, mkdirSync, createWriteStream, readdirSync } from "node:fs";
2
+ import { join, relative } from "node:path";
3
+ import { spawn } from "node:child_process";
4
+ import { createInterface } from "node:readline";
5
+ import chalk from "chalk";
6
+ import { loadAllGuardrails } from "../guardrails/loader.js";
7
+ import { loadRole } from "../storage/roles.js";
8
+ /**
9
+ * Read an approved spec file and extract Stage 1 + Stage 3 content.
10
+ * Exits non-zero if the file is missing or either stage is absent.
11
+ */
12
+ export function readApprovedSpec(name) {
13
+ const specDir = join(process.cwd(), ".stoa", "specs", name);
14
+ const descPath = join(specDir, "01-problem-statement.md");
15
+ const constraintsPath = join(specDir, "03-constraints.md");
16
+ if (!existsSync(descPath)) {
17
+ process.stderr.write(`Error: Spec description not found: ${descPath}\n`);
18
+ process.exit(1);
19
+ }
20
+ if (!existsSync(constraintsPath)) {
21
+ process.stderr.write(`Error: Spec constraints not found: ${constraintsPath}\n`);
22
+ process.exit(1);
23
+ }
24
+ const stage1 = readFileSync(descPath, "utf-8").trim();
25
+ const stage3 = readFileSync(constraintsPath, "utf-8").trim();
26
+ if (stage1.length === 0) {
27
+ process.stderr.write(`Error: Stage 1 (Problem Statement) is empty in ${descPath}\n`);
28
+ process.exit(1);
29
+ }
30
+ if (stage3.length === 0) {
31
+ process.stderr.write(`Error: Stage 3 (Constraints) is empty in ${constraintsPath}\n`);
32
+ process.exit(1);
33
+ }
34
+ return { stage1, stage3 };
35
+ }
36
+ /**
37
+ * Extract a stage section from the approved spec markdown.
38
+ * Matches `## Stage N:` headers and captures content until the next `## Stage` header or EOF.
39
+ */
40
+ function extractSection(content, stageNum) {
41
+ const pattern = new RegExp(`^## Stage ${stageNum}:[^\\n]*\\n([\\s\\S]*?)(?=^## Stage \\d|$)`, "m");
42
+ const match = pattern.exec(content);
43
+ if (!match)
44
+ return null;
45
+ const text = match[1].trim();
46
+ return text.length > 0 ? text : null;
47
+ }
48
+ /**
49
+ * Compose a full build prompt from an approved spec, role, guardrails, and moodboard.
50
+ * Does NOT include scenario content.
51
+ */
52
+ export function composePrompt(name, opts) {
53
+ const { stage1, stage3 } = readApprovedSpec(name);
54
+ const roleText = loadRole(opts.role);
55
+ const guardrailsText = loadAllGuardrails();
56
+ const parts = [];
57
+ // Role persona
58
+ parts.push("# Role\n");
59
+ parts.push(roleText);
60
+ // Stage 1: Problem Statement
61
+ parts.push("\n\n# Task\n");
62
+ parts.push(stage1);
63
+ // Stage 3: Constraints
64
+ parts.push("\n\n# Constraints\n");
65
+ parts.push(stage3);
66
+ // Guardrails
67
+ if (guardrailsText.length > 0) {
68
+ parts.push("\n\n# Guardrails\n");
69
+ parts.push(guardrailsText);
70
+ }
71
+ // Moodboard reference
72
+ const moodboardPath = join(process.cwd(), ".stoa", "moodboard", "notes.md");
73
+ if (existsSync(moodboardPath)) {
74
+ const moodboardText = readFileSync(moodboardPath, "utf-8").trim();
75
+ if (moodboardText.length > 0) {
76
+ parts.push("\n\n# Moodboard\n");
77
+ parts.push(moodboardText);
78
+ }
79
+ }
80
+ return parts.join("");
81
+ }
82
+ const ALLOWED_TOOLS = "Edit,Write,Read,Glob,Grep,LSP";
83
+ const OVERALL_TIMEOUT_MS = 600_000;
84
+ /**
85
+ * Spawn Claude Code in Edit Files mode with the build prompt.
86
+ * Streams output to both terminal and a session log file in `.stoa/sessions/`.
87
+ * Uses --allowedTools so Claude Code can create/edit files (not --print).
88
+ * Completes when the close event fires (Claude Code exits normally in Edit Files mode).
89
+ */
90
+ export function runBuild(name, prompt) {
91
+ return new Promise((resolve, reject) => {
92
+ const startTime = Date.now();
93
+ // Ensure sessions directory exists
94
+ const sessionsDir = join(process.cwd(), ".stoa", "sessions");
95
+ mkdirSync(sessionsDir, { recursive: true });
96
+ // Session file: <name>-<ISO8601>.md
97
+ const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
98
+ const sessionFile = `${name}-${timestamp}.md`;
99
+ const sessionPath = join(sessionsDir, sessionFile);
100
+ // Write session header
101
+ const logStream = createWriteStream(sessionPath, { flags: "a" });
102
+ logStream.write(`# Build Session: ${name}\n`);
103
+ logStream.write(`- Timestamp: ${new Date().toISOString()}\n`);
104
+ logStream.write(`- Spec: ${name}\n`);
105
+ logStream.write(`- Mode: claude-code (Edit Files)\n\n---\n\n`);
106
+ const child = spawn("claude", [
107
+ "--output-format", "text",
108
+ "--allowedTools", ALLOWED_TOOLS,
109
+ ], {
110
+ shell: false,
111
+ stdio: ["pipe", "pipe", "pipe"],
112
+ cwd: process.cwd(),
113
+ });
114
+ let resolved = false;
115
+ const finish = () => {
116
+ if (resolved)
117
+ return;
118
+ resolved = true;
119
+ clearTimeout(overallTimer);
120
+ process.removeListener("SIGINT", onParentSigint);
121
+ child.kill();
122
+ const durationSec = ((Date.now() - startTime) / 1000).toFixed(1);
123
+ logStream.write(`\n\n---\nDuration: ${durationSec}s\n`);
124
+ logStream.end();
125
+ process.stdout.write("\n");
126
+ process.stdout.write(chalk.green(`Build complete in ${durationSec}s\n`));
127
+ process.stdout.write(chalk.dim(`Session saved: ${sessionPath}\n`));
128
+ // Post-build: scan for package.json files needing npm install
129
+ postBuildInstall();
130
+ // Detect start command
131
+ postBuildStartHint();
132
+ process.stdout.write(chalk.cyan(`Run ${chalk.white("stoa verify")} to check blind test scenarios.\n`));
133
+ resolve();
134
+ };
135
+ child.stdout.on("data", (chunk) => {
136
+ process.stdout.write(chunk);
137
+ logStream.write(chunk);
138
+ });
139
+ child.stderr.on("data", (chunk) => {
140
+ process.stderr.write(chunk);
141
+ });
142
+ child.on("close", () => {
143
+ finish();
144
+ });
145
+ const overallTimer = setTimeout(() => {
146
+ if (!resolved) {
147
+ resolved = true;
148
+ process.removeListener("SIGINT", onParentSigint);
149
+ child.kill("SIGKILL");
150
+ logStream.end();
151
+ reject(new Error(`Claude Code subprocess timed out after ${OVERALL_TIMEOUT_MS / 1000}s`));
152
+ }
153
+ }, OVERALL_TIMEOUT_MS);
154
+ const onParentSigint = () => {
155
+ child.kill("SIGINT");
156
+ };
157
+ process.once("SIGINT", onParentSigint);
158
+ child.on("error", (err) => {
159
+ if (!resolved) {
160
+ resolved = true;
161
+ clearTimeout(overallTimer);
162
+ process.removeListener("SIGINT", onParentSigint);
163
+ logStream.end();
164
+ if (err.code === "ENOENT") {
165
+ process.stderr.write(chalk.red("\nError: Claude Code CLI not found.\n") +
166
+ chalk.dim("Install: https://docs.anthropic.com/en/docs/claude-code\n") +
167
+ chalk.dim("Or use `stoa export " + name + "` to copy the prompt to clipboard.\n"));
168
+ }
169
+ reject(err);
170
+ }
171
+ });
172
+ // Write prompt to stdin and close
173
+ child.stdin.write(prompt);
174
+ child.stdin.end();
175
+ });
176
+ }
177
+ /**
178
+ * Scan for package.json files (max 3 levels deep) that lack node_modules/.
179
+ * Auto-run npm install for each.
180
+ */
181
+ function postBuildInstall() {
182
+ const cwd = process.cwd();
183
+ const found = findPackageJsons(cwd, 0, 3);
184
+ for (const dir of found) {
185
+ const nodeModulesPath = join(dir, "node_modules");
186
+ if (!existsSync(nodeModulesPath)) {
187
+ const relDir = relative(cwd, dir) || ".";
188
+ process.stdout.write(chalk.dim(`Installing dependencies in ./${relDir}...\n`));
189
+ try {
190
+ const child = spawn("npm", ["install"], {
191
+ cwd: dir,
192
+ stdio: "inherit",
193
+ shell: false,
194
+ });
195
+ // Fire-and-forget — don't block on npm install
196
+ child.unref();
197
+ }
198
+ catch {
199
+ // Non-critical — continue
200
+ }
201
+ }
202
+ }
203
+ }
204
+ /**
205
+ * Recursively find directories containing package.json, up to maxDepth levels.
206
+ */
207
+ function findPackageJsons(dir, depth, maxDepth) {
208
+ const results = [];
209
+ if (depth > maxDepth)
210
+ return results;
211
+ if (existsSync(join(dir, "package.json"))) {
212
+ results.push(dir);
213
+ }
214
+ if (depth < maxDepth) {
215
+ try {
216
+ const entries = readdirSync(dir, { withFileTypes: true });
217
+ for (const entry of entries) {
218
+ if (entry.isDirectory() && entry.name !== "node_modules" && !entry.name.startsWith(".")) {
219
+ results.push(...findPackageJsons(join(dir, entry.name), depth + 1, maxDepth));
220
+ }
221
+ }
222
+ }
223
+ catch {
224
+ // Permission error or similar — skip
225
+ }
226
+ }
227
+ return results;
228
+ }
229
+ /**
230
+ * Check for dev or start script in package.json and print a hint.
231
+ */
232
+ function postBuildStartHint() {
233
+ const pkgPath = join(process.cwd(), "package.json");
234
+ if (!existsSync(pkgPath))
235
+ return;
236
+ try {
237
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
238
+ const scripts = pkg.scripts ?? {};
239
+ if (scripts.dev) {
240
+ process.stdout.write(chalk.dim(`To start the app: ${chalk.white("npm run dev")}\n`));
241
+ }
242
+ else if (scripts.start) {
243
+ process.stdout.write(chalk.dim(`To start the app: ${chalk.white("npm start")}\n`));
244
+ }
245
+ }
246
+ catch {
247
+ // ignore malformed package.json
248
+ }
249
+ }
250
+ /**
251
+ * Parse a `## Subtasks` section from spec content.
252
+ * Extracts numbered items (e.g. "1. Do something").
253
+ * Returns empty array if no Subtasks section exists.
254
+ */
255
+ export function parseSubtasks(specContent) {
256
+ const pattern = /^## Subtasks\s*\n([\s\S]*?)(?=\n## )/m;
257
+ const match = pattern.exec(specContent);
258
+ // If no next ## heading, try matching to end of string
259
+ const endPattern = /^## Subtasks\s*\n([\s\S]*)$/m;
260
+ const result = match ?? endPattern.exec(specContent);
261
+ if (!result)
262
+ return [];
263
+ const body = result[1];
264
+ const subtasks = [];
265
+ const itemPattern = /^(\d+)\.\s+(.+(?:\n(?!\d+\.).*)*)/gm;
266
+ let itemMatch;
267
+ while ((itemMatch = itemPattern.exec(body)) !== null) {
268
+ subtasks.push({
269
+ index: parseInt(itemMatch[1], 10),
270
+ text: itemMatch[2].trim(),
271
+ });
272
+ }
273
+ return subtasks;
274
+ }
275
+ /**
276
+ * Prompt user to choose subtask execution mode.
277
+ * Returns "all", "q", or a 1-based subtask number.
278
+ */
279
+ export function promptSubtaskChoice(subtasks) {
280
+ return new Promise((resolve) => {
281
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
282
+ rl.question(chalk.cyan(`Build all sequentially or pick one? [all/1-${subtasks.length}/q] `), (answer) => {
283
+ rl.close();
284
+ resolve(answer.trim().toLowerCase());
285
+ });
286
+ });
287
+ }
288
+ //# sourceMappingURL=build.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/cli/build.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function runReviewLoop(specDir: string): Promise<void>;
2
+ //# sourceMappingURL=review-loop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-loop.d.ts","sourceRoot":"","sources":["../../src/cli/review-loop.ts"],"names":[],"mappings":"AAuCA,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAiEf"}
@@ -0,0 +1,97 @@
1
+ import { readFile, appendFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { spawnSync } from "node:child_process";
4
+ import { createInterface } from "node:readline/promises";
5
+ const SECTIONS = [
6
+ { display: "DESCRIPTION", file: "01-problem-statement.md" },
7
+ { display: "CRITERIA", file: "02-acceptance-criteria.md" },
8
+ { display: "CONSTRAINTS", file: "03-constraints.md" },
9
+ { display: "SUBTASKS", file: "04-decomposition.md" },
10
+ { display: "SCENARIOS", file: "05-evaluation-design.md" },
11
+ ];
12
+ function readKeypress() {
13
+ return new Promise((resolve, reject) => {
14
+ const wasRaw = process.stdin.isRaw;
15
+ process.stdin.setRawMode(true);
16
+ process.stdin.resume();
17
+ process.stdin.once("data", (data) => {
18
+ process.stdin.setRawMode(wasRaw);
19
+ process.stdin.pause();
20
+ resolve(data);
21
+ });
22
+ process.stdin.once("error", (err) => {
23
+ process.stdin.setRawMode(wasRaw);
24
+ process.stdin.pause();
25
+ reject(err);
26
+ });
27
+ });
28
+ }
29
+ async function readSectionContent(filePath) {
30
+ try {
31
+ return await readFile(filePath, "utf-8");
32
+ }
33
+ catch {
34
+ return null;
35
+ }
36
+ }
37
+ export async function runReviewLoop(specDir) {
38
+ for (const section of SECTIONS) {
39
+ const filePath = join(specDir, section.file);
40
+ process.stdout.write(`\n=== ${section.display} ===\n`);
41
+ const content = await readSectionContent(filePath);
42
+ if (content === null) {
43
+ process.stdout.write("[no content]\n");
44
+ }
45
+ else {
46
+ process.stdout.write(content);
47
+ if (!content.endsWith("\n")) {
48
+ process.stdout.write("\n");
49
+ }
50
+ }
51
+ let handled = false;
52
+ while (!handled) {
53
+ process.stdout.write("[Enter] continue [e] edit [s] skip");
54
+ const buf = await readKeypress();
55
+ const byte = buf[0];
56
+ process.stdout.write("\n");
57
+ if (byte === 0x0d || byte === 0x0a) {
58
+ // Enter — advance
59
+ handled = true;
60
+ }
61
+ else if (byte === 0x65) {
62
+ // 'e' — edit
63
+ const editor = process.env["EDITOR"] || "vi";
64
+ try {
65
+ spawnSync(editor, [filePath], { stdio: "inherit" });
66
+ }
67
+ catch (err) {
68
+ if (err instanceof Error &&
69
+ "code" in err &&
70
+ err.code === "ENOENT") {
71
+ process.stderr.write(`Editor not found: ${editor}\n`);
72
+ continue;
73
+ }
74
+ throw err;
75
+ }
76
+ handled = true;
77
+ }
78
+ else if (byte === 0x73) {
79
+ // 's' — skip
80
+ handled = true;
81
+ }
82
+ // Any other key: loop re-prompts
83
+ }
84
+ }
85
+ // Additional notes prompt
86
+ process.stdout.write("\nAdditional notes (leave blank to skip): ");
87
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
88
+ const line = await rl.question("");
89
+ rl.close();
90
+ const trimmed = line.trim();
91
+ if (trimmed.length > 0) {
92
+ const now = new Date().toISOString();
93
+ const entry = `\n## Notes — ${now}\n${trimmed}\n`;
94
+ await appendFile(join(specDir, "user-notes.md"), entry, "utf-8");
95
+ }
96
+ }
97
+ //# sourceMappingURL=review-loop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-loop.js","sourceRoot":"","sources":["../../src/cli/review-loop.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ interface Scenario {
2
+ title: string;
3
+ given: string;
4
+ expected: string;
5
+ }
6
+ export declare function loadSpecScenarios(specName?: string): Promise<{
7
+ specName: string;
8
+ scenarios: Scenario[];
9
+ }>;
10
+ export declare function runSpecScenarios(specName?: string): Promise<void>;
11
+ export {};
12
+ //# sourceMappingURL=scenarios-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scenarios-runner.d.ts","sourceRoot":"","sources":["../../src/cli/scenarios-runner.ts"],"names":[],"mappings":"AAIA,UAAU,QAAQ;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAoGD,wBAAsB,iBAAiB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,QAAQ,EAAE,CAAA;CAAE,CAAC,CAkB/G;AAUD,wBAAsB,gBAAgB,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAiDvE"}
@@ -0,0 +1,158 @@
1
+ import { createInterface } from "node:readline";
2
+ import { readdir, readFile } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ function parseSpecScenarios(content) {
5
+ const scenarios = [];
6
+ // Strip markdown code fences if present
7
+ const stripped = content.replace(/^```(?:json)?\s*\n?/gm, "").replace(/\n?```\s*$/gm, "");
8
+ const trimmed = stripped.trim();
9
+ // Try JSON array first (raw stage 5 output)
10
+ if (trimmed.startsWith("[")) {
11
+ try {
12
+ const parsed = JSON.parse(trimmed);
13
+ if (Array.isArray(parsed)) {
14
+ for (const item of parsed) {
15
+ if (typeof item === "object" && item !== null &&
16
+ typeof item.title === "string" &&
17
+ typeof item.given === "string" &&
18
+ typeof item.expected === "string") {
19
+ scenarios.push(item);
20
+ }
21
+ }
22
+ if (scenarios.length > 0)
23
+ return scenarios;
24
+ }
25
+ }
26
+ catch {
27
+ // Not JSON — fall through to markdown parsing
28
+ }
29
+ }
30
+ // Parse markdown format: ## Title blocks with **Given:**/**Expected:** or Given:/Expected:
31
+ const blocks = content.split(/^##\s+/m);
32
+ for (const block of blocks) {
33
+ const blockTrimmed = block.trim();
34
+ if (blockTrimmed.length === 0)
35
+ continue;
36
+ const firstNewline = blockTrimmed.indexOf("\n");
37
+ if (firstNewline === -1)
38
+ continue;
39
+ const title = blockTrimmed.slice(0, firstNewline).trim();
40
+ const body = blockTrimmed.slice(firstNewline + 1);
41
+ const givenMatch = body.match(/\*{0,2}(?:given|GIVEN)\*{0,2}[:\s]+(.+?)(?=\*{0,2}(?:expected|EXPECTED)\*{0,2}[:\s])/is);
42
+ const expectedMatch = body.match(/\*{0,2}(?:expected|EXPECTED)\*{0,2}[:\s]+(.+)/is);
43
+ if (givenMatch && expectedMatch) {
44
+ scenarios.push({
45
+ title,
46
+ given: givenMatch[1].replace(/^\*+|\*+$/g, "").trim(),
47
+ expected: expectedMatch[1].replace(/^\*+|\*+$/g, "").trim(),
48
+ });
49
+ }
50
+ }
51
+ // Fallback: numbered list with title / given / expected per block
52
+ if (scenarios.length === 0) {
53
+ const numberedBlocks = content.split(/^\d+\.\s+/m);
54
+ for (const block of numberedBlocks) {
55
+ const blockTrimmed = block.trim();
56
+ if (blockTrimmed.length === 0)
57
+ continue;
58
+ const titleMatch = blockTrimmed.match(/^\*{0,2}(.+?)\*{0,2}\s*$/m);
59
+ const givenMatch = blockTrimmed.match(/\*{0,2}(?:given|GIVEN)\*{0,2}[:\s]+(.+?)(?=\*{0,2}(?:expected|EXPECTED)\*{0,2}[:\s])/is);
60
+ const expectedMatch = blockTrimmed.match(/\*{0,2}(?:expected|EXPECTED)\*{0,2}[:\s]+(.+)/is);
61
+ if (titleMatch && givenMatch && expectedMatch) {
62
+ scenarios.push({
63
+ title: titleMatch[1].replace(/^\*+|\*+$/g, "").trim(),
64
+ given: givenMatch[1].replace(/^\*+|\*+$/g, "").trim(),
65
+ expected: expectedMatch[1].replace(/^\*+|\*+$/g, "").trim(),
66
+ });
67
+ }
68
+ }
69
+ }
70
+ return scenarios;
71
+ }
72
+ async function getMostRecentSpec() {
73
+ const specsDir = join(process.cwd(), ".stoa", "specs");
74
+ const entries = await readdir(specsDir);
75
+ const { stat } = await import("node:fs/promises");
76
+ const dirs = [];
77
+ for (const entry of entries) {
78
+ const s = await stat(join(specsDir, entry));
79
+ if (s.isDirectory()) {
80
+ dirs.push({ name: entry, mtime: s.mtimeMs });
81
+ }
82
+ }
83
+ if (dirs.length === 0) {
84
+ throw new Error("No specs found. Run 'stoa refine' first.");
85
+ }
86
+ dirs.sort((a, b) => b.mtime - a.mtime);
87
+ return dirs[0].name;
88
+ }
89
+ export async function loadSpecScenarios(specName) {
90
+ const resolvedName = specName ?? await getMostRecentSpec();
91
+ const specDir = join(process.cwd(), ".stoa", "specs", resolvedName);
92
+ const scenarioFile = join(specDir, "05-evaluation-design.md");
93
+ let content;
94
+ try {
95
+ content = await readFile(scenarioFile, "utf-8");
96
+ }
97
+ catch {
98
+ throw new Error(`No scenarios found for spec "${resolvedName}". Run a full refine first.`);
99
+ }
100
+ const scenarios = parseSpecScenarios(content);
101
+ if (scenarios.length === 0) {
102
+ throw new Error(`Could not parse scenarios from spec "${resolvedName}".`);
103
+ }
104
+ return { specName: resolvedName, scenarios };
105
+ }
106
+ function askQuestion(rl, prompt) {
107
+ return new Promise((resolve) => {
108
+ rl.question(prompt, (answer) => {
109
+ resolve(answer.trim().toLowerCase());
110
+ });
111
+ });
112
+ }
113
+ export async function runSpecScenarios(specName) {
114
+ const { specName: name, scenarios } = await loadSpecScenarios(specName);
115
+ process.stdout.write(`\nScenarios for: ${name}\n`);
116
+ process.stdout.write(`${scenarios.length} scenario(s)\n`);
117
+ process.stdout.write("─".repeat(40) + "\n");
118
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
119
+ let passed = 0;
120
+ let failed = 0;
121
+ let skipped = 0;
122
+ const failures = [];
123
+ try {
124
+ for (let i = 0; i < scenarios.length; i++) {
125
+ const s = scenarios[i];
126
+ process.stdout.write(`\nScenario ${i + 1}/${scenarios.length}: ${s.title}\n\n`);
127
+ process.stdout.write(` GIVEN:\n ${s.given}\n\n`);
128
+ process.stdout.write(` EXPECTED:\n ${s.expected}\n\n`);
129
+ const answer = await askQuestion(rl, " Pass? [y/n/s(skip)] ");
130
+ if (answer === "y" || answer === "yes") {
131
+ passed++;
132
+ process.stdout.write(" ✓ Passed\n");
133
+ }
134
+ else if (answer === "s" || answer === "skip") {
135
+ skipped++;
136
+ process.stdout.write(" — Skipped\n");
137
+ }
138
+ else {
139
+ failed++;
140
+ failures.push(s.title);
141
+ process.stdout.write(" ✗ Failed\n");
142
+ }
143
+ }
144
+ }
145
+ finally {
146
+ rl.close();
147
+ }
148
+ // Summary
149
+ process.stdout.write("\n" + "─".repeat(40) + "\n");
150
+ process.stdout.write(`Results: ${passed} passed, ${failed} failed, ${skipped} skipped\n`);
151
+ if (failures.length > 0) {
152
+ process.stdout.write("Failed:\n");
153
+ for (const f of failures) {
154
+ process.stdout.write(` - ${f}\n`);
155
+ }
156
+ }
157
+ }
158
+ //# sourceMappingURL=scenarios-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scenarios-runner.js","sourceRoot":"","sources":["../../src/cli/scenarios-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export interface VerifyFailure {
2
+ scenarioId: number;
3
+ expected: string;
4
+ actual: string;
5
+ }
6
+ export interface VerifyResult {
7
+ passed: number;
8
+ failed: number;
9
+ skipped: number;
10
+ failures: VerifyFailure[];
11
+ }
12
+ export declare function runVerify(name: string): Promise<VerifyResult>;
13
+ //# sourceMappingURL=verify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../src/cli/verify.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B;AAsED,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CA2FnE"}