popeye-cli 2.1.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.
- package/dist/adapters/gemini.d.ts +14 -0
- package/dist/adapters/gemini.d.ts.map +1 -1
- package/dist/adapters/gemini.js +41 -6
- package/dist/adapters/gemini.js.map +1 -1
- package/dist/adapters/grok.d.ts +14 -0
- package/dist/adapters/grok.d.ts.map +1 -1
- package/dist/adapters/grok.js +42 -6
- package/dist/adapters/grok.js.map +1 -1
- package/dist/adapters/openai.d.ts +10 -0
- package/dist/adapters/openai.d.ts.map +1 -1
- package/dist/adapters/openai.js +44 -5
- package/dist/adapters/openai.js.map +1 -1
- package/dist/cli/commands/create.js +1 -1
- package/dist/cli/commands/create.js.map +1 -1
- package/dist/cli/interactive.d.ts.map +1 -1
- package/dist/cli/interactive.js +328 -21
- package/dist/cli/interactive.js.map +1 -1
- package/dist/generators/all.d.ts.map +1 -1
- package/dist/generators/all.js +25 -2
- package/dist/generators/all.js.map +1 -1
- package/dist/generators/doc-parser.d.ts +21 -6
- package/dist/generators/doc-parser.d.ts.map +1 -1
- package/dist/generators/doc-parser.js +55 -4
- package/dist/generators/doc-parser.js.map +1 -1
- package/dist/generators/templates/fullstack.js +1 -1
- package/dist/generators/templates/website-components.js +1 -1
- package/dist/generators/templates/website-components.js.map +1 -1
- package/dist/generators/templates/website-config.d.ts +4 -1
- package/dist/generators/templates/website-config.d.ts.map +1 -1
- package/dist/generators/templates/website-config.js +17 -11
- package/dist/generators/templates/website-config.js.map +1 -1
- package/dist/generators/templates/website-conversion.js +1 -1
- package/dist/generators/templates/website-conversion.js.map +1 -1
- package/dist/generators/templates/website-landing.js +1 -1
- package/dist/generators/templates/website-landing.js.map +1 -1
- package/dist/generators/templates/website-layout.d.ts +36 -4
- package/dist/generators/templates/website-layout.d.ts.map +1 -1
- package/dist/generators/templates/website-layout.js +466 -23
- package/dist/generators/templates/website-layout.js.map +1 -1
- package/dist/generators/templates/website-pricing.js +1 -1
- package/dist/generators/templates/website-pricing.js.map +1 -1
- package/dist/generators/templates/website-sections.js +1 -1
- package/dist/generators/templates/website-sections.js.map +1 -1
- package/dist/generators/templates/website-seo.d.ts.map +1 -1
- package/dist/generators/templates/website-seo.js +4 -1
- package/dist/generators/templates/website-seo.js.map +1 -1
- package/dist/generators/templates/website.d.ts +1 -1
- package/dist/generators/templates/website.d.ts.map +1 -1
- package/dist/generators/templates/website.js +1 -1
- package/dist/generators/templates/website.js.map +1 -1
- package/dist/generators/website-content-ai.d.ts +52 -0
- package/dist/generators/website-content-ai.d.ts.map +1 -0
- package/dist/generators/website-content-ai.js +141 -0
- package/dist/generators/website-content-ai.js.map +1 -0
- package/dist/generators/website-content-scanner.d.ts +1 -1
- package/dist/generators/website-content-scanner.d.ts.map +1 -1
- package/dist/generators/website-content-scanner.js +98 -1
- package/dist/generators/website-content-scanner.js.map +1 -1
- package/dist/generators/website-context.d.ts +34 -1
- package/dist/generators/website-context.d.ts.map +1 -1
- package/dist/generators/website-context.js +131 -9
- package/dist/generators/website-context.js.map +1 -1
- package/dist/generators/website-debug.d.ts +12 -0
- package/dist/generators/website-debug.d.ts.map +1 -1
- package/dist/generators/website-debug.js +16 -0
- package/dist/generators/website-debug.js.map +1 -1
- package/dist/generators/website.d.ts.map +1 -1
- package/dist/generators/website.js +26 -4
- package/dist/generators/website.js.map +1 -1
- package/dist/pipeline/artifact-manager.d.ts.map +1 -1
- package/dist/pipeline/artifact-manager.js +3 -0
- package/dist/pipeline/artifact-manager.js.map +1 -1
- package/dist/pipeline/auto-recovery.d.ts +56 -0
- package/dist/pipeline/auto-recovery.d.ts.map +1 -0
- package/dist/pipeline/auto-recovery.js +185 -0
- package/dist/pipeline/auto-recovery.js.map +1 -0
- package/dist/pipeline/change-request.d.ts +39 -0
- package/dist/pipeline/change-request.d.ts.map +1 -1
- package/dist/pipeline/change-request.js +40 -1
- package/dist/pipeline/change-request.js.map +1 -1
- package/dist/pipeline/check-runner.d.ts +30 -1
- package/dist/pipeline/check-runner.d.ts.map +1 -1
- package/dist/pipeline/check-runner.js +122 -1
- package/dist/pipeline/check-runner.js.map +1 -1
- package/dist/pipeline/command-resolver.d.ts.map +1 -1
- package/dist/pipeline/command-resolver.js +33 -2
- package/dist/pipeline/command-resolver.js.map +1 -1
- package/dist/pipeline/consensus/arbitrator-query.d.ts +22 -0
- package/dist/pipeline/consensus/arbitrator-query.d.ts.map +1 -0
- package/dist/pipeline/consensus/arbitrator-query.js +70 -0
- package/dist/pipeline/consensus/arbitrator-query.js.map +1 -0
- package/dist/pipeline/consensus/consensus-runner.d.ts +131 -7
- package/dist/pipeline/consensus/consensus-runner.d.ts.map +1 -1
- package/dist/pipeline/consensus/consensus-runner.js +809 -35
- package/dist/pipeline/consensus/consensus-runner.js.map +1 -1
- package/dist/pipeline/cr-lifecycle.d.ts +42 -0
- package/dist/pipeline/cr-lifecycle.d.ts.map +1 -0
- package/dist/pipeline/cr-lifecycle.js +89 -0
- package/dist/pipeline/cr-lifecycle.js.map +1 -0
- package/dist/pipeline/gate-engine.d.ts +1 -0
- package/dist/pipeline/gate-engine.d.ts.map +1 -1
- package/dist/pipeline/gate-engine.js +27 -8
- package/dist/pipeline/gate-engine.js.map +1 -1
- package/dist/pipeline/migration.d.ts.map +1 -1
- package/dist/pipeline/migration.js +3 -26
- package/dist/pipeline/migration.js.map +1 -1
- package/dist/pipeline/orchestrator.d.ts +1 -1
- package/dist/pipeline/orchestrator.d.ts.map +1 -1
- package/dist/pipeline/orchestrator.js +311 -16
- package/dist/pipeline/orchestrator.js.map +1 -1
- package/dist/pipeline/packets/consensus-packet-builder.d.ts +15 -4
- package/dist/pipeline/packets/consensus-packet-builder.d.ts.map +1 -1
- package/dist/pipeline/packets/consensus-packet-builder.js +29 -17
- package/dist/pipeline/packets/consensus-packet-builder.js.map +1 -1
- package/dist/pipeline/phases/architecture.d.ts.map +1 -1
- package/dist/pipeline/phases/architecture.js +5 -3
- package/dist/pipeline/phases/architecture.js.map +1 -1
- package/dist/pipeline/phases/audit.d.ts.map +1 -1
- package/dist/pipeline/phases/audit.js +5 -3
- package/dist/pipeline/phases/audit.js.map +1 -1
- package/dist/pipeline/phases/consensus-architecture.d.ts.map +1 -1
- package/dist/pipeline/phases/consensus-architecture.js +10 -1
- package/dist/pipeline/phases/consensus-architecture.js.map +1 -1
- package/dist/pipeline/phases/consensus-master-plan.d.ts.map +1 -1
- package/dist/pipeline/phases/consensus-master-plan.js +10 -3
- package/dist/pipeline/phases/consensus-master-plan.js.map +1 -1
- package/dist/pipeline/phases/consensus-role-plans.d.ts.map +1 -1
- package/dist/pipeline/phases/consensus-role-plans.js +10 -1
- package/dist/pipeline/phases/consensus-role-plans.js.map +1 -1
- package/dist/pipeline/phases/done.d.ts.map +1 -1
- package/dist/pipeline/phases/done.js +9 -4
- package/dist/pipeline/phases/done.js.map +1 -1
- package/dist/pipeline/phases/intake.d.ts +1 -0
- package/dist/pipeline/phases/intake.d.ts.map +1 -1
- package/dist/pipeline/phases/intake.js +56 -13
- package/dist/pipeline/phases/intake.js.map +1 -1
- package/dist/pipeline/phases/phase-context.d.ts +2 -0
- package/dist/pipeline/phases/phase-context.d.ts.map +1 -1
- package/dist/pipeline/phases/phase-context.js +3 -1
- package/dist/pipeline/phases/phase-context.js.map +1 -1
- package/dist/pipeline/phases/production-gate.d.ts.map +1 -1
- package/dist/pipeline/phases/production-gate.js +28 -3
- package/dist/pipeline/phases/production-gate.js.map +1 -1
- package/dist/pipeline/phases/qa-validation.d.ts.map +1 -1
- package/dist/pipeline/phases/qa-validation.js +38 -5
- package/dist/pipeline/phases/qa-validation.js.map +1 -1
- package/dist/pipeline/phases/recovery-loop.d.ts +2 -0
- package/dist/pipeline/phases/recovery-loop.d.ts.map +1 -1
- package/dist/pipeline/phases/recovery-loop.js +200 -6
- package/dist/pipeline/phases/recovery-loop.js.map +1 -1
- package/dist/pipeline/phases/review.d.ts.map +1 -1
- package/dist/pipeline/phases/review.js +58 -28
- package/dist/pipeline/phases/review.js.map +1 -1
- package/dist/pipeline/phases/role-planning.d.ts.map +1 -1
- package/dist/pipeline/phases/role-planning.js +20 -5
- package/dist/pipeline/phases/role-planning.js.map +1 -1
- package/dist/pipeline/phases/stuck.d.ts.map +1 -1
- package/dist/pipeline/phases/stuck.js +10 -0
- package/dist/pipeline/phases/stuck.js.map +1 -1
- package/dist/pipeline/repo-snapshot.d.ts.map +1 -1
- package/dist/pipeline/repo-snapshot.js +3 -0
- package/dist/pipeline/repo-snapshot.js.map +1 -1
- package/dist/pipeline/role-execution-adapter.d.ts +2 -1
- package/dist/pipeline/role-execution-adapter.d.ts.map +1 -1
- package/dist/pipeline/role-execution-adapter.js +22 -7
- package/dist/pipeline/role-execution-adapter.js.map +1 -1
- package/dist/pipeline/skill-loader.d.ts +19 -0
- package/dist/pipeline/skill-loader.d.ts.map +1 -1
- package/dist/pipeline/skill-loader.js +22 -0
- package/dist/pipeline/skill-loader.js.map +1 -1
- package/dist/pipeline/skills/constitution-generator.d.ts +51 -0
- package/dist/pipeline/skills/constitution-generator.d.ts.map +1 -0
- package/dist/pipeline/skills/constitution-generator.js +210 -0
- package/dist/pipeline/skills/constitution-generator.js.map +1 -0
- package/dist/pipeline/skills/coverage-gate.d.ts +44 -0
- package/dist/pipeline/skills/coverage-gate.d.ts.map +1 -0
- package/dist/pipeline/skills/coverage-gate.js +143 -0
- package/dist/pipeline/skills/coverage-gate.js.map +1 -0
- package/dist/pipeline/skills/generator.d.ts +65 -0
- package/dist/pipeline/skills/generator.d.ts.map +1 -0
- package/dist/pipeline/skills/generator.js +221 -0
- package/dist/pipeline/skills/generator.js.map +1 -0
- package/dist/pipeline/skills/role-map.d.ts +38 -0
- package/dist/pipeline/skills/role-map.d.ts.map +1 -0
- package/dist/pipeline/skills/role-map.js +234 -0
- package/dist/pipeline/skills/role-map.js.map +1 -0
- package/dist/pipeline/skills/types.d.ts +47 -0
- package/dist/pipeline/skills/types.d.ts.map +1 -0
- package/dist/pipeline/skills/types.js +5 -0
- package/dist/pipeline/skills/types.js.map +1 -0
- package/dist/pipeline/skills/usage-registry.d.ts +48 -0
- package/dist/pipeline/skills/usage-registry.d.ts.map +1 -0
- package/dist/pipeline/skills/usage-registry.js +55 -0
- package/dist/pipeline/skills/usage-registry.js.map +1 -0
- package/dist/pipeline/strategy-context.d.ts +20 -0
- package/dist/pipeline/strategy-context.d.ts.map +1 -0
- package/dist/pipeline/strategy-context.js +55 -0
- package/dist/pipeline/strategy-context.js.map +1 -0
- package/dist/pipeline/type-defs/artifacts.d.ts +30 -5
- package/dist/pipeline/type-defs/artifacts.d.ts.map +1 -1
- package/dist/pipeline/type-defs/artifacts.js +5 -0
- package/dist/pipeline/type-defs/artifacts.js.map +1 -1
- package/dist/pipeline/type-defs/audit.d.ts +28 -13
- package/dist/pipeline/type-defs/audit.d.ts.map +1 -1
- package/dist/pipeline/type-defs/checks.d.ts +19 -8
- package/dist/pipeline/type-defs/checks.d.ts.map +1 -1
- package/dist/pipeline/type-defs/checks.js +4 -0
- package/dist/pipeline/type-defs/checks.js.map +1 -1
- package/dist/pipeline/type-defs/packets.d.ts +119 -18
- package/dist/pipeline/type-defs/packets.d.ts.map +1 -1
- package/dist/pipeline/type-defs/packets.js +17 -1
- package/dist/pipeline/type-defs/packets.js.map +1 -1
- package/dist/pipeline/type-defs/state.d.ts +165 -16
- package/dist/pipeline/type-defs/state.d.ts.map +1 -1
- package/dist/pipeline/type-defs/state.js +26 -1
- package/dist/pipeline/type-defs/state.js.map +1 -1
- package/dist/shared/text-utils.d.ts +23 -0
- package/dist/shared/text-utils.d.ts.map +1 -0
- package/dist/shared/text-utils.js +66 -0
- package/dist/shared/text-utils.js.map +1 -0
- package/dist/shared/website-strategy-format.d.ts +18 -0
- package/dist/shared/website-strategy-format.d.ts.map +1 -0
- package/dist/shared/website-strategy-format.js +47 -0
- package/dist/shared/website-strategy-format.js.map +1 -0
- package/dist/state/index.d.ts +2 -0
- package/dist/state/index.d.ts.map +1 -1
- package/dist/state/index.js +57 -8
- package/dist/state/index.js.map +1 -1
- package/dist/types/consensus.d.ts +1 -0
- package/dist/types/consensus.d.ts.map +1 -1
- package/dist/types/consensus.js.map +1 -1
- package/dist/types/website-strategy.d.ts +1 -1
- package/dist/types/workflow.d.ts +447 -0
- package/dist/types/workflow.d.ts.map +1 -1
- package/dist/types/workflow.js +3 -0
- package/dist/types/workflow.js.map +1 -1
- package/dist/upgrade/handlers.d.ts.map +1 -1
- package/dist/upgrade/handlers.js +6 -3
- package/dist/upgrade/handlers.js.map +1 -1
- package/dist/workflow/consensus.d.ts.map +1 -1
- package/dist/workflow/consensus.js +1 -0
- package/dist/workflow/consensus.js.map +1 -1
- package/dist/workflow/website-strategy.d.ts.map +1 -1
- package/dist/workflow/website-strategy.js +2 -29
- package/dist/workflow/website-strategy.js.map +1 -1
- package/dist/workflow/website-updater.d.ts.map +1 -1
- package/dist/workflow/website-updater.js +3 -2
- package/dist/workflow/website-updater.js.map +1 -1
- package/package.json +1 -1
- package/src/adapters/gemini.ts +51 -6
- package/src/adapters/grok.ts +51 -6
- package/src/adapters/openai.ts +53 -5
- package/src/cli/commands/create.ts +1 -1
- package/src/cli/interactive.ts +337 -20
- package/src/generators/all.ts +25 -2
- package/src/generators/doc-parser.ts +75 -15
- package/src/generators/templates/fullstack.ts +1 -1
- package/src/generators/templates/website-components.ts +1 -1
- package/src/generators/templates/website-config.ts +23 -11
- package/src/generators/templates/website-conversion.ts +1 -1
- package/src/generators/templates/website-landing.ts +1 -1
- package/src/generators/templates/website-layout.ts +491 -23
- package/src/generators/templates/website-pricing.ts +1 -1
- package/src/generators/templates/website-sections.ts +1 -1
- package/src/generators/templates/website-seo.ts +4 -1
- package/src/generators/templates/website.ts +3 -0
- package/src/generators/website-content-ai.ts +186 -0
- package/src/generators/website-content-scanner.ts +113 -1
- package/src/generators/website-context.ts +151 -12
- package/src/generators/website-debug.ts +26 -0
- package/src/generators/website.ts +28 -3
- package/src/pipeline/artifact-manager.ts +3 -0
- package/src/pipeline/auto-recovery.ts +283 -0
- package/src/pipeline/change-request.ts +63 -1
- package/src/pipeline/check-runner.ts +141 -2
- package/src/pipeline/command-resolver.ts +34 -2
- package/src/pipeline/consensus/arbitrator-query.ts +101 -0
- package/src/pipeline/consensus/consensus-runner.ts +1099 -42
- package/src/pipeline/cr-lifecycle.ts +103 -0
- package/src/pipeline/gate-engine.ts +36 -8
- package/src/pipeline/migration.ts +5 -30
- package/src/pipeline/orchestrator.ts +367 -16
- package/src/pipeline/packets/consensus-packet-builder.ts +44 -18
- package/src/pipeline/phases/architecture.ts +6 -3
- package/src/pipeline/phases/audit.ts +6 -3
- package/src/pipeline/phases/consensus-architecture.ts +10 -1
- package/src/pipeline/phases/consensus-master-plan.ts +10 -3
- package/src/pipeline/phases/consensus-role-plans.ts +10 -1
- package/src/pipeline/phases/done.ts +15 -4
- package/src/pipeline/phases/intake.ts +67 -14
- package/src/pipeline/phases/phase-context.ts +6 -1
- package/src/pipeline/phases/production-gate.ts +41 -3
- package/src/pipeline/phases/qa-validation.ts +51 -5
- package/src/pipeline/phases/recovery-loop.ts +229 -7
- package/src/pipeline/phases/review.ts +73 -30
- package/src/pipeline/phases/role-planning.ts +23 -5
- package/src/pipeline/phases/stuck.ts +10 -0
- package/src/pipeline/repo-snapshot.ts +3 -0
- package/src/pipeline/role-execution-adapter.ts +30 -4
- package/src/pipeline/skill-loader.ts +33 -0
- package/src/pipeline/skills/constitution-generator.ts +236 -0
- package/src/pipeline/skills/coverage-gate.ts +199 -0
- package/src/pipeline/skills/generator.ts +287 -0
- package/src/pipeline/skills/role-map.ts +248 -0
- package/src/pipeline/skills/types.ts +53 -0
- package/src/pipeline/skills/usage-registry.ts +87 -0
- package/src/pipeline/strategy-context.ts +60 -0
- package/src/pipeline/type-defs/artifacts.ts +5 -0
- package/src/pipeline/type-defs/checks.ts +4 -0
- package/src/pipeline/type-defs/packets.ts +18 -1
- package/src/pipeline/type-defs/state.ts +26 -1
- package/src/shared/text-utils.ts +70 -0
- package/src/shared/website-strategy-format.ts +56 -0
- package/src/state/index.ts +60 -8
- package/src/types/consensus.ts +1 -0
- package/src/types/workflow.ts +6 -0
- package/src/upgrade/handlers.ts +9 -3
- package/src/workflow/consensus.ts +1 -0
- package/src/workflow/website-strategy.ts +2 -36
- package/src/workflow/website-updater.ts +4 -2
- package/tests/adapters/gemini.test.ts +165 -0
- package/tests/adapters/grok.test.ts +137 -0
- package/tests/adapters/openai.test.ts +128 -0
- package/tests/generators/doc-parser.test.ts +88 -9
- package/tests/generators/quality-gate.test.ts +19 -3
- package/tests/generators/website-components.test.ts +34 -0
- package/tests/generators/website-content-ai.test.ts +308 -0
- package/tests/generators/website-content-scanner.test.ts +86 -0
- package/tests/generators/website-context.test.ts +3 -2
- package/tests/integration/smokestack-scaffold.test.ts +385 -0
- package/tests/pipeline/auto-recovery.test.ts +337 -0
- package/tests/pipeline/change-request.test.ts +70 -0
- package/tests/pipeline/command-resolver.test.ts +42 -0
- package/tests/pipeline/consensus/arbitrator-query.test.ts +107 -0
- package/tests/pipeline/consensus-runner.test.ts +1333 -10
- package/tests/pipeline/consensus-scoring.test.ts +602 -18
- package/tests/pipeline/gate-engine.test.ts +34 -0
- package/tests/pipeline/install-check.test.ts +261 -0
- package/tests/pipeline/migration.test.ts +4 -3
- package/tests/pipeline/orchestrator.test.ts +1506 -15
- package/tests/pipeline/packets/builders.test.ts +29 -6
- package/tests/pipeline/phases/role-planning.strategy.test.ts +204 -0
- package/tests/pipeline/pipeline-persistence.test.ts +230 -0
- package/tests/pipeline/recovery-loop-guidance.test.ts +280 -0
- package/tests/pipeline/role-execution-adapter.test.ts +88 -0
- package/tests/pipeline/skills/constitution-generator.test.ts +201 -0
- package/tests/pipeline/skills/coverage-gate.test.ts +370 -0
- package/tests/pipeline/skills/generator.test.ts +213 -0
- package/tests/pipeline/skills/role-map.test.ts +198 -0
- package/tests/pipeline/skills/usage-registry.test.ts +114 -0
- package/tests/pipeline/strategy-context.test.ts +148 -0
- package/tests/shared/text-utils.test.ts +155 -0
- package/tests/state/progress-analysis.test.ts +375 -0
- package/tests/upgrade/handlers.test.ts +33 -2
- package/tests/workflow/consensus.test.ts +6 -0
- package/tsconfig.json +1 -1
package/dist/cli/interactive.js
CHANGED
|
@@ -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
|
*/
|
|
@@ -1674,7 +1741,10 @@ async function handleResume(state, args) {
|
|
|
1674
1741
|
}
|
|
1675
1742
|
}
|
|
1676
1743
|
// Only discover projects if no active project with pending work
|
|
1677
|
-
|
|
1744
|
+
// Reason: Also discover when state.projectDir is CWD but has no project state (project may be in subdirectory)
|
|
1745
|
+
const currentStatus = state.projectDir ? await getWorkflowStatus(state.projectDir) : null;
|
|
1746
|
+
const needsDiscovery = !state.projectDir || !currentStatus?.exists || currentStatus?.state?.phase === 'complete';
|
|
1747
|
+
if (needsDiscovery) {
|
|
1678
1748
|
// Discover all projects (registered + scanned in current directory)
|
|
1679
1749
|
console.log();
|
|
1680
1750
|
printInfo('Scanning for projects...');
|
|
@@ -1763,12 +1833,38 @@ async function handleResume(state, args) {
|
|
|
1763
1833
|
// Get detailed progress analysis
|
|
1764
1834
|
const progressAnalysis = await analyzeProjectProgress(state.projectDir);
|
|
1765
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';
|
|
1766
1854
|
console.log();
|
|
1767
1855
|
console.log(theme.primary.bold(' Project Status:'));
|
|
1768
1856
|
console.log(` ${theme.dim('Name:')} ${status.state.name}`);
|
|
1769
1857
|
console.log(` ${theme.dim('Language:')} ${theme.primary(status.state.language)}`);
|
|
1770
|
-
|
|
1771
|
-
|
|
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
|
+
}
|
|
1772
1868
|
// Show detailed progress comparison
|
|
1773
1869
|
console.log();
|
|
1774
1870
|
console.log(theme.primary.bold(' Progress Analysis:'));
|
|
@@ -1828,8 +1924,87 @@ async function handleResume(state, args) {
|
|
|
1828
1924
|
console.log();
|
|
1829
1925
|
console.log(theme.dim(` Plan file: ${progressAnalysis.planParseError}`));
|
|
1830
1926
|
}
|
|
1831
|
-
//
|
|
1832
|
-
|
|
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)
|
|
1833
2008
|
console.log();
|
|
1834
2009
|
console.log(theme.warning.bold(' WARNING: Status Mismatch Detected!'));
|
|
1835
2010
|
console.log(theme.warning(` Project status says '${status.state.status}' but work is incomplete.`));
|
|
@@ -1881,15 +2056,23 @@ async function handleResume(state, args) {
|
|
|
1881
2056
|
// successful build verification (sets status='complete', phase='complete').
|
|
1882
2057
|
// If all tasks are done but status is still 'in-progress', the final
|
|
1883
2058
|
// verification phase (build, tests, README) never completed successfully.
|
|
1884
|
-
|
|
2059
|
+
const pipelineDone = status.state.pipeline?.pipelinePhase === 'DONE';
|
|
2060
|
+
if ((verification.isComplete && projectExplicitlyCompleted) ||
|
|
2061
|
+
(pipelineDone && progressAnalysis.totalMilestones === 0)) {
|
|
1885
2062
|
console.log();
|
|
1886
2063
|
printSuccess('Project is fully complete!');
|
|
1887
2064
|
console.log();
|
|
1888
2065
|
console.log(theme.primary.bold(' Project Summary:'));
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
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
|
+
}
|
|
1892
2074
|
console.log(` ${theme.dim('Location:')} ${state.projectDir}`);
|
|
2075
|
+
printNextSteps(status.state.language, state.projectDir);
|
|
1893
2076
|
return;
|
|
1894
2077
|
}
|
|
1895
2078
|
// All tasks complete but project was never explicitly marked complete
|
|
@@ -1900,8 +2083,49 @@ async function handleResume(state, args) {
|
|
|
1900
2083
|
}
|
|
1901
2084
|
// Check if user provided context as argument
|
|
1902
2085
|
let additionalContext = args.join(' ').trim();
|
|
2086
|
+
const isStuck = pp === 'STUCK';
|
|
1903
2087
|
// If no context provided, ask if they want to add guidance
|
|
1904
|
-
|
|
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
|
|
1905
2129
|
console.log();
|
|
1906
2130
|
const wantsContext = await promptYesNo(theme.primary('Would you like to add guidance before resuming?'), false);
|
|
1907
2131
|
if (wantsContext) {
|
|
@@ -1965,6 +2189,7 @@ async function handleResume(state, args) {
|
|
|
1965
2189
|
else if (testSt === 'no-tests') {
|
|
1966
2190
|
console.log(` ${theme.dim('Tests:')} ${theme.dim('No tests found')}`);
|
|
1967
2191
|
}
|
|
2192
|
+
printNextSteps(status.state.language, state.projectDir);
|
|
1968
2193
|
}
|
|
1969
2194
|
else if (result.rateLimitPaused) {
|
|
1970
2195
|
// Rate limit pause - show friendly message, not an error
|
|
@@ -1984,8 +2209,26 @@ async function handleResume(state, args) {
|
|
|
1984
2209
|
const failBuildLabel = getBuildLabel(status.state.language);
|
|
1985
2210
|
console.log(` ${theme.dim('Build:')} ${theme.error(`${failBuildLabel} build failed`)}`);
|
|
1986
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
|
+
}
|
|
1987
2228
|
printInfo('You can run /resume again with additional guidance');
|
|
1988
2229
|
}
|
|
2230
|
+
// v2.5.4: Recreate readline after workflow run (stdin corruption fix)
|
|
2231
|
+
state.refreshReadline?.();
|
|
1989
2232
|
return;
|
|
1990
2233
|
}
|
|
1991
2234
|
// No formal project state - try to discover context from docs/
|
|
@@ -2110,11 +2353,16 @@ async function handleResume(state, args) {
|
|
|
2110
2353
|
}
|
|
2111
2354
|
printSuccess('Workflow completed!');
|
|
2112
2355
|
console.log(` ${theme.dim('Location:')} ${state.projectDir}`);
|
|
2356
|
+
if (state.projectDir) {
|
|
2357
|
+
printNextSteps(spec.language, state.projectDir);
|
|
2358
|
+
}
|
|
2113
2359
|
}
|
|
2114
2360
|
else {
|
|
2115
2361
|
printError(result.error || 'Workflow failed');
|
|
2116
2362
|
printInfo('You can run /resume again with additional guidance');
|
|
2117
2363
|
}
|
|
2364
|
+
// v2.5.4: Recreate readline after workflow run (stdin corruption fix)
|
|
2365
|
+
state.refreshReadline?.();
|
|
2118
2366
|
}
|
|
2119
2367
|
/**
|
|
2120
2368
|
* Directories that are too generic to use as project names.
|
|
@@ -2456,7 +2704,11 @@ async function handleIdea(idea, state) {
|
|
|
2456
2704
|
}
|
|
2457
2705
|
else {
|
|
2458
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.');
|
|
2459
2709
|
}
|
|
2710
|
+
// v2.5.4: Recreate readline after workflow run (stdin corruption fix)
|
|
2711
|
+
state.refreshReadline?.();
|
|
2460
2712
|
}
|
|
2461
2713
|
/**
|
|
2462
2714
|
* Handle /new command - force create a new project (skips existing project check)
|
|
@@ -2559,7 +2811,11 @@ async function handleNewProject(idea, state) {
|
|
|
2559
2811
|
}
|
|
2560
2812
|
else {
|
|
2561
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.');
|
|
2562
2816
|
}
|
|
2817
|
+
// v2.5.4: Recreate readline after workflow run (stdin corruption fix)
|
|
2818
|
+
state.refreshReadline?.();
|
|
2563
2819
|
}
|
|
2564
2820
|
/**
|
|
2565
2821
|
* Start interactive mode with auto-authentication
|
|
@@ -2607,26 +2863,77 @@ export async function startInteractiveMode() {
|
|
|
2607
2863
|
printSuccess('Ready! Type your project idea or /help for commands');
|
|
2608
2864
|
}
|
|
2609
2865
|
console.log();
|
|
2610
|
-
//
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
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;
|
|
2615
2907
|
// Input loop
|
|
2616
2908
|
const promptUser = () => {
|
|
2909
|
+
if (isPrompting)
|
|
2910
|
+
return; // re-entrancy guard
|
|
2911
|
+
isPrompting = true;
|
|
2617
2912
|
drawInputBoxTop(state);
|
|
2618
2913
|
rl.question(getPrompt(), async (input) => {
|
|
2619
2914
|
// Draw bottom of input box after user presses enter
|
|
2620
2915
|
drawInputBoxBottom();
|
|
2621
|
-
|
|
2622
|
-
|
|
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.');
|
|
2623
2933
|
console.log();
|
|
2934
|
+
refreshReadline();
|
|
2624
2935
|
promptUser();
|
|
2625
2936
|
}
|
|
2626
|
-
else {
|
|
2627
|
-
rl.close();
|
|
2628
|
-
process.exit(0);
|
|
2629
|
-
}
|
|
2630
2937
|
});
|
|
2631
2938
|
};
|
|
2632
2939
|
promptUser();
|