popeye-cli 2.2.0 → 2.7.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 (323) hide show
  1. package/dist/adapters/gemini.d.ts +14 -0
  2. package/dist/adapters/gemini.d.ts.map +1 -1
  3. package/dist/adapters/gemini.js +41 -6
  4. package/dist/adapters/gemini.js.map +1 -1
  5. package/dist/adapters/grok.d.ts +14 -0
  6. package/dist/adapters/grok.d.ts.map +1 -1
  7. package/dist/adapters/grok.js +42 -6
  8. package/dist/adapters/grok.js.map +1 -1
  9. package/dist/adapters/openai.d.ts +10 -0
  10. package/dist/adapters/openai.d.ts.map +1 -1
  11. package/dist/adapters/openai.js +44 -5
  12. package/dist/adapters/openai.js.map +1 -1
  13. package/dist/cli/commands/create.js +1 -1
  14. package/dist/cli/commands/create.js.map +1 -1
  15. package/dist/cli/interactive.d.ts.map +1 -1
  16. package/dist/cli/interactive.js +324 -20
  17. package/dist/cli/interactive.js.map +1 -1
  18. package/dist/generators/all.d.ts.map +1 -1
  19. package/dist/generators/all.js +3 -2
  20. package/dist/generators/all.js.map +1 -1
  21. package/dist/generators/doc-parser.d.ts +21 -6
  22. package/dist/generators/doc-parser.d.ts.map +1 -1
  23. package/dist/generators/doc-parser.js +55 -4
  24. package/dist/generators/doc-parser.js.map +1 -1
  25. package/dist/generators/templates/fullstack.js +1 -1
  26. package/dist/generators/templates/website-components.js +1 -1
  27. package/dist/generators/templates/website-components.js.map +1 -1
  28. package/dist/generators/templates/website-config.d.ts +4 -1
  29. package/dist/generators/templates/website-config.d.ts.map +1 -1
  30. package/dist/generators/templates/website-config.js +17 -11
  31. package/dist/generators/templates/website-config.js.map +1 -1
  32. package/dist/generators/templates/website-conversion.js +1 -1
  33. package/dist/generators/templates/website-conversion.js.map +1 -1
  34. package/dist/generators/templates/website-landing.js +1 -1
  35. package/dist/generators/templates/website-landing.js.map +1 -1
  36. package/dist/generators/templates/website-layout.d.ts +36 -4
  37. package/dist/generators/templates/website-layout.d.ts.map +1 -1
  38. package/dist/generators/templates/website-layout.js +466 -23
  39. package/dist/generators/templates/website-layout.js.map +1 -1
  40. package/dist/generators/templates/website-pricing.js +1 -1
  41. package/dist/generators/templates/website-pricing.js.map +1 -1
  42. package/dist/generators/templates/website-sections.js +1 -1
  43. package/dist/generators/templates/website-sections.js.map +1 -1
  44. package/dist/generators/templates/website-seo.d.ts.map +1 -1
  45. package/dist/generators/templates/website-seo.js +4 -1
  46. package/dist/generators/templates/website-seo.js.map +1 -1
  47. package/dist/generators/templates/website.d.ts +1 -1
  48. package/dist/generators/templates/website.d.ts.map +1 -1
  49. package/dist/generators/templates/website.js +1 -1
  50. package/dist/generators/templates/website.js.map +1 -1
  51. package/dist/generators/website-content-ai.d.ts +52 -0
  52. package/dist/generators/website-content-ai.d.ts.map +1 -0
  53. package/dist/generators/website-content-ai.js +141 -0
  54. package/dist/generators/website-content-ai.js.map +1 -0
  55. package/dist/generators/website-content-scanner.d.ts +1 -1
  56. package/dist/generators/website-content-scanner.d.ts.map +1 -1
  57. package/dist/generators/website-content-scanner.js +98 -1
  58. package/dist/generators/website-content-scanner.js.map +1 -1
  59. package/dist/generators/website-context.d.ts +34 -1
  60. package/dist/generators/website-context.d.ts.map +1 -1
  61. package/dist/generators/website-context.js +131 -9
  62. package/dist/generators/website-context.js.map +1 -1
  63. package/dist/generators/website-debug.d.ts +12 -0
  64. package/dist/generators/website-debug.d.ts.map +1 -1
  65. package/dist/generators/website-debug.js +16 -0
  66. package/dist/generators/website-debug.js.map +1 -1
  67. package/dist/generators/website.d.ts.map +1 -1
  68. package/dist/generators/website.js +26 -4
  69. package/dist/generators/website.js.map +1 -1
  70. package/dist/pipeline/auto-recovery.d.ts +56 -0
  71. package/dist/pipeline/auto-recovery.d.ts.map +1 -0
  72. package/dist/pipeline/auto-recovery.js +185 -0
  73. package/dist/pipeline/auto-recovery.js.map +1 -0
  74. package/dist/pipeline/change-request.d.ts +39 -0
  75. package/dist/pipeline/change-request.d.ts.map +1 -1
  76. package/dist/pipeline/change-request.js +40 -1
  77. package/dist/pipeline/change-request.js.map +1 -1
  78. package/dist/pipeline/check-runner.d.ts +30 -1
  79. package/dist/pipeline/check-runner.d.ts.map +1 -1
  80. package/dist/pipeline/check-runner.js +122 -1
  81. package/dist/pipeline/check-runner.js.map +1 -1
  82. package/dist/pipeline/command-resolver.d.ts.map +1 -1
  83. package/dist/pipeline/command-resolver.js +33 -2
  84. package/dist/pipeline/command-resolver.js.map +1 -1
  85. package/dist/pipeline/consensus/arbitrator-query.d.ts +22 -0
  86. package/dist/pipeline/consensus/arbitrator-query.d.ts.map +1 -0
  87. package/dist/pipeline/consensus/arbitrator-query.js +70 -0
  88. package/dist/pipeline/consensus/arbitrator-query.js.map +1 -0
  89. package/dist/pipeline/consensus/consensus-runner.d.ts +131 -7
  90. package/dist/pipeline/consensus/consensus-runner.d.ts.map +1 -1
  91. package/dist/pipeline/consensus/consensus-runner.js +809 -35
  92. package/dist/pipeline/consensus/consensus-runner.js.map +1 -1
  93. package/dist/pipeline/cr-lifecycle.d.ts +42 -0
  94. package/dist/pipeline/cr-lifecycle.d.ts.map +1 -0
  95. package/dist/pipeline/cr-lifecycle.js +89 -0
  96. package/dist/pipeline/cr-lifecycle.js.map +1 -0
  97. package/dist/pipeline/gate-engine.d.ts +1 -0
  98. package/dist/pipeline/gate-engine.d.ts.map +1 -1
  99. package/dist/pipeline/gate-engine.js +26 -7
  100. package/dist/pipeline/gate-engine.js.map +1 -1
  101. package/dist/pipeline/orchestrator.d.ts +1 -1
  102. package/dist/pipeline/orchestrator.d.ts.map +1 -1
  103. package/dist/pipeline/orchestrator.js +306 -16
  104. package/dist/pipeline/orchestrator.js.map +1 -1
  105. package/dist/pipeline/packets/consensus-packet-builder.d.ts +15 -4
  106. package/dist/pipeline/packets/consensus-packet-builder.d.ts.map +1 -1
  107. package/dist/pipeline/packets/consensus-packet-builder.js +29 -17
  108. package/dist/pipeline/packets/consensus-packet-builder.js.map +1 -1
  109. package/dist/pipeline/phases/architecture.d.ts.map +1 -1
  110. package/dist/pipeline/phases/architecture.js +5 -3
  111. package/dist/pipeline/phases/architecture.js.map +1 -1
  112. package/dist/pipeline/phases/audit.d.ts.map +1 -1
  113. package/dist/pipeline/phases/audit.js +5 -3
  114. package/dist/pipeline/phases/audit.js.map +1 -1
  115. package/dist/pipeline/phases/consensus-architecture.d.ts.map +1 -1
  116. package/dist/pipeline/phases/consensus-architecture.js +10 -1
  117. package/dist/pipeline/phases/consensus-architecture.js.map +1 -1
  118. package/dist/pipeline/phases/consensus-master-plan.d.ts.map +1 -1
  119. package/dist/pipeline/phases/consensus-master-plan.js +10 -3
  120. package/dist/pipeline/phases/consensus-master-plan.js.map +1 -1
  121. package/dist/pipeline/phases/consensus-role-plans.d.ts.map +1 -1
  122. package/dist/pipeline/phases/consensus-role-plans.js +10 -1
  123. package/dist/pipeline/phases/consensus-role-plans.js.map +1 -1
  124. package/dist/pipeline/phases/done.d.ts.map +1 -1
  125. package/dist/pipeline/phases/done.js +9 -4
  126. package/dist/pipeline/phases/done.js.map +1 -1
  127. package/dist/pipeline/phases/intake.d.ts.map +1 -1
  128. package/dist/pipeline/phases/intake.js +7 -3
  129. package/dist/pipeline/phases/intake.js.map +1 -1
  130. package/dist/pipeline/phases/phase-context.d.ts +2 -0
  131. package/dist/pipeline/phases/phase-context.d.ts.map +1 -1
  132. package/dist/pipeline/phases/phase-context.js +3 -1
  133. package/dist/pipeline/phases/phase-context.js.map +1 -1
  134. package/dist/pipeline/phases/production-gate.d.ts.map +1 -1
  135. package/dist/pipeline/phases/production-gate.js +28 -3
  136. package/dist/pipeline/phases/production-gate.js.map +1 -1
  137. package/dist/pipeline/phases/qa-validation.d.ts.map +1 -1
  138. package/dist/pipeline/phases/qa-validation.js +38 -5
  139. package/dist/pipeline/phases/qa-validation.js.map +1 -1
  140. package/dist/pipeline/phases/recovery-loop.d.ts +2 -0
  141. package/dist/pipeline/phases/recovery-loop.d.ts.map +1 -1
  142. package/dist/pipeline/phases/recovery-loop.js +200 -6
  143. package/dist/pipeline/phases/recovery-loop.js.map +1 -1
  144. package/dist/pipeline/phases/review.d.ts.map +1 -1
  145. package/dist/pipeline/phases/review.js +58 -28
  146. package/dist/pipeline/phases/review.js.map +1 -1
  147. package/dist/pipeline/phases/role-planning.d.ts.map +1 -1
  148. package/dist/pipeline/phases/role-planning.js +18 -2
  149. package/dist/pipeline/phases/role-planning.js.map +1 -1
  150. package/dist/pipeline/phases/stuck.d.ts.map +1 -1
  151. package/dist/pipeline/phases/stuck.js +10 -0
  152. package/dist/pipeline/phases/stuck.js.map +1 -1
  153. package/dist/pipeline/repo-snapshot.d.ts.map +1 -1
  154. package/dist/pipeline/repo-snapshot.js +3 -0
  155. package/dist/pipeline/repo-snapshot.js.map +1 -1
  156. package/dist/pipeline/role-execution-adapter.d.ts +2 -1
  157. package/dist/pipeline/role-execution-adapter.d.ts.map +1 -1
  158. package/dist/pipeline/role-execution-adapter.js +22 -7
  159. package/dist/pipeline/role-execution-adapter.js.map +1 -1
  160. package/dist/pipeline/skill-loader.d.ts +19 -0
  161. package/dist/pipeline/skill-loader.d.ts.map +1 -1
  162. package/dist/pipeline/skill-loader.js +22 -0
  163. package/dist/pipeline/skill-loader.js.map +1 -1
  164. package/dist/pipeline/skills/coverage-gate.d.ts +44 -0
  165. package/dist/pipeline/skills/coverage-gate.d.ts.map +1 -0
  166. package/dist/pipeline/skills/coverage-gate.js +143 -0
  167. package/dist/pipeline/skills/coverage-gate.js.map +1 -0
  168. package/dist/pipeline/skills/usage-registry.d.ts +48 -0
  169. package/dist/pipeline/skills/usage-registry.d.ts.map +1 -0
  170. package/dist/pipeline/skills/usage-registry.js +55 -0
  171. package/dist/pipeline/skills/usage-registry.js.map +1 -0
  172. package/dist/pipeline/strategy-context.d.ts +20 -0
  173. package/dist/pipeline/strategy-context.d.ts.map +1 -0
  174. package/dist/pipeline/strategy-context.js +55 -0
  175. package/dist/pipeline/strategy-context.js.map +1 -0
  176. package/dist/pipeline/type-defs/artifacts.d.ts +25 -5
  177. package/dist/pipeline/type-defs/artifacts.d.ts.map +1 -1
  178. package/dist/pipeline/type-defs/artifacts.js +4 -0
  179. package/dist/pipeline/type-defs/artifacts.js.map +1 -1
  180. package/dist/pipeline/type-defs/audit.d.ts +25 -13
  181. package/dist/pipeline/type-defs/audit.d.ts.map +1 -1
  182. package/dist/pipeline/type-defs/checks.d.ts +18 -8
  183. package/dist/pipeline/type-defs/checks.d.ts.map +1 -1
  184. package/dist/pipeline/type-defs/checks.js +4 -0
  185. package/dist/pipeline/type-defs/checks.js.map +1 -1
  186. package/dist/pipeline/type-defs/packets.d.ts +104 -18
  187. package/dist/pipeline/type-defs/packets.d.ts.map +1 -1
  188. package/dist/pipeline/type-defs/packets.js +17 -1
  189. package/dist/pipeline/type-defs/packets.js.map +1 -1
  190. package/dist/pipeline/type-defs/state.d.ts +160 -16
  191. package/dist/pipeline/type-defs/state.d.ts.map +1 -1
  192. package/dist/pipeline/type-defs/state.js +26 -1
  193. package/dist/pipeline/type-defs/state.js.map +1 -1
  194. package/dist/shared/text-utils.d.ts +23 -0
  195. package/dist/shared/text-utils.d.ts.map +1 -0
  196. package/dist/shared/text-utils.js +66 -0
  197. package/dist/shared/text-utils.js.map +1 -0
  198. package/dist/shared/website-strategy-format.d.ts +18 -0
  199. package/dist/shared/website-strategy-format.d.ts.map +1 -0
  200. package/dist/shared/website-strategy-format.js +47 -0
  201. package/dist/shared/website-strategy-format.js.map +1 -0
  202. package/dist/state/index.d.ts +2 -0
  203. package/dist/state/index.d.ts.map +1 -1
  204. package/dist/state/index.js +57 -8
  205. package/dist/state/index.js.map +1 -1
  206. package/dist/types/consensus.d.ts +1 -0
  207. package/dist/types/consensus.d.ts.map +1 -1
  208. package/dist/types/consensus.js.map +1 -1
  209. package/dist/types/website-strategy.d.ts +1 -1
  210. package/dist/types/workflow.d.ts +447 -0
  211. package/dist/types/workflow.d.ts.map +1 -1
  212. package/dist/types/workflow.js +3 -0
  213. package/dist/types/workflow.js.map +1 -1
  214. package/dist/upgrade/handlers.d.ts.map +1 -1
  215. package/dist/upgrade/handlers.js +6 -3
  216. package/dist/upgrade/handlers.js.map +1 -1
  217. package/dist/workflow/consensus.d.ts.map +1 -1
  218. package/dist/workflow/consensus.js +1 -0
  219. package/dist/workflow/consensus.js.map +1 -1
  220. package/dist/workflow/website-strategy.d.ts.map +1 -1
  221. package/dist/workflow/website-strategy.js +2 -29
  222. package/dist/workflow/website-strategy.js.map +1 -1
  223. package/dist/workflow/website-updater.d.ts.map +1 -1
  224. package/dist/workflow/website-updater.js +3 -2
  225. package/dist/workflow/website-updater.js.map +1 -1
  226. package/package.json +1 -1
  227. package/src/adapters/gemini.ts +51 -6
  228. package/src/adapters/grok.ts +51 -6
  229. package/src/adapters/openai.ts +53 -5
  230. package/src/cli/commands/create.ts +1 -1
  231. package/src/cli/interactive.ts +333 -19
  232. package/src/generators/all.ts +3 -2
  233. package/src/generators/doc-parser.ts +75 -15
  234. package/src/generators/templates/fullstack.ts +1 -1
  235. package/src/generators/templates/website-components.ts +1 -1
  236. package/src/generators/templates/website-config.ts +23 -11
  237. package/src/generators/templates/website-conversion.ts +1 -1
  238. package/src/generators/templates/website-landing.ts +1 -1
  239. package/src/generators/templates/website-layout.ts +491 -23
  240. package/src/generators/templates/website-pricing.ts +1 -1
  241. package/src/generators/templates/website-sections.ts +1 -1
  242. package/src/generators/templates/website-seo.ts +4 -1
  243. package/src/generators/templates/website.ts +3 -0
  244. package/src/generators/website-content-ai.ts +186 -0
  245. package/src/generators/website-content-scanner.ts +113 -1
  246. package/src/generators/website-context.ts +151 -12
  247. package/src/generators/website-debug.ts +26 -0
  248. package/src/generators/website.ts +28 -3
  249. package/src/pipeline/auto-recovery.ts +283 -0
  250. package/src/pipeline/change-request.ts +63 -1
  251. package/src/pipeline/check-runner.ts +141 -2
  252. package/src/pipeline/command-resolver.ts +34 -2
  253. package/src/pipeline/consensus/arbitrator-query.ts +101 -0
  254. package/src/pipeline/consensus/consensus-runner.ts +1099 -42
  255. package/src/pipeline/cr-lifecycle.ts +103 -0
  256. package/src/pipeline/gate-engine.ts +35 -7
  257. package/src/pipeline/orchestrator.ts +361 -16
  258. package/src/pipeline/packets/consensus-packet-builder.ts +44 -18
  259. package/src/pipeline/phases/architecture.ts +6 -3
  260. package/src/pipeline/phases/audit.ts +6 -3
  261. package/src/pipeline/phases/consensus-architecture.ts +10 -1
  262. package/src/pipeline/phases/consensus-master-plan.ts +10 -3
  263. package/src/pipeline/phases/consensus-role-plans.ts +10 -1
  264. package/src/pipeline/phases/done.ts +15 -4
  265. package/src/pipeline/phases/intake.ts +7 -3
  266. package/src/pipeline/phases/phase-context.ts +6 -1
  267. package/src/pipeline/phases/production-gate.ts +41 -3
  268. package/src/pipeline/phases/qa-validation.ts +51 -5
  269. package/src/pipeline/phases/recovery-loop.ts +229 -7
  270. package/src/pipeline/phases/review.ts +73 -30
  271. package/src/pipeline/phases/role-planning.ts +21 -2
  272. package/src/pipeline/phases/stuck.ts +10 -0
  273. package/src/pipeline/repo-snapshot.ts +3 -0
  274. package/src/pipeline/role-execution-adapter.ts +30 -4
  275. package/src/pipeline/skill-loader.ts +33 -0
  276. package/src/pipeline/skills/coverage-gate.ts +199 -0
  277. package/src/pipeline/skills/usage-registry.ts +87 -0
  278. package/src/pipeline/strategy-context.ts +60 -0
  279. package/src/pipeline/type-defs/artifacts.ts +4 -0
  280. package/src/pipeline/type-defs/checks.ts +4 -0
  281. package/src/pipeline/type-defs/packets.ts +18 -1
  282. package/src/pipeline/type-defs/state.ts +26 -1
  283. package/src/shared/text-utils.ts +70 -0
  284. package/src/shared/website-strategy-format.ts +56 -0
  285. package/src/state/index.ts +60 -8
  286. package/src/types/consensus.ts +1 -0
  287. package/src/types/workflow.ts +6 -0
  288. package/src/upgrade/handlers.ts +9 -3
  289. package/src/workflow/consensus.ts +1 -0
  290. package/src/workflow/website-strategy.ts +2 -36
  291. package/src/workflow/website-updater.ts +4 -2
  292. package/tests/adapters/gemini.test.ts +165 -0
  293. package/tests/adapters/grok.test.ts +137 -0
  294. package/tests/adapters/openai.test.ts +128 -0
  295. package/tests/generators/doc-parser.test.ts +88 -9
  296. package/tests/generators/quality-gate.test.ts +19 -3
  297. package/tests/generators/website-components.test.ts +34 -0
  298. package/tests/generators/website-content-ai.test.ts +308 -0
  299. package/tests/generators/website-content-scanner.test.ts +86 -0
  300. package/tests/generators/website-context.test.ts +3 -2
  301. package/tests/integration/smokestack-scaffold.test.ts +385 -0
  302. package/tests/pipeline/auto-recovery.test.ts +337 -0
  303. package/tests/pipeline/change-request.test.ts +70 -0
  304. package/tests/pipeline/command-resolver.test.ts +42 -0
  305. package/tests/pipeline/consensus/arbitrator-query.test.ts +107 -0
  306. package/tests/pipeline/consensus-runner.test.ts +1333 -10
  307. package/tests/pipeline/consensus-scoring.test.ts +602 -18
  308. package/tests/pipeline/gate-engine.test.ts +34 -0
  309. package/tests/pipeline/install-check.test.ts +261 -0
  310. package/tests/pipeline/orchestrator.test.ts +1506 -15
  311. package/tests/pipeline/packets/builders.test.ts +29 -6
  312. package/tests/pipeline/phases/role-planning.strategy.test.ts +204 -0
  313. package/tests/pipeline/pipeline-persistence.test.ts +230 -0
  314. package/tests/pipeline/recovery-loop-guidance.test.ts +280 -0
  315. package/tests/pipeline/role-execution-adapter.test.ts +88 -0
  316. package/tests/pipeline/skills/coverage-gate.test.ts +370 -0
  317. package/tests/pipeline/skills/usage-registry.test.ts +114 -0
  318. package/tests/pipeline/strategy-context.test.ts +148 -0
  319. package/tests/shared/text-utils.test.ts +155 -0
  320. package/tests/state/progress-analysis.test.ts +375 -0
  321. package/tests/upgrade/handlers.test.ts +33 -2
  322. package/tests/workflow/consensus.test.ts +6 -0
  323. package/tsconfig.json +1 -1
