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,58 @@
|
|
|
1
|
+
import { select } from '@inquirer/prompts';
|
|
2
|
+
import { discoverProjects, deriveProjectState, getDerivedStats } from '../core/state-derivation.js';
|
|
3
|
+
import { extractProjectNumber, formatProjectNumber } from '../utils/paths.js';
|
|
4
|
+
/**
|
|
5
|
+
* Get all projects that have pending tasks (not fully completed).
|
|
6
|
+
* Returns projects sorted by number (oldest first).
|
|
7
|
+
*/
|
|
8
|
+
export function getPendingProjects(rafDir) {
|
|
9
|
+
const allProjects = discoverProjects(rafDir);
|
|
10
|
+
const pendingProjects = [];
|
|
11
|
+
for (const project of allProjects) {
|
|
12
|
+
const state = deriveProjectState(project.path);
|
|
13
|
+
const stats = getDerivedStats(state);
|
|
14
|
+
// Include projects that are not fully completed (have pending or failed tasks)
|
|
15
|
+
if (stats.pending > 0 || stats.failed > 0) {
|
|
16
|
+
const projectNumber = extractProjectNumber(project.path);
|
|
17
|
+
const formattedNumber = projectNumber ?? formatProjectNumber(project.number);
|
|
18
|
+
pendingProjects.push({
|
|
19
|
+
folder: `${formattedNumber}-${project.name}`,
|
|
20
|
+
number: project.number,
|
|
21
|
+
name: project.name,
|
|
22
|
+
path: project.path,
|
|
23
|
+
completedTasks: stats.completed,
|
|
24
|
+
totalTasks: stats.total,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
// Sort by number (already sorted by discoverProjects, but ensure it)
|
|
29
|
+
return pendingProjects.sort((a, b) => a.number - b.number);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Format a project for display in the picker.
|
|
33
|
+
* Example: "001 fix-auth-bug (2/5 tasks)"
|
|
34
|
+
*/
|
|
35
|
+
export function formatProjectChoice(project) {
|
|
36
|
+
const projectNumber = extractProjectNumber(project.path) ?? formatProjectNumber(project.number);
|
|
37
|
+
return `${projectNumber} ${project.name} (${project.completedTasks}/${project.totalTasks} tasks)`;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Display an interactive project picker for pending projects.
|
|
41
|
+
* Returns the selected project folder name or null if no projects or cancelled.
|
|
42
|
+
*/
|
|
43
|
+
export async function pickPendingProject(rafDir) {
|
|
44
|
+
const pendingProjects = getPendingProjects(rafDir);
|
|
45
|
+
if (pendingProjects.length === 0) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
const choices = pendingProjects.map((project) => ({
|
|
49
|
+
name: formatProjectChoice(project),
|
|
50
|
+
value: project.folder,
|
|
51
|
+
}));
|
|
52
|
+
const selected = await select({
|
|
53
|
+
message: 'Select a project to execute:',
|
|
54
|
+
choices,
|
|
55
|
+
});
|
|
56
|
+
return selected;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=project-picker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-picker.js","sourceRoot":"","sources":["../../src/ui/project-picker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AACpG,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAc9E;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,MAAM,WAAW,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAC7C,MAAM,eAAe,GAAyB,EAAE,CAAC;IAEjD,KAAK,MAAM,OAAO,IAAI,WAAW,EAAE,CAAC;QAClC,MAAM,KAAK,GAAG,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/C,MAAM,KAAK,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;QAErC,+EAA+E;QAC/E,IAAI,KAAK,CAAC,OAAO,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1C,MAAM,aAAa,GAAG,oBAAoB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACzD,MAAM,eAAe,GAAG,aAAa,IAAI,mBAAmB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAE7E,eAAe,CAAC,IAAI,CAAC;gBACnB,MAAM,EAAE,GAAG,eAAe,IAAI,OAAO,CAAC,IAAI,EAAE;gBAC5C,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,cAAc,EAAE,KAAK,CAAC,SAAS;gBAC/B,UAAU,EAAE,KAAK,CAAC,KAAK;aACxB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,qEAAqE;IACrE,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;AAC7D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,OAA2B;IAC7D,MAAM,aAAa,GAAG,oBAAoB,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,mBAAmB,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAChG,OAAO,GAAG,aAAa,IAAI,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,cAAc,IAAI,OAAO,CAAC,UAAU,SAAS,CAAC;AACpG,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAc;IACrD,MAAM,eAAe,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAEnD,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAChD,IAAI,EAAE,mBAAmB,CAAC,OAAO,CAAC;QAClC,KAAK,EAAE,OAAO,CAAC,MAAM;KACtB,CAAC,CAAC,CAAC;IAEJ,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC;QAC5B,OAAO,EAAE,8BAA8B;QACvC,OAAO;KACR,CAAC,CAAC;IAEH,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { RafConfig } from '../types/config.js';
|
|
2
|
+
/**
|
|
3
|
+
* Get the path to Claude CLI settings file.
|
|
4
|
+
*/
|
|
5
|
+
export declare function getClaudeSettingsPath(): string;
|
|
6
|
+
export declare function loadConfig(rafDir: string): RafConfig;
|
|
7
|
+
export declare function saveConfig(rafDir: string, config: RafConfig): void;
|
|
8
|
+
export declare function getEditor(): string;
|
|
9
|
+
/**
|
|
10
|
+
* Get the Claude model name from Claude CLI settings.
|
|
11
|
+
* Returns the model name or null if not found.
|
|
12
|
+
* @param settingsPath Optional path to settings file (for testing)
|
|
13
|
+
*/
|
|
14
|
+
export declare function getClaudeModel(settingsPath?: string): string | null;
|
|
15
|
+
/**
|
|
16
|
+
* Get runtime configuration for task execution.
|
|
17
|
+
* Returns default values which can be overridden by command line options.
|
|
18
|
+
*/
|
|
19
|
+
export declare function getConfig(): {
|
|
20
|
+
timeout: number;
|
|
21
|
+
maxRetries: number;
|
|
22
|
+
autoCommit: boolean;
|
|
23
|
+
};
|
|
24
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAsB,MAAM,oBAAoB,CAAC;AAInE;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAcpD;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAGlE;AAED,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAYnE;AAED;;;GAGG;AACH,wBAAgB,SAAS,IAAI;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,OAAO,CAAA;CAAE,CAMxF"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import * as os from 'node:os';
|
|
4
|
+
import { DEFAULT_RAF_CONFIG } from '../types/config.js';
|
|
5
|
+
const CONFIG_FILENAME = 'raf.config.json';
|
|
6
|
+
/**
|
|
7
|
+
* Get the path to Claude CLI settings file.
|
|
8
|
+
*/
|
|
9
|
+
export function getClaudeSettingsPath() {
|
|
10
|
+
return path.join(os.homedir(), '.claude', 'settings.json');
|
|
11
|
+
}
|
|
12
|
+
export function loadConfig(rafDir) {
|
|
13
|
+
const configPath = path.join(rafDir, CONFIG_FILENAME);
|
|
14
|
+
if (!fs.existsSync(configPath)) {
|
|
15
|
+
return { ...DEFAULT_RAF_CONFIG };
|
|
16
|
+
}
|
|
17
|
+
try {
|
|
18
|
+
const content = fs.readFileSync(configPath, 'utf-8');
|
|
19
|
+
const userConfig = JSON.parse(content);
|
|
20
|
+
return { ...DEFAULT_RAF_CONFIG, ...userConfig };
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return { ...DEFAULT_RAF_CONFIG };
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export function saveConfig(rafDir, config) {
|
|
27
|
+
const configPath = path.join(rafDir, CONFIG_FILENAME);
|
|
28
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
29
|
+
}
|
|
30
|
+
export function getEditor() {
|
|
31
|
+
return process.env['EDITOR'] ?? process.env['VISUAL'] ?? 'vi';
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Get the Claude model name from Claude CLI settings.
|
|
35
|
+
* Returns the model name or null if not found.
|
|
36
|
+
* @param settingsPath Optional path to settings file (for testing)
|
|
37
|
+
*/
|
|
38
|
+
export function getClaudeModel(settingsPath) {
|
|
39
|
+
const filePath = settingsPath ?? getClaudeSettingsPath();
|
|
40
|
+
try {
|
|
41
|
+
if (!fs.existsSync(filePath)) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
45
|
+
const settings = JSON.parse(content);
|
|
46
|
+
return settings.model ?? null;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Get runtime configuration for task execution.
|
|
54
|
+
* Returns default values which can be overridden by command line options.
|
|
55
|
+
*/
|
|
56
|
+
export function getConfig() {
|
|
57
|
+
return {
|
|
58
|
+
timeout: DEFAULT_RAF_CONFIG.defaultTimeout,
|
|
59
|
+
maxRetries: DEFAULT_RAF_CONFIG.defaultMaxRetries,
|
|
60
|
+
autoCommit: DEFAULT_RAF_CONFIG.autoCommit,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/utils/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAa,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAEnE,MAAM,eAAe,GAAG,iBAAiB,CAAC;AAE1C;;GAEG;AACH,MAAM,UAAU,qBAAqB;IACnC,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,eAAe,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IAEtD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,OAAO,EAAE,GAAG,kBAAkB,EAAE,CAAC;IACnC,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACrD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAuB,CAAC;QAC7D,OAAO,EAAE,GAAG,kBAAkB,EAAE,GAAG,UAAU,EAAE,CAAC;IAClD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,GAAG,kBAAkB,EAAE,CAAC;IACnC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAc,EAAE,MAAiB;IAC1D,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACtD,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,SAAS;IACvB,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC;AAChE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,YAAqB;IAClD,MAAM,QAAQ,GAAG,YAAY,IAAI,qBAAqB,EAAE,CAAC;IACzD,IAAI,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACnD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAuB,CAAC;QAC3D,OAAO,QAAQ,CAAC,KAAK,IAAI,IAAI,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS;IACvB,OAAO;QACL,OAAO,EAAE,kBAAkB,CAAC,cAAc;QAC1C,UAAU,EAAE,kBAAkB,CAAC,iBAAiB;QAChD,UAAU,EAAE,kBAAkB,CAAC,UAAU;KAC1C,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
2
|
+
interface LoggerOptions {
|
|
3
|
+
verbose?: boolean;
|
|
4
|
+
debug?: boolean;
|
|
5
|
+
}
|
|
6
|
+
declare class Logger {
|
|
7
|
+
private verbose;
|
|
8
|
+
private debugMode;
|
|
9
|
+
configure(options: LoggerOptions): void;
|
|
10
|
+
/**
|
|
11
|
+
* @deprecated No longer used - kept for backwards compatibility
|
|
12
|
+
*/
|
|
13
|
+
setContext(_prefix: string): void;
|
|
14
|
+
/**
|
|
15
|
+
* @deprecated No longer used - kept for backwards compatibility
|
|
16
|
+
*/
|
|
17
|
+
clearContext(): void;
|
|
18
|
+
private formatMessage;
|
|
19
|
+
debug(message: string, ...args: unknown[]): void;
|
|
20
|
+
info(message: string, ...args: unknown[]): void;
|
|
21
|
+
verbose_log(message: string, ...args: unknown[]): void;
|
|
22
|
+
warn(message: string, ...args: unknown[]): void;
|
|
23
|
+
error(message: string, ...args: unknown[]): void;
|
|
24
|
+
print(message: string, ...args: unknown[]): void;
|
|
25
|
+
success(message: string, ...args: unknown[]): void;
|
|
26
|
+
task(status: string, name: string): void;
|
|
27
|
+
newline(): void;
|
|
28
|
+
dim(message: string, ...args: unknown[]): void;
|
|
29
|
+
}
|
|
30
|
+
export declare const logger: Logger;
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAE3D,UAAU,aAAa;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,cAAM,MAAM;IACV,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAS;IAE1B,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAKvC;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIjC;;OAEG;IACH,YAAY,IAAI,IAAI;IAIpB,OAAO,CAAC,aAAa;IAIrB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAMhD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAI/C,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAMtD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAI/C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAIhD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAIhD,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAIlD,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAIxC,OAAO,IAAI,IAAI;IAIf,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;CAI/C;AAED,eAAO,MAAM,MAAM,QAAe,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
class Logger {
|
|
2
|
+
verbose = false;
|
|
3
|
+
debugMode = false;
|
|
4
|
+
configure(options) {
|
|
5
|
+
this.verbose = options.verbose ?? false;
|
|
6
|
+
this.debugMode = options.debug ?? false;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* @deprecated No longer used - kept for backwards compatibility
|
|
10
|
+
*/
|
|
11
|
+
setContext(_prefix) {
|
|
12
|
+
// No-op: context prefix feature removed in favor of minimal output style
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* @deprecated No longer used - kept for backwards compatibility
|
|
16
|
+
*/
|
|
17
|
+
clearContext() {
|
|
18
|
+
// No-op: context prefix feature removed in favor of minimal output style
|
|
19
|
+
}
|
|
20
|
+
formatMessage(message) {
|
|
21
|
+
return message;
|
|
22
|
+
}
|
|
23
|
+
debug(message, ...args) {
|
|
24
|
+
if (this.debugMode) {
|
|
25
|
+
console.log(`[DEBUG] ${message}`, ...args);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
info(message, ...args) {
|
|
29
|
+
console.log(this.formatMessage(message), ...args);
|
|
30
|
+
}
|
|
31
|
+
verbose_log(message, ...args) {
|
|
32
|
+
if (this.verbose || this.debugMode) {
|
|
33
|
+
console.log(this.formatMessage(message), ...args);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
warn(message, ...args) {
|
|
37
|
+
console.warn(`⚠️ ${this.formatMessage(message)}`, ...args);
|
|
38
|
+
}
|
|
39
|
+
error(message, ...args) {
|
|
40
|
+
console.error(`✗ ${this.formatMessage(message)}`, ...args);
|
|
41
|
+
}
|
|
42
|
+
print(message, ...args) {
|
|
43
|
+
console.log(message, ...args);
|
|
44
|
+
}
|
|
45
|
+
success(message, ...args) {
|
|
46
|
+
console.log(`✓ ${this.formatMessage(message)}`, ...args);
|
|
47
|
+
}
|
|
48
|
+
task(status, name) {
|
|
49
|
+
console.log(`${status} ${name}`);
|
|
50
|
+
}
|
|
51
|
+
newline() {
|
|
52
|
+
console.log();
|
|
53
|
+
}
|
|
54
|
+
dim(message, ...args) {
|
|
55
|
+
// ANSI escape code for dim text
|
|
56
|
+
console.log(`\x1b[2m${this.formatMessage(message)}\x1b[0m`, ...args);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export const logger = new Logger();
|
|
60
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM;IACF,OAAO,GAAG,KAAK,CAAC;IAChB,SAAS,GAAG,KAAK,CAAC;IAE1B,SAAS,CAAC,OAAsB;QAC9B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,KAAK,CAAC;QACxC,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC;IAC1C,CAAC;IAED;;OAEG;IACH,UAAU,CAAC,OAAe;QACxB,yEAAyE;IAC3E,CAAC;IAED;;OAEG;IACH,YAAY;QACV,yEAAyE;IAC3E,CAAC;IAEO,aAAa,CAAC,OAAe;QACnC,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,GAAG,IAAe;QACvC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,WAAW,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;QAC7C,CAAC;IACH,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,GAAG,IAAe;QACtC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;IACpD,CAAC;IAED,WAAW,CAAC,OAAe,EAAE,GAAG,IAAe;QAC7C,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAED,IAAI,CAAC,OAAe,EAAE,GAAG,IAAe;QACtC,OAAO,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IAC9D,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,GAAG,IAAe;QACvC,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IAC7D,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,GAAG,IAAe;QACvC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;IAChC,CAAC;IAED,OAAO,CAAC,OAAe,EAAE,GAAG,IAAe;QACzC,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IAC3D,CAAC;IAED,IAAI,CAAC,MAAc,EAAE,IAAY;QAC/B,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC;IACnC,CAAC;IAED,OAAO;QACL,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;IAED,GAAG,CAAC,OAAe,EAAE,GAAG,IAAe;QACrC,gCAAgC;QAChC,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,IAAI,CAAC,CAAC;IACvE,CAAC;CACF;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate a single project name using Claude Sonnet.
|
|
3
|
+
* Falls back to extracting words from the description if the API call fails.
|
|
4
|
+
*/
|
|
5
|
+
export declare function generateProjectName(description: string): Promise<string>;
|
|
6
|
+
/**
|
|
7
|
+
* Generate multiple project name suggestions using Claude Sonnet.
|
|
8
|
+
* Returns 3-5 unique names with varied styles.
|
|
9
|
+
*/
|
|
10
|
+
export declare function generateProjectNames(description: string): Promise<string[]>;
|
|
11
|
+
/**
|
|
12
|
+
* Escape a string for use as a shell argument.
|
|
13
|
+
*/
|
|
14
|
+
declare function escapeShellArg(arg: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* Sanitize the generated name to ensure it's a valid kebab-case folder name.
|
|
17
|
+
*/
|
|
18
|
+
declare function sanitizeGeneratedName(name: string): string | null;
|
|
19
|
+
export { sanitizeGeneratedName, escapeShellArg };
|
|
20
|
+
//# sourceMappingURL=name-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"name-generator.d.ts","sourceRoot":"","sources":["../../src/utils/name-generator.ts"],"names":[],"mappings":"AAyCA;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAgB9E;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAejF;AAkED;;GAEG;AACH,iBAAS,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAQ3C;AAED;;GAEG;AACH,iBAAS,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAyB1D;AAqBD,OAAO,EAAE,qBAAqB,EAAE,cAAc,EAAE,CAAC"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { execSync } from 'node:child_process';
|
|
2
|
+
import { logger } from './logger.js';
|
|
3
|
+
import { sanitizeProjectName } from './validation.js';
|
|
4
|
+
const SONNET_MODEL = 'sonnet';
|
|
5
|
+
const NAME_GENERATION_PROMPT = `Generate a short, punchy, creative project name (1-3 words, kebab-case).
|
|
6
|
+
|
|
7
|
+
Be creative! Use metaphors, analogies, or evocative words that capture the SPIRIT of the project.
|
|
8
|
+
Don't literally describe what it does - make it memorable and fun.
|
|
9
|
+
|
|
10
|
+
Good examples:
|
|
11
|
+
- Bug fix → 'bug-squasher', 'exterminator', 'patch-adams'
|
|
12
|
+
- Performance optimization → 'turbo-boost', 'lightning-rod', 'speed-demon'
|
|
13
|
+
- Auth system → 'gatekeeper', 'bouncer', 'key-master'
|
|
14
|
+
- Refactoring → 'spring-cleaning', 'phoenix', 'makeover'
|
|
15
|
+
- New feature → 'moonshot', 'secret-sauce', 'magic-wand'
|
|
16
|
+
|
|
17
|
+
Output ONLY the kebab-case name. No quotes, no explanation.
|
|
18
|
+
|
|
19
|
+
Project description:`;
|
|
20
|
+
const MULTI_NAME_GENERATION_PROMPT = `Generate 5 creative project names for the description below.
|
|
21
|
+
|
|
22
|
+
IMPORTANT: Each name should use a DIFFERENT naming style:
|
|
23
|
+
1. **Metaphorical** - Use a metaphor or analogy (e.g., 'phoenix', 'lighthouse', 'compass')
|
|
24
|
+
2. **Fun/Playful** - Make it fun or quirky (e.g., 'turbo-boost', 'magic-beans', 'ninja-move')
|
|
25
|
+
3. **Action-oriented** - Focus on what it does with flair (e.g., 'bug-squasher', 'speed-demon', 'data-whisperer')
|
|
26
|
+
4. **Abstract** - Use abstract/poetic concepts (e.g., 'horizon', 'cascade', 'catalyst')
|
|
27
|
+
5. **Cultural reference** - Reference pop culture, mythology, or literature (e.g., 'atlas', 'merlin', 'gandalf')
|
|
28
|
+
|
|
29
|
+
Rules:
|
|
30
|
+
- Each name should be 1-3 words in kebab-case
|
|
31
|
+
- Names must be lowercase with hyphens only
|
|
32
|
+
- Make them memorable and evocative
|
|
33
|
+
- If the project has many unrelated tasks, prefer abstract/metaphorical/fun names over descriptive ones
|
|
34
|
+
|
|
35
|
+
Output format: ONLY output 5 names, one per line, no numbers, no explanations, no quotes.
|
|
36
|
+
|
|
37
|
+
Project description:`;
|
|
38
|
+
/**
|
|
39
|
+
* Generate a single project name using Claude Sonnet.
|
|
40
|
+
* Falls back to extracting words from the description if the API call fails.
|
|
41
|
+
*/
|
|
42
|
+
export async function generateProjectName(description) {
|
|
43
|
+
try {
|
|
44
|
+
const name = await callSonnetForName(description);
|
|
45
|
+
if (name) {
|
|
46
|
+
const sanitized = sanitizeGeneratedName(name);
|
|
47
|
+
if (sanitized) {
|
|
48
|
+
logger.debug(`Generated project name: ${sanitized}`);
|
|
49
|
+
return sanitized;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
logger.debug(`Failed to generate name with Sonnet: ${error}`);
|
|
55
|
+
}
|
|
56
|
+
// Fallback to extracting words from description
|
|
57
|
+
return generateFallbackName(description);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Generate multiple project name suggestions using Claude Sonnet.
|
|
61
|
+
* Returns 3-5 unique names with varied styles.
|
|
62
|
+
*/
|
|
63
|
+
export async function generateProjectNames(description) {
|
|
64
|
+
try {
|
|
65
|
+
const names = await callSonnetForMultipleNames(description);
|
|
66
|
+
if (names.length >= 3) {
|
|
67
|
+
logger.debug(`Generated ${names.length} project names`);
|
|
68
|
+
return names;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
logger.debug(`Failed to generate names with Sonnet: ${error}`);
|
|
73
|
+
}
|
|
74
|
+
// Fallback: generate a single fallback name
|
|
75
|
+
const fallbackName = generateFallbackName(description);
|
|
76
|
+
logger.debug(`Using fallback name: ${fallbackName}`);
|
|
77
|
+
return [fallbackName];
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Call Claude Sonnet to generate a single project name.
|
|
81
|
+
*/
|
|
82
|
+
async function callSonnetForName(description) {
|
|
83
|
+
try {
|
|
84
|
+
const fullPrompt = `${NAME_GENERATION_PROMPT}\n${description}`;
|
|
85
|
+
// Use claude CLI with --model sonnet and --print for non-interactive output
|
|
86
|
+
const result = execSync(`claude --model ${SONNET_MODEL} --print "${escapeShellArg(fullPrompt)}"`, {
|
|
87
|
+
encoding: 'utf-8',
|
|
88
|
+
timeout: 30000, // 30 second timeout
|
|
89
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
90
|
+
});
|
|
91
|
+
return result.trim();
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
logger.debug(`Sonnet API call failed: ${error}`);
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Call Claude Sonnet to generate multiple project names.
|
|
100
|
+
*/
|
|
101
|
+
async function callSonnetForMultipleNames(description) {
|
|
102
|
+
try {
|
|
103
|
+
const fullPrompt = `${MULTI_NAME_GENERATION_PROMPT}\n${description}`;
|
|
104
|
+
const result = execSync(`claude --model ${SONNET_MODEL} --print "${escapeShellArg(fullPrompt)}"`, {
|
|
105
|
+
encoding: 'utf-8',
|
|
106
|
+
timeout: 30000,
|
|
107
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
108
|
+
});
|
|
109
|
+
// Parse the multiline response
|
|
110
|
+
const lines = result
|
|
111
|
+
.trim()
|
|
112
|
+
.split('\n')
|
|
113
|
+
.map((line) => line.trim())
|
|
114
|
+
.filter((line) => line.length > 0);
|
|
115
|
+
// Sanitize and validate each name
|
|
116
|
+
const validNames = [];
|
|
117
|
+
for (const line of lines) {
|
|
118
|
+
const sanitized = sanitizeGeneratedName(line);
|
|
119
|
+
if (sanitized && !validNames.includes(sanitized)) {
|
|
120
|
+
validNames.push(sanitized);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Return 3-5 names
|
|
124
|
+
return validNames.slice(0, 5);
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
logger.debug(`Sonnet API call for multiple names failed: ${error}`);
|
|
128
|
+
return [];
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Escape a string for use as a shell argument.
|
|
133
|
+
*/
|
|
134
|
+
function escapeShellArg(arg) {
|
|
135
|
+
// Replace double quotes with escaped double quotes
|
|
136
|
+
// Replace backslashes with escaped backslashes
|
|
137
|
+
return arg
|
|
138
|
+
.replace(/\\/g, '\\\\')
|
|
139
|
+
.replace(/"/g, '\\"')
|
|
140
|
+
.replace(/\$/g, '\\$')
|
|
141
|
+
.replace(/`/g, '\\`');
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Sanitize the generated name to ensure it's a valid kebab-case folder name.
|
|
145
|
+
*/
|
|
146
|
+
function sanitizeGeneratedName(name) {
|
|
147
|
+
// Remove any leading/trailing whitespace and quotes
|
|
148
|
+
let sanitized = name.trim().replace(/^["']|["']$/g, '');
|
|
149
|
+
// Remove any numbering prefix like "1." or "1:" or "1)"
|
|
150
|
+
sanitized = sanitized.replace(/^\d+[.:)]\s*/, '');
|
|
151
|
+
// Convert to lowercase
|
|
152
|
+
sanitized = sanitized.toLowerCase();
|
|
153
|
+
// Replace any non-alphanumeric characters with hyphens
|
|
154
|
+
sanitized = sanitized.replace(/[^a-z0-9]+/g, '-');
|
|
155
|
+
// Remove leading and trailing hyphens
|
|
156
|
+
sanitized = sanitized.replace(/^-+|-+$/g, '');
|
|
157
|
+
// Truncate if too long (max 50 chars)
|
|
158
|
+
sanitized = sanitized.substring(0, 50);
|
|
159
|
+
// Return null if the result is empty or too short
|
|
160
|
+
if (sanitized.length < 2) {
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
return sanitized;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Generate a fallback name by extracting meaningful words from the description.
|
|
167
|
+
*/
|
|
168
|
+
function generateFallbackName(description) {
|
|
169
|
+
// Extract first meaningful words from input
|
|
170
|
+
const words = description
|
|
171
|
+
.split(/\s+/)
|
|
172
|
+
.filter((w) => w.length > 2)
|
|
173
|
+
.slice(0, 3)
|
|
174
|
+
.join('-')
|
|
175
|
+
.toLowerCase()
|
|
176
|
+
.replace(/[^a-z0-9-]/g, '');
|
|
177
|
+
const name = sanitizeProjectName(words || 'project');
|
|
178
|
+
logger.debug(`Using fallback project name: ${name}`);
|
|
179
|
+
return name;
|
|
180
|
+
}
|
|
181
|
+
// Export for testing
|
|
182
|
+
export { sanitizeGeneratedName, escapeShellArg };
|
|
183
|
+
//# sourceMappingURL=name-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"name-generator.js","sourceRoot":"","sources":["../../src/utils/name-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
export declare const RAF_DIR = "RAF";
|
|
2
|
+
/**
|
|
3
|
+
* Encode a project number >= 1000 to a 3-character base36 string.
|
|
4
|
+
* The encoding offsets by 1000, so:
|
|
5
|
+
* - 1000 -> 'a00'
|
|
6
|
+
* - 1001 -> 'a01'
|
|
7
|
+
* - 1035 -> 'a0z'
|
|
8
|
+
* - 1036 -> 'a10'
|
|
9
|
+
* - etc.
|
|
10
|
+
*
|
|
11
|
+
* First character uses a-z (10-35 in base36, letters only).
|
|
12
|
+
* Second and third characters use 0-9a-z (0-35 in base36).
|
|
13
|
+
*/
|
|
14
|
+
export declare function encodeBase36(num: number): string;
|
|
15
|
+
/**
|
|
16
|
+
* Decode a 3-character base36 string to a project number.
|
|
17
|
+
* Returns the decoded number >= 1000, or null if invalid format.
|
|
18
|
+
*/
|
|
19
|
+
export declare function decodeBase36(str: string): number | null;
|
|
20
|
+
/**
|
|
21
|
+
* Check if a string is a valid base36 project prefix.
|
|
22
|
+
* Valid format: starts with a-z, followed by two base36 chars (0-9, a-z).
|
|
23
|
+
*/
|
|
24
|
+
export declare function isBase36Prefix(str: string): boolean;
|
|
25
|
+
export declare function getRafDir(): string;
|
|
26
|
+
export declare function ensureRafDir(): string;
|
|
27
|
+
export declare function getNextProjectNumber(rafDir: string): number;
|
|
28
|
+
export declare function formatProjectNumber(num: number): string;
|
|
29
|
+
export declare function getProjectDir(rafDir: string, projectName: string): string | null;
|
|
30
|
+
/**
|
|
31
|
+
* Extract project number prefix from a project path.
|
|
32
|
+
* Supports both numeric (001-999) and base36 (a00-zzz) formats.
|
|
33
|
+
* E.g., "/Users/foo/RAF/001-my-project" -> "001"
|
|
34
|
+
* E.g., "/Users/foo/RAF/a00-my-project" -> "a00"
|
|
35
|
+
* Returns the prefix string (e.g., "001" or "a00") or null if not found.
|
|
36
|
+
*/
|
|
37
|
+
export declare function extractProjectNumber(projectPath: string): string | null;
|
|
38
|
+
/**
|
|
39
|
+
* Parse a project prefix string to its numeric value.
|
|
40
|
+
* Handles both numeric (001-999) and base36 (a00-zzz) formats.
|
|
41
|
+
* Returns the numeric project number or null if invalid.
|
|
42
|
+
*/
|
|
43
|
+
export declare function parseProjectPrefix(prefix: string): number | null;
|
|
44
|
+
/**
|
|
45
|
+
* Extract project name from a project path (without number prefix).
|
|
46
|
+
* Supports both numeric (001-999) and base36 (a00-zzz) formats.
|
|
47
|
+
* E.g., "/Users/foo/RAF/001-my-project" -> "my-project"
|
|
48
|
+
* E.g., "/Users/foo/RAF/a00-my-project" -> "my-project"
|
|
49
|
+
* Returns the project name or null if not found.
|
|
50
|
+
*/
|
|
51
|
+
export declare function extractProjectName(projectPath: string): string | null;
|
|
52
|
+
/**
|
|
53
|
+
* Extract task name from a plan filename (without number prefix and extension).
|
|
54
|
+
* E.g., "002-fix-login-bug.md" -> "fix-login-bug"
|
|
55
|
+
* Returns the task name or null if not found.
|
|
56
|
+
*/
|
|
57
|
+
export declare function extractTaskNameFromPlanFile(planFilename: string): string | null;
|
|
58
|
+
export declare function listProjects(rafDir: string): Array<{
|
|
59
|
+
number: number;
|
|
60
|
+
name: string;
|
|
61
|
+
path: string;
|
|
62
|
+
}>;
|
|
63
|
+
export declare function getPlansDir(projectPath: string): string;
|
|
64
|
+
export declare function getOutcomesDir(projectPath: string): string;
|
|
65
|
+
export declare function getOutcomeFilePath(projectPath: string, taskId: string, taskName: string): string;
|
|
66
|
+
export declare function getDecisionsPath(projectPath: string): string;
|
|
67
|
+
export declare function getLogsDir(projectPath: string): string;
|
|
68
|
+
export declare function getInputPath(projectPath: string): string;
|
|
69
|
+
/**
|
|
70
|
+
* Result of resolving a project identifier.
|
|
71
|
+
*/
|
|
72
|
+
export interface ProjectResolutionResult {
|
|
73
|
+
/** Resolved project path (null if not found or ambiguous) */
|
|
74
|
+
path: string | null;
|
|
75
|
+
/** Error type if resolution failed */
|
|
76
|
+
error?: 'not_found' | 'ambiguous';
|
|
77
|
+
/** For ambiguous matches, list of matching projects */
|
|
78
|
+
matches?: Array<{
|
|
79
|
+
number: number;
|
|
80
|
+
name: string;
|
|
81
|
+
path: string;
|
|
82
|
+
folder: string;
|
|
83
|
+
}>;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Resolve a project identifier with detailed result including ambiguity detection.
|
|
87
|
+
*
|
|
88
|
+
* Supported identifier formats (checked in this order):
|
|
89
|
+
* 1. Full folder name (e.g., "001-fix-stuff", "a01-important-project")
|
|
90
|
+
* - Must be an exact match to an existing folder
|
|
91
|
+
* - Pattern: numeric prefix (2-3 digits) or base36 prefix, followed by hyphen and name
|
|
92
|
+
* 2. Numeric ID (e.g., "003", "3", "1000")
|
|
93
|
+
* - Looks up by project number
|
|
94
|
+
* 3. Base36 prefix (e.g., "a00", "a01")
|
|
95
|
+
* - Looks up by base36 project number (for projects >= 1000)
|
|
96
|
+
* 4. Project name (e.g., "my-project", "fix-stuff")
|
|
97
|
+
* - Looks up by the name portion of the folder (after the prefix)
|
|
98
|
+
* - Case-insensitive matching
|
|
99
|
+
* - Returns error if multiple projects have the same name
|
|
100
|
+
*
|
|
101
|
+
* @param rafDir - The RAF directory containing project folders
|
|
102
|
+
* @param identifier - The identifier to resolve
|
|
103
|
+
* @returns Resolution result with path, error type, and matches for ambiguous cases
|
|
104
|
+
*/
|
|
105
|
+
export declare function resolveProjectIdentifierWithDetails(rafDir: string, identifier: string): ProjectResolutionResult;
|
|
106
|
+
/**
|
|
107
|
+
* Resolve a project identifier to a full project path.
|
|
108
|
+
*
|
|
109
|
+
* Supported identifier formats (checked in this order):
|
|
110
|
+
* 1. Full folder name (e.g., "001-fix-stuff", "a01-important-project")
|
|
111
|
+
* - Must be an exact match to an existing folder
|
|
112
|
+
* - Pattern: numeric prefix (2-3 digits) or base36 prefix, followed by hyphen and name
|
|
113
|
+
* 2. Numeric ID (e.g., "003", "3", "1000")
|
|
114
|
+
* - Looks up by project number
|
|
115
|
+
* 3. Base36 prefix (e.g., "a00", "a01")
|
|
116
|
+
* - Looks up by base36 project number (for projects >= 1000)
|
|
117
|
+
* 4. Project name (e.g., "my-project", "fix-stuff")
|
|
118
|
+
* - Looks up by the name portion of the folder (after the prefix)
|
|
119
|
+
* - Case-insensitive matching
|
|
120
|
+
*
|
|
121
|
+
* Note: For ambiguity detection (multiple projects with same name), use
|
|
122
|
+
* resolveProjectIdentifierWithDetails instead.
|
|
123
|
+
*
|
|
124
|
+
* This function is designed to be extensible for future task-level references
|
|
125
|
+
* like "001-project/002-task".
|
|
126
|
+
*
|
|
127
|
+
* @param rafDir - The RAF directory containing project folders
|
|
128
|
+
* @param identifier - The identifier to resolve
|
|
129
|
+
* @returns The full project path or null if not found (or ambiguous)
|
|
130
|
+
*/
|
|
131
|
+
export declare function resolveProjectIdentifier(rafDir: string, identifier: string): string | null;
|
|
132
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/utils/paths.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,OAAO,QAAQ,CAAC;AAO7B;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAyBhD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA6BvD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAKnD;AAED,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED,wBAAgB,YAAY,IAAI,MAAM,CAMrC;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAiC3D;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAKvD;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAwBhF;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgBvE;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAYhE;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgBrE;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI/E;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAqClG;AAED,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEhG;AAED,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,6DAA6D;IAC7D,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,sCAAsC;IACtC,KAAK,CAAC,EAAE,WAAW,GAAG,WAAW,CAAC;IAClC,uDAAuD;IACvD,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjF;AAsCD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,mCAAmC,CACjD,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,GACjB,uBAAuB,CA0EzB;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,GACjB,MAAM,GAAG,IAAI,CAGf"}
|