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,193 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import { getRafDir, ensureRafDir, getNextProjectNumber, formatProjectNumber, getProjectDir, getPlansDir, getOutcomesDir, getDecisionsPath, getInputPath, listProjects, } from '../utils/paths.js';
|
|
4
|
+
import { sanitizeProjectName } from '../utils/validation.js';
|
|
5
|
+
import { logger } from '../utils/logger.js';
|
|
6
|
+
import { deriveProjectState, getDerivedStats } from './state-derivation.js';
|
|
7
|
+
export class ProjectManager {
|
|
8
|
+
rafDir;
|
|
9
|
+
constructor() {
|
|
10
|
+
this.rafDir = getRafDir();
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Create a new project folder with initial structure.
|
|
14
|
+
* Returns the project path.
|
|
15
|
+
*/
|
|
16
|
+
createProject(projectName) {
|
|
17
|
+
ensureRafDir();
|
|
18
|
+
const sanitizedName = sanitizeProjectName(projectName);
|
|
19
|
+
const projectNumber = getNextProjectNumber(this.rafDir);
|
|
20
|
+
const folderName = `${formatProjectNumber(projectNumber)}-${sanitizedName}`;
|
|
21
|
+
const projectPath = path.join(this.rafDir, folderName);
|
|
22
|
+
// Create directory structure
|
|
23
|
+
fs.mkdirSync(projectPath, { recursive: true });
|
|
24
|
+
fs.mkdirSync(getPlansDir(projectPath), { recursive: true });
|
|
25
|
+
fs.mkdirSync(getOutcomesDir(projectPath), { recursive: true });
|
|
26
|
+
// Create empty decisions.md file
|
|
27
|
+
fs.writeFileSync(getDecisionsPath(projectPath), '# Project Decisions\n');
|
|
28
|
+
logger.debug(`Created project at ${projectPath}`);
|
|
29
|
+
return projectPath;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Find an existing project by name.
|
|
33
|
+
*/
|
|
34
|
+
findProject(projectName) {
|
|
35
|
+
return getProjectDir(this.rafDir, projectName);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* List all projects with derived state information.
|
|
39
|
+
*/
|
|
40
|
+
listProjects() {
|
|
41
|
+
const projects = listProjects(this.rafDir);
|
|
42
|
+
return projects.map((p) => {
|
|
43
|
+
const info = {
|
|
44
|
+
number: p.number,
|
|
45
|
+
name: p.name,
|
|
46
|
+
path: p.path,
|
|
47
|
+
};
|
|
48
|
+
// Derive state from folder structure
|
|
49
|
+
try {
|
|
50
|
+
const state = deriveProjectState(p.path);
|
|
51
|
+
const stats = getDerivedStats(state);
|
|
52
|
+
info.taskCount = stats.total;
|
|
53
|
+
info.completedCount = stats.completed;
|
|
54
|
+
info.failedCount = stats.failed;
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// Failed to derive state
|
|
58
|
+
}
|
|
59
|
+
return info;
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Save user input to input.md.
|
|
64
|
+
*/
|
|
65
|
+
saveInput(projectPath, content) {
|
|
66
|
+
const inputPath = getInputPath(projectPath);
|
|
67
|
+
fs.writeFileSync(inputPath, content);
|
|
68
|
+
logger.debug(`Saved input to ${inputPath}`);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Read user input from input.md.
|
|
72
|
+
*/
|
|
73
|
+
readInput(projectPath) {
|
|
74
|
+
const inputPath = getInputPath(projectPath);
|
|
75
|
+
if (!fs.existsSync(inputPath)) {
|
|
76
|
+
throw new Error(`Input file not found: ${inputPath}`);
|
|
77
|
+
}
|
|
78
|
+
return fs.readFileSync(inputPath, 'utf-8');
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Save an outcome file for a completed task.
|
|
82
|
+
*/
|
|
83
|
+
saveOutcome(projectPath, taskId, content) {
|
|
84
|
+
const outcomesDir = getOutcomesDir(projectPath);
|
|
85
|
+
if (!fs.existsSync(outcomesDir)) {
|
|
86
|
+
fs.mkdirSync(outcomesDir, { recursive: true });
|
|
87
|
+
}
|
|
88
|
+
// Find the plan file name to match naming convention
|
|
89
|
+
const plansDir = getPlansDir(projectPath);
|
|
90
|
+
const planFiles = fs.readdirSync(plansDir);
|
|
91
|
+
const planFile = planFiles.find((f) => f.startsWith(`${taskId}-`));
|
|
92
|
+
const outcomeName = planFile ?? `${taskId}-task.md`;
|
|
93
|
+
const outcomePath = path.join(outcomesDir, outcomeName);
|
|
94
|
+
fs.writeFileSync(outcomePath, content);
|
|
95
|
+
logger.debug(`Saved outcome to ${outcomePath}`);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Read all outcomes for context.
|
|
99
|
+
*/
|
|
100
|
+
readOutcomes(projectPath) {
|
|
101
|
+
const outcomesDir = getOutcomesDir(projectPath);
|
|
102
|
+
if (!fs.existsSync(outcomesDir)) {
|
|
103
|
+
return [];
|
|
104
|
+
}
|
|
105
|
+
const outcomes = [];
|
|
106
|
+
const files = fs.readdirSync(outcomesDir).filter((f) => f.endsWith('.md')).sort();
|
|
107
|
+
for (const file of files) {
|
|
108
|
+
const match = file.match(/^(\d{2,3})-/);
|
|
109
|
+
if (match && match[1]) {
|
|
110
|
+
const content = fs.readFileSync(path.join(outcomesDir, file), 'utf-8');
|
|
111
|
+
outcomes.push({ taskId: match[1], content });
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return outcomes;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Save a log file to the project's logs directory.
|
|
118
|
+
*/
|
|
119
|
+
saveLog(projectPath, taskId, content) {
|
|
120
|
+
const logsDir = path.join(projectPath, 'logs');
|
|
121
|
+
if (!fs.existsSync(logsDir)) {
|
|
122
|
+
fs.mkdirSync(logsDir, { recursive: true });
|
|
123
|
+
}
|
|
124
|
+
const logPath = path.join(logsDir, `${taskId}-task.log`);
|
|
125
|
+
fs.writeFileSync(logPath, content);
|
|
126
|
+
logger.debug(`Saved log to ${logPath}`);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Read a plan file.
|
|
130
|
+
*/
|
|
131
|
+
readPlan(projectPath, planFile) {
|
|
132
|
+
const planPath = path.join(projectPath, planFile);
|
|
133
|
+
if (!fs.existsSync(planPath)) {
|
|
134
|
+
throw new Error(`Plan file not found: ${planPath}`);
|
|
135
|
+
}
|
|
136
|
+
return fs.readFileSync(planPath, 'utf-8');
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Get absolute path to a plan file.
|
|
140
|
+
*/
|
|
141
|
+
getPlanPath(projectPath, planFile) {
|
|
142
|
+
return path.join(projectPath, planFile);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Ensure logs directory exists in project folder.
|
|
146
|
+
*/
|
|
147
|
+
ensureLogsDir(projectPath) {
|
|
148
|
+
const logsDir = path.join(projectPath, 'logs');
|
|
149
|
+
if (!fs.existsSync(logsDir)) {
|
|
150
|
+
fs.mkdirSync(logsDir, { recursive: true });
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Check if a project folder is empty (contains no plan files).
|
|
155
|
+
* Returns true if the folder has no plan files, false otherwise.
|
|
156
|
+
*/
|
|
157
|
+
isProjectFolderEmpty(projectPath) {
|
|
158
|
+
if (!fs.existsSync(projectPath)) {
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
const plansDir = getPlansDir(projectPath);
|
|
162
|
+
// If plans directory doesn't exist, consider it empty
|
|
163
|
+
if (!fs.existsSync(plansDir)) {
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
// Check if there are any .md files in the plans directory
|
|
167
|
+
const planFiles = fs.readdirSync(plansDir).filter((f) => f.endsWith('.md'));
|
|
168
|
+
return planFiles.length === 0;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Clean up an empty project folder.
|
|
172
|
+
* Only removes the folder if it contains no plan files.
|
|
173
|
+
* This is idempotent - safe to call multiple times.
|
|
174
|
+
*/
|
|
175
|
+
cleanupEmptyProject(projectPath) {
|
|
176
|
+
if (!fs.existsSync(projectPath)) {
|
|
177
|
+
logger.debug(`Project folder does not exist: ${projectPath}`);
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
if (!this.isProjectFolderEmpty(projectPath)) {
|
|
181
|
+
logger.debug(`Project folder is not empty (has plans), skipping cleanup: ${projectPath}`);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
try {
|
|
185
|
+
fs.rmSync(projectPath, { recursive: true, force: true });
|
|
186
|
+
logger.debug(`Cleaned up empty project folder: ${projectPath}`);
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
logger.warn(`Failed to clean up empty project folder: ${error}`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=project-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-manager.js","sourceRoot":"","sources":["../../src/core/project-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface RetryOptions {
|
|
2
|
+
maxRetries: number;
|
|
3
|
+
onRetry?: (attempt: number, error: Error) => void;
|
|
4
|
+
}
|
|
5
|
+
export interface RetryResult<T> {
|
|
6
|
+
success: boolean;
|
|
7
|
+
result?: T;
|
|
8
|
+
attempts: number;
|
|
9
|
+
lastError?: Error;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Execute a function with retry logic.
|
|
13
|
+
*/
|
|
14
|
+
export declare function withRetry<T>(fn: () => Promise<T>, options: RetryOptions): Promise<RetryResult<T>>;
|
|
15
|
+
/**
|
|
16
|
+
* Determine if an error is retryable.
|
|
17
|
+
*/
|
|
18
|
+
export declare function isRetryableError(error: Error): boolean;
|
|
19
|
+
//# sourceMappingURL=retry-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry-handler.d.ts","sourceRoot":"","sources":["../../src/core/retry-handler.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACnD;AAED,MAAM,WAAW,WAAW,CAAC,CAAC;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,KAAK,CAAC;CACnB;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAC/B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CA2BzB;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAmBtD"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { logger } from '../utils/logger.js';
|
|
2
|
+
/**
|
|
3
|
+
* Execute a function with retry logic.
|
|
4
|
+
*/
|
|
5
|
+
export async function withRetry(fn, options) {
|
|
6
|
+
const { maxRetries, onRetry } = options;
|
|
7
|
+
let lastError;
|
|
8
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
9
|
+
try {
|
|
10
|
+
const result = await fn();
|
|
11
|
+
return {
|
|
12
|
+
success: true,
|
|
13
|
+
result,
|
|
14
|
+
attempts: attempt,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
19
|
+
if (attempt < maxRetries) {
|
|
20
|
+
logger.debug(`Attempt ${attempt} failed, retrying...`);
|
|
21
|
+
onRetry?.(attempt, lastError);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
success: false,
|
|
27
|
+
attempts: maxRetries,
|
|
28
|
+
lastError,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Determine if an error is retryable.
|
|
33
|
+
*/
|
|
34
|
+
export function isRetryableError(error) {
|
|
35
|
+
const message = error.message.toLowerCase();
|
|
36
|
+
// Non-retryable errors
|
|
37
|
+
const nonRetryable = [
|
|
38
|
+
'context overflow',
|
|
39
|
+
'token limit',
|
|
40
|
+
'rate limit exceeded',
|
|
41
|
+
'authentication failed',
|
|
42
|
+
'permission denied',
|
|
43
|
+
];
|
|
44
|
+
for (const pattern of nonRetryable) {
|
|
45
|
+
if (message.includes(pattern)) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=retry-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry-handler.js","sourceRoot":"","sources":["../../src/core/retry-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAc5C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,EAAoB,EACpB,OAAqB;IAErB,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;IACxC,IAAI,SAA4B,CAAC;IAEjC,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,UAAU,EAAE,OAAO,EAAE,EAAE,CAAC;QACvD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,EAAE,EAAE,CAAC;YAC1B,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,MAAM;gBACN,QAAQ,EAAE,OAAO;aAClB,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,SAAS,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAEtE,IAAI,OAAO,GAAG,UAAU,EAAE,CAAC;gBACzB,MAAM,CAAC,KAAK,CAAC,WAAW,OAAO,sBAAsB,CAAC,CAAC;gBACvD,OAAO,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;YAChC,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO;QACL,OAAO,EAAE,KAAK;QACd,QAAQ,EAAE,UAAU;QACpB,SAAS;KACV,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAY;IAC3C,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;IAE5C,uBAAuB;IACvB,MAAM,YAAY,GAAG;QACnB,kBAAkB;QAClB,aAAa;QACb,qBAAqB;QACrB,uBAAuB;QACvB,mBAAmB;KACpB,CAAC;IAEF,KAAK,MAAM,OAAO,IAAI,YAAY,EAAE,CAAC;QACnC,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC9B,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ClaudeRunner } from './claude-runner.js';
|
|
2
|
+
type CleanupCallback = () => void | Promise<void>;
|
|
3
|
+
declare class ShutdownHandler {
|
|
4
|
+
private claudeRunner;
|
|
5
|
+
private cleanupCallbacks;
|
|
6
|
+
private isShuttingDown;
|
|
7
|
+
/**
|
|
8
|
+
* Register a Claude runner to be killed on shutdown.
|
|
9
|
+
*/
|
|
10
|
+
registerClaudeRunner(runner: ClaudeRunner): void;
|
|
11
|
+
/**
|
|
12
|
+
* Register a custom cleanup callback.
|
|
13
|
+
*/
|
|
14
|
+
onShutdown(callback: CleanupCallback): void;
|
|
15
|
+
/**
|
|
16
|
+
* Initialize signal handlers.
|
|
17
|
+
*/
|
|
18
|
+
init(): void;
|
|
19
|
+
/**
|
|
20
|
+
* Handle graceful shutdown.
|
|
21
|
+
*/
|
|
22
|
+
private handleShutdown;
|
|
23
|
+
/**
|
|
24
|
+
* Clear registrations (useful for testing).
|
|
25
|
+
*/
|
|
26
|
+
clear(): void;
|
|
27
|
+
}
|
|
28
|
+
export declare const shutdownHandler: ShutdownHandler;
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=shutdown-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shutdown-handler.d.ts","sourceRoot":"","sources":["../../src/core/shutdown-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,KAAK,eAAe,GAAG,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAElD,cAAM,eAAe;IACnB,OAAO,CAAC,YAAY,CAA6B;IACjD,OAAO,CAAC,gBAAgB,CAAyB;IACjD,OAAO,CAAC,cAAc,CAAS;IAE/B;;OAEG;IACH,oBAAoB,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI;IAIhD;;OAEG;IACH,UAAU,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI;IAI3C;;OAEG;IACH,IAAI,IAAI,IAAI;IAgBZ;;OAEG;YACW,cAAc;IAqC5B;;OAEG;IACH,KAAK,IAAI,IAAI;CAId;AAED,eAAO,MAAM,eAAe,iBAAwB,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { logger } from '../utils/logger.js';
|
|
2
|
+
class ShutdownHandler {
|
|
3
|
+
claudeRunner = null;
|
|
4
|
+
cleanupCallbacks = [];
|
|
5
|
+
isShuttingDown = false;
|
|
6
|
+
/**
|
|
7
|
+
* Register a Claude runner to be killed on shutdown.
|
|
8
|
+
*/
|
|
9
|
+
registerClaudeRunner(runner) {
|
|
10
|
+
this.claudeRunner = runner;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Register a custom cleanup callback.
|
|
14
|
+
*/
|
|
15
|
+
onShutdown(callback) {
|
|
16
|
+
this.cleanupCallbacks.push(callback);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Initialize signal handlers.
|
|
20
|
+
*/
|
|
21
|
+
init() {
|
|
22
|
+
process.on('SIGINT', () => this.handleShutdown('SIGINT'));
|
|
23
|
+
process.on('SIGTERM', () => this.handleShutdown('SIGTERM'));
|
|
24
|
+
// Handle uncaught errors
|
|
25
|
+
process.on('uncaughtException', (error) => {
|
|
26
|
+
logger.error(`Uncaught exception: ${error.message}`);
|
|
27
|
+
this.handleShutdown('uncaughtException');
|
|
28
|
+
});
|
|
29
|
+
process.on('unhandledRejection', (reason) => {
|
|
30
|
+
logger.error(`Unhandled rejection: ${reason}`);
|
|
31
|
+
// Don't exit on unhandled rejection, just log
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Handle graceful shutdown.
|
|
36
|
+
*/
|
|
37
|
+
async handleShutdown(signal) {
|
|
38
|
+
if (this.isShuttingDown) {
|
|
39
|
+
// Force exit on second signal
|
|
40
|
+
logger.info('\nForce exiting...');
|
|
41
|
+
process.exit(130);
|
|
42
|
+
}
|
|
43
|
+
this.isShuttingDown = true;
|
|
44
|
+
logger.info(`\nReceived ${signal}, shutting down gracefully...`);
|
|
45
|
+
// Kill Claude process if running
|
|
46
|
+
if (this.claudeRunner?.isRunning()) {
|
|
47
|
+
logger.debug('Killing Claude process...');
|
|
48
|
+
this.claudeRunner.kill();
|
|
49
|
+
}
|
|
50
|
+
// Run cleanup callbacks
|
|
51
|
+
for (const callback of this.cleanupCallbacks) {
|
|
52
|
+
try {
|
|
53
|
+
await callback();
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
logger.error(`Cleanup callback failed: ${error}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
// Reset terminal if needed
|
|
60
|
+
if (process.stdin.isTTY) {
|
|
61
|
+
try {
|
|
62
|
+
process.stdin.setRawMode(false);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// Ignore
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
process.exit(130);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Clear registrations (useful for testing).
|
|
72
|
+
*/
|
|
73
|
+
clear() {
|
|
74
|
+
this.claudeRunner = null;
|
|
75
|
+
this.cleanupCallbacks = [];
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
export const shutdownHandler = new ShutdownHandler();
|
|
79
|
+
//# sourceMappingURL=shutdown-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shutdown-handler.js","sourceRoot":"","sources":["../../src/core/shutdown-handler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAI5C,MAAM,eAAe;IACX,YAAY,GAAwB,IAAI,CAAC;IACzC,gBAAgB,GAAsB,EAAE,CAAC;IACzC,cAAc,GAAG,KAAK,CAAC;IAE/B;;OAEG;IACH,oBAAoB,CAAC,MAAoB;QACvC,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,UAAU,CAAC,QAAyB;QAClC,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,IAAI;QACF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC1D,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC;QAE5D,yBAAyB;QACzB,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,KAAK,EAAE,EAAE;YACxC,MAAM,CAAC,KAAK,CAAC,uBAAuB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;YACrD,IAAI,CAAC,cAAc,CAAC,mBAAmB,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAM,EAAE,EAAE;YAC1C,MAAM,CAAC,KAAK,CAAC,wBAAwB,MAAM,EAAE,CAAC,CAAC;YAC/C,8CAA8C;QAChD,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,cAAc,CAAC,MAAc;QACzC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,8BAA8B;YAC9B,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;YAClC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC;QAED,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC3B,MAAM,CAAC,IAAI,CAAC,cAAc,MAAM,+BAA+B,CAAC,CAAC;QAEjE,iCAAiC;QACjC,IAAI,IAAI,CAAC,YAAY,EAAE,SAAS,EAAE,EAAE,CAAC;YACnC,MAAM,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;YAC1C,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC;QAC3B,CAAC;QAED,wBAAwB;QACxB,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC7C,IAAI,CAAC;gBACH,MAAM,QAAQ,EAAE,CAAC;YACnB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,KAAK,CAAC,4BAA4B,KAAK,EAAE,CAAC,CAAC;YACpD,CAAC;QACH,CAAC;QAED,2BAA2B;QAC3B,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACxB,IAAI,CAAC;gBACH,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YAClC,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;QACH,CAAC;QAED,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,gBAAgB,GAAG,EAAE,CAAC;IAC7B,CAAC;CACF;AAED,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAC"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
export type DerivedTaskStatus = 'pending' | 'completed' | 'failed' | 'blocked';
|
|
2
|
+
export type DerivedProjectStatus = 'planning' | 'ready' | 'executing' | 'completed' | 'failed';
|
|
3
|
+
export interface DerivedTask {
|
|
4
|
+
id: string;
|
|
5
|
+
planFile: string;
|
|
6
|
+
status: DerivedTaskStatus;
|
|
7
|
+
dependencies: string[];
|
|
8
|
+
}
|
|
9
|
+
export interface DerivedProjectState {
|
|
10
|
+
tasks: DerivedTask[];
|
|
11
|
+
status: DerivedProjectStatus;
|
|
12
|
+
}
|
|
13
|
+
export interface DiscoveredProject {
|
|
14
|
+
number: number;
|
|
15
|
+
name: string;
|
|
16
|
+
path: string;
|
|
17
|
+
}
|
|
18
|
+
export interface DerivedStats {
|
|
19
|
+
pending: number;
|
|
20
|
+
completed: number;
|
|
21
|
+
failed: number;
|
|
22
|
+
blocked: number;
|
|
23
|
+
total: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Discover all projects in the RAF directory.
|
|
27
|
+
* Projects are directories matching the pattern NNN-project-name.
|
|
28
|
+
*/
|
|
29
|
+
export declare function discoverProjects(rafDir: string): DiscoveredProject[];
|
|
30
|
+
/**
|
|
31
|
+
* Parse the Dependencies section from plan file content.
|
|
32
|
+
* Format: `## Dependencies\n001, 002` → ["001", "002"]
|
|
33
|
+
* Returns empty array if no Dependencies section exists.
|
|
34
|
+
*/
|
|
35
|
+
export declare function parseDependencies(content: string): string[];
|
|
36
|
+
/**
|
|
37
|
+
* Parse an outcome file to extract its status.
|
|
38
|
+
* Status is determined by the presence of promise markers:
|
|
39
|
+
* - `<promise>COMPLETE</promise>` → completed
|
|
40
|
+
* - `<promise>FAILED</promise>` → failed
|
|
41
|
+
* - `<promise>BLOCKED</promise>` → blocked
|
|
42
|
+
* Uses the last occurrence if multiple markers exist.
|
|
43
|
+
*/
|
|
44
|
+
export declare function parseOutcomeStatus(content: string): DerivedTaskStatus | null;
|
|
45
|
+
/**
|
|
46
|
+
* Derive project status from tasks.
|
|
47
|
+
* - planning: has input.md but no plans folder or empty plans
|
|
48
|
+
* - ready: has plan files but no outcome files
|
|
49
|
+
* - executing: has some outcome files but not all (or has failed outcomes without SUCCESS)
|
|
50
|
+
* - completed: all plan files have corresponding SUCCESS outcomes
|
|
51
|
+
* - failed: has FAILED outcome files
|
|
52
|
+
*/
|
|
53
|
+
export declare function deriveProjectStatus(projectPath: string, tasks: DerivedTask[]): DerivedProjectStatus;
|
|
54
|
+
/**
|
|
55
|
+
* Derive project state from the folder structure.
|
|
56
|
+
* Scans plans/ for plan files and outcomes/ for outcome files.
|
|
57
|
+
* Matches them by task ID (NNN prefix) and determines status.
|
|
58
|
+
* Also parses dependencies and derives blocked status.
|
|
59
|
+
*/
|
|
60
|
+
export declare function deriveProjectState(projectPath: string): DerivedProjectState;
|
|
61
|
+
/**
|
|
62
|
+
* Get the next pending task from derived state.
|
|
63
|
+
*/
|
|
64
|
+
export declare function getNextPendingTask(state: DerivedProjectState): DerivedTask | null;
|
|
65
|
+
/**
|
|
66
|
+
* Get the next task that should be executed (pending or failed).
|
|
67
|
+
* Skips blocked tasks - they cannot be executed until their dependencies pass.
|
|
68
|
+
*/
|
|
69
|
+
export declare function getNextExecutableTask(state: DerivedProjectState): DerivedTask | null;
|
|
70
|
+
/**
|
|
71
|
+
* Calculate statistics from derived state.
|
|
72
|
+
*/
|
|
73
|
+
export declare function getDerivedStats(state: DerivedProjectState): DerivedStats;
|
|
74
|
+
/**
|
|
75
|
+
* Check if all tasks are completed.
|
|
76
|
+
*/
|
|
77
|
+
export declare function isProjectComplete(state: DerivedProjectState): boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Check if any task has failed.
|
|
80
|
+
*/
|
|
81
|
+
export declare function hasProjectFailed(state: DerivedProjectState): boolean;
|
|
82
|
+
//# sourceMappingURL=state-derivation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-derivation.d.ts","sourceRoot":"","sources":["../../src/core/state-derivation.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE/E,MAAM,MAAM,oBAAoB,GAC5B,UAAU,GACV,OAAO,GACP,WAAW,GACX,WAAW,GACX,QAAQ,CAAC;AAEb,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,WAAW,EAAE,CAAC;IACrB,MAAM,EAAE,oBAAoB,CAAC;CAC9B;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAsBpE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAgB3D;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI,CAoB5E;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,WAAW,EAAE,GACnB,oBAAoB,CAyCtB;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,mBAAmB,CAoF3E;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,mBAAmB,GAAG,WAAW,GAAG,IAAI,CAOjF;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,mBAAmB,GAAG,WAAW,GAAG,IAAI,CAcpF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,mBAAmB,GAAG,YAAY,CA2BxE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAErE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAEpE"}
|