@@ -220,6 +220,73 @@ function getBuildLabel(language) {
220
220
  default: return language;
221
221
  }
222
222
  }
223
+ /**
224
+ * Get language-specific next steps for the project completion summary.
225
+ * Returns an array of instruction strings the user should follow after generation.
226
+ */
227
+ function getNextSteps(language, projectDir) {
228
+ const steps = [];
229
+ switch (language) {
230
+ case 'website':
231
+ steps.push('cd ' + projectDir);
232
+ steps.push('npm install');
233
+ steps.push('npm run dev # Start the development server');
234
+ steps.push('Open http://localhost:3000 in your browser');
235
+ steps.push('npm run build # Create production build');
236
+ break;
237
+ case 'typescript':
238
+ case 'javascript':
239
+ steps.push('cd ' + projectDir);
240
+ steps.push('npm install');
241
+ steps.push('npm run dev # Start the development server');
242
+ steps.push('npm test # Run tests');
243
+ steps.push('npm run build # Create production build');
244
+ break;
245
+ case 'python':
246
+ steps.push('cd ' + projectDir);
247
+ steps.push('python -m venv venv && source venv/bin/activate');
248
+ steps.push('pip install -r requirements.txt');
249
+ steps.push('python main.py # Run the application');
250
+ steps.push('pytest # Run tests');
251
+ break;
252
+ case 'fullstack':
253
+ steps.push('cd ' + projectDir);
254
+ steps.push('npm install # Install workspace dependencies');
255
+ steps.push('# Frontend:');
256
+ steps.push('cd apps/frontend && npm run dev');
257
+ steps.push('# Backend:');
258
+ steps.push('cd apps/backend && pip install -r requirements.txt && python main.py');
259
+ break;
260
+ case 'all':
261
+ steps.push('cd ' + projectDir);
262
+ steps.push('npm install # Install workspace dependencies');
263
+ steps.push('# Frontend:');
264
+ steps.push('cd apps/frontend && npm run dev');
265
+ steps.push('# Backend:');
266
+ steps.push('cd apps/backend && pip install -r requirements.txt && python main.py');
267
+ steps.push('# Website:');
268
+ steps.push('cd apps/website && npm run dev');
269
+ break;
270
+ default:
271
+ steps.push('cd ' + projectDir);
272
+ steps.push('Review the README.md for setup instructions');
273
+ break;
274
+ }
275
+ return steps;
276
+ }
277
+ /**
278
+ * Print next steps section for project completion summary.
279
+ */
280
+ function printNextSteps(language, projectDir) {
281
+ const steps = getNextSteps(language, projectDir);
282
+ console.log();
283
+ console.log(theme.primary.bold(' Next Steps:'));
284
+ for (const step of steps) {
285
+ console.log(` ${theme.dim('$')} ${step}`);
286
+ }
287
+ console.log();
288
+ console.log(` ${theme.dim('Review the generated README.md for full documentation.')}`);
289
+ }
223
290
  /**
224
291
  * Draw the header box
225
292
  */
