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,137 @@
|
|
|
1
|
+
import { getPlanningPrompt, PlanningPromptParams } from '../../src/prompts/planning.js';
|
|
2
|
+
|
|
3
|
+
describe('Planning Prompt', () => {
|
|
4
|
+
describe('getPlanningPrompt', () => {
|
|
5
|
+
it('should return systemPrompt and userMessage', () => {
|
|
6
|
+
const params: PlanningPromptParams = {
|
|
7
|
+
projectPath: '/test/project',
|
|
8
|
+
inputContent: 'Build a todo app with user authentication',
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const result = getPlanningPrompt(params);
|
|
12
|
+
|
|
13
|
+
expect(result).toHaveProperty('systemPrompt');
|
|
14
|
+
expect(result).toHaveProperty('userMessage');
|
|
15
|
+
expect(typeof result.systemPrompt).toBe('string');
|
|
16
|
+
expect(typeof result.userMessage).toBe('string');
|
|
17
|
+
expect(result.systemPrompt.length).toBeGreaterThan(0);
|
|
18
|
+
expect(result.userMessage.length).toBeGreaterThan(0);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('should include project path in system prompt', () => {
|
|
22
|
+
const params: PlanningPromptParams = {
|
|
23
|
+
projectPath: '/my/custom/project/path',
|
|
24
|
+
inputContent: 'Some description',
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const { systemPrompt } = getPlanningPrompt(params);
|
|
28
|
+
|
|
29
|
+
expect(systemPrompt).toContain('/my/custom/project/path');
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('should include inputContent in user message', () => {
|
|
33
|
+
const params: PlanningPromptParams = {
|
|
34
|
+
projectPath: '/test/project',
|
|
35
|
+
inputContent: 'Build a REST API with Express and MongoDB',
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const { userMessage } = getPlanningPrompt(params);
|
|
39
|
+
|
|
40
|
+
expect(userMessage).toContain('Build a REST API with Express and MongoDB');
|
|
41
|
+
expect(userMessage).toContain('planning interview');
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should include planning instructions in system prompt', () => {
|
|
45
|
+
const params: PlanningPromptParams = {
|
|
46
|
+
projectPath: '/test/project',
|
|
47
|
+
inputContent: 'Some project',
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const { systemPrompt } = getPlanningPrompt(params);
|
|
51
|
+
|
|
52
|
+
expect(systemPrompt).toContain('project planning assistant');
|
|
53
|
+
expect(systemPrompt).toContain('RAF');
|
|
54
|
+
expect(systemPrompt).toContain('Identify and Order Tasks');
|
|
55
|
+
expect(systemPrompt).toContain('Interview the User');
|
|
56
|
+
expect(systemPrompt).toContain('Create Plan Files');
|
|
57
|
+
expect(systemPrompt).toContain('AskUserQuestion');
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('should include decisions file path in system prompt', () => {
|
|
61
|
+
const params: PlanningPromptParams = {
|
|
62
|
+
projectPath: '/test/project',
|
|
63
|
+
inputContent: 'Some project',
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const { systemPrompt } = getPlanningPrompt(params);
|
|
67
|
+
|
|
68
|
+
expect(systemPrompt).toContain('/test/project/decisions.md');
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('should include plans directory path in system prompt', () => {
|
|
72
|
+
const params: PlanningPromptParams = {
|
|
73
|
+
projectPath: '/test/project',
|
|
74
|
+
inputContent: 'Some project',
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const { systemPrompt } = getPlanningPrompt(params);
|
|
78
|
+
|
|
79
|
+
expect(systemPrompt).toContain('/test/project/plans/001-task-name.md');
|
|
80
|
+
expect(systemPrompt).toContain('/test/project/plans/002-task-name.md');
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it('should include task guidelines in system prompt', () => {
|
|
84
|
+
const params: PlanningPromptParams = {
|
|
85
|
+
projectPath: '/test/project',
|
|
86
|
+
inputContent: 'Some project',
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const { systemPrompt } = getPlanningPrompt(params);
|
|
90
|
+
|
|
91
|
+
expect(systemPrompt).toContain('3-8 distinct');
|
|
92
|
+
expect(systemPrompt).toContain('independently completable');
|
|
93
|
+
expect(systemPrompt).toContain('10-30 minutes');
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('should include plan file structure template in system prompt', () => {
|
|
97
|
+
const params: PlanningPromptParams = {
|
|
98
|
+
projectPath: '/test/project',
|
|
99
|
+
inputContent: 'Some project',
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
const { systemPrompt } = getPlanningPrompt(params);
|
|
103
|
+
|
|
104
|
+
expect(systemPrompt).toContain('## Objective');
|
|
105
|
+
expect(systemPrompt).toContain('## Context');
|
|
106
|
+
expect(systemPrompt).toContain('## Requirements');
|
|
107
|
+
expect(systemPrompt).toContain('## Implementation Steps');
|
|
108
|
+
expect(systemPrompt).toContain('## Acceptance Criteria');
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('should include important rules in system prompt', () => {
|
|
112
|
+
const params: PlanningPromptParams = {
|
|
113
|
+
projectPath: '/test/project',
|
|
114
|
+
inputContent: 'Some project',
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const { systemPrompt } = getPlanningPrompt(params);
|
|
118
|
+
|
|
119
|
+
expect(systemPrompt).toContain('ALWAYS interview the user before creating plans');
|
|
120
|
+
expect(systemPrompt).toContain('numbered order (001, 002, 003');
|
|
121
|
+
expect(systemPrompt).toContain('kebab-case names');
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
it('should include project description in user message', () => {
|
|
125
|
+
const params: PlanningPromptParams = {
|
|
126
|
+
projectPath: '/test/project',
|
|
127
|
+
inputContent: 'Build a dashboard with charts and graphs',
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
const { userMessage } = getPlanningPrompt(params);
|
|
131
|
+
|
|
132
|
+
// User message should contain the actual project description
|
|
133
|
+
expect(userMessage).toContain('Build a dashboard with charts and graphs');
|
|
134
|
+
expect(userMessage).toContain('project description');
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
});
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import * as os from 'node:os';
|
|
4
|
+
import { ProjectManager } from '../../src/core/project-manager.js';
|
|
5
|
+
|
|
6
|
+
describe('ProjectManager', () => {
|
|
7
|
+
let tempDir: string;
|
|
8
|
+
let originalCwd: string;
|
|
9
|
+
|
|
10
|
+
beforeEach(() => {
|
|
11
|
+
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'raf-test-'));
|
|
12
|
+
originalCwd = process.cwd();
|
|
13
|
+
process.chdir(tempDir);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
afterEach(() => {
|
|
17
|
+
process.chdir(originalCwd);
|
|
18
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
describe('createProject', () => {
|
|
22
|
+
it('should create project with correct structure', () => {
|
|
23
|
+
const manager = new ProjectManager();
|
|
24
|
+
const projectPath = manager.createProject('test-project');
|
|
25
|
+
|
|
26
|
+
expect(fs.existsSync(projectPath)).toBe(true);
|
|
27
|
+
expect(fs.existsSync(path.join(projectPath, 'plans'))).toBe(true);
|
|
28
|
+
expect(fs.existsSync(path.join(projectPath, 'outcomes'))).toBe(true);
|
|
29
|
+
expect(fs.existsSync(path.join(projectPath, 'decisions.md'))).toBe(true);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('should auto-increment project numbers', () => {
|
|
33
|
+
const manager = new ProjectManager();
|
|
34
|
+
|
|
35
|
+
const path1 = manager.createProject('first');
|
|
36
|
+
const path2 = manager.createProject('second');
|
|
37
|
+
|
|
38
|
+
expect(path.basename(path1)).toBe('001-first');
|
|
39
|
+
expect(path.basename(path2)).toBe('002-second');
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('should sanitize project names', () => {
|
|
43
|
+
const manager = new ProjectManager();
|
|
44
|
+
const projectPath = manager.createProject('My Project Name!');
|
|
45
|
+
|
|
46
|
+
expect(path.basename(projectPath)).toBe('001-my-project-name');
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
describe('findProject', () => {
|
|
51
|
+
it('should find existing project by name', () => {
|
|
52
|
+
const manager = new ProjectManager();
|
|
53
|
+
manager.createProject('findme');
|
|
54
|
+
|
|
55
|
+
const found = manager.findProject('findme');
|
|
56
|
+
expect(found).not.toBeNull();
|
|
57
|
+
expect(found).toContain('001-findme');
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('should return null for non-existent project', () => {
|
|
61
|
+
const manager = new ProjectManager();
|
|
62
|
+
const found = manager.findProject('nonexistent');
|
|
63
|
+
expect(found).toBeNull();
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
describe('listProjects', () => {
|
|
68
|
+
it('should list all projects', () => {
|
|
69
|
+
const manager = new ProjectManager();
|
|
70
|
+
manager.createProject('alpha');
|
|
71
|
+
manager.createProject('beta');
|
|
72
|
+
|
|
73
|
+
const projects = manager.listProjects();
|
|
74
|
+
expect(projects).toHaveLength(2);
|
|
75
|
+
expect(projects[0]?.name).toBe('alpha');
|
|
76
|
+
expect(projects[1]?.name).toBe('beta');
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('should return empty array when no projects', () => {
|
|
80
|
+
const manager = new ProjectManager();
|
|
81
|
+
const projects = manager.listProjects();
|
|
82
|
+
expect(projects).toEqual([]);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('should include task counts from derived state', () => {
|
|
86
|
+
const manager = new ProjectManager();
|
|
87
|
+
const projectPath = manager.createProject('test');
|
|
88
|
+
|
|
89
|
+
// Create plan files
|
|
90
|
+
fs.writeFileSync(path.join(projectPath, 'plans', '001-task.md'), '# Task 1');
|
|
91
|
+
fs.writeFileSync(path.join(projectPath, 'plans', '002-task.md'), '# Task 2');
|
|
92
|
+
|
|
93
|
+
// Create outcome with COMPLETE promise marker
|
|
94
|
+
fs.writeFileSync(
|
|
95
|
+
path.join(projectPath, 'outcomes', '001-task.md'),
|
|
96
|
+
'# Task 001 - Completed\n\n<promise>COMPLETE</promise>'
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
const projects = manager.listProjects();
|
|
100
|
+
expect(projects[0]?.taskCount).toBe(2);
|
|
101
|
+
expect(projects[0]?.completedCount).toBe(1);
|
|
102
|
+
expect(projects[0]?.failedCount).toBe(0);
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
describe('saveInput and readInput', () => {
|
|
107
|
+
it('should save and read input', () => {
|
|
108
|
+
const manager = new ProjectManager();
|
|
109
|
+
const projectPath = manager.createProject('test');
|
|
110
|
+
|
|
111
|
+
const content = '# My Project\n\nDescription here.';
|
|
112
|
+
manager.saveInput(projectPath, content);
|
|
113
|
+
|
|
114
|
+
const read = manager.readInput(projectPath);
|
|
115
|
+
expect(read).toBe(content);
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
describe('saveOutcome and readOutcomes', () => {
|
|
120
|
+
it('should save and read outcomes', () => {
|
|
121
|
+
const manager = new ProjectManager();
|
|
122
|
+
const projectPath = manager.createProject('test');
|
|
123
|
+
|
|
124
|
+
// Create a plan file to match naming
|
|
125
|
+
fs.writeFileSync(
|
|
126
|
+
path.join(projectPath, 'plans', '01-task.md'),
|
|
127
|
+
'# Task'
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
manager.saveOutcome(projectPath, '01', 'Outcome content');
|
|
131
|
+
|
|
132
|
+
const outcomes = manager.readOutcomes(projectPath);
|
|
133
|
+
expect(outcomes).toHaveLength(1);
|
|
134
|
+
expect(outcomes[0]?.taskId).toBe('01');
|
|
135
|
+
expect(outcomes[0]?.content).toBe('Outcome content');
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
describe('saveLog', () => {
|
|
140
|
+
it('should create logs directory in project and save log', () => {
|
|
141
|
+
const manager = new ProjectManager();
|
|
142
|
+
const projectPath = manager.createProject('test');
|
|
143
|
+
|
|
144
|
+
manager.saveLog(projectPath, '01', 'Log content');
|
|
145
|
+
|
|
146
|
+
const logPath = path.join(projectPath, 'logs', '01-task.log');
|
|
147
|
+
expect(fs.existsSync(logPath)).toBe(true);
|
|
148
|
+
expect(fs.readFileSync(logPath, 'utf-8')).toBe('Log content');
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
describe('isProjectFolderEmpty', () => {
|
|
153
|
+
it('should return true for non-existent folder', () => {
|
|
154
|
+
const manager = new ProjectManager();
|
|
155
|
+
const nonExistentPath = path.join(tempDir, 'nonexistent');
|
|
156
|
+
|
|
157
|
+
expect(manager.isProjectFolderEmpty(nonExistentPath)).toBe(true);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it('should return true when plans directory does not exist', () => {
|
|
161
|
+
const manager = new ProjectManager();
|
|
162
|
+
const projectPath = manager.createProject('test');
|
|
163
|
+
|
|
164
|
+
// Remove plans directory
|
|
165
|
+
const plansDir = path.join(projectPath, 'plans');
|
|
166
|
+
fs.rmSync(plansDir, { recursive: true, force: true });
|
|
167
|
+
|
|
168
|
+
expect(manager.isProjectFolderEmpty(projectPath)).toBe(true);
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it('should return true when plans directory is empty', () => {
|
|
172
|
+
const manager = new ProjectManager();
|
|
173
|
+
const projectPath = manager.createProject('test');
|
|
174
|
+
|
|
175
|
+
// Plans directory exists but has no files
|
|
176
|
+
expect(manager.isProjectFolderEmpty(projectPath)).toBe(true);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
it('should return false when at least one plan file exists', () => {
|
|
180
|
+
const manager = new ProjectManager();
|
|
181
|
+
const projectPath = manager.createProject('test');
|
|
182
|
+
|
|
183
|
+
// Create a plan file
|
|
184
|
+
const plansDir = path.join(projectPath, 'plans');
|
|
185
|
+
fs.writeFileSync(path.join(plansDir, '01-task.md'), '# Task 1');
|
|
186
|
+
|
|
187
|
+
expect(manager.isProjectFolderEmpty(projectPath)).toBe(false);
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it('should ignore non-.md files in plans directory', () => {
|
|
191
|
+
const manager = new ProjectManager();
|
|
192
|
+
const projectPath = manager.createProject('test');
|
|
193
|
+
|
|
194
|
+
// Create a non-.md file
|
|
195
|
+
const plansDir = path.join(projectPath, 'plans');
|
|
196
|
+
fs.writeFileSync(path.join(plansDir, 'notes.txt'), 'Notes');
|
|
197
|
+
|
|
198
|
+
expect(manager.isProjectFolderEmpty(projectPath)).toBe(true);
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
describe('cleanupEmptyProject', () => {
|
|
203
|
+
it('should delete folder when no plans exist', () => {
|
|
204
|
+
const manager = new ProjectManager();
|
|
205
|
+
const projectPath = manager.createProject('test');
|
|
206
|
+
|
|
207
|
+
// Verify folder exists
|
|
208
|
+
expect(fs.existsSync(projectPath)).toBe(true);
|
|
209
|
+
|
|
210
|
+
// Cleanup should remove the folder
|
|
211
|
+
manager.cleanupEmptyProject(projectPath);
|
|
212
|
+
|
|
213
|
+
expect(fs.existsSync(projectPath)).toBe(false);
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
it('should not delete folder when plans exist', () => {
|
|
217
|
+
const manager = new ProjectManager();
|
|
218
|
+
const projectPath = manager.createProject('test');
|
|
219
|
+
|
|
220
|
+
// Create a plan file
|
|
221
|
+
const plansDir = path.join(projectPath, 'plans');
|
|
222
|
+
fs.writeFileSync(path.join(plansDir, '01-task.md'), '# Task 1');
|
|
223
|
+
|
|
224
|
+
// Cleanup should NOT remove the folder
|
|
225
|
+
manager.cleanupEmptyProject(projectPath);
|
|
226
|
+
|
|
227
|
+
expect(fs.existsSync(projectPath)).toBe(true);
|
|
228
|
+
expect(fs.existsSync(path.join(plansDir, '01-task.md'))).toBe(true);
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
it('should handle non-existent folder gracefully', () => {
|
|
232
|
+
const manager = new ProjectManager();
|
|
233
|
+
const nonExistentPath = path.join(tempDir, 'nonexistent');
|
|
234
|
+
|
|
235
|
+
// Should not throw
|
|
236
|
+
expect(() => {
|
|
237
|
+
manager.cleanupEmptyProject(nonExistentPath);
|
|
238
|
+
}).not.toThrow();
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
it('should be idempotent - safe to call multiple times', () => {
|
|
242
|
+
const manager = new ProjectManager();
|
|
243
|
+
const projectPath = manager.createProject('test');
|
|
244
|
+
|
|
245
|
+
// Call cleanup multiple times
|
|
246
|
+
manager.cleanupEmptyProject(projectPath);
|
|
247
|
+
manager.cleanupEmptyProject(projectPath);
|
|
248
|
+
manager.cleanupEmptyProject(projectPath);
|
|
249
|
+
|
|
250
|
+
expect(fs.existsSync(projectPath)).toBe(false);
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
it('should delete folder even if only subdirectories exist (no plans)', () => {
|
|
254
|
+
const manager = new ProjectManager();
|
|
255
|
+
const projectPath = manager.createProject('test');
|
|
256
|
+
|
|
257
|
+
// Create additional subdirectories but no plan files
|
|
258
|
+
fs.mkdirSync(path.join(projectPath, 'extra'), { recursive: true });
|
|
259
|
+
|
|
260
|
+
manager.cleanupEmptyProject(projectPath);
|
|
261
|
+
|
|
262
|
+
expect(fs.existsSync(projectPath)).toBe(false);
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
|
+
});
|