rafcode 1.0.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/.claude/settings.local.json +32 -0
- package/CLAUDE.md +187 -0
- package/LICENSE +21 -0
- package/RAF/001-raf-task-improvements/input.md +9 -0
- package/RAF/001-raf-task-improvements/outcomes/001-add-decisions-folder.md +21 -0
- package/RAF/001-raf-task-improvements/outcomes/002-fix-write-error-on-shutdown.md +22 -0
- package/RAF/001-raf-task-improvements/outcomes/003-stash-changes-on-failure.md +34 -0
- package/RAF/001-raf-task-improvements/outcomes/004-add-project-name-to-commits.md +28 -0
- package/RAF/001-raf-task-improvements/outcomes/005-add-running-time-display.md +36 -0
- package/RAF/001-raf-task-improvements/outcomes/006-add-task-name-to-logs.md +22 -0
- package/RAF/001-raf-task-improvements/outcomes/007-show-model-at-task-start.md +52 -0
- package/RAF/001-raf-task-improvements/outcomes/009-remove-editor-placeholder-text.md +20 -0
- package/RAF/001-raf-task-improvements/outcomes/SUMMARY.md +83 -0
- package/RAF/001-raf-task-improvements/plans/001-add-decisions-folder.md +38 -0
- package/RAF/001-raf-task-improvements/plans/002-fix-write-error-on-shutdown.md +33 -0
- package/RAF/001-raf-task-improvements/plans/003-stash-changes-on-failure.md +37 -0
- package/RAF/001-raf-task-improvements/plans/004-add-project-name-to-commits.md +34 -0
- package/RAF/001-raf-task-improvements/plans/005-add-running-time-display.md +39 -0
- package/RAF/001-raf-task-improvements/plans/006-add-task-name-to-logs.md +37 -0
- package/RAF/001-raf-task-improvements/plans/009-remove-editor-placeholder-text.md +34 -0
- package/RAF/002-raf-task-improvements-execution/decisions/DECISIONS.md +13 -0
- package/RAF/002-raf-task-improvements-execution/input.md +3 -0
- package/RAF/002-raf-task-improvements-execution/outcomes/001-commit-show-model-at-task-start.md +17 -0
- package/RAF/002-raf-task-improvements-execution/outcomes/002-delete-skipped-plan.md +23 -0
- package/RAF/002-raf-task-improvements-execution/outcomes/SUMMARY.md +32 -0
- package/RAF/002-raf-task-improvements-execution/plans/001-commit-show-model-at-task-start.md +37 -0
- package/RAF/002-raf-task-improvements-execution/plans/002-delete-skipped-plan.md +23 -0
- package/RAF/003-multi-project-execution/decisions/DECISIONS.md +68 -0
- package/RAF/003-multi-project-execution/input.md +6 -0
- package/RAF/003-multi-project-execution/outcomes/001-remove-state-json.md +52 -0
- package/RAF/003-multi-project-execution/outcomes/002-update-raf-status.md +50 -0
- package/RAF/003-multi-project-execution/outcomes/003-simplify-git-logic.md +35 -0
- package/RAF/003-multi-project-execution/outcomes/004-auto-commit-planning.md +43 -0
- package/RAF/003-multi-project-execution/outcomes/005-rerun-failed-tasks.md +43 -0
- package/RAF/003-multi-project-execution/outcomes/006-multi-project-execution.md +42 -0
- package/RAF/003-multi-project-execution/outcomes/007-verify-timeout.md +54 -0
- package/RAF/003-multi-project-execution/outcomes/008-move-decisions-file.md +38 -0
- package/RAF/003-multi-project-execution/outcomes/SUMMARY.md +79 -0
- package/RAF/003-multi-project-execution/plans/001-remove-state-json.md +71 -0
- package/RAF/003-multi-project-execution/plans/002-update-raf-status.md +65 -0
- package/RAF/003-multi-project-execution/plans/003-simplify-git-logic.md +74 -0
- package/RAF/003-multi-project-execution/plans/004-auto-commit-planning.md +57 -0
- package/RAF/003-multi-project-execution/plans/005-rerun-failed-tasks.md +69 -0
- package/RAF/003-multi-project-execution/plans/006-multi-project-execution.md +81 -0
- package/RAF/003-multi-project-execution/plans/007-verify-timeout.md +63 -0
- package/RAF/003-multi-project-execution/plans/008-move-decisions-file.md +78 -0
- package/RAF/004-task-naming-optimization/decisions.md +22 -0
- package/RAF/004-task-naming-optimization/input.md +6 -0
- package/RAF/004-task-naming-optimization/outcomes/001-remove-summary-file.md +17 -0
- package/RAF/004-task-naming-optimization/outcomes/002-base36-project-numbering.md +32 -0
- package/RAF/004-task-naming-optimization/outcomes/003-improve-haiku-prompt.md +20 -0
- package/RAF/004-task-naming-optimization/outcomes/SUMMARY.md +28 -0
- package/RAF/004-task-naming-optimization/plans/001-remove-summary-file.md +34 -0
- package/RAF/004-task-naming-optimization/plans/002-base36-project-numbering.md +56 -0
- package/RAF/004-task-naming-optimization/plans/003-improve-haiku-prompt.md +50 -0
- package/RAF/005-task-naming-improvements/decisions.md +60 -0
- package/RAF/005-task-naming-improvements/input.md +2 -0
- package/RAF/005-task-naming-improvements/outcomes/001-enhance-identifier-resolution.md +42 -0
- package/RAF/005-task-naming-improvements/outcomes/002-add-identifier-support-to-status.md +38 -0
- package/RAF/005-task-naming-improvements/outcomes/003-update-do-for-full-folder-names.md +44 -0
- package/RAF/005-task-naming-improvements/outcomes/004-implement-amend-flag-for-plan.md +55 -0
- package/RAF/005-task-naming-improvements/outcomes/005-commit-outcomes-on-complete.md +47 -0
- package/RAF/005-task-naming-improvements/outcomes/006-update-execution-prompt-commit-schema.md +40 -0
- package/RAF/005-task-naming-improvements/outcomes/007-allow-pending-task-amendments.md +38 -0
- package/RAF/005-task-naming-improvements/outcomes/008-fix-timeout-label.md +24 -0
- package/RAF/005-task-naming-improvements/plans/001-enhance-identifier-resolution.md +46 -0
- package/RAF/005-task-naming-improvements/plans/002-add-identifier-support-to-status.md +36 -0
- package/RAF/005-task-naming-improvements/plans/003-update-do-for-full-folder-names.md +38 -0
- package/RAF/005-task-naming-improvements/plans/004-implement-amend-flag-for-plan.md +67 -0
- package/RAF/005-task-naming-improvements/plans/005-commit-outcomes-on-complete.md +86 -0
- package/RAF/005-task-naming-improvements/plans/006-update-execution-prompt-commit-schema.md +60 -0
- package/RAF/005-task-naming-improvements/plans/007-allow-pending-task-amendments.md +60 -0
- package/RAF/005-task-naming-improvements/plans/008-fix-timeout-label.md +31 -0
- package/RAF/006-fix-double-summary-headers/decisions.md +28 -0
- package/RAF/006-fix-double-summary-headers/input.md +3 -0
- package/RAF/006-fix-double-summary-headers/outcomes/001-fix-double-summary-headers.md +29 -0
- package/RAF/006-fix-double-summary-headers/outcomes/002-update-readme-for-npm.md +31 -0
- package/RAF/006-fix-double-summary-headers/outcomes/003-npm-publish-instructions.md +30 -0
- package/RAF/006-fix-double-summary-headers/outcomes/004-flexible-project-lookup.md +47 -0
- package/RAF/006-fix-double-summary-headers/plans/001-fix-double-summary-headers.md +42 -0
- package/RAF/006-fix-double-summary-headers/plans/002-update-readme-for-npm.md +44 -0
- package/RAF/006-fix-double-summary-headers/plans/003-npm-publish-instructions.md +45 -0
- package/RAF/006-fix-double-summary-headers/plans/004-flexible-project-lookup.md +40 -0
- package/RAF/007-improve-outcome-format/decisions.md +28 -0
- package/RAF/007-improve-outcome-format/input.md +2 -0
- package/RAF/007-improve-outcome-format/outcomes/001-update-execution-prompt.md +10 -0
- package/RAF/007-improve-outcome-format/outcomes/002-update-state-derivation.md +17 -0
- package/RAF/007-improve-outcome-format/outcomes/003-update-do-command-outcome-handling.md +16 -0
- package/RAF/007-improve-outcome-format/outcomes/004-implement-failure-analysis.md +16 -0
- package/RAF/007-improve-outcome-format/outcomes/005-update-documentation.md +15 -0
- package/RAF/007-improve-outcome-format/plans/001-update-execution-prompt.md +36 -0
- package/RAF/007-improve-outcome-format/plans/002-update-state-derivation.md +35 -0
- package/RAF/007-improve-outcome-format/plans/003-update-do-command-outcome-handling.md +37 -0
- package/RAF/007-improve-outcome-format/plans/004-implement-failure-analysis.md +44 -0
- package/RAF/007-improve-outcome-format/plans/005-update-documentation.md +33 -0
- package/RAF/008-beautiful-do/decisions.md +31 -0
- package/RAF/008-beautiful-do/input.md +1 -0
- package/RAF/008-beautiful-do/outcomes/001-terminal-symbols.md +55 -0
- package/RAF/008-beautiful-do/outcomes/002-refactor-do-output.md +95 -0
- package/RAF/008-beautiful-do/outcomes/003-refactor-status-output.md +71 -0
- package/RAF/008-beautiful-do/outcomes/004-simplify-logger.md +53 -0
- package/RAF/008-beautiful-do/outcomes/005-add-tests.md +41 -0
- package/RAF/008-beautiful-do/plans/001-terminal-symbols.md +41 -0
- package/RAF/008-beautiful-do/plans/002-refactor-do-output.md +44 -0
- package/RAF/008-beautiful-do/plans/003-refactor-status-output.md +37 -0
- package/RAF/008-beautiful-do/plans/004-simplify-logger.md +32 -0
- package/RAF/008-beautiful-do/plans/005-add-tests.md +40 -0
- package/RAF/009-system-promt-ammend/decisions.md +13 -0
- package/RAF/009-system-promt-ammend/input.md +9 -0
- package/RAF/009-system-promt-ammend/outcomes/001-model-override.md +79 -0
- package/RAF/009-system-promt-ammend/outcomes/002-system-prompt-append.md +51 -0
- package/RAF/009-system-promt-ammend/outcomes/003-retry-context.md +60 -0
- package/RAF/009-system-promt-ammend/plans/001-model-override.md +61 -0
- package/RAF/009-system-promt-ammend/plans/002-system-prompt-append.md +56 -0
- package/RAF/009-system-promt-ammend/plans/003-retry-context.md +76 -0
- package/RAF/010-outcome-marker-fallback/decisions.md +19 -0
- package/RAF/010-outcome-marker-fallback/input.md +1 -0
- package/RAF/010-outcome-marker-fallback/outcomes/001-outcome-file-marker-fallback.md +35 -0
- package/RAF/010-outcome-marker-fallback/outcomes/002-creative-project-naming.md +47 -0
- package/RAF/010-outcome-marker-fallback/plans/001-outcome-file-marker-fallback.md +58 -0
- package/RAF/010-outcome-marker-fallback/plans/002-creative-project-naming.md +68 -0
- package/RAF/011-do-task-in-commit/decisions.md +22 -0
- package/RAF/011-do-task-in-commit/input.md +1 -0
- package/RAF/011-do-task-in-commit/outcomes/001-update-execution-prompt.md +54 -0
- package/RAF/011-do-task-in-commit/outcomes/002-update-tests.md +61 -0
- package/RAF/011-do-task-in-commit/outcomes/003-update-documentation.md +51 -0
- package/RAF/011-do-task-in-commit/plans/001-update-execution-prompt.md +46 -0
- package/RAF/011-do-task-in-commit/plans/002-update-tests.md +51 -0
- package/RAF/011-do-task-in-commit/plans/003-update-documentation.md +45 -0
- package/RAF/012-name-picker-buffet/decisions.md +40 -0
- package/RAF/012-name-picker-buffet/input.md +6 -0
- package/RAF/012-name-picker-buffet/outcomes/001-name-picker-for-raf-plan.md +49 -0
- package/RAF/012-name-picker-buffet/outcomes/002-interactive-project-picker-for-raf-do.md +49 -0
- package/RAF/012-name-picker-buffet/outcomes/003-raf-status-truncation.md +55 -0
- package/RAF/012-name-picker-buffet/outcomes/004-failure-reason-details.md +65 -0
- package/RAF/012-name-picker-buffet/outcomes/005-remove-raf-commits.md +57 -0
- package/RAF/012-name-picker-buffet/outcomes/006-update-execution-prompt-for-commits.md +47 -0
- package/RAF/012-name-picker-buffet/outcomes/007-fix-plan-mode-user-prompt.md +83 -0
- package/RAF/012-name-picker-buffet/outcomes/008-add-auto-flag-for-plan-mode.md +77 -0
- package/RAF/012-name-picker-buffet/plans/001-name-picker-for-raf-plan.md +47 -0
- package/RAF/012-name-picker-buffet/plans/002-interactive-project-picker-for-raf-do.md +43 -0
- package/RAF/012-name-picker-buffet/plans/003-raf-status-truncation.md +36 -0
- package/RAF/012-name-picker-buffet/plans/004-failure-reason-details.md +46 -0
- package/RAF/012-name-picker-buffet/plans/005-remove-raf-commits.md +42 -0
- package/RAF/012-name-picker-buffet/plans/006-update-execution-prompt-for-commits.md +47 -0
- package/RAF/012-name-picker-buffet/plans/007-fix-plan-mode-user-prompt.md +55 -0
- package/RAF/012-name-picker-buffet/plans/008-add-auto-flag-for-plan-mode.md +49 -0
- package/RAF/013-dependencies-watchdog/decisions.md +37 -0
- package/RAF/013-dependencies-watchdog/input.md +1 -0
- package/RAF/013-dependencies-watchdog/outcomes/001-define-dependency-syntax.md +56 -0
- package/RAF/013-dependencies-watchdog/outcomes/002-update-planning-prompts.md +60 -0
- package/RAF/013-dependencies-watchdog/outcomes/003-parse-dependencies-update-state.md +81 -0
- package/RAF/013-dependencies-watchdog/outcomes/004-implement-dependency-checking-in-do.md +116 -0
- package/RAF/013-dependencies-watchdog/outcomes/005-update-execution-prompts.md +75 -0
- package/RAF/013-dependencies-watchdog/outcomes/006-add-tests.md +100 -0
- package/RAF/013-dependencies-watchdog/outcomes/007-add-act-alias.md +46 -0
- package/RAF/013-dependencies-watchdog/outcomes/008-add-exit-message.md +52 -0
- package/RAF/013-dependencies-watchdog/plans/001-define-dependency-syntax.md +32 -0
- package/RAF/013-dependencies-watchdog/plans/002-update-planning-prompts.md +38 -0
- package/RAF/013-dependencies-watchdog/plans/003-parse-dependencies-update-state.md +46 -0
- package/RAF/013-dependencies-watchdog/plans/004-implement-dependency-checking-in-do.md +48 -0
- package/RAF/013-dependencies-watchdog/plans/005-update-execution-prompts.md +44 -0
- package/RAF/013-dependencies-watchdog/plans/006-add-tests.md +54 -0
- package/RAF/013-dependencies-watchdog/plans/007-add-act-alias.md +26 -0
- package/RAF/013-dependencies-watchdog/plans/008-add-exit-message.md +31 -0
- package/RAF/014-watchdog/decisions.md +16 -0
- package/RAF/014-watchdog/input.md +2 -0
- package/RAF/014-watchdog/outcomes/001-amend-flag-position.md +50 -0
- package/RAF/014-watchdog/outcomes/002-details-only-on-failure.md +58 -0
- package/RAF/014-watchdog/plans/001-amend-flag-position.md +34 -0
- package/RAF/014-watchdog/plans/002-details-only-on-failure.md +46 -0
- package/RAF/015-name-lottery/decisions.md +14 -0
- package/RAF/015-name-lottery/input.md +3 -0
- package/RAF/015-name-lottery/outcomes/001-auto-pick-project-name.md +31 -0
- package/RAF/015-name-lottery/outcomes/002-mention-plan-files-in-commit.md +23 -0
- package/RAF/015-name-lottery/outcomes/003-fix-input-md-in-amend-flow.md +44 -0
- package/RAF/015-name-lottery/plans/001-auto-pick-project-name.md +38 -0
- package/RAF/015-name-lottery/plans/002-mention-plan-files-in-commit.md +32 -0
- package/RAF/015-name-lottery/plans/003-fix-input-md-in-amend-flow.md +44 -0
- package/README.md +116 -0
- package/dist/commands/do.d.ts +12 -0
- package/dist/commands/do.d.ts.map +1 -0
- package/dist/commands/do.js +684 -0
- package/dist/commands/do.js.map +1 -0
- package/dist/commands/plan.d.ts +3 -0
- package/dist/commands/plan.d.ts.map +1 -0
- package/dist/commands/plan.js +345 -0
- package/dist/commands/plan.js.map +1 -0
- package/dist/commands/status.d.ts +3 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +117 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/core/claude-runner.d.ts +78 -0
- package/dist/core/claude-runner.d.ts.map +1 -0
- package/dist/core/claude-runner.js +297 -0
- package/dist/core/claude-runner.js.map +1 -0
- package/dist/core/editor.d.ts +10 -0
- package/dist/core/editor.d.ts.map +1 -0
- package/dist/core/editor.js +77 -0
- package/dist/core/editor.js.map +1 -0
- package/dist/core/failure-analyzer.d.ts +28 -0
- package/dist/core/failure-analyzer.d.ts.map +1 -0
- package/dist/core/failure-analyzer.js +305 -0
- package/dist/core/failure-analyzer.js.map +1 -0
- package/dist/core/git.d.ts +42 -0
- package/dist/core/git.d.ts.map +1 -0
- package/dist/core/git.js +148 -0
- package/dist/core/git.js.map +1 -0
- package/dist/core/project-manager.d.ts +72 -0
- package/dist/core/project-manager.d.ts.map +1 -0
- package/dist/core/project-manager.js +193 -0
- package/dist/core/project-manager.js.map +1 -0
- package/dist/core/retry-handler.d.ts +19 -0
- package/dist/core/retry-handler.d.ts.map +1 -0
- package/dist/core/retry-handler.js +51 -0
- package/dist/core/retry-handler.js.map +1 -0
- package/dist/core/shutdown-handler.d.ts +30 -0
- package/dist/core/shutdown-handler.d.ts.map +1 -0
- package/dist/core/shutdown-handler.js +79 -0
- package/dist/core/shutdown-handler.js.map +1 -0
- package/dist/core/state-derivation.d.ts +82 -0
- package/dist/core/state-derivation.d.ts.map +1 -0
- package/dist/core/state-derivation.js +271 -0
- package/dist/core/state-derivation.js.map +1 -0
- package/dist/core/state-manager.d.ts +54 -0
- package/dist/core/state-manager.d.ts.map +1 -0
- package/dist/core/state-manager.js +198 -0
- package/dist/core/state-manager.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/parsers/output-parser.d.ts +19 -0
- package/dist/parsers/output-parser.d.ts.map +1 -0
- package/dist/parsers/output-parser.js +137 -0
- package/dist/parsers/output-parser.js.map +1 -0
- package/dist/prompts/amend.d.ts +20 -0
- package/dist/prompts/amend.d.ts.map +1 -0
- package/dist/prompts/amend.js +166 -0
- package/dist/prompts/amend.js.map +1 -0
- package/dist/prompts/execution.d.ts +30 -0
- package/dist/prompts/execution.d.ts.map +1 -0
- package/dist/prompts/execution.js +179 -0
- package/dist/prompts/execution.js.map +1 -0
- package/dist/prompts/planning.d.ts +15 -0
- package/dist/prompts/planning.d.ts.map +1 -0
- package/dist/prompts/planning.js +163 -0
- package/dist/prompts/planning.js.map +1 -0
- package/dist/types/config.d.ts +26 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +7 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/state.d.ts +33 -0
- package/dist/types/state.d.ts.map +1 -0
- package/dist/types/state.js +28 -0
- package/dist/types/state.js.map +1 -0
- package/dist/ui/name-picker-subprocess.d.ts +11 -0
- package/dist/ui/name-picker-subprocess.d.ts.map +1 -0
- package/dist/ui/name-picker-subprocess.js +83 -0
- package/dist/ui/name-picker-subprocess.js.map +1 -0
- package/dist/ui/name-picker.d.ts +19 -0
- package/dist/ui/name-picker.d.ts.map +1 -0
- package/dist/ui/name-picker.js +173 -0
- package/dist/ui/name-picker.js.map +1 -0
- package/dist/ui/project-picker.d.ts +27 -0
- package/dist/ui/project-picker.d.ts.map +1 -0
- package/dist/ui/project-picker.js +58 -0
- package/dist/ui/project-picker.js.map +1 -0
- package/dist/utils/config.d.ts +24 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +63 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/logger.d.ts +32 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +60 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/name-generator.d.ts +20 -0
- package/dist/utils/name-generator.d.ts.map +1 -0
- package/dist/utils/name-generator.js +183 -0
- package/dist/utils/name-generator.js.map +1 -0
- package/dist/utils/paths.d.ts +132 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +412 -0
- package/dist/utils/paths.js.map +1 -0
- package/dist/utils/status-line.d.ts +14 -0
- package/dist/utils/status-line.d.ts.map +1 -0
- package/dist/utils/status-line.js +36 -0
- package/dist/utils/status-line.js.map +1 -0
- package/dist/utils/terminal-symbols.d.ts +50 -0
- package/dist/utils/terminal-symbols.d.ts.map +1 -0
- package/dist/utils/terminal-symbols.js +97 -0
- package/dist/utils/terminal-symbols.js.map +1 -0
- package/dist/utils/timer.d.ts +17 -0
- package/dist/utils/timer.d.ts.map +1 -0
- package/dist/utils/timer.js +56 -0
- package/dist/utils/timer.js.map +1 -0
- package/dist/utils/validation.d.ts +17 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js +106 -0
- package/dist/utils/validation.js.map +1 -0
- package/dist/utils/version.d.ts +2 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +12 -0
- package/dist/utils/version.js.map +1 -0
- package/jest.config.ts +30 -0
- package/package.json +55 -0
- package/src/commands/do.ts +829 -0
- package/src/commands/plan.ts +422 -0
- package/src/commands/status.ts +146 -0
- package/src/core/claude-runner.ts +374 -0
- package/src/core/editor.ts +85 -0
- package/src/core/failure-analyzer.ts +372 -0
- package/src/core/git.ts +166 -0
- package/src/core/project-manager.ts +243 -0
- package/src/core/retry-handler.ts +72 -0
- package/src/core/shutdown-handler.ts +93 -0
- package/src/core/state-derivation.ts +343 -0
- package/src/index.ts +20 -0
- package/src/parsers/output-parser.ts +164 -0
- package/src/prompts/amend.ts +194 -0
- package/src/prompts/execution.ts +223 -0
- package/src/prompts/planning.ts +175 -0
- package/src/types/config.ts +35 -0
- package/src/ui/name-picker-subprocess.ts +96 -0
- package/src/ui/name-picker.ts +198 -0
- package/src/ui/project-picker.ts +80 -0
- package/src/utils/config.ts +69 -0
- package/src/utils/logger.ts +81 -0
- package/src/utils/name-generator.ts +211 -0
- package/src/utils/paths.ts +497 -0
- package/src/utils/status-line.ts +45 -0
- package/src/utils/terminal-symbols.ts +124 -0
- package/src/utils/timer.ts +64 -0
- package/src/utils/validation.ts +132 -0
- package/src/utils/version.ts +12 -0
- package/tests/unit/claude-runner-interactive.test.ts +343 -0
- package/tests/unit/claude-runner.test.ts +629 -0
- package/tests/unit/command-output.test.ts +295 -0
- package/tests/unit/config.test.ts +72 -0
- package/tests/unit/dependency-integration.test.ts +559 -0
- package/tests/unit/do-blocked-tasks.test.ts +323 -0
- package/tests/unit/do-command.test.ts +198 -0
- package/tests/unit/do-multiproject.test.ts +270 -0
- package/tests/unit/do-rerun.test.ts +270 -0
- package/tests/unit/execution-prompt.test.ts +406 -0
- package/tests/unit/failure-analyzer.test.ts +276 -0
- package/tests/unit/failure-history.test.ts +143 -0
- package/tests/unit/git-stash.test.ts +138 -0
- package/tests/unit/git.test.ts +80 -0
- package/tests/unit/logger.test.ts +132 -0
- package/tests/unit/name-generator.test.ts +283 -0
- package/tests/unit/name-picker.test.ts +179 -0
- package/tests/unit/outcome-content.test.ts +166 -0
- package/tests/unit/output-parser.test.ts +178 -0
- package/tests/unit/paths.test.ts +741 -0
- package/tests/unit/plan-command-amend-flag.test.ts +115 -0
- package/tests/unit/plan-command-amend-input.test.ts +156 -0
- package/tests/unit/plan-command-auto-flag.test.ts +112 -0
- package/tests/unit/plan-command.test.ts +580 -0
- package/tests/unit/planning-prompt.test.ts +137 -0
- package/tests/unit/project-manager.test.ts +265 -0
- package/tests/unit/project-picker.test.ts +338 -0
- package/tests/unit/retry-handler.test.ts +89 -0
- package/tests/unit/state-derivation.test.ts +714 -0
- package/tests/unit/status-command.test.ts +271 -0
- package/tests/unit/status-line.test.ts +92 -0
- package/tests/unit/terminal-symbols.test.ts +214 -0
- package/tests/unit/timer.test.ts +102 -0
- package/tests/unit/validation.test.ts +118 -0
- package/tsconfig.json +26 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate the planning prompt with system instructions and user message separated.
|
|
3
|
+
* - systemPrompt: RAF planning conventions, file structure, interview process (via --append-system-prompt)
|
|
4
|
+
* - userMessage: Reference to input.md file (via positional argument, triggers Claude to start)
|
|
5
|
+
*/
|
|
6
|
+
export function getPlanningPrompt(params) {
|
|
7
|
+
const { projectPath } = params;
|
|
8
|
+
const systemPrompt = `You are a project planning assistant for RAF (Ralph's Automation Framework). Your task is to analyze the user's project description and create detailed task plans.
|
|
9
|
+
|
|
10
|
+
## Your Goals
|
|
11
|
+
|
|
12
|
+
1. **Analyze the input** and identify 3-8 distinct, actionable tasks
|
|
13
|
+
2. **Interview the user** about EACH task to gather specific requirements
|
|
14
|
+
3. **Create plan files** for each task with clear instructions
|
|
15
|
+
|
|
16
|
+
## Project Location
|
|
17
|
+
|
|
18
|
+
Project folder: ${projectPath}
|
|
19
|
+
|
|
20
|
+
## Instructions
|
|
21
|
+
|
|
22
|
+
### Step 1: Identify and Order Tasks
|
|
23
|
+
|
|
24
|
+
Based on the project description, identify 3-8 distinct tasks. Each task should:
|
|
25
|
+
- Be independently completable
|
|
26
|
+
- Have a clear outcome
|
|
27
|
+
- Take roughly 10-30 minutes of work for Claude
|
|
28
|
+
|
|
29
|
+
**CRITICAL: Order tasks by logical execution order.** Lower-numbered tasks should be completed before higher-numbered ones. Consider:
|
|
30
|
+
- Setup/foundation tasks come first (e.g., defining schemas, creating interfaces)
|
|
31
|
+
- Core implementation tasks come next
|
|
32
|
+
- Integration and extension tasks come later
|
|
33
|
+
- Testing and validation tasks typically come last
|
|
34
|
+
|
|
35
|
+
### Step 2: Interview the User
|
|
36
|
+
|
|
37
|
+
For EACH task you identify, you MUST use the AskUserQuestion tool to gather:
|
|
38
|
+
- Specific requirements and constraints
|
|
39
|
+
- Technology preferences
|
|
40
|
+
- Any existing code or patterns to follow
|
|
41
|
+
- Edge cases to handle
|
|
42
|
+
|
|
43
|
+
DO NOT skip the interview step. The quality of your plans depends on understanding the user's exact needs.
|
|
44
|
+
|
|
45
|
+
### Step 2.5: Record Decisions
|
|
46
|
+
|
|
47
|
+
After EACH interview question is answered, record the Q&A pair in the decisions file:
|
|
48
|
+
- ${projectPath}/decisions.md
|
|
49
|
+
|
|
50
|
+
Use this format:
|
|
51
|
+
\`\`\`markdown
|
|
52
|
+
# Project Decisions
|
|
53
|
+
|
|
54
|
+
## [Question asked]
|
|
55
|
+
[User's answer]
|
|
56
|
+
|
|
57
|
+
## [Question asked]
|
|
58
|
+
[User's answer]
|
|
59
|
+
\`\`\`
|
|
60
|
+
|
|
61
|
+
This file serves as documentation of design choices made during planning. Append each new Q&A pair as you conduct the interview.
|
|
62
|
+
|
|
63
|
+
### Step 3: Create Plan Files
|
|
64
|
+
|
|
65
|
+
After interviewing the user about all tasks, create plan files in the plans folder:
|
|
66
|
+
- ${projectPath}/plans/001-task-name.md
|
|
67
|
+
- ${projectPath}/plans/002-task-name.md
|
|
68
|
+
- etc.
|
|
69
|
+
|
|
70
|
+
Each plan file should follow this structure:
|
|
71
|
+
|
|
72
|
+
\`\`\`markdown
|
|
73
|
+
# Task: [Task Name]
|
|
74
|
+
|
|
75
|
+
## Objective
|
|
76
|
+
[Clear, one-sentence description of what this task accomplishes]
|
|
77
|
+
|
|
78
|
+
## Context
|
|
79
|
+
[Why this task is needed, how it fits into the larger project]
|
|
80
|
+
|
|
81
|
+
## Dependencies
|
|
82
|
+
[Optional section - omit if task has no dependencies]
|
|
83
|
+
[Comma-separated list of task IDs this task depends on, e.g., "001, 002"]
|
|
84
|
+
[If a dependency fails, this task will be automatically blocked]
|
|
85
|
+
|
|
86
|
+
## Requirements
|
|
87
|
+
[Specific requirements gathered from the user interview]
|
|
88
|
+
- Requirement 1
|
|
89
|
+
- Requirement 2
|
|
90
|
+
- ...
|
|
91
|
+
|
|
92
|
+
## Implementation Steps
|
|
93
|
+
1. [Step 1]
|
|
94
|
+
2. [Step 2]
|
|
95
|
+
3. [Step 3]
|
|
96
|
+
...
|
|
97
|
+
|
|
98
|
+
## Acceptance Criteria
|
|
99
|
+
- [ ] Criterion 1
|
|
100
|
+
- [ ] Criterion 2
|
|
101
|
+
- [ ] All tests pass
|
|
102
|
+
|
|
103
|
+
## Notes
|
|
104
|
+
[Any additional context, warnings, or considerations]
|
|
105
|
+
\`\`\`
|
|
106
|
+
|
|
107
|
+
### Step 4: Infer Task Dependencies
|
|
108
|
+
|
|
109
|
+
For each task, analyze which other tasks must complete successfully before it can begin. Add a \`## Dependencies\` section to plan files that have prerequisites.
|
|
110
|
+
|
|
111
|
+
**How to identify dependencies:**
|
|
112
|
+
- If task B uses output/artifacts from task A → B depends on A
|
|
113
|
+
- If task B modifies code created by task A → B depends on A
|
|
114
|
+
- If task B tests functionality from task A → B depends on A
|
|
115
|
+
- If task B extends or builds upon task A → B depends on A
|
|
116
|
+
|
|
117
|
+
**Dependency format examples:**
|
|
118
|
+
\`\`\`markdown
|
|
119
|
+
## Dependencies
|
|
120
|
+
001
|
|
121
|
+
\`\`\`
|
|
122
|
+
or for multiple dependencies:
|
|
123
|
+
\`\`\`markdown
|
|
124
|
+
## Dependencies
|
|
125
|
+
001, 002
|
|
126
|
+
\`\`\`
|
|
127
|
+
|
|
128
|
+
**Rules for dependencies:**
|
|
129
|
+
- Only reference lower-numbered tasks (tasks are ordered by execution order)
|
|
130
|
+
- Omit the Dependencies section entirely if a task has no prerequisites
|
|
131
|
+
- Keep dependency lists minimal - only direct dependencies, not transitive ones
|
|
132
|
+
- Never create circular dependencies (impossible if you only reference lower-numbered tasks)
|
|
133
|
+
|
|
134
|
+
### Step 5: Confirm Completion
|
|
135
|
+
|
|
136
|
+
After creating all plan files:
|
|
137
|
+
1. Provide a summary of the tasks you've created
|
|
138
|
+
2. Display this exit message to the user:
|
|
139
|
+
|
|
140
|
+
\`\`\`
|
|
141
|
+
Planning complete! To exit this session and run your tasks:
|
|
142
|
+
1. Press Ctrl-C twice to exit
|
|
143
|
+
2. Then run: raf do <project>
|
|
144
|
+
\`\`\`
|
|
145
|
+
|
|
146
|
+
## Important Rules
|
|
147
|
+
|
|
148
|
+
1. ALWAYS interview the user before creating plans
|
|
149
|
+
2. Create plans in numbered order (001, 002, 003, etc.) reflecting logical execution order
|
|
150
|
+
3. Use descriptive, kebab-case names for plan files
|
|
151
|
+
4. Each plan should be self-contained with all context needed
|
|
152
|
+
5. Infer dependencies automatically - analyze task relationships, don't ask the user about dependencies
|
|
153
|
+
6. Only add Dependencies section when a task genuinely requires another to complete first
|
|
154
|
+
7. Dependencies must only reference lower-numbered tasks to prevent circular dependencies
|
|
155
|
+
8. Be specific - vague plans lead to poor execution`;
|
|
156
|
+
const userMessage = `Here is my project description:
|
|
157
|
+
|
|
158
|
+
${params.inputContent}
|
|
159
|
+
|
|
160
|
+
Please analyze this and start the planning interview.`;
|
|
161
|
+
return { systemPrompt, userMessage };
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=planning.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planning.js","sourceRoot":"","sources":["../../src/prompts/planning.ts"],"names":[],"mappings":"AAUA;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAA4B;IAC5D,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC;IAE/B,MAAM,YAAY,GAAG;;;;;;;;;;kBAUL,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA8BzB,WAAW;;;;;;;;;;;;;;;;;;IAkBX,WAAW;IACX,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oDAwFqC,CAAC;IAEnD,MAAM,WAAW,GAAG;;EAEpB,MAAM,CAAC,YAAY;;sDAEiC,CAAC;IAErD,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface RafConfig {
|
|
2
|
+
defaultTimeout: number;
|
|
3
|
+
defaultMaxRetries: number;
|
|
4
|
+
autoCommit: boolean;
|
|
5
|
+
claudeCommand: string;
|
|
6
|
+
editor?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const DEFAULT_RAF_CONFIG: RafConfig;
|
|
9
|
+
export type ClaudeModelName = 'sonnet' | 'haiku' | 'opus';
|
|
10
|
+
export interface PlanCommandOptions {
|
|
11
|
+
projectName?: string;
|
|
12
|
+
model?: ClaudeModelName;
|
|
13
|
+
sonnet?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface DoCommandOptions {
|
|
16
|
+
timeout?: number;
|
|
17
|
+
verbose?: boolean;
|
|
18
|
+
debug?: boolean;
|
|
19
|
+
force?: boolean;
|
|
20
|
+
model?: ClaudeModelName;
|
|
21
|
+
sonnet?: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface StatusCommandOptions {
|
|
24
|
+
json?: boolean;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,SAAS;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,kBAAkB,EAAE,SAKhC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;AAE1D,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAQA,MAAM,CAAC,MAAM,kBAAkB,GAAc;IAC3C,cAAc,EAAE,EAAE;IAClB,iBAAiB,EAAE,CAAC;IACpB,UAAU,EAAE,IAAI;IAChB,aAAa,EAAE,QAAQ;CACxB,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export type ProjectStatus = 'planning' | 'ready' | 'executing' | 'completed' | 'failed';
|
|
2
|
+
export type TaskStatus = 'pending' | 'in_progress' | 'completed' | 'failed' | 'skipped';
|
|
3
|
+
export interface TaskState {
|
|
4
|
+
id: string;
|
|
5
|
+
planFile: string;
|
|
6
|
+
status: TaskStatus;
|
|
7
|
+
attempts: number;
|
|
8
|
+
startedAt?: string;
|
|
9
|
+
completedAt?: string;
|
|
10
|
+
failureReason?: string;
|
|
11
|
+
commitHash?: string;
|
|
12
|
+
filesBeforeTask?: string[];
|
|
13
|
+
}
|
|
14
|
+
export interface ProjectConfig {
|
|
15
|
+
timeout: number;
|
|
16
|
+
maxRetries: number;
|
|
17
|
+
autoCommit: boolean;
|
|
18
|
+
}
|
|
19
|
+
export interface ProjectState {
|
|
20
|
+
version: 1;
|
|
21
|
+
projectName: string;
|
|
22
|
+
createdAt: string;
|
|
23
|
+
updatedAt: string;
|
|
24
|
+
inputFile: string;
|
|
25
|
+
status: ProjectStatus;
|
|
26
|
+
tasks: TaskState[];
|
|
27
|
+
currentTaskIndex: number;
|
|
28
|
+
config: ProjectConfig;
|
|
29
|
+
}
|
|
30
|
+
export declare const DEFAULT_PROJECT_CONFIG: ProjectConfig;
|
|
31
|
+
export declare function createInitialState(projectName: string, inputFile: string): ProjectState;
|
|
32
|
+
export declare function createTask(id: string, planFile: string): TaskState;
|
|
33
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/types/state.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,OAAO,GAAG,WAAW,GAAG,WAAW,GAAG,QAAQ,CAAC;AAExF,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,aAAa,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC;AAExF,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,UAAU,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,CAAC,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,aAAa,CAAC;IACtB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,aAAa,CAAC;CACvB;AAED,eAAO,MAAM,sBAAsB,EAAE,aAIpC,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,CAavF;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,SAAS,CAOlE"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export const DEFAULT_PROJECT_CONFIG = {
|
|
2
|
+
timeout: 60,
|
|
3
|
+
maxRetries: 3,
|
|
4
|
+
autoCommit: true,
|
|
5
|
+
};
|
|
6
|
+
export function createInitialState(projectName, inputFile) {
|
|
7
|
+
const now = new Date().toISOString();
|
|
8
|
+
return {
|
|
9
|
+
version: 1,
|
|
10
|
+
projectName,
|
|
11
|
+
createdAt: now,
|
|
12
|
+
updatedAt: now,
|
|
13
|
+
inputFile,
|
|
14
|
+
status: 'planning',
|
|
15
|
+
tasks: [],
|
|
16
|
+
currentTaskIndex: 0,
|
|
17
|
+
config: { ...DEFAULT_PROJECT_CONFIG },
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export function createTask(id, planFile) {
|
|
21
|
+
return {
|
|
22
|
+
id,
|
|
23
|
+
planFile,
|
|
24
|
+
status: 'pending',
|
|
25
|
+
attempts: 0,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/types/state.ts"],"names":[],"mappings":"AAkCA,MAAM,CAAC,MAAM,sBAAsB,GAAkB;IACnD,OAAO,EAAE,EAAE;IACX,UAAU,EAAE,CAAC;IACb,UAAU,EAAE,IAAI;CACjB,CAAC;AAEF,MAAM,UAAU,kBAAkB,CAAC,WAAmB,EAAE,SAAiB;IACvE,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,OAAO;QACL,OAAO,EAAE,CAAC;QACV,WAAW;QACX,SAAS,EAAE,GAAG;QACd,SAAS,EAAE,GAAG;QACd,SAAS;QACT,MAAM,EAAE,UAAU;QAClB,KAAK,EAAE,EAAE;QACT,gBAAgB,EAAE,CAAC;QACnB,MAAM,EAAE,EAAE,GAAG,sBAAsB,EAAE;KACtC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,EAAU,EAAE,QAAgB;IACrD,OAAO;QACL,EAAE;QACF,QAAQ;QACR,MAAM,EAAE,SAAS;QACjB,QAAQ,EAAE,CAAC;KACZ,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Subprocess script for running the name picker.
|
|
4
|
+
* This isolates @inquirer/prompts from the main process to prevent
|
|
5
|
+
* stdin corruption that affects subsequent node-pty usage.
|
|
6
|
+
*
|
|
7
|
+
* Usage: node name-picker-subprocess.js <json-encoded-names-array> <output-file>
|
|
8
|
+
* Output: Selected name written to output file
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=name-picker-subprocess.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"name-picker-subprocess.d.ts","sourceRoot":"","sources":["../../src/ui/name-picker-subprocess.ts"],"names":[],"mappings":";AACA;;;;;;;GAOG"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Subprocess script for running the name picker.
|
|
4
|
+
* This isolates @inquirer/prompts from the main process to prevent
|
|
5
|
+
* stdin corruption that affects subsequent node-pty usage.
|
|
6
|
+
*
|
|
7
|
+
* Usage: node name-picker-subprocess.js <json-encoded-names-array> <output-file>
|
|
8
|
+
* Output: Selected name written to output file
|
|
9
|
+
*/
|
|
10
|
+
import { select, input } from '@inquirer/prompts';
|
|
11
|
+
import * as fs from 'node:fs';
|
|
12
|
+
const OTHER_OPTION_VALUE = '__OTHER__';
|
|
13
|
+
async function main() {
|
|
14
|
+
// Get names from command line argument
|
|
15
|
+
const namesJson = process.argv[2];
|
|
16
|
+
const outputFile = process.argv[3];
|
|
17
|
+
if (!namesJson || !outputFile) {
|
|
18
|
+
console.error('Usage: name-picker-subprocess <json-encoded-names-array> <output-file>');
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
let names;
|
|
22
|
+
try {
|
|
23
|
+
names = JSON.parse(namesJson);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
console.error('Invalid JSON input');
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
const result = await pickProjectName(names);
|
|
30
|
+
// Write result to output file
|
|
31
|
+
fs.writeFileSync(outputFile, result, 'utf-8');
|
|
32
|
+
}
|
|
33
|
+
async function pickProjectName(names) {
|
|
34
|
+
if (names.length === 0) {
|
|
35
|
+
return promptForCustomName();
|
|
36
|
+
}
|
|
37
|
+
const choices = [
|
|
38
|
+
...names.map((name) => ({
|
|
39
|
+
name: name,
|
|
40
|
+
value: name,
|
|
41
|
+
})),
|
|
42
|
+
{
|
|
43
|
+
name: 'Other (enter custom name)',
|
|
44
|
+
value: OTHER_OPTION_VALUE,
|
|
45
|
+
},
|
|
46
|
+
];
|
|
47
|
+
const selected = await select({
|
|
48
|
+
message: 'Select a project name:',
|
|
49
|
+
choices,
|
|
50
|
+
});
|
|
51
|
+
if (selected === OTHER_OPTION_VALUE) {
|
|
52
|
+
return promptForCustomName();
|
|
53
|
+
}
|
|
54
|
+
return selected;
|
|
55
|
+
}
|
|
56
|
+
async function promptForCustomName() {
|
|
57
|
+
const customName = await input({
|
|
58
|
+
message: 'Enter project name:',
|
|
59
|
+
validate: (value) => {
|
|
60
|
+
const trimmed = value.trim();
|
|
61
|
+
if (!trimmed) {
|
|
62
|
+
return 'Project name cannot be empty';
|
|
63
|
+
}
|
|
64
|
+
if (trimmed.length > 50) {
|
|
65
|
+
return 'Project name must be 50 characters or less';
|
|
66
|
+
}
|
|
67
|
+
if (!/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/.test(trimmed)) {
|
|
68
|
+
return 'Project name can only contain letters, numbers, hyphens, and underscores';
|
|
69
|
+
}
|
|
70
|
+
return true;
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
return customName.trim().toLowerCase();
|
|
74
|
+
}
|
|
75
|
+
main().catch((error) => {
|
|
76
|
+
// Check if user cancelled with Ctrl+C
|
|
77
|
+
if (error.message?.includes('User force closed') || error.name === 'ExitPromptError') {
|
|
78
|
+
process.exit(130); // Standard SIGINT exit code
|
|
79
|
+
}
|
|
80
|
+
console.error('Error:', error.message);
|
|
81
|
+
process.exit(1);
|
|
82
|
+
});
|
|
83
|
+
//# sourceMappingURL=name-picker-subprocess.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"name-picker-subprocess.js","sourceRoot":"","sources":["../../src/ui/name-picker-subprocess.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enable direct mode for testing (bypasses subprocess).
|
|
3
|
+
* This should only be called in test setup.
|
|
4
|
+
*/
|
|
5
|
+
export declare function enableDirectMode(): Promise<void>;
|
|
6
|
+
/**
|
|
7
|
+
* Disable direct mode (use subprocess).
|
|
8
|
+
*/
|
|
9
|
+
export declare function disableDirectMode(): void;
|
|
10
|
+
/**
|
|
11
|
+
* Display an interactive name picker with arrow-key navigation.
|
|
12
|
+
* Runs in a PTY subprocess to completely isolate @inquirer/prompts
|
|
13
|
+
* stdin manipulation from the main process.
|
|
14
|
+
*
|
|
15
|
+
* @param names - Array of generated name suggestions (3-5 names)
|
|
16
|
+
* @returns The selected or custom project name
|
|
17
|
+
*/
|
|
18
|
+
export declare function pickProjectName(names: string[]): Promise<string>;
|
|
19
|
+
//# sourceMappingURL=name-picker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"name-picker.d.ts","sourceRoot":"","sources":["../../src/ui/name-picker.ts"],"names":[],"mappings":"AAYA;;;GAGG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAItD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,IAAI,CAGxC;AAED;;;;;;;GAOG;AACH,wBAAsB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAgGtE"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { fileURLToPath } from 'node:url';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import * as fs from 'node:fs';
|
|
4
|
+
import * as os from 'node:os';
|
|
5
|
+
import * as pty from 'node-pty';
|
|
6
|
+
// For testing: allow direct import of @inquirer/prompts functions
|
|
7
|
+
let directSelect = null;
|
|
8
|
+
let directInput = null;
|
|
9
|
+
const OTHER_OPTION_VALUE = '__OTHER__';
|
|
10
|
+
/**
|
|
11
|
+
* Enable direct mode for testing (bypasses subprocess).
|
|
12
|
+
* This should only be called in test setup.
|
|
13
|
+
*/
|
|
14
|
+
export async function enableDirectMode() {
|
|
15
|
+
const inquirer = await import('@inquirer/prompts');
|
|
16
|
+
directSelect = inquirer.select;
|
|
17
|
+
directInput = inquirer.input;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Disable direct mode (use subprocess).
|
|
21
|
+
*/
|
|
22
|
+
export function disableDirectMode() {
|
|
23
|
+
directSelect = null;
|
|
24
|
+
directInput = null;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Display an interactive name picker with arrow-key navigation.
|
|
28
|
+
* Runs in a PTY subprocess to completely isolate @inquirer/prompts
|
|
29
|
+
* stdin manipulation from the main process.
|
|
30
|
+
*
|
|
31
|
+
* @param names - Array of generated name suggestions (3-5 names)
|
|
32
|
+
* @returns The selected or custom project name
|
|
33
|
+
*/
|
|
34
|
+
export async function pickProjectName(names) {
|
|
35
|
+
// Use direct mode if enabled (for testing)
|
|
36
|
+
if (directSelect) {
|
|
37
|
+
return pickProjectNameDirect(names);
|
|
38
|
+
}
|
|
39
|
+
// Get path to the subprocess script
|
|
40
|
+
const currentFile = fileURLToPath(import.meta.url);
|
|
41
|
+
const currentDir = path.dirname(currentFile);
|
|
42
|
+
// Use the compiled js file
|
|
43
|
+
const subprocessScript = path.join(currentDir, 'name-picker-subprocess.js');
|
|
44
|
+
// Create temp file for result
|
|
45
|
+
const tempFile = path.join(os.tmpdir(), `raf-name-picker-${process.pid}.txt`);
|
|
46
|
+
return new Promise((resolve, reject) => {
|
|
47
|
+
// Spawn subprocess in its own PTY (completely isolates stdin)
|
|
48
|
+
const ptyProcess = pty.spawn('node', [subprocessScript, JSON.stringify(names), tempFile], {
|
|
49
|
+
name: 'xterm-256color',
|
|
50
|
+
cols: process.stdout.columns ?? 80,
|
|
51
|
+
rows: process.stdout.rows ?? 24,
|
|
52
|
+
cwd: process.cwd(),
|
|
53
|
+
env: process.env,
|
|
54
|
+
});
|
|
55
|
+
// Set raw mode on our stdin to pass through keypresses
|
|
56
|
+
if (process.stdin.isTTY) {
|
|
57
|
+
process.stdin.setRawMode(true);
|
|
58
|
+
}
|
|
59
|
+
process.stdin.resume();
|
|
60
|
+
// Forward input from our stdin to the PTY
|
|
61
|
+
const onData = (data) => {
|
|
62
|
+
ptyProcess.write(data.toString());
|
|
63
|
+
};
|
|
64
|
+
process.stdin.on('data', onData);
|
|
65
|
+
// Forward output from PTY to our stdout
|
|
66
|
+
ptyProcess.onData((data) => {
|
|
67
|
+
process.stdout.write(data);
|
|
68
|
+
});
|
|
69
|
+
ptyProcess.onExit(({ exitCode }) => {
|
|
70
|
+
// Cleanup stdin
|
|
71
|
+
process.stdin.off('data', onData);
|
|
72
|
+
if (process.stdin.isTTY) {
|
|
73
|
+
process.stdin.setRawMode(false);
|
|
74
|
+
}
|
|
75
|
+
process.stdin.pause();
|
|
76
|
+
if (exitCode === 130) {
|
|
77
|
+
// SIGINT - user cancelled
|
|
78
|
+
process.exit(130);
|
|
79
|
+
}
|
|
80
|
+
if (exitCode !== 0) {
|
|
81
|
+
// Clean up temp file
|
|
82
|
+
try {
|
|
83
|
+
if (fs.existsSync(tempFile)) {
|
|
84
|
+
fs.unlinkSync(tempFile);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
// Ignore
|
|
89
|
+
}
|
|
90
|
+
reject(new Error(`Name picker subprocess failed with code ${exitCode}`));
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
// Read the result from temp file
|
|
94
|
+
try {
|
|
95
|
+
if (!fs.existsSync(tempFile)) {
|
|
96
|
+
reject(new Error('Name picker did not write a selection'));
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const selectedName = fs.readFileSync(tempFile, 'utf-8').trim();
|
|
100
|
+
// Clean up temp file
|
|
101
|
+
try {
|
|
102
|
+
fs.unlinkSync(tempFile);
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
// Ignore
|
|
106
|
+
}
|
|
107
|
+
if (!selectedName) {
|
|
108
|
+
reject(new Error('Name picker returned empty selection'));
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
resolve(selectedName);
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
reject(error);
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Direct implementation for testing (uses @inquirer/prompts in-process).
|
|
121
|
+
*/
|
|
122
|
+
async function pickProjectNameDirect(names) {
|
|
123
|
+
if (!directSelect || !directInput) {
|
|
124
|
+
throw new Error('Direct mode not enabled');
|
|
125
|
+
}
|
|
126
|
+
if (names.length === 0) {
|
|
127
|
+
return promptForCustomNameDirect();
|
|
128
|
+
}
|
|
129
|
+
const choices = [
|
|
130
|
+
...names.map((name) => ({
|
|
131
|
+
name: name,
|
|
132
|
+
value: name,
|
|
133
|
+
})),
|
|
134
|
+
{
|
|
135
|
+
name: 'Other (enter custom name)',
|
|
136
|
+
value: OTHER_OPTION_VALUE,
|
|
137
|
+
},
|
|
138
|
+
];
|
|
139
|
+
const selected = await directSelect({
|
|
140
|
+
message: 'Select a project name:',
|
|
141
|
+
choices,
|
|
142
|
+
});
|
|
143
|
+
if (selected === OTHER_OPTION_VALUE) {
|
|
144
|
+
return promptForCustomNameDirect();
|
|
145
|
+
}
|
|
146
|
+
return selected;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Prompt user to enter a custom project name (direct mode).
|
|
150
|
+
*/
|
|
151
|
+
async function promptForCustomNameDirect() {
|
|
152
|
+
if (!directInput) {
|
|
153
|
+
throw new Error('Direct mode not enabled');
|
|
154
|
+
}
|
|
155
|
+
const customName = await directInput({
|
|
156
|
+
message: 'Enter project name:',
|
|
157
|
+
validate: (value) => {
|
|
158
|
+
const trimmed = value.trim();
|
|
159
|
+
if (!trimmed) {
|
|
160
|
+
return 'Project name cannot be empty';
|
|
161
|
+
}
|
|
162
|
+
if (trimmed.length > 50) {
|
|
163
|
+
return 'Project name must be 50 characters or less';
|
|
164
|
+
}
|
|
165
|
+
if (!/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/.test(trimmed)) {
|
|
166
|
+
return 'Project name can only contain letters, numbers, hyphens, and underscores';
|
|
167
|
+
}
|
|
168
|
+
return true;
|
|
169
|
+
},
|
|
170
|
+
});
|
|
171
|
+
return customName.trim().toLowerCase();
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=name-picker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"name-picker.js","sourceRoot":"","sources":["../../src/ui/name-picker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Information about a pending project for display in the picker.
|
|
3
|
+
*/
|
|
4
|
+
export interface PendingProjectInfo {
|
|
5
|
+
folder: string;
|
|
6
|
+
number: number;
|
|
7
|
+
name: string;
|
|
8
|
+
path: string;
|
|
9
|
+
completedTasks: number;
|
|
10
|
+
totalTasks: number;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Get all projects that have pending tasks (not fully completed).
|
|
14
|
+
* Returns projects sorted by number (oldest first).
|
|
15
|
+
*/
|
|
16
|
+
export declare function getPendingProjects(rafDir: string): PendingProjectInfo[];
|
|
17
|
+
/**
|
|
18
|
+
* Format a project for display in the picker.
|
|
19
|
+
* Example: "001 fix-auth-bug (2/5 tasks)"
|
|
20
|
+
*/
|
|
21
|
+
export declare function formatProjectChoice(project: PendingProjectInfo): string;
|
|
22
|
+
/**
|
|
23
|
+
* Display an interactive project picker for pending projects.
|
|
24
|
+
* Returns the selected project folder name or null if no projects or cancelled.
|
|
25
|
+
*/
|
|
26
|
+
export declare function pickPendingProject(rafDir: string): Promise<string | null>;
|
|
27
|
+
//# sourceMappingURL=project-picker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-picker.d.ts","sourceRoot":"","sources":["../../src/ui/project-picker.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,kBAAkB,EAAE,CA0BvE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,CAGvE;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAkB/E"}
|