@@ -1766,12 +1833,38 @@ async function handleResume(state, args) {
1766
1833
  // Get detailed progress analysis
1767
1834
  const progressAnalysis = await analyzeProjectProgress(state.projectDir);
1768
1835
  const verification = await verifyProjectCompletion(state.projectDir);
1836
+ // v2.5.3: Compute failing gates once for STUCK/RECOVERY_LOOP display.
1837
+ // failedPhase can be misleading (e.g. QA_VALIDATION when the real blocker is
1838
+ // CONSENSUS_MASTER_PLAN). Scan all gateResults for actual failures.
1839
+ const pp = status.state.pipeline?.pipelinePhase;
1840
+ const pl = status.state.pipeline;
1841
+ const failingGates = pl
1842
+ ? Object.entries(pl.gateResults)
1843
+ .filter(([, gr]) => !gr.pass)
1844
+ .filter(([, gr]) => gr.blockers.length > 0 || gr.missingArtifacts.length > 0 || gr.failedChecks.length > 0)
1845
+ .sort((a, b) => {
1846
+ const aConsensus = a[1].consensusScore !== undefined ? 0 : 1;
1847
+ const bConsensus = b[1].consensusScore !== undefined ? 0 : 1;
1848
+ if (aConsensus !== bConsensus)
1849
+ return aConsensus - bConsensus;
1850
+ return b[1].blockers.length - a[1].blockers.length;
1851
+ })
1852
+ : [];
1853
+ const blockingAt = failingGates[0]?.[0] ?? pl?.failedPhase ?? 'unknown';
1769
1854
  console.log();
1770
1855
  console.log(theme.primary.bold(' Project Status:'));
1771
1856
  console.log(` ${theme.dim('Name:')} ${status.state.name}`);
1772
1857
  console.log(` ${theme.dim('Language:')} ${theme.primary(status.state.language)}`);
1773
- console.log(` ${theme.dim('Phase:')} ${theme.primary(status.state.phase)}`);
1774
- console.log(` ${theme.dim('Status:')} ${status.state.status}`);
1858
+ if (pp === 'STUCK' || pp === 'RECOVERY_LOOP') {
1859
+ // Reason: toLegacyPhase('STUCK') returns 'execution' and status may be stale 'complete'
1860
+ // from a prior completeProject() call — override both with accurate info.
1861
+ console.log(` ${theme.dim('Phase:')} ${theme.error(pp)} (blocking at ${blockingAt})`);
1862
+ console.log(` ${theme.dim('Status:')} ${theme.error('requires intervention')}`);
1863
+ }
1864
+ else {
1865
+ console.log(` ${theme.dim('Phase:')} ${theme.primary(status.state.phase)}`);
1866
+ console.log(` ${theme.dim('Status:')} ${status.state.status}`);
1867
+ }
1775
1868
  // Show detailed progress comparison
1776
1869
  console.log();
1777
1870
  console.log(theme.primary.bold(' Progress Analysis:'));
@@ -1831,8 +1924,87 @@ async function handleResume(state, args) {
1831
1924
  console.log();
1832
1925
  console.log(theme.dim(` Plan file: ${progressAnalysis.planParseError}`));
1833
1926
  }
1834
- // Check for status mismatch (status says complete but state tasks are incomplete)
1835
- if (progressAnalysis.statusMismatch && !progressAnalysis.planMismatch) {
1927
+ // Pipeline-specific messaging takes priority over legacy mismatch
1928
+ // Reason: pp, pl, failingGates, blockingAt already computed above (Change 1)
1929
+ if (pp) {
1930
+ if (pp === 'STUCK') {
1931
+ console.log();
1932
+ console.log(theme.error.bold(' PIPELINE STUCK:'));
1933
+ console.log(theme.error(` Blocking at: ${blockingAt}`));
1934
+ console.log(theme.error(` Recovery attempts: ${pl.recoveryCount ?? 0}/${pl.maxRecoveryIterations ?? 5}`));
1935
+ // Top-line summary: if the primary failing gate has a consensus score, show it
1936
+ const primaryGate = failingGates[0];
1937
+ if (primaryGate?.[1].consensusScore !== undefined) {
1938
+ const threshold = 0.95;
1939
+ console.log(theme.error(` Consensus score: ${primaryGate[1].consensusScore.toFixed(2)} < ${threshold}`));
1940
+ }
1941
+ // Show all failing gates with details
1942
+ if (failingGates.length > 0) {
1943
+ console.log();
1944
+ console.log(theme.warning(' Gate Blockers:'));
1945
+ for (const [phase, gr] of failingGates) {
1946
+ const scoreStr = gr.consensusScore !== undefined
1947
+ ? ` (score: ${gr.consensusScore.toFixed(2)})`
1948
+ : '';
1949
+ console.log(theme.warning(` ${phase}${scoreStr}:`));
1950
+ if (gr.blockers.length > 0) {
1951
+ for (const blocker of gr.blockers.slice(0, 3)) {
1952
+ console.log(` ${theme.dim('-')} ${blocker}`);
1953
+ }
1954
+ }
1955
+ else if (gr.missingArtifacts.length > 0) {
1956
+ console.log(` ${theme.dim('-')} Missing artifacts: ${gr.missingArtifacts.join(', ')}`);
1957
+ }
1958
+ else if (gr.failedChecks.length > 0) {
1959
+ console.log(` ${theme.dim('-')} Failed checks: ${gr.failedChecks.join(', ')}`);
1960
+ }
1961
+ else {
1962
+ console.log(` ${theme.dim('-')} Gate failed (no details reported)`);
1963
+ }
1964
+ }
1965
+ }
1966
+ // Surface diagnostic report paths
1967
+ const stuckReport = pl.artifacts?.find(a => a.type === 'stuck_report');
1968
+ const rcaReport = pl.artifacts
1969
+ ?.filter(a => a.type === 'rca_report')
1970
+ .sort((a, b) => b.timestamp.localeCompare(a.timestamp))[0];
1971
+ if (stuckReport || rcaReport) {
1972
+ console.log();
1973
+ console.log(theme.secondary(' Diagnostic Reports:'));
1974
+ if (stuckReport)
1975
+ console.log(` ${theme.dim('Stuck report:')} ${stuckReport.path}`);
1976
+ if (rcaReport)
1977
+ console.log(` ${theme.dim('RCA report:')} ${rcaReport.path}`);
1978
+ // v2.6.0: Surface auto-recovery artifact and result
1979
+ const autoRecoveryArtifact = pl.artifacts?.find(a => a.type === 'auto_recovery_guidance');
1980
+ if (autoRecoveryArtifact) {
1981
+ console.log(` ${theme.dim('Auto-recovery:')} ${autoRecoveryArtifact.path}`);
1982
+ }
1983
+ if (pl.autoRecoveryResult) {
1984
+ console.log(` ${theme.dim('Auto-recovery result:')} ${pl.autoRecoveryResult}`);
1985
+ }
1986
+ }
1987
+ console.log();
1988
+ console.log(theme.secondary(' Provide guidance when resuming to attempt recovery.'));
1989
+ }
1990
+ else if (pp === 'RECOVERY_LOOP') {
1991
+ const count = pl.recoveryCount ?? 0;
1992
+ const max = pl.maxRecoveryIterations ?? 5;
1993
+ console.log();
1994
+ console.log(theme.warning.bold(' RECOVERY IN PROGRESS:'));
1995
+ console.log(theme.warning(` Failed at: ${pl.failedPhase ?? 'unknown'}`));
1996
+ console.log(theme.warning(` Recovery attempts: ${count}/${max}`));
1997
+ if (count < max) {
1998
+ console.log(theme.secondary(' Resume will auto-retry. Optional: add guidance to steer recovery.'));
1999
+ console.log(theme.secondary(' Once attempts are exhausted, guidance will be required.'));
2000
+ }
2001
+ else {
2002
+ console.log(theme.secondary(' All attempts exhausted. Add guidance when resuming to retry.'));
2003
+ }
2004
+ }
2005
+ }
2006
+ else if (progressAnalysis.statusMismatch && !progressAnalysis.planMismatch) {
2007
+ // Legacy mismatch (non-pipeline projects only)
1836
2008
  console.log();
1837
2009
  console.log(theme.warning.bold(' WARNING: Status Mismatch Detected!'));
1838
2010
  console.log(theme.warning(` Project status says '${status.state.status}' but work is incomplete.`));
@@ -1884,15 +2056,23 @@ async function handleResume(state, args) {
1884
2056
  // successful build verification (sets status='complete', phase='complete').
1885
2057
  // If all tasks are done but status is still 'in-progress', the final
1886
2058
  // verification phase (build, tests, README) never completed successfully.
1887
- if (verification.isComplete && projectExplicitlyCompleted) {
2059
+ const pipelineDone = status.state.pipeline?.pipelinePhase === 'DONE';
2060
+ if ((verification.isComplete && projectExplicitlyCompleted) ||
2061
+ (pipelineDone && progressAnalysis.totalMilestones === 0)) {
1888
2062
  console.log();
1889
2063
  printSuccess('Project is fully complete!');
1890
2064
  console.log();
1891
2065
  console.log(theme.primary.bold(' Project Summary:'));
1892
- console.log(` ${theme.dim('Milestones:')} ${progressAnalysis.totalMilestones}/${progressAnalysis.totalMilestones} complete`);
1893
- console.log(` ${theme.dim('Tasks:')} ${progressAnalysis.totalTasks}/${progressAnalysis.totalTasks} complete (100%)`);
1894
- console.log(` ${theme.dim('Build:')} ${theme.success(`${buildLabel} build passed`)}`);
2066
+ if (pipelineDone && progressAnalysis.totalMilestones === 0) {
2067
+ console.log(` ${theme.dim('Pipeline:')} ${theme.success('completed')}`);
2068
+ }
2069
+ else {
2070
+ console.log(` ${theme.dim('Milestones:')} ${progressAnalysis.totalMilestones}/${progressAnalysis.totalMilestones} complete`);
2071
+ console.log(` ${theme.dim('Tasks:')} ${progressAnalysis.totalTasks}/${progressAnalysis.totalTasks} complete (100%)`);
2072
+ console.log(` ${theme.dim('Build:')} ${theme.success(`${buildLabel} build passed`)}`);
2073
+ }
1895
2074
  console.log(` ${theme.dim('Location:')} ${state.projectDir}`);
2075
+ printNextSteps(status.state.language, state.projectDir);
1896
2076
  return;
1897
2077
  }
1898
2078
  // All tasks complete but project was never explicitly marked complete
@@ -1903,8 +2083,49 @@ async function handleResume(state, args) {
1903
2083
  }
1904
2084
  // Check if user provided context as argument
1905
2085
  let additionalContext = args.join(' ').trim();
2086
+ const isStuck = pp === 'STUCK';
1906
2087
  // If no context provided, ask if they want to add guidance
1907
- if (!additionalContext) {
2088
+ // v2.5.3: STUCK pipelines get context-aware prompt with blocker details and phase-specific hints
2089
+ if (!additionalContext && isStuck) {
2090
+ if (failingGates.length > 0) {
2091
+ console.log();
2092
+ console.log(theme.warning.bold(' Guidance should address:'));
2093
+ for (const [phase, gr] of failingGates) {
2094
+ for (const b of gr.blockers.slice(0, 2)) {
2095
+ console.log(` ${theme.dim('-')} [${phase}] ${b}`);
2096
+ }
2097
+ }
2098
+ }
2099
+ // Phase-specific actionable hints
2100
+ let promptHint = 'e.g., "Focus on fixing the specific blocker above"';
2101
+ if (blockingAt.startsWith('CONSENSUS_')) {
2102
+ promptHint = 'e.g., "Reduce scope to core features only", "Split into smaller milestones", "Lower the consensus threshold"';
2103
+ }
2104
+ else if (blockingAt === 'QA_VALIDATION') {
2105
+ promptHint = 'e.g., "Fix failing test X", "Skip flaky tests", "Adjust build config"';
2106
+ }
2107
+ else if (blockingAt === 'PRODUCTION_GATE') {
2108
+ promptHint = 'e.g., "Mark finding as non-blocking", "Implement quick fix for issue X"';
2109
+ }
2110
+ console.log();
2111
+ // Default YES — STUCK pipelines strongly need guidance
2112
+ const wantsContext = failingGates.length > 0
2113
+ ? await promptYesNo(theme.primary('Would you like to provide guidance to unblock the pipeline?'), true)
2114
+ : await promptYesNo(theme.primary('Would you like to add guidance before resuming?'), false);
2115
+ if (wantsContext) {
2116
+ additionalContext = await promptForContext(`What guidance would you like to give? (${promptHint})`);
2117
+ }
2118
+ else {
2119
+ // v2.6.0: Don't return early — let the orchestrator attempt auto-recovery
2120
+ // via the arbitrator before giving up. If auto-recovery fails,
2121
+ // resumePipeline() returns STUCK and the normal error path handles it.
2122
+ console.log();
2123
+ console.log(theme.secondary(' No guidance provided. Attempting auto-recovery...'));
2124
+ // additionalContext stays empty — resumePipeline will attempt auto-recovery
2125
+ }
2126
+ }
2127
+ else if (!additionalContext) {
2128
+ // Non-STUCK: existing generic guidance prompt
1908
2129
  console.log();
1909
2130
  const wantsContext = await promptYesNo(theme.primary('Would you like to add guidance before resuming?'), false);
1910
2131
  if (wantsContext) {
@@ -1968,6 +2189,7 @@ async function handleResume(state, args) {
1968
2189
  else if (testSt === 'no-tests') {
1969
2190
  console.log(` ${theme.dim('Tests:')} ${theme.dim('No tests found')}`);
1970
2191
  }
2192
+ printNextSteps(status.state.language, state.projectDir);
1971
2193
  }
1972
2194
  else if (result.rateLimitPaused) {
1973
2195
  // Rate limit pause - show friendly message, not an error
@@ -1987,8 +2209,26 @@ async function handleResume(state, args) {
1987
2209
  const failBuildLabel = getBuildLabel(status.state.language);
1988
2210
  console.log(` ${theme.dim('Build:')} ${theme.error(`${failBuildLabel} build failed`)}`);
1989
2211
  }
2212
+ // v2.5.3: For STUCK failures, surface gate blockers so user knows what to fix.
2213
+ // Try refreshed state first (from result), fall back to pre-resume state.
2214
+ const stuckPipeline = result.state?.pipeline ?? status.state.pipeline;
2215
+ if (stuckPipeline?.pipelinePhase === 'STUCK') {
2216
+ const stuckFailingGates = Object.entries(stuckPipeline.gateResults)
2217
+ .filter(([, gr]) => !gr.pass)
2218
+ .filter(([, gr]) => gr.blockers.length > 0 || gr.missingArtifacts.length > 0 || gr.failedChecks.length > 0);
2219
+ if (stuckFailingGates.length > 0) {
2220
+ console.log();
2221
+ console.log(theme.warning(' Blockers:'));
2222
+ for (const [phase, gr] of stuckFailingGates) {
2223
+ const firstIssue = gr.blockers[0] ?? `Missing: ${gr.missingArtifacts[0] ?? gr.failedChecks[0] ?? 'unknown'}`;
2224
+ console.log(` ${theme.dim('-')} [${phase}] ${firstIssue}`);
2225
+ }
2226
+ }
2227
+ }
1990
2228
  printInfo('You can run /resume again with additional guidance');
1991
2229
  }
2230
+ // v2.5.4: Recreate readline after workflow run (stdin corruption fix)
2231
+ state.refreshReadline?.();
1992
2232
  return;
1993
2233
  }
1994
2234
  // No formal project state - try to discover context from docs/
@@ -2113,11 +2353,16 @@ async function handleResume(state, args) {
2113
2353
  }
2114
2354
  printSuccess('Workflow completed!');
2115
2355
  console.log(` ${theme.dim('Location:')} ${state.projectDir}`);
2356
+ if (state.projectDir) {
2357
+ printNextSteps(spec.language, state.projectDir);
2358
+ }
2116
2359
  }
2117
2360
  else {
2118
2361
  printError(result.error || 'Workflow failed');
2119
2362
  printInfo('You can run /resume again with additional guidance');
2120
2363
  }
2364
+ // v2.5.4: Recreate readline after workflow run (stdin corruption fix)
2365
+ state.refreshReadline?.();
2121
2366
  }
2122
2367
  /**
2123
2368
  * Directories that are too generic to use as project names.
@@ -2459,7 +2704,11 @@ async function handleIdea(idea, state) {
2459
2704
  }
2460
2705
  else {
2461
2706
  printError(workflowResult.error || 'Workflow failed');
2707
+ state.projectDir = projectDir; // v2.5.4: Project exists, track it for /resume
2708
+ printInfo('Run /resume with guidance to continue.');
2462
2709
  }
2710
+ // v2.5.4: Recreate readline after workflow run (stdin corruption fix)
2711
+ state.refreshReadline?.();
2463
2712
  }
2464
2713
  /**
2465
2714
  * Handle /new command - force create a new project (skips existing project check)
@@ -2562,7 +2811,11 @@ async function handleNewProject(idea, state) {
2562
2811
  }
2563
2812
  else {
2564
2813
  printError(workflowResult.error || 'Workflow failed');
2814
+ state.projectDir = projectDir; // v2.5.4: Project exists, track it for /resume
2815
+ printInfo('Run /resume with guidance to continue.');
2565
2816
  }
2817
+ // v2.5.4: Recreate readline after workflow run (stdin corruption fix)
2818
+ state.refreshReadline?.();
2566
2819
  }
2567
2820
  /**
2568
2821
  * Start interactive mode with auto-authentication
@@ -2610,26 +2863,77 @@ export async function startInteractiveMode() {
2610
2863
  printSuccess('Ready! Type your project idea or /help for commands');
2611
2864
  }
2612
2865
  console.log();
2613
- // Create readline interface
2614
- const rl = readline.createInterface({
2615
- input: process.stdin,
2616
- output: process.stdout,
2617
- });
2866
+ // v2.5.4: Mutable readline — recreated after workflow runs to recover from
2867
+ // stdin corruption caused by the Claude SDK's query() function.
2868
+ // See src/cli/commands/debug.ts:378-379 for documentation of the issue.
2869
+ let intentionalExit = false;
2870
+ let isPrompting = false;
2871
+ function createReadlineInterface() {
2872
+ const iface = readline.createInterface({
2873
+ input: process.stdin,
2874
+ output: process.stdout,
2875
+ });
2876
+ // Last-resort safety net: if stdin closes unexpectedly, exit cleanly or recreate
2877
+ iface.on('close', () => {
2878
+ if (intentionalExit)
2879
+ return;
2880
+ // Only attempt to recreate if stdin is still usable (TTY and not destroyed)
2881
+ if (process.stdin.isTTY && !process.stdin.destroyed && !isPrompting) {
2882
+ isPrompting = false;
2883
+ rl = createReadlineInterface();
2884
+ console.log();
2885
+ printWarning('Input stream interrupted. Restoring prompt...');
2886
+ promptUser();
2887
+ }
2888
+ else {
2889
+ // stdin is gone (piped input finished, non-TTY, etc.) — exit cleanly
2890
+ console.log();
2891
+ printInfo('Input stream closed (stdin EOF). Re-run in an interactive terminal if this was unexpected.');
2892
+ process.exit(1);
2893
+ }
2894
+ });
2895
+ return iface;
2896
+ }
2897
+ function refreshReadline() {
2898
+ try {
2899
+ rl.close();
2900
+ }
2901
+ catch { /* already closed */ }
2902
+ rl = createReadlineInterface();
2903
+ }
2904
+ let rl = createReadlineInterface();
2905
+ // Expose refreshReadline on state so handleIdea/handleResume/handleNewProject can call it
2906
+ state.refreshReadline = refreshReadline;
2618
2907
  // Input loop
2619
2908
  const promptUser = () => {
2909
+ if (isPrompting)
2910
+ return; // re-entrancy guard
2911
+ isPrompting = true;
2620
2912
  drawInputBoxTop(state);
2621
2913
  rl.question(getPrompt(), async (input) => {
2622
2914
  // Draw bottom of input box after user presses enter
2623
2915
  drawInputBoxBottom();
2624
- const shouldContinue = await handleInput(input, state);
2625
- if (shouldContinue) {
2916
+ try {
2917
+ const shouldContinue = await handleInput(input, state);
2918
+ if (shouldContinue) {
2919
+ isPrompting = false;
2920
+ console.log();
2921
+ promptUser();
2922
+ }
2923
+ else {
2924
+ intentionalExit = true;
2925
+ rl.close();
2926
+ process.exit(0);
2927
+ }
2928
+ }
2929
+ catch (err) {
2930
+ isPrompting = false;
2931
+ printError(`Unexpected error: ${err instanceof Error ? err.message : String(err)}`);
2932
+ printInfo('Returning to prompt. Your progress has been saved.');
2626
2933
  console.log();
2934
+ refreshReadline();
2627
2935
  promptUser();
2628
2936
  }
2629
- else {
2630
- rl.close();
2631
- process.exit(0);
2632
- }
2633
2937
  });
2634
2938
  };
2635
2939
  promptUser();