rafcode 1.2.0 → 2.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.md +118 -22
- package/RAF/aaaabt-verbose-chronicle/decisions.md +25 -0
- package/RAF/aaaabt-verbose-chronicle/input.md +3 -0
- package/RAF/aaaabt-verbose-chronicle/outcomes/01-amend-iteration-references.md +25 -0
- package/RAF/aaaabt-verbose-chronicle/outcomes/02-verbose-task-name-display.md +31 -0
- package/RAF/aaaabt-verbose-chronicle/outcomes/03-verbose-streaming-fix.md +48 -0
- package/RAF/aaaabt-verbose-chronicle/outcomes/04-commit-verification-before-halt.md +56 -0
- package/RAF/aaaabt-verbose-chronicle/plans/01-amend-iteration-references.md +35 -0
- package/RAF/aaaabt-verbose-chronicle/plans/02-verbose-task-name-display.md +38 -0
- package/RAF/aaaabt-verbose-chronicle/plans/03-verbose-streaming-fix.md +45 -0
- package/RAF/aaaabt-verbose-chronicle/plans/04-commit-verification-before-halt.md +62 -0
- package/RAF/aaaacu-worktree-weaver/decisions.md +88 -0
- package/RAF/aaaacu-worktree-weaver/input.md +27 -0
- package/RAF/aaaacu-worktree-weaver/outcomes/01-git-worktree-utilities.md +41 -0
- package/RAF/aaaacu-worktree-weaver/outcomes/02-worktree-plan-command.md +44 -0
- package/RAF/aaaacu-worktree-weaver/outcomes/03-worktree-do-command.md +58 -0
- package/RAF/aaaacu-worktree-weaver/outcomes/04-auto-merge-and-cleanup.md +40 -0
- package/RAF/aaaacu-worktree-weaver/outcomes/05-worktree-tests.md +43 -0
- package/RAF/aaaacu-worktree-weaver/outcomes/06-update-documentation.md +33 -0
- package/RAF/aaaacu-worktree-weaver/plans/01-git-worktree-utilities.md +51 -0
- package/RAF/aaaacu-worktree-weaver/plans/02-worktree-plan-command.md +93 -0
- package/RAF/aaaacu-worktree-weaver/plans/03-worktree-do-command.md +81 -0
- package/RAF/aaaacu-worktree-weaver/plans/04-auto-merge-and-cleanup.md +51 -0
- package/RAF/aaaacu-worktree-weaver/plans/05-worktree-tests.md +52 -0
- package/RAF/aaaacu-worktree-weaver/plans/06-update-documentation.md +55 -0
- package/RAF/aaaacv-trim-the-fat/decisions.md +34 -0
- package/RAF/aaaacv-trim-the-fat/input.md +5 -0
- package/RAF/aaaacv-trim-the-fat/outcomes/01-add-worktree-support-to-status.md +43 -0
- package/RAF/aaaacv-trim-the-fat/outcomes/02-remove-multi-project-from-do.md +50 -0
- package/RAF/aaaacv-trim-the-fat/outcomes/03-commit-artifacts-on-amend.md +35 -0
- package/RAF/aaaacv-trim-the-fat/outcomes/04-worktree-aware-exit-messages.md +36 -0
- package/RAF/aaaacv-trim-the-fat/plans/01-add-worktree-support-to-status.md +43 -0
- package/RAF/aaaacv-trim-the-fat/plans/02-remove-multi-project-from-do.md +44 -0
- package/RAF/aaaacv-trim-the-fat/plans/03-commit-artifacts-on-amend.md +38 -0
- package/RAF/aaaacv-trim-the-fat/plans/04-worktree-aware-exit-messages.md +38 -0
- package/RAF/aaaacw-prune-cycle/decisions.md +25 -0
- package/RAF/aaaacw-prune-cycle/input.md +5 -0
- package/RAF/aaaacw-prune-cycle/outcomes/01-create-worktree-from-branch.md +32 -0
- package/RAF/aaaacw-prune-cycle/outcomes/02-cleanup-worktree-on-success.md +33 -0
- package/RAF/aaaacw-prune-cycle/outcomes/03-amend-recreate-worktree.md +40 -0
- package/RAF/aaaacw-prune-cycle/plans/01-create-worktree-from-branch.md +31 -0
- package/RAF/aaaacw-prune-cycle/plans/02-cleanup-worktree-on-success.md +38 -0
- package/RAF/aaaacw-prune-cycle/plans/03-amend-recreate-worktree.md +50 -0
- package/RAF/aaaacx-epoch-shift/decisions.md +25 -0
- package/RAF/aaaacx-epoch-shift/input.md +1 -0
- package/RAF/aaaacx-epoch-shift/outcomes/01-epoch-id-generation.md +34 -0
- package/RAF/aaaacx-epoch-shift/outcomes/02-update-pattern-matching.md +32 -0
- package/RAF/aaaacx-epoch-shift/outcomes/03-update-tests.md +59 -0
- package/RAF/aaaacx-epoch-shift/outcomes/04-update-documentation.md +30 -0
- package/RAF/aaaacx-epoch-shift/plans/01-epoch-id-generation.md +40 -0
- package/RAF/aaaacx-epoch-shift/plans/02-update-pattern-matching.md +60 -0
- package/RAF/aaaacx-epoch-shift/plans/03-update-tests.md +48 -0
- package/RAF/aaaacx-epoch-shift/plans/04-update-documentation.md +44 -0
- package/RAF/ahmpro-merge-guardian/decisions.md +25 -0
- package/RAF/ahmpro-merge-guardian/input.md +4 -0
- package/RAF/ahmpro-merge-guardian/outcomes/001-fix-amend-worktree-commit.md +45 -0
- package/RAF/ahmpro-merge-guardian/outcomes/002-base36-task-ids.md +55 -0
- package/RAF/ahmpro-merge-guardian/outcomes/003-worktree-pr-creation.md +41 -0
- package/RAF/ahmpro-merge-guardian/outcomes/004-post-execution-picker.md +53 -0
- package/RAF/ahmpro-merge-guardian/plans/001-fix-amend-worktree-commit.md +39 -0
- package/RAF/ahmpro-merge-guardian/plans/002-base36-task-ids.md +43 -0
- package/RAF/ahmpro-merge-guardian/plans/003-worktree-pr-creation.md +43 -0
- package/RAF/ahmpro-merge-guardian/plans/004-post-execution-picker.md +51 -0
- package/RAF/ahnbcu-letterjam/decisions.md +13 -0
- package/RAF/ahnbcu-letterjam/input.md +3 -0
- package/RAF/ahnbcu-letterjam/outcomes/01-base26-encoding.md +42 -0
- package/RAF/ahnbcu-letterjam/outcomes/02-update-tests.md +38 -0
- package/RAF/ahnbcu-letterjam/outcomes/03-migrate-command.md +51 -0
- package/RAF/ahnbcu-letterjam/outcomes/04-update-documentation.md +29 -0
- package/RAF/ahnbcu-letterjam/plans/01-base26-encoding.md +36 -0
- package/RAF/ahnbcu-letterjam/plans/02-update-tests.md +37 -0
- package/RAF/ahnbcu-letterjam/plans/03-migrate-command.md +49 -0
- package/RAF/ahnbcu-letterjam/plans/04-update-documentation.md +39 -0
- package/RAF/ahnwrk-worktree-weaver/decisions.md +19 -0
- package/RAF/ahnwrk-worktree-weaver/input.md +4 -0
- package/RAF/ahnwrk-worktree-weaver/outcomes/01-remove-co-authored-by.md +20 -0
- package/RAF/ahnwrk-worktree-weaver/outcomes/02-update-task-status-format.md +21 -0
- package/RAF/ahnwrk-worktree-weaver/outcomes/03-worktree-auto-discovery.md +34 -0
- package/RAF/ahnwrk-worktree-weaver/outcomes/04-fix-pr-description.md +30 -0
- package/RAF/ahnwrk-worktree-weaver/plans/01-remove-co-authored-by.md +26 -0
- package/RAF/ahnwrk-worktree-weaver/plans/02-update-task-status-format.md +27 -0
- package/RAF/ahnwrk-worktree-weaver/plans/03-worktree-auto-discovery.md +37 -0
- package/RAF/ahnwrk-worktree-weaver/plans/04-fix-pr-description.md +50 -0
- package/README.md +56 -10
- package/dist/commands/do.d.ts +15 -0
- package/dist/commands/do.d.ts.map +1 -1
- package/dist/commands/do.js +400 -131
- package/dist/commands/do.js.map +1 -1
- package/dist/commands/migrate.d.ts +14 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +228 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/plan.d.ts.map +1 -1
- package/dist/commands/plan.js +237 -40
- package/dist/commands/plan.js.map +1 -1
- package/dist/commands/status.d.ts.map +1 -1
- package/dist/commands/status.js +221 -47
- package/dist/commands/status.js.map +1 -1
- package/dist/core/claude-runner.d.ts +52 -1
- package/dist/core/claude-runner.d.ts.map +1 -1
- package/dist/core/claude-runner.js +195 -17
- package/dist/core/claude-runner.js.map +1 -1
- package/dist/core/git.d.ts +29 -5
- package/dist/core/git.d.ts.map +1 -1
- package/dist/core/git.js +95 -18
- package/dist/core/git.js.map +1 -1
- package/dist/core/project-manager.d.ts.map +1 -1
- package/dist/core/project-manager.js +2 -2
- package/dist/core/project-manager.js.map +1 -1
- package/dist/core/pull-request.d.ts +84 -0
- package/dist/core/pull-request.d.ts.map +1 -0
- package/dist/core/pull-request.js +414 -0
- package/dist/core/pull-request.js.map +1 -0
- package/dist/core/state-derivation.d.ts +3 -3
- package/dist/core/state-derivation.d.ts.map +1 -1
- package/dist/core/state-derivation.js +18 -14
- package/dist/core/state-derivation.js.map +1 -1
- package/dist/core/worktree.d.ts +120 -0
- package/dist/core/worktree.d.ts.map +1 -0
- package/dist/core/worktree.js +322 -0
- package/dist/core/worktree.js.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/parsers/stream-renderer.d.ts +42 -0
- package/dist/parsers/stream-renderer.d.ts.map +1 -0
- package/dist/parsers/stream-renderer.js +100 -0
- package/dist/parsers/stream-renderer.js.map +1 -0
- package/dist/prompts/amend.d.ts +1 -0
- package/dist/prompts/amend.d.ts.map +1 -1
- package/dist/prompts/amend.js +25 -10
- package/dist/prompts/amend.js.map +1 -1
- package/dist/prompts/execution.js +5 -5
- package/dist/prompts/execution.js.map +1 -1
- package/dist/prompts/planning.d.ts +1 -0
- package/dist/prompts/planning.d.ts.map +1 -1
- package/dist/prompts/planning.js +11 -10
- package/dist/prompts/planning.js.map +1 -1
- package/dist/types/config.d.ts +5 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/ui/project-picker.d.ts +34 -3
- package/dist/ui/project-picker.d.ts.map +1 -1
- package/dist/ui/project-picker.js +78 -10
- package/dist/ui/project-picker.js.map +1 -1
- package/dist/utils/paths.d.ts +38 -43
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +123 -193
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/terminal-symbols.d.ts +2 -2
- package/dist/utils/terminal-symbols.js +3 -3
- package/dist/utils/terminal-symbols.js.map +1 -1
- package/dist/utils/validation.d.ts.map +1 -1
- package/dist/utils/validation.js +2 -8
- package/dist/utils/validation.js.map +1 -1
- package/package.json +1 -1
- package/src/commands/do.ts +471 -142
- package/src/commands/migrate.ts +269 -0
- package/src/commands/plan.ts +264 -40
- package/src/commands/status.ts +252 -45
- package/src/core/claude-runner.ts +270 -17
- package/src/core/git.ts +99 -19
- package/src/core/project-manager.ts +2 -1
- package/src/core/pull-request.ts +480 -0
- package/src/core/state-derivation.ts +18 -14
- package/src/core/worktree.ts +357 -0
- package/src/index.ts +2 -0
- package/src/parsers/stream-renderer.ts +139 -0
- package/src/prompts/amend.ts +27 -9
- package/src/prompts/execution.ts +5 -5
- package/src/prompts/planning.ts +12 -10
- package/src/types/config.ts +6 -0
- package/src/ui/project-picker.ts +110 -10
- package/src/utils/paths.ts +129 -214
- package/src/utils/terminal-symbols.ts +3 -3
- package/src/utils/validation.ts +2 -9
- package/tests/unit/amend-prompt.test.ts +85 -0
- package/tests/unit/claude-runner.test.ts +567 -1
- package/tests/unit/commit-planning-artifacts-worktree.test.ts +327 -0
- package/tests/unit/commit-planning-artifacts.test.ts +303 -35
- package/tests/unit/dependency-integration.test.ts +95 -95
- package/tests/unit/do-blocked-tasks.test.ts +53 -53
- package/tests/unit/do-command.test.ts +39 -132
- package/tests/unit/do-rerun.test.ts +65 -65
- package/tests/unit/do-worktree-cleanup.test.ts +151 -0
- package/tests/unit/execution-prompt.test.ts +71 -60
- package/tests/unit/failure-history.test.ts +19 -19
- package/tests/unit/git-commit-helpers.test.ts +103 -0
- package/tests/unit/git-stash.test.ts +4 -4
- package/tests/unit/migrate-command.test.ts +197 -0
- package/tests/unit/outcome-content.test.ts +20 -20
- package/tests/unit/paths.test.ts +269 -467
- package/tests/unit/plan-amend-worktree-recreate.test.ts +246 -0
- package/tests/unit/plan-command.test.ts +144 -93
- package/tests/unit/planning-prompt.test.ts +41 -4
- package/tests/unit/post-execution-picker.test.ts +251 -0
- package/tests/unit/project-manager.test.ts +20 -8
- package/tests/unit/project-picker.test.ts +425 -42
- package/tests/unit/pull-request.test.ts +852 -0
- package/tests/unit/state-derivation.test.ts +138 -137
- package/tests/unit/status-command.test.ts +344 -76
- package/tests/unit/stream-renderer.test.ts +286 -0
- package/tests/unit/terminal-symbols.test.ts +4 -4
- package/tests/unit/worktree-integration.test.ts +405 -0
- package/tests/unit/worktree.test.ts +523 -0
- package/tests/unit/do-multiproject.test.ts +0 -270
- /package/RAF/{001-raf-task-improvements → aaaaab-raf-task-improvements}/input.md +0 -0
- /package/RAF/{001-raf-task-improvements/outcomes/001-add-decisions-folder.md → aaaaab-raf-task-improvements/outcomes/01-add-decisions-folder.md} +0 -0
- /package/RAF/{001-raf-task-improvements/outcomes/002-fix-write-error-on-shutdown.md → aaaaab-raf-task-improvements/outcomes/02-fix-write-error-on-shutdown.md} +0 -0
- /package/RAF/{001-raf-task-improvements/outcomes/003-stash-changes-on-failure.md → aaaaab-raf-task-improvements/outcomes/03-stash-changes-on-failure.md} +0 -0
- /package/RAF/{001-raf-task-improvements/outcomes/004-add-project-name-to-commits.md → aaaaab-raf-task-improvements/outcomes/04-add-project-name-to-commits.md} +0 -0
- /package/RAF/{001-raf-task-improvements/outcomes/005-add-running-time-display.md → aaaaab-raf-task-improvements/outcomes/05-add-running-time-display.md} +0 -0
- /package/RAF/{001-raf-task-improvements/outcomes/006-add-task-name-to-logs.md → aaaaab-raf-task-improvements/outcomes/06-add-task-name-to-logs.md} +0 -0
- /package/RAF/{001-raf-task-improvements/outcomes/007-show-model-at-task-start.md → aaaaab-raf-task-improvements/outcomes/07-show-model-at-task-start.md} +0 -0
- /package/RAF/{001-raf-task-improvements/outcomes/009-remove-editor-placeholder-text.md → aaaaab-raf-task-improvements/outcomes/09-remove-editor-placeholder-text.md} +0 -0
- /package/RAF/{001-raf-task-improvements → aaaaab-raf-task-improvements}/outcomes/SUMMARY.md +0 -0
- /package/RAF/{001-raf-task-improvements/plans/001-add-decisions-folder.md → aaaaab-raf-task-improvements/plans/01-add-decisions-folder.md} +0 -0
- /package/RAF/{001-raf-task-improvements/plans/002-fix-write-error-on-shutdown.md → aaaaab-raf-task-improvements/plans/02-fix-write-error-on-shutdown.md} +0 -0
- /package/RAF/{001-raf-task-improvements/plans/003-stash-changes-on-failure.md → aaaaab-raf-task-improvements/plans/03-stash-changes-on-failure.md} +0 -0
- /package/RAF/{001-raf-task-improvements/plans/004-add-project-name-to-commits.md → aaaaab-raf-task-improvements/plans/04-add-project-name-to-commits.md} +0 -0
- /package/RAF/{001-raf-task-improvements/plans/005-add-running-time-display.md → aaaaab-raf-task-improvements/plans/05-add-running-time-display.md} +0 -0
- /package/RAF/{001-raf-task-improvements/plans/006-add-task-name-to-logs.md → aaaaab-raf-task-improvements/plans/06-add-task-name-to-logs.md} +0 -0
- /package/RAF/{001-raf-task-improvements/plans/009-remove-editor-placeholder-text.md → aaaaab-raf-task-improvements/plans/09-remove-editor-placeholder-text.md} +0 -0
- /package/RAF/{002-raf-task-improvements-execution → aaaaac-raf-task-improvements-execution}/decisions/DECISIONS.md +0 -0
- /package/RAF/{002-raf-task-improvements-execution → aaaaac-raf-task-improvements-execution}/input.md +0 -0
- /package/RAF/{002-raf-task-improvements-execution/outcomes/001-commit-show-model-at-task-start.md → aaaaac-raf-task-improvements-execution/outcomes/01-commit-show-model-at-task-start.md} +0 -0
- /package/RAF/{002-raf-task-improvements-execution/outcomes/002-delete-skipped-plan.md → aaaaac-raf-task-improvements-execution/outcomes/02-delete-skipped-plan.md} +0 -0
- /package/RAF/{002-raf-task-improvements-execution → aaaaac-raf-task-improvements-execution}/outcomes/SUMMARY.md +0 -0
- /package/RAF/{002-raf-task-improvements-execution/plans/001-commit-show-model-at-task-start.md → aaaaac-raf-task-improvements-execution/plans/01-commit-show-model-at-task-start.md} +0 -0
- /package/RAF/{002-raf-task-improvements-execution/plans/002-delete-skipped-plan.md → aaaaac-raf-task-improvements-execution/plans/02-delete-skipped-plan.md} +0 -0
- /package/RAF/{003-multi-project-execution → aaaaad-multi-project-execution}/decisions/DECISIONS.md +0 -0
- /package/RAF/{003-multi-project-execution → aaaaad-multi-project-execution}/input.md +0 -0
- /package/RAF/{003-multi-project-execution/outcomes/001-remove-state-json.md → aaaaad-multi-project-execution/outcomes/01-remove-state-json.md} +0 -0
- /package/RAF/{003-multi-project-execution/outcomes/002-update-raf-status.md → aaaaad-multi-project-execution/outcomes/02-update-raf-status.md} +0 -0
- /package/RAF/{003-multi-project-execution/outcomes/003-simplify-git-logic.md → aaaaad-multi-project-execution/outcomes/03-simplify-git-logic.md} +0 -0
- /package/RAF/{003-multi-project-execution/outcomes/004-auto-commit-planning.md → aaaaad-multi-project-execution/outcomes/04-auto-commit-planning.md} +0 -0
- /package/RAF/{003-multi-project-execution/outcomes/005-rerun-failed-tasks.md → aaaaad-multi-project-execution/outcomes/05-rerun-failed-tasks.md} +0 -0
- /package/RAF/{003-multi-project-execution/outcomes/006-multi-project-execution.md → aaaaad-multi-project-execution/outcomes/06-multi-project-execution.md} +0 -0
- /package/RAF/{003-multi-project-execution/outcomes/007-verify-timeout.md → aaaaad-multi-project-execution/outcomes/07-verify-timeout.md} +0 -0
- /package/RAF/{003-multi-project-execution/outcomes/008-move-decisions-file.md → aaaaad-multi-project-execution/outcomes/08-move-decisions-file.md} +0 -0
- /package/RAF/{003-multi-project-execution → aaaaad-multi-project-execution}/outcomes/SUMMARY.md +0 -0
- /package/RAF/{003-multi-project-execution/plans/001-remove-state-json.md → aaaaad-multi-project-execution/plans/01-remove-state-json.md} +0 -0
- /package/RAF/{003-multi-project-execution/plans/002-update-raf-status.md → aaaaad-multi-project-execution/plans/02-update-raf-status.md} +0 -0
- /package/RAF/{003-multi-project-execution/plans/003-simplify-git-logic.md → aaaaad-multi-project-execution/plans/03-simplify-git-logic.md} +0 -0
- /package/RAF/{003-multi-project-execution/plans/004-auto-commit-planning.md → aaaaad-multi-project-execution/plans/04-auto-commit-planning.md} +0 -0
- /package/RAF/{003-multi-project-execution/plans/005-rerun-failed-tasks.md → aaaaad-multi-project-execution/plans/05-rerun-failed-tasks.md} +0 -0
- /package/RAF/{003-multi-project-execution/plans/006-multi-project-execution.md → aaaaad-multi-project-execution/plans/06-multi-project-execution.md} +0 -0
- /package/RAF/{003-multi-project-execution/plans/007-verify-timeout.md → aaaaad-multi-project-execution/plans/07-verify-timeout.md} +0 -0
- /package/RAF/{003-multi-project-execution/plans/008-move-decisions-file.md → aaaaad-multi-project-execution/plans/08-move-decisions-file.md} +0 -0
- /package/RAF/{004-task-naming-optimization → aaaaae-task-naming-optimization}/decisions.md +0 -0
- /package/RAF/{004-task-naming-optimization → aaaaae-task-naming-optimization}/input.md +0 -0
- /package/RAF/{004-task-naming-optimization/outcomes/001-remove-summary-file.md → aaaaae-task-naming-optimization/outcomes/01-remove-summary-file.md} +0 -0
- /package/RAF/{004-task-naming-optimization/outcomes/002-base36-project-numbering.md → aaaaae-task-naming-optimization/outcomes/02-base36-project-numbering.md} +0 -0
- /package/RAF/{004-task-naming-optimization/outcomes/003-improve-haiku-prompt.md → aaaaae-task-naming-optimization/outcomes/03-improve-haiku-prompt.md} +0 -0
- /package/RAF/{004-task-naming-optimization → aaaaae-task-naming-optimization}/outcomes/SUMMARY.md +0 -0
- /package/RAF/{004-task-naming-optimization/plans/001-remove-summary-file.md → aaaaae-task-naming-optimization/plans/01-remove-summary-file.md} +0 -0
- /package/RAF/{004-task-naming-optimization/plans/002-base36-project-numbering.md → aaaaae-task-naming-optimization/plans/02-base36-project-numbering.md} +0 -0
- /package/RAF/{004-task-naming-optimization/plans/003-improve-haiku-prompt.md → aaaaae-task-naming-optimization/plans/03-improve-haiku-prompt.md} +0 -0
- /package/RAF/{005-task-naming-improvements → aaaaaf-task-naming-improvements}/decisions.md +0 -0
- /package/RAF/{005-task-naming-improvements → aaaaaf-task-naming-improvements}/input.md +0 -0
- /package/RAF/{005-task-naming-improvements/outcomes/001-enhance-identifier-resolution.md → aaaaaf-task-naming-improvements/outcomes/01-enhance-identifier-resolution.md} +0 -0
- /package/RAF/{005-task-naming-improvements/outcomes/002-add-identifier-support-to-status.md → aaaaaf-task-naming-improvements/outcomes/02-add-identifier-support-to-status.md} +0 -0
- /package/RAF/{005-task-naming-improvements/outcomes/003-update-do-for-full-folder-names.md → aaaaaf-task-naming-improvements/outcomes/03-update-do-for-full-folder-names.md} +0 -0
- /package/RAF/{005-task-naming-improvements/outcomes/004-implement-amend-flag-for-plan.md → aaaaaf-task-naming-improvements/outcomes/04-implement-amend-flag-for-plan.md} +0 -0
- /package/RAF/{005-task-naming-improvements/outcomes/005-commit-outcomes-on-complete.md → aaaaaf-task-naming-improvements/outcomes/05-commit-outcomes-on-complete.md} +0 -0
- /package/RAF/{005-task-naming-improvements/outcomes/006-update-execution-prompt-commit-schema.md → aaaaaf-task-naming-improvements/outcomes/06-update-execution-prompt-commit-schema.md} +0 -0
- /package/RAF/{005-task-naming-improvements/outcomes/007-allow-pending-task-amendments.md → aaaaaf-task-naming-improvements/outcomes/07-allow-pending-task-amendments.md} +0 -0
- /package/RAF/{005-task-naming-improvements/outcomes/008-fix-timeout-label.md → aaaaaf-task-naming-improvements/outcomes/08-fix-timeout-label.md} +0 -0
- /package/RAF/{005-task-naming-improvements/plans/001-enhance-identifier-resolution.md → aaaaaf-task-naming-improvements/plans/01-enhance-identifier-resolution.md} +0 -0
- /package/RAF/{005-task-naming-improvements/plans/002-add-identifier-support-to-status.md → aaaaaf-task-naming-improvements/plans/02-add-identifier-support-to-status.md} +0 -0
- /package/RAF/{005-task-naming-improvements/plans/003-update-do-for-full-folder-names.md → aaaaaf-task-naming-improvements/plans/03-update-do-for-full-folder-names.md} +0 -0
- /package/RAF/{005-task-naming-improvements/plans/004-implement-amend-flag-for-plan.md → aaaaaf-task-naming-improvements/plans/04-implement-amend-flag-for-plan.md} +0 -0
- /package/RAF/{005-task-naming-improvements/plans/005-commit-outcomes-on-complete.md → aaaaaf-task-naming-improvements/plans/05-commit-outcomes-on-complete.md} +0 -0
- /package/RAF/{005-task-naming-improvements/plans/006-update-execution-prompt-commit-schema.md → aaaaaf-task-naming-improvements/plans/06-update-execution-prompt-commit-schema.md} +0 -0
- /package/RAF/{005-task-naming-improvements/plans/007-allow-pending-task-amendments.md → aaaaaf-task-naming-improvements/plans/07-allow-pending-task-amendments.md} +0 -0
- /package/RAF/{005-task-naming-improvements/plans/008-fix-timeout-label.md → aaaaaf-task-naming-improvements/plans/08-fix-timeout-label.md} +0 -0
- /package/RAF/{006-fix-double-summary-headers → aaaaag-fix-double-summary-headers}/decisions.md +0 -0
- /package/RAF/{006-fix-double-summary-headers → aaaaag-fix-double-summary-headers}/input.md +0 -0
- /package/RAF/{006-fix-double-summary-headers/outcomes/001-fix-double-summary-headers.md → aaaaag-fix-double-summary-headers/outcomes/01-fix-double-summary-headers.md} +0 -0
- /package/RAF/{006-fix-double-summary-headers/outcomes/002-update-readme-for-npm.md → aaaaag-fix-double-summary-headers/outcomes/02-update-readme-for-npm.md} +0 -0
- /package/RAF/{006-fix-double-summary-headers/outcomes/003-npm-publish-instructions.md → aaaaag-fix-double-summary-headers/outcomes/03-npm-publish-instructions.md} +0 -0
- /package/RAF/{006-fix-double-summary-headers/outcomes/004-flexible-project-lookup.md → aaaaag-fix-double-summary-headers/outcomes/04-flexible-project-lookup.md} +0 -0
- /package/RAF/{006-fix-double-summary-headers/plans/001-fix-double-summary-headers.md → aaaaag-fix-double-summary-headers/plans/01-fix-double-summary-headers.md} +0 -0
- /package/RAF/{006-fix-double-summary-headers/plans/002-update-readme-for-npm.md → aaaaag-fix-double-summary-headers/plans/02-update-readme-for-npm.md} +0 -0
- /package/RAF/{006-fix-double-summary-headers/plans/003-npm-publish-instructions.md → aaaaag-fix-double-summary-headers/plans/03-npm-publish-instructions.md} +0 -0
- /package/RAF/{006-fix-double-summary-headers/plans/004-flexible-project-lookup.md → aaaaag-fix-double-summary-headers/plans/04-flexible-project-lookup.md} +0 -0
- /package/RAF/{007-improve-outcome-format → aaaaah-improve-outcome-format}/decisions.md +0 -0
- /package/RAF/{007-improve-outcome-format → aaaaah-improve-outcome-format}/input.md +0 -0
- /package/RAF/{007-improve-outcome-format/outcomes/001-update-execution-prompt.md → aaaaah-improve-outcome-format/outcomes/01-update-execution-prompt.md} +0 -0
- /package/RAF/{007-improve-outcome-format/outcomes/002-update-state-derivation.md → aaaaah-improve-outcome-format/outcomes/02-update-state-derivation.md} +0 -0
- /package/RAF/{007-improve-outcome-format/outcomes/003-update-do-command-outcome-handling.md → aaaaah-improve-outcome-format/outcomes/03-update-do-command-outcome-handling.md} +0 -0
- /package/RAF/{007-improve-outcome-format/outcomes/004-implement-failure-analysis.md → aaaaah-improve-outcome-format/outcomes/04-implement-failure-analysis.md} +0 -0
- /package/RAF/{007-improve-outcome-format/outcomes/005-update-documentation.md → aaaaah-improve-outcome-format/outcomes/05-update-documentation.md} +0 -0
- /package/RAF/{007-improve-outcome-format/plans/001-update-execution-prompt.md → aaaaah-improve-outcome-format/plans/01-update-execution-prompt.md} +0 -0
- /package/RAF/{007-improve-outcome-format/plans/002-update-state-derivation.md → aaaaah-improve-outcome-format/plans/02-update-state-derivation.md} +0 -0
- /package/RAF/{007-improve-outcome-format/plans/003-update-do-command-outcome-handling.md → aaaaah-improve-outcome-format/plans/03-update-do-command-outcome-handling.md} +0 -0
- /package/RAF/{007-improve-outcome-format/plans/004-implement-failure-analysis.md → aaaaah-improve-outcome-format/plans/04-implement-failure-analysis.md} +0 -0
- /package/RAF/{007-improve-outcome-format/plans/005-update-documentation.md → aaaaah-improve-outcome-format/plans/05-update-documentation.md} +0 -0
- /package/RAF/{008-beautiful-do → aaaaai-beautiful-do}/decisions.md +0 -0
- /package/RAF/{008-beautiful-do → aaaaai-beautiful-do}/input.md +0 -0
- /package/RAF/{008-beautiful-do/outcomes/001-terminal-symbols.md → aaaaai-beautiful-do/outcomes/01-terminal-symbols.md} +0 -0
- /package/RAF/{008-beautiful-do/outcomes/002-refactor-do-output.md → aaaaai-beautiful-do/outcomes/02-refactor-do-output.md} +0 -0
- /package/RAF/{008-beautiful-do/outcomes/003-refactor-status-output.md → aaaaai-beautiful-do/outcomes/03-refactor-status-output.md} +0 -0
- /package/RAF/{008-beautiful-do/outcomes/004-simplify-logger.md → aaaaai-beautiful-do/outcomes/04-simplify-logger.md} +0 -0
- /package/RAF/{008-beautiful-do/outcomes/005-add-tests.md → aaaaai-beautiful-do/outcomes/05-add-tests.md} +0 -0
- /package/RAF/{008-beautiful-do/plans/001-terminal-symbols.md → aaaaai-beautiful-do/plans/01-terminal-symbols.md} +0 -0
- /package/RAF/{008-beautiful-do/plans/002-refactor-do-output.md → aaaaai-beautiful-do/plans/02-refactor-do-output.md} +0 -0
- /package/RAF/{008-beautiful-do/plans/003-refactor-status-output.md → aaaaai-beautiful-do/plans/03-refactor-status-output.md} +0 -0
- /package/RAF/{008-beautiful-do/plans/004-simplify-logger.md → aaaaai-beautiful-do/plans/04-simplify-logger.md} +0 -0
- /package/RAF/{008-beautiful-do/plans/005-add-tests.md → aaaaai-beautiful-do/plans/05-add-tests.md} +0 -0
- /package/RAF/{009-system-promt-ammend → aaaaaj-system-promt-ammend}/decisions.md +0 -0
- /package/RAF/{009-system-promt-ammend → aaaaaj-system-promt-ammend}/input.md +0 -0
- /package/RAF/{009-system-promt-ammend/outcomes/001-model-override.md → aaaaaj-system-promt-ammend/outcomes/01-model-override.md} +0 -0
- /package/RAF/{009-system-promt-ammend/outcomes/002-system-prompt-append.md → aaaaaj-system-promt-ammend/outcomes/02-system-prompt-append.md} +0 -0
- /package/RAF/{009-system-promt-ammend/outcomes/003-retry-context.md → aaaaaj-system-promt-ammend/outcomes/03-retry-context.md} +0 -0
- /package/RAF/{009-system-promt-ammend/plans/001-model-override.md → aaaaaj-system-promt-ammend/plans/01-model-override.md} +0 -0
- /package/RAF/{009-system-promt-ammend/plans/002-system-prompt-append.md → aaaaaj-system-promt-ammend/plans/02-system-prompt-append.md} +0 -0
- /package/RAF/{009-system-promt-ammend/plans/003-retry-context.md → aaaaaj-system-promt-ammend/plans/03-retry-context.md} +0 -0
- /package/RAF/{010-outcome-marker-fallback → aaaabk-outcome-marker-fallback}/decisions.md +0 -0
- /package/RAF/{010-outcome-marker-fallback → aaaabk-outcome-marker-fallback}/input.md +0 -0
- /package/RAF/{010-outcome-marker-fallback/outcomes/001-outcome-file-marker-fallback.md → aaaabk-outcome-marker-fallback/outcomes/01-outcome-file-marker-fallback.md} +0 -0
- /package/RAF/{010-outcome-marker-fallback/outcomes/002-creative-project-naming.md → aaaabk-outcome-marker-fallback/outcomes/02-creative-project-naming.md} +0 -0
- /package/RAF/{010-outcome-marker-fallback/plans/001-outcome-file-marker-fallback.md → aaaabk-outcome-marker-fallback/plans/01-outcome-file-marker-fallback.md} +0 -0
- /package/RAF/{010-outcome-marker-fallback/plans/002-creative-project-naming.md → aaaabk-outcome-marker-fallback/plans/02-creative-project-naming.md} +0 -0
- /package/RAF/{011-do-task-in-commit → aaaabl-do-task-in-commit}/decisions.md +0 -0
- /package/RAF/{011-do-task-in-commit → aaaabl-do-task-in-commit}/input.md +0 -0
- /package/RAF/{011-do-task-in-commit/outcomes/001-update-execution-prompt.md → aaaabl-do-task-in-commit/outcomes/01-update-execution-prompt.md} +0 -0
- /package/RAF/{011-do-task-in-commit/outcomes/002-update-tests.md → aaaabl-do-task-in-commit/outcomes/02-update-tests.md} +0 -0
- /package/RAF/{011-do-task-in-commit/outcomes/003-update-documentation.md → aaaabl-do-task-in-commit/outcomes/03-update-documentation.md} +0 -0
- /package/RAF/{011-do-task-in-commit/plans/001-update-execution-prompt.md → aaaabl-do-task-in-commit/plans/01-update-execution-prompt.md} +0 -0
- /package/RAF/{011-do-task-in-commit/plans/002-update-tests.md → aaaabl-do-task-in-commit/plans/02-update-tests.md} +0 -0
- /package/RAF/{011-do-task-in-commit/plans/003-update-documentation.md → aaaabl-do-task-in-commit/plans/03-update-documentation.md} +0 -0
- /package/RAF/{012-name-picker-buffet → aaaabm-name-picker-buffet}/decisions.md +0 -0
- /package/RAF/{012-name-picker-buffet → aaaabm-name-picker-buffet}/input.md +0 -0
- /package/RAF/{012-name-picker-buffet/outcomes/001-name-picker-for-raf-plan.md → aaaabm-name-picker-buffet/outcomes/01-name-picker-for-raf-plan.md} +0 -0
- /package/RAF/{012-name-picker-buffet/outcomes/002-interactive-project-picker-for-raf-do.md → aaaabm-name-picker-buffet/outcomes/02-interactive-project-picker-for-raf-do.md} +0 -0
- /package/RAF/{012-name-picker-buffet/outcomes/003-raf-status-truncation.md → aaaabm-name-picker-buffet/outcomes/03-raf-status-truncation.md} +0 -0
- /package/RAF/{012-name-picker-buffet/outcomes/004-failure-reason-details.md → aaaabm-name-picker-buffet/outcomes/04-failure-reason-details.md} +0 -0
- /package/RAF/{012-name-picker-buffet/outcomes/005-remove-raf-commits.md → aaaabm-name-picker-buffet/outcomes/05-remove-raf-commits.md} +0 -0
- /package/RAF/{012-name-picker-buffet/outcomes/006-update-execution-prompt-for-commits.md → aaaabm-name-picker-buffet/outcomes/06-update-execution-prompt-for-commits.md} +0 -0
- /package/RAF/{012-name-picker-buffet/outcomes/007-fix-plan-mode-user-prompt.md → aaaabm-name-picker-buffet/outcomes/07-fix-plan-mode-user-prompt.md} +0 -0
- /package/RAF/{012-name-picker-buffet/outcomes/008-add-auto-flag-for-plan-mode.md → aaaabm-name-picker-buffet/outcomes/08-add-auto-flag-for-plan-mode.md} +0 -0
- /package/RAF/{012-name-picker-buffet/plans/001-name-picker-for-raf-plan.md → aaaabm-name-picker-buffet/plans/01-name-picker-for-raf-plan.md} +0 -0
- /package/RAF/{012-name-picker-buffet/plans/002-interactive-project-picker-for-raf-do.md → aaaabm-name-picker-buffet/plans/02-interactive-project-picker-for-raf-do.md} +0 -0
- /package/RAF/{012-name-picker-buffet/plans/003-raf-status-truncation.md → aaaabm-name-picker-buffet/plans/03-raf-status-truncation.md} +0 -0
- /package/RAF/{012-name-picker-buffet/plans/004-failure-reason-details.md → aaaabm-name-picker-buffet/plans/04-failure-reason-details.md} +0 -0
- /package/RAF/{012-name-picker-buffet/plans/005-remove-raf-commits.md → aaaabm-name-picker-buffet/plans/05-remove-raf-commits.md} +0 -0
- /package/RAF/{012-name-picker-buffet/plans/006-update-execution-prompt-for-commits.md → aaaabm-name-picker-buffet/plans/06-update-execution-prompt-for-commits.md} +0 -0
- /package/RAF/{012-name-picker-buffet/plans/007-fix-plan-mode-user-prompt.md → aaaabm-name-picker-buffet/plans/07-fix-plan-mode-user-prompt.md} +0 -0
- /package/RAF/{012-name-picker-buffet/plans/008-add-auto-flag-for-plan-mode.md → aaaabm-name-picker-buffet/plans/08-add-auto-flag-for-plan-mode.md} +0 -0
- /package/RAF/{013-dependencies-watchdog → aaaabn-dependencies-watchdog}/decisions.md +0 -0
- /package/RAF/{013-dependencies-watchdog → aaaabn-dependencies-watchdog}/input.md +0 -0
- /package/RAF/{013-dependencies-watchdog/outcomes/001-define-dependency-syntax.md → aaaabn-dependencies-watchdog/outcomes/01-define-dependency-syntax.md} +0 -0
- /package/RAF/{013-dependencies-watchdog/outcomes/002-update-planning-prompts.md → aaaabn-dependencies-watchdog/outcomes/02-update-planning-prompts.md} +0 -0
- /package/RAF/{013-dependencies-watchdog/outcomes/003-parse-dependencies-update-state.md → aaaabn-dependencies-watchdog/outcomes/03-parse-dependencies-update-state.md} +0 -0
- /package/RAF/{013-dependencies-watchdog/outcomes/004-implement-dependency-checking-in-do.md → aaaabn-dependencies-watchdog/outcomes/04-implement-dependency-checking-in-do.md} +0 -0
- /package/RAF/{013-dependencies-watchdog/outcomes/005-update-execution-prompts.md → aaaabn-dependencies-watchdog/outcomes/05-update-execution-prompts.md} +0 -0
- /package/RAF/{013-dependencies-watchdog/outcomes/006-add-tests.md → aaaabn-dependencies-watchdog/outcomes/06-add-tests.md} +0 -0
- /package/RAF/{013-dependencies-watchdog/outcomes/007-add-act-alias.md → aaaabn-dependencies-watchdog/outcomes/07-add-act-alias.md} +0 -0
- /package/RAF/{013-dependencies-watchdog/outcomes/008-add-exit-message.md → aaaabn-dependencies-watchdog/outcomes/08-add-exit-message.md} +0 -0
- /package/RAF/{013-dependencies-watchdog/plans/001-define-dependency-syntax.md → aaaabn-dependencies-watchdog/plans/01-define-dependency-syntax.md} +0 -0
- /package/RAF/{013-dependencies-watchdog/plans/002-update-planning-prompts.md → aaaabn-dependencies-watchdog/plans/02-update-planning-prompts.md} +0 -0
- /package/RAF/{013-dependencies-watchdog/plans/003-parse-dependencies-update-state.md → aaaabn-dependencies-watchdog/plans/03-parse-dependencies-update-state.md} +0 -0
- /package/RAF/{013-dependencies-watchdog/plans/004-implement-dependency-checking-in-do.md → aaaabn-dependencies-watchdog/plans/04-implement-dependency-checking-in-do.md} +0 -0
- /package/RAF/{013-dependencies-watchdog/plans/005-update-execution-prompts.md → aaaabn-dependencies-watchdog/plans/05-update-execution-prompts.md} +0 -0
- /package/RAF/{013-dependencies-watchdog/plans/006-add-tests.md → aaaabn-dependencies-watchdog/plans/06-add-tests.md} +0 -0
- /package/RAF/{013-dependencies-watchdog/plans/007-add-act-alias.md → aaaabn-dependencies-watchdog/plans/07-add-act-alias.md} +0 -0
- /package/RAF/{013-dependencies-watchdog/plans/008-add-exit-message.md → aaaabn-dependencies-watchdog/plans/08-add-exit-message.md} +0 -0
- /package/RAF/{014-watchdog → aaaabo-watchdog}/decisions.md +0 -0
- /package/RAF/{014-watchdog → aaaabo-watchdog}/input.md +0 -0
- /package/RAF/{014-watchdog/outcomes/001-amend-flag-position.md → aaaabo-watchdog/outcomes/01-amend-flag-position.md} +0 -0
- /package/RAF/{014-watchdog/outcomes/002-details-only-on-failure.md → aaaabo-watchdog/outcomes/02-details-only-on-failure.md} +0 -0
- /package/RAF/{014-watchdog/plans/001-amend-flag-position.md → aaaabo-watchdog/plans/01-amend-flag-position.md} +0 -0
- /package/RAF/{014-watchdog/plans/002-details-only-on-failure.md → aaaabo-watchdog/plans/02-details-only-on-failure.md} +0 -0
- /package/RAF/{015-name-lottery → aaaabp-name-lottery}/decisions.md +0 -0
- /package/RAF/{015-name-lottery → aaaabp-name-lottery}/input.md +0 -0
- /package/RAF/{015-name-lottery/outcomes/001-auto-pick-project-name.md → aaaabp-name-lottery/outcomes/01-auto-pick-project-name.md} +0 -0
- /package/RAF/{015-name-lottery/outcomes/002-mention-plan-files-in-commit.md → aaaabp-name-lottery/outcomes/02-mention-plan-files-in-commit.md} +0 -0
- /package/RAF/{015-name-lottery/outcomes/003-fix-input-md-in-amend-flow.md → aaaabp-name-lottery/outcomes/03-fix-input-md-in-amend-flow.md} +0 -0
- /package/RAF/{015-name-lottery/plans/001-auto-pick-project-name.md → aaaabp-name-lottery/plans/01-auto-pick-project-name.md} +0 -0
- /package/RAF/{015-name-lottery/plans/002-mention-plan-files-in-commit.md → aaaabp-name-lottery/plans/02-mention-plan-files-in-commit.md} +0 -0
- /package/RAF/{015-name-lottery/plans/003-fix-input-md-in-amend-flow.md → aaaabp-name-lottery/plans/03-fix-input-md-in-amend-flow.md} +0 -0
- /package/RAF/{016-planning-scalpel → aaaabq-planning-scalpel}/decisions.md +0 -0
- /package/RAF/{016-planning-scalpel → aaaabq-planning-scalpel}/input.md +0 -0
- /package/RAF/{016-planning-scalpel/outcomes/001-update-git-commit-instructions.md → aaaabq-planning-scalpel/outcomes/01-update-git-commit-instructions.md} +0 -0
- /package/RAF/{016-planning-scalpel/plans/001-update-git-commit-instructions.md → aaaabq-planning-scalpel/plans/01-update-git-commit-instructions.md} +0 -0
- /package/RAF/{017-decision-vault → aaaabr-decision-vault}/decisions.md +0 -0
- /package/RAF/{017-decision-vault → aaaabr-decision-vault}/input.md +0 -0
- /package/RAF/{017-decision-vault/outcomes/001-create-git-commit-utility.md → aaaabr-decision-vault/outcomes/01-create-git-commit-utility.md} +0 -0
- /package/RAF/{017-decision-vault/outcomes/002-integrate-commit-into-plan.md → aaaabr-decision-vault/outcomes/02-integrate-commit-into-plan.md} +0 -0
- /package/RAF/{017-decision-vault/outcomes/003-add-tests-for-planning-commit.md → aaaabr-decision-vault/outcomes/03-add-tests-for-planning-commit.md} +0 -0
- /package/RAF/{017-decision-vault/plans/001-create-git-commit-utility.md → aaaabr-decision-vault/plans/01-create-git-commit-utility.md} +0 -0
- /package/RAF/{017-decision-vault/plans/002-integrate-commit-into-plan.md → aaaabr-decision-vault/plans/02-integrate-commit-into-plan.md} +0 -0
- /package/RAF/{017-decision-vault/plans/003-add-tests-for-planning-commit.md → aaaabr-decision-vault/plans/03-add-tests-for-planning-commit.md} +0 -0
- /package/RAF/{018-workflow-forge → aaaabs-workflow-forge}/decisions.md +0 -0
- /package/RAF/{018-workflow-forge → aaaabs-workflow-forge}/input.md +0 -0
- /package/RAF/{018-workflow-forge/outcomes/001-add-task-number-progress.md → aaaabs-workflow-forge/outcomes/01-add-task-number-progress.md} +0 -0
- /package/RAF/{018-workflow-forge/outcomes/002-update-plan-do-prompts.md → aaaabs-workflow-forge/outcomes/02-update-plan-do-prompts.md} +0 -0
- /package/RAF/{018-workflow-forge/plans/001-add-task-number-progress.md → aaaabs-workflow-forge/plans/01-add-task-number-progress.md} +0 -0
- /package/RAF/{018-workflow-forge/plans/002-update-plan-do-prompts.md → aaaabs-workflow-forge/plans/02-update-plan-do-prompts.md} +0 -0
package/dist/commands/do.js
CHANGED
|
@@ -1,21 +1,25 @@
|
|
|
1
1
|
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
2
3
|
import { Command } from 'commander';
|
|
4
|
+
import { select } from '@inquirer/prompts';
|
|
3
5
|
import { ProjectManager } from '../core/project-manager.js';
|
|
4
6
|
import { ClaudeRunner } from '../core/claude-runner.js';
|
|
5
7
|
import { shutdownHandler } from '../core/shutdown-handler.js';
|
|
6
|
-
import { stashChanges, hasUncommittedChanges } from '../core/git.js';
|
|
8
|
+
import { stashChanges, hasUncommittedChanges, isGitRepo, getHeadCommitHash } from '../core/git.js';
|
|
7
9
|
import { getExecutionPrompt } from '../prompts/execution.js';
|
|
8
10
|
import { parseOutput, isRetryableFailure } from '../parsers/output-parser.js';
|
|
9
11
|
import { validatePlansExist, resolveModelOption } from '../utils/validation.js';
|
|
10
|
-
import { getRafDir, extractProjectNumber, extractProjectName, extractTaskNameFromPlanFile, resolveProjectIdentifierWithDetails, getOutcomeFilePath } from '../utils/paths.js';
|
|
11
|
-
import { pickPendingProject, getPendingProjects } from '../ui/project-picker.js';
|
|
12
|
+
import { getRafDir, extractProjectNumber, extractProjectName, extractTaskNameFromPlanFile, resolveProjectIdentifierWithDetails, getOutcomeFilePath, parseProjectPrefix } from '../utils/paths.js';
|
|
13
|
+
import { pickPendingProject, getPendingProjects, getPendingWorktreeProjects } from '../ui/project-picker.js';
|
|
12
14
|
import { logger } from '../utils/logger.js';
|
|
13
15
|
import { getConfig } from '../utils/config.js';
|
|
14
16
|
import { createTaskTimer, formatElapsedTime } from '../utils/timer.js';
|
|
15
17
|
import { createStatusLine } from '../utils/status-line.js';
|
|
16
|
-
import {
|
|
17
|
-
import { deriveProjectState, getNextExecutableTask, getDerivedStats, getDerivedStatsForTasks, isProjectComplete, hasProjectFailed, parseOutcomeStatus, } from '../core/state-derivation.js';
|
|
18
|
+
import { formatProjectHeader, formatSummary, formatTaskProgress, } from '../utils/terminal-symbols.js';
|
|
19
|
+
import { deriveProjectState, discoverProjects, getNextExecutableTask, getDerivedStats, getDerivedStatsForTasks, isProjectComplete, hasProjectFailed, parseOutcomeStatus, } from '../core/state-derivation.js';
|
|
18
20
|
import { analyzeFailure } from '../core/failure-analyzer.js';
|
|
21
|
+
import { getRepoRoot, getRepoBasename, getCurrentBranch, computeWorktreePath, computeWorktreeBaseDir, validateWorktree, listWorktreeProjects, mergeWorktreeBranch, removeWorktree, } from '../core/worktree.js';
|
|
22
|
+
import { createPullRequest, prPreflight } from '../core/pull-request.js';
|
|
19
23
|
/**
|
|
20
24
|
* Format failure history for console output.
|
|
21
25
|
* Shows attempts that failed before eventual success or final failure.
|
|
@@ -38,23 +42,25 @@ export function formatRetryHistoryForConsole(taskId, taskName, failureHistory, f
|
|
|
38
42
|
}
|
|
39
43
|
export function createDoCommand() {
|
|
40
44
|
const command = new Command('do')
|
|
41
|
-
.description('Execute planned tasks for
|
|
45
|
+
.description('Execute planned tasks for a project')
|
|
42
46
|
.alias('act')
|
|
43
|
-
.argument('[
|
|
47
|
+
.argument('[project]', 'Project identifier: ID (00j3k1), name (my-project), or folder (00j3k1-my-project)')
|
|
44
48
|
.option('-t, --timeout <minutes>', 'Timeout per task in minutes', '60')
|
|
45
49
|
.option('-v, --verbose', 'Show full Claude output')
|
|
46
50
|
.option('-d, --debug', 'Save all logs and show debug output')
|
|
47
51
|
.option('-f, --force', 'Re-run all tasks regardless of status')
|
|
48
52
|
.option('-m, --model <name>', 'Claude model to use (sonnet, haiku, opus)')
|
|
49
53
|
.option('--sonnet', 'Use Sonnet model (shorthand for --model sonnet)')
|
|
50
|
-
.
|
|
51
|
-
|
|
54
|
+
.option('-w, --worktree', 'Execute tasks in a git worktree')
|
|
55
|
+
.action(async (project, options) => {
|
|
56
|
+
await runDoCommand(project, options);
|
|
52
57
|
});
|
|
53
58
|
return command;
|
|
54
59
|
}
|
|
55
|
-
async function runDoCommand(
|
|
60
|
+
async function runDoCommand(projectIdentifierArg, options) {
|
|
56
61
|
const rafDir = getRafDir();
|
|
57
|
-
let
|
|
62
|
+
let projectIdentifier = projectIdentifierArg;
|
|
63
|
+
let worktreeMode = options.worktree ?? false;
|
|
58
64
|
// Validate and resolve model option
|
|
59
65
|
let model;
|
|
60
66
|
try {
|
|
@@ -64,24 +70,61 @@ async function runDoCommand(projectIdentifiersArg, options) {
|
|
|
64
70
|
logger.error(error.message);
|
|
65
71
|
process.exit(1);
|
|
66
72
|
}
|
|
67
|
-
//
|
|
68
|
-
|
|
69
|
-
|
|
73
|
+
// Variables for worktree context (set when --worktree is used)
|
|
74
|
+
let worktreeRoot;
|
|
75
|
+
let originalBranch;
|
|
76
|
+
if (worktreeMode) {
|
|
77
|
+
// Validate git repo
|
|
78
|
+
const repoRoot = getRepoRoot();
|
|
79
|
+
if (!repoRoot) {
|
|
80
|
+
logger.error('--worktree requires a git repository');
|
|
81
|
+
process.exit(1);
|
|
82
|
+
}
|
|
83
|
+
const repoBasename = getRepoBasename();
|
|
84
|
+
const rafRelativePath = path.relative(repoRoot, rafDir);
|
|
85
|
+
// Record original branch before any worktree operations
|
|
86
|
+
originalBranch = getCurrentBranch() ?? undefined;
|
|
87
|
+
if (!projectIdentifier) {
|
|
88
|
+
// Auto-discovery flow
|
|
89
|
+
const selected = await discoverAndPickWorktreeProject(repoBasename, rafDir, rafRelativePath);
|
|
90
|
+
if (!selected) {
|
|
91
|
+
process.exit(0);
|
|
92
|
+
}
|
|
93
|
+
worktreeRoot = selected.worktreeRoot;
|
|
94
|
+
projectIdentifier = selected.projectFolder;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Handle no project identifier (non-worktree mode) - show interactive picker
|
|
98
|
+
if (!projectIdentifier) {
|
|
99
|
+
// Discover worktree projects for the current repo (if in a git repo)
|
|
100
|
+
let worktreeProjects = [];
|
|
101
|
+
const repoRoot = getRepoRoot();
|
|
102
|
+
if (repoRoot) {
|
|
103
|
+
const repoBasename = getRepoBasename();
|
|
104
|
+
const rafRelativePath = path.relative(repoRoot, rafDir);
|
|
105
|
+
worktreeProjects = getPendingWorktreeProjects(repoBasename, rafRelativePath);
|
|
106
|
+
}
|
|
107
|
+
// Check if there are any pending projects (local or worktree)
|
|
70
108
|
const pendingProjects = getPendingProjects(rafDir);
|
|
71
|
-
if (pendingProjects.length === 0) {
|
|
109
|
+
if (pendingProjects.length === 0 && worktreeProjects.length === 0) {
|
|
72
110
|
logger.info('No pending projects found.');
|
|
73
111
|
logger.info("Run 'raf plan' to create a new project.");
|
|
74
112
|
process.exit(0);
|
|
75
113
|
}
|
|
76
114
|
try {
|
|
77
|
-
const selectedProject = await pickPendingProject(rafDir);
|
|
115
|
+
const selectedProject = await pickPendingProject(rafDir, worktreeProjects);
|
|
78
116
|
if (!selectedProject) {
|
|
79
|
-
// This shouldn't happen since we already checked pendingProjects.length
|
|
80
117
|
logger.info('No pending projects found.');
|
|
81
118
|
process.exit(0);
|
|
82
119
|
}
|
|
83
120
|
// Use the selected project
|
|
84
|
-
|
|
121
|
+
projectIdentifier = selectedProject.folder;
|
|
122
|
+
// If a worktree project was selected, auto-switch to worktree mode
|
|
123
|
+
if (selectedProject.source === 'worktree' && selectedProject.worktreeRoot) {
|
|
124
|
+
worktreeMode = true;
|
|
125
|
+
worktreeRoot = selectedProject.worktreeRoot;
|
|
126
|
+
originalBranch = getCurrentBranch() ?? undefined;
|
|
127
|
+
}
|
|
85
128
|
}
|
|
86
129
|
catch (error) {
|
|
87
130
|
// Handle Ctrl+C (user cancellation)
|
|
@@ -91,45 +134,101 @@ async function runDoCommand(projectIdentifiersArg, options) {
|
|
|
91
134
|
throw error;
|
|
92
135
|
}
|
|
93
136
|
}
|
|
94
|
-
// Resolve
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
const
|
|
137
|
+
// Resolve project identifier
|
|
138
|
+
let resolvedProject;
|
|
139
|
+
if (worktreeMode) {
|
|
140
|
+
// Worktree mode: resolve project inside the worktree
|
|
141
|
+
const repoRoot = getRepoRoot();
|
|
142
|
+
const repoBasename = getRepoBasename();
|
|
143
|
+
const rafRelativePath = path.relative(repoRoot, rafDir);
|
|
144
|
+
// If worktreeRoot was set by auto-discovery, use it directly
|
|
145
|
+
if (worktreeRoot) {
|
|
146
|
+
const wtRafDir = path.join(worktreeRoot, rafRelativePath);
|
|
147
|
+
const result = resolveProjectIdentifierWithDetails(wtRafDir, projectIdentifier);
|
|
148
|
+
if (!result.path) {
|
|
149
|
+
logger.error(`Project not found in worktree: ${projectIdentifier}`);
|
|
150
|
+
process.exit(1);
|
|
151
|
+
}
|
|
152
|
+
const projectName = extractProjectName(result.path) ?? projectIdentifier;
|
|
153
|
+
resolvedProject = { identifier: projectIdentifier, path: result.path, name: projectName };
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
// Explicit identifier: resolve from main repo to get folder name, then validate worktree
|
|
157
|
+
const mainResult = resolveProjectIdentifierWithDetails(rafDir, projectIdentifier);
|
|
158
|
+
let projectFolderName;
|
|
159
|
+
if (mainResult.path) {
|
|
160
|
+
// Found in main repo - use its folder name
|
|
161
|
+
projectFolderName = path.basename(mainResult.path);
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
// Not found in main repo - try to find it in worktrees directly
|
|
165
|
+
// This handles projects that only exist in worktrees
|
|
166
|
+
const worktreeBaseDir = computeWorktreeBaseDir(repoBasename);
|
|
167
|
+
if (!fs.existsSync(worktreeBaseDir)) {
|
|
168
|
+
logger.error(`No worktree found for project "${projectIdentifier}". Did you plan with --worktree?`);
|
|
169
|
+
process.exit(1);
|
|
170
|
+
}
|
|
171
|
+
// Search worktrees for the project
|
|
172
|
+
const wtProjects = listWorktreeProjects(repoBasename);
|
|
173
|
+
let found = false;
|
|
174
|
+
for (const wtProjectDir of wtProjects) {
|
|
175
|
+
const wtPath = computeWorktreePath(repoBasename, wtProjectDir);
|
|
176
|
+
const wtRafDir = path.join(wtPath, rafRelativePath);
|
|
177
|
+
if (!fs.existsSync(wtRafDir))
|
|
178
|
+
continue;
|
|
179
|
+
const resolution = resolveProjectIdentifierWithDetails(wtRafDir, projectIdentifier);
|
|
180
|
+
if (resolution.path) {
|
|
181
|
+
projectFolderName = path.basename(resolution.path);
|
|
182
|
+
worktreeRoot = wtPath;
|
|
183
|
+
found = true;
|
|
184
|
+
break;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
if (!found) {
|
|
188
|
+
logger.error(`No worktree found for project "${projectIdentifier}". Did you plan with --worktree?`);
|
|
189
|
+
process.exit(1);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
// Compute worktree path if not already set
|
|
193
|
+
if (!worktreeRoot) {
|
|
194
|
+
worktreeRoot = computeWorktreePath(repoBasename, projectFolderName);
|
|
195
|
+
}
|
|
196
|
+
// Validate the worktree
|
|
197
|
+
const wtProjectRelPath = path.join(rafRelativePath, projectFolderName);
|
|
198
|
+
const validation = validateWorktree(worktreeRoot, wtProjectRelPath);
|
|
199
|
+
if (!validation.exists || !validation.isValidWorktree) {
|
|
200
|
+
logger.error(`No worktree found for project "${projectIdentifier}". Did you plan with --worktree?`);
|
|
201
|
+
logger.error(`Expected worktree at: ${worktreeRoot}`);
|
|
202
|
+
process.exit(1);
|
|
203
|
+
}
|
|
204
|
+
if (!validation.hasProjectFolder || !validation.hasPlans) {
|
|
205
|
+
logger.error(`Worktree exists but project content is missing.`);
|
|
206
|
+
logger.error(`Expected project folder at: ${validation.projectPath ?? path.join(worktreeRoot, wtProjectRelPath)}`);
|
|
207
|
+
process.exit(1);
|
|
208
|
+
}
|
|
209
|
+
const projectPath = validation.projectPath;
|
|
210
|
+
const projectName = extractProjectName(projectPath) ?? projectIdentifier;
|
|
211
|
+
resolvedProject = { identifier: projectIdentifier, path: projectPath, name: projectName };
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
// Standard mode: resolve from main repo
|
|
216
|
+
const result = resolveProjectIdentifierWithDetails(rafDir, projectIdentifier);
|
|
100
217
|
if (!result.path) {
|
|
101
218
|
if (result.error === 'ambiguous' && result.matches) {
|
|
102
219
|
const matchList = result.matches
|
|
103
220
|
.map((m) => ` - ${m.folder}`)
|
|
104
221
|
.join('\n');
|
|
105
|
-
|
|
106
|
-
identifier,
|
|
107
|
-
error: `Ambiguous project name. Multiple projects match:\n${matchList}\nPlease specify the project ID or full folder name.`,
|
|
108
|
-
});
|
|
222
|
+
logger.error(`${projectIdentifier}: Ambiguous project name. Multiple projects match:\n${matchList}\nPlease specify the project ID or full folder name.`);
|
|
109
223
|
}
|
|
110
224
|
else {
|
|
111
|
-
|
|
225
|
+
logger.error(`${projectIdentifier}: Project not found`);
|
|
112
226
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
const projectPath = result.path;
|
|
116
|
-
// Skip duplicates
|
|
117
|
-
if (seenPaths.has(projectPath)) {
|
|
118
|
-
logger.info(`Skipping duplicate: ${identifier}`);
|
|
119
|
-
continue;
|
|
227
|
+
logger.info("Run 'raf status' to see available projects.");
|
|
228
|
+
process.exit(1);
|
|
120
229
|
}
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
resolvedProjects.push({ identifier, path: projectPath, name: projectName });
|
|
124
|
-
}
|
|
125
|
-
// Report resolution errors
|
|
126
|
-
for (const { identifier, error } of errors) {
|
|
127
|
-
logger.error(`${identifier}: ${error}`);
|
|
128
|
-
}
|
|
129
|
-
if (resolvedProjects.length === 0) {
|
|
130
|
-
logger.error('No valid projects to execute.');
|
|
131
|
-
logger.info("Run 'raf status' to see available projects.");
|
|
132
|
-
process.exit(1);
|
|
230
|
+
const projectName = extractProjectName(result.path) ?? projectIdentifier;
|
|
231
|
+
resolvedProject = { identifier: projectIdentifier, path: result.path, name: projectName };
|
|
133
232
|
}
|
|
134
233
|
// Get configuration
|
|
135
234
|
const config = getConfig();
|
|
@@ -141,60 +240,249 @@ async function runDoCommand(projectIdentifiersArg, options) {
|
|
|
141
240
|
const autoCommit = config.autoCommit;
|
|
142
241
|
// Configure logger
|
|
143
242
|
logger.configure({ verbose, debug });
|
|
144
|
-
//
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
logger.newline();
|
|
148
|
-
}
|
|
149
|
-
// Execute projects
|
|
150
|
-
const results = [];
|
|
151
|
-
const isMultiProject = resolvedProjects.length > 1;
|
|
152
|
-
for (const [i, project] of resolvedProjects.entries()) {
|
|
153
|
-
if (isMultiProject && verbose) {
|
|
154
|
-
logger.info(`=== Project ${i + 1}/${resolvedProjects.length}: ${project.name} ===`);
|
|
155
|
-
logger.newline();
|
|
156
|
-
}
|
|
243
|
+
// Show post-execution picker before task execution (worktree mode only)
|
|
244
|
+
let postAction = 'leave';
|
|
245
|
+
if (worktreeMode && worktreeRoot) {
|
|
157
246
|
try {
|
|
158
|
-
|
|
159
|
-
timeout,
|
|
160
|
-
verbose,
|
|
161
|
-
debug,
|
|
162
|
-
force,
|
|
163
|
-
maxRetries,
|
|
164
|
-
autoCommit,
|
|
165
|
-
showModel: !isMultiProject, // Only show model for single project
|
|
166
|
-
model,
|
|
167
|
-
});
|
|
168
|
-
results.push(result);
|
|
247
|
+
postAction = await pickPostExecutionAction(worktreeRoot);
|
|
169
248
|
}
|
|
170
249
|
catch (error) {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
tasksCompleted: 0,
|
|
177
|
-
totalTasks: 0,
|
|
178
|
-
error: errorMessage,
|
|
179
|
-
});
|
|
180
|
-
logger.error(`Project ${project.name} failed: ${errorMessage}`);
|
|
181
|
-
}
|
|
182
|
-
if (isMultiProject && i < resolvedProjects.length - 1) {
|
|
183
|
-
logger.newline();
|
|
250
|
+
// Handle Ctrl+C (user cancellation)
|
|
251
|
+
if (error instanceof Error && error.message.includes('User force closed')) {
|
|
252
|
+
process.exit(0);
|
|
253
|
+
}
|
|
254
|
+
throw error;
|
|
184
255
|
}
|
|
185
256
|
}
|
|
186
|
-
//
|
|
187
|
-
|
|
188
|
-
|
|
257
|
+
// Execute project
|
|
258
|
+
let result;
|
|
259
|
+
try {
|
|
260
|
+
result = await executeSingleProject(resolvedProject.path, resolvedProject.name, {
|
|
261
|
+
timeout,
|
|
262
|
+
verbose,
|
|
263
|
+
debug,
|
|
264
|
+
force,
|
|
265
|
+
maxRetries,
|
|
266
|
+
autoCommit,
|
|
267
|
+
showModel: true,
|
|
268
|
+
model,
|
|
269
|
+
worktreeCwd: worktreeRoot,
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
catch (error) {
|
|
273
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
274
|
+
logger.error(`Project ${resolvedProject.name} failed: ${errorMessage}`);
|
|
275
|
+
process.exit(1);
|
|
276
|
+
}
|
|
277
|
+
// Execute post-execution action based on picker choice
|
|
278
|
+
if (worktreeMode && worktreeRoot) {
|
|
279
|
+
const worktreeBranch = path.basename(worktreeRoot);
|
|
280
|
+
if (result.success) {
|
|
281
|
+
await executePostAction(postAction, worktreeRoot, worktreeBranch, originalBranch, resolvedProject.path);
|
|
282
|
+
}
|
|
283
|
+
else {
|
|
284
|
+
if (postAction !== 'leave') {
|
|
285
|
+
logger.newline();
|
|
286
|
+
logger.info(`Skipping post-execution action — project has failures. Branch "${worktreeBranch}" is available for inspection.`);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
189
289
|
}
|
|
190
290
|
// Exit with appropriate code
|
|
191
|
-
|
|
192
|
-
|
|
291
|
+
if (!result.success) {
|
|
292
|
+
process.exit(1);
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Show an interactive picker for the post-execution action in worktree mode.
|
|
297
|
+
* Presented before task execution so the user declares intent upfront.
|
|
298
|
+
*
|
|
299
|
+
* If "Create PR" is chosen, runs preflight checks immediately. If preflight fails,
|
|
300
|
+
* warns the user and falls back to re-prompting.
|
|
301
|
+
*/
|
|
302
|
+
export async function pickPostExecutionAction(worktreeRoot) {
|
|
303
|
+
const worktreeBranch = path.basename(worktreeRoot);
|
|
304
|
+
const chosen = await select({
|
|
305
|
+
message: `After tasks complete, what should happen with branch "${worktreeBranch}"?`,
|
|
306
|
+
choices: [
|
|
307
|
+
{ name: 'Merge into current branch', value: 'merge' },
|
|
308
|
+
{ name: 'Create a GitHub PR', value: 'pr' },
|
|
309
|
+
{ name: 'Leave branch as-is', value: 'leave' },
|
|
310
|
+
],
|
|
311
|
+
});
|
|
312
|
+
// Early preflight check for PR option
|
|
313
|
+
if (chosen === 'pr') {
|
|
314
|
+
const preflight = prPreflight(worktreeBranch, worktreeRoot);
|
|
315
|
+
if (!preflight.ready) {
|
|
316
|
+
logger.warn(`PR preflight failed: ${preflight.error}`);
|
|
317
|
+
logger.warn('Falling back to "Leave branch" — you can create a PR manually later.');
|
|
318
|
+
return 'leave';
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
return chosen;
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Execute the chosen post-execution action.
|
|
325
|
+
* Called after all tasks succeed.
|
|
326
|
+
*/
|
|
327
|
+
async function executePostAction(action, worktreeRoot, worktreeBranch, originalBranch, projectPath) {
|
|
328
|
+
switch (action) {
|
|
329
|
+
case 'merge': {
|
|
330
|
+
// Clean up worktree before merge (merge uses branch, not directory)
|
|
331
|
+
const cleanupResult = removeWorktree(worktreeRoot);
|
|
332
|
+
if (cleanupResult.success) {
|
|
333
|
+
logger.info(`Cleaned up worktree: ${worktreeRoot}`);
|
|
334
|
+
}
|
|
335
|
+
else {
|
|
336
|
+
logger.warn(`Could not clean up worktree: ${cleanupResult.error}`);
|
|
337
|
+
}
|
|
338
|
+
if (!originalBranch) {
|
|
339
|
+
logger.warn('Could not determine original branch for merge.');
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
logger.newline();
|
|
343
|
+
logger.info(`Merging branch "${worktreeBranch}" into "${originalBranch}"...`);
|
|
344
|
+
const mergeResult = mergeWorktreeBranch(worktreeBranch, originalBranch);
|
|
345
|
+
if (mergeResult.success) {
|
|
346
|
+
const mergeType = mergeResult.fastForward ? 'fast-forward' : 'merge commit';
|
|
347
|
+
logger.success(`Merged "${worktreeBranch}" into "${originalBranch}" (${mergeType})`);
|
|
348
|
+
}
|
|
349
|
+
else {
|
|
350
|
+
logger.warn(`Could not auto-merge: ${mergeResult.error}`);
|
|
351
|
+
logger.warn(`You can merge manually: git merge ${worktreeBranch}`);
|
|
352
|
+
}
|
|
353
|
+
break;
|
|
354
|
+
}
|
|
355
|
+
case 'pr': {
|
|
356
|
+
logger.newline();
|
|
357
|
+
logger.info(`Creating PR for branch "${worktreeBranch}"...`);
|
|
358
|
+
const prResult = await createPullRequest(worktreeBranch, projectPath, { cwd: worktreeRoot });
|
|
359
|
+
if (prResult.success) {
|
|
360
|
+
logger.success(`PR created: ${prResult.prUrl}`);
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
logger.warn(`Could not create PR: ${prResult.error}`);
|
|
364
|
+
logger.warn(`Branch "${worktreeBranch}" has been pushed. You can create a PR manually.`);
|
|
365
|
+
}
|
|
366
|
+
// Clean up worktree directory (branch is preserved)
|
|
367
|
+
const prCleanupResult = removeWorktree(worktreeRoot);
|
|
368
|
+
if (prCleanupResult.success) {
|
|
369
|
+
logger.info(`Cleaned up worktree: ${worktreeRoot}`);
|
|
370
|
+
}
|
|
371
|
+
else {
|
|
372
|
+
logger.warn(`Could not clean up worktree: ${prCleanupResult.error}`);
|
|
373
|
+
}
|
|
374
|
+
break;
|
|
375
|
+
}
|
|
376
|
+
case 'leave': {
|
|
377
|
+
// Clean up worktree directory (branch is preserved)
|
|
378
|
+
const cleanupResult = removeWorktree(worktreeRoot);
|
|
379
|
+
if (cleanupResult.success) {
|
|
380
|
+
logger.info(`Cleaned up worktree: ${worktreeRoot}`);
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
logger.warn(`Could not clean up worktree: ${cleanupResult.error}`);
|
|
384
|
+
}
|
|
385
|
+
break;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Auto-discovery flow for `raf do --worktree` without a project identifier.
|
|
391
|
+
* Lists worktree projects, finds latest completed main-tree project, filters,
|
|
392
|
+
* and shows an interactive picker.
|
|
393
|
+
*
|
|
394
|
+
* @returns Selected project info or null if cancelled/no projects
|
|
395
|
+
*/
|
|
396
|
+
async function discoverAndPickWorktreeProject(repoBasename, rafDir, rafRelativePath) {
|
|
397
|
+
// List all worktree projects for this repo
|
|
398
|
+
const wtProjects = listWorktreeProjects(repoBasename);
|
|
399
|
+
if (wtProjects.length === 0) {
|
|
400
|
+
logger.error('No worktree projects found. Did you plan with --worktree?');
|
|
193
401
|
process.exit(1);
|
|
194
402
|
}
|
|
403
|
+
// Find the highest-numbered completed project in the MAIN tree
|
|
404
|
+
const mainProjects = discoverProjects(rafDir);
|
|
405
|
+
let highestCompletedNumber = 0;
|
|
406
|
+
for (const project of mainProjects) {
|
|
407
|
+
const state = deriveProjectState(project.path);
|
|
408
|
+
if (isProjectComplete(state) && state.tasks.length > 0) {
|
|
409
|
+
if (project.number > highestCompletedNumber) {
|
|
410
|
+
highestCompletedNumber = project.number;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
// Filter threshold: highest completed - 3 (or 0 if none completed)
|
|
415
|
+
const threshold = highestCompletedNumber > 3 ? highestCompletedNumber - 3 : 0;
|
|
416
|
+
// Filter worktree projects by number threshold and completion status
|
|
417
|
+
const uncompletedProjects = [];
|
|
418
|
+
for (const wtProjectDir of wtProjects) {
|
|
419
|
+
// Extract project number from the worktree directory name
|
|
420
|
+
const numPrefix = extractProjectNumber(wtProjectDir);
|
|
421
|
+
if (!numPrefix)
|
|
422
|
+
continue;
|
|
423
|
+
const projectNumber = parseProjectPrefix(numPrefix);
|
|
424
|
+
if (projectNumber === null)
|
|
425
|
+
continue;
|
|
426
|
+
// Apply threshold filter
|
|
427
|
+
if (projectNumber < threshold)
|
|
428
|
+
continue;
|
|
429
|
+
// Check if this worktree has a valid project
|
|
430
|
+
const wtPath = computeWorktreePath(repoBasename, wtProjectDir);
|
|
431
|
+
const wtProjectPath = path.join(wtPath, rafRelativePath, wtProjectDir);
|
|
432
|
+
if (!fs.existsSync(wtProjectPath))
|
|
433
|
+
continue;
|
|
434
|
+
// Derive project state from worktree
|
|
435
|
+
const state = deriveProjectState(wtProjectPath);
|
|
436
|
+
if (state.tasks.length === 0)
|
|
437
|
+
continue;
|
|
438
|
+
// Keep only uncompleted projects
|
|
439
|
+
if (isProjectComplete(state))
|
|
440
|
+
continue;
|
|
441
|
+
const stats = getDerivedStats(state);
|
|
442
|
+
uncompletedProjects.push({
|
|
443
|
+
folder: wtProjectDir,
|
|
444
|
+
worktreeRoot: wtPath,
|
|
445
|
+
projectPath: wtProjectPath,
|
|
446
|
+
completedTasks: stats.completed,
|
|
447
|
+
totalTasks: stats.total,
|
|
448
|
+
projectNumber,
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
if (uncompletedProjects.length === 0) {
|
|
452
|
+
logger.info('All worktree projects are completed.');
|
|
453
|
+
return null;
|
|
454
|
+
}
|
|
455
|
+
// Sort by project number
|
|
456
|
+
uncompletedProjects.sort((a, b) => a.projectNumber - b.projectNumber);
|
|
457
|
+
// Show interactive picker (even if only one project)
|
|
458
|
+
const choices = uncompletedProjects.map((p) => {
|
|
459
|
+
const name = extractProjectName(p.folder) ?? p.folder;
|
|
460
|
+
const numPrefix = extractProjectNumber(p.folder) ?? '';
|
|
461
|
+
return {
|
|
462
|
+
name: `${numPrefix} ${name} (${p.completedTasks}/${p.totalTasks} tasks)`,
|
|
463
|
+
value: p,
|
|
464
|
+
};
|
|
465
|
+
});
|
|
466
|
+
try {
|
|
467
|
+
const selected = await select({
|
|
468
|
+
message: 'Select a worktree project to execute:',
|
|
469
|
+
choices,
|
|
470
|
+
});
|
|
471
|
+
return {
|
|
472
|
+
worktreeRoot: selected.worktreeRoot,
|
|
473
|
+
projectFolder: selected.folder,
|
|
474
|
+
};
|
|
475
|
+
}
|
|
476
|
+
catch (error) {
|
|
477
|
+
// Handle Ctrl+C (user cancellation)
|
|
478
|
+
if (error instanceof Error && error.message.includes('User force closed')) {
|
|
479
|
+
return null;
|
|
480
|
+
}
|
|
481
|
+
throw error;
|
|
482
|
+
}
|
|
195
483
|
}
|
|
196
484
|
async function executeSingleProject(projectPath, projectName, options) {
|
|
197
|
-
const { timeout, verbose, debug, force, maxRetries, autoCommit, showModel, model } = options;
|
|
485
|
+
const { timeout, verbose, debug, force, maxRetries, autoCommit, showModel, model, worktreeCwd } = options;
|
|
198
486
|
if (!validatePlansExist(projectPath)) {
|
|
199
487
|
return {
|
|
200
488
|
projectName,
|
|
@@ -333,6 +621,7 @@ async function executeSingleProject(projectPath, projectName, options) {
|
|
|
333
621
|
const taskName = extractTaskNameFromPlanFile(task.planFile);
|
|
334
622
|
const displayName = taskName ?? task.id;
|
|
335
623
|
const taskId = task.id; // Capture for closure
|
|
624
|
+
const taskLabel = displayName !== task.id ? `${task.id} (${displayName})` : task.id;
|
|
336
625
|
// Handle blocked tasks separately - skip Claude execution
|
|
337
626
|
if (task.status === 'blocked') {
|
|
338
627
|
// Find which dependency caused the block for the message
|
|
@@ -344,7 +633,7 @@ async function executeSingleProject(projectPath, projectName, options) {
|
|
|
344
633
|
if (verbose) {
|
|
345
634
|
const taskContext = `[Task ${taskNumber}/${totalTasks}: ${displayName}]`;
|
|
346
635
|
logger.setContext(taskContext);
|
|
347
|
-
logger.warn(`Task ${
|
|
636
|
+
logger.warn(`Task ${taskLabel} blocked by failed dependency: ${blockingDep}`);
|
|
348
637
|
}
|
|
349
638
|
else {
|
|
350
639
|
// Minimal mode: show blocked task line with distinct symbol
|
|
@@ -365,13 +654,13 @@ async function executeSingleProject(projectPath, projectName, options) {
|
|
|
365
654
|
logger.setContext(taskContext);
|
|
366
655
|
// Log task execution status
|
|
367
656
|
if (task.status === 'failed') {
|
|
368
|
-
logger.info(`Retrying task ${
|
|
657
|
+
logger.info(`Retrying task ${taskLabel} (previously failed)...`);
|
|
369
658
|
}
|
|
370
659
|
else if (task.status === 'completed' && force) {
|
|
371
|
-
logger.info(`Re-running task ${
|
|
660
|
+
logger.info(`Re-running task ${taskLabel} (force mode)...`);
|
|
372
661
|
}
|
|
373
662
|
else {
|
|
374
|
-
logger.info(`Executing task ${
|
|
663
|
+
logger.info(`Executing task ${taskLabel}...`);
|
|
375
664
|
}
|
|
376
665
|
}
|
|
377
666
|
// Get previous outcomes for context
|
|
@@ -402,7 +691,7 @@ async function executeSingleProject(projectPath, projectName, options) {
|
|
|
402
691
|
while (!success && attempts < maxRetries) {
|
|
403
692
|
attempts++;
|
|
404
693
|
if (verbose && attempts > 1) {
|
|
405
|
-
logger.info(` Retry ${attempts}/${maxRetries}...`);
|
|
694
|
+
logger.info(` Retry ${attempts}/${maxRetries} for task ${taskLabel}...`);
|
|
406
695
|
}
|
|
407
696
|
// Build execution prompt (inside loop to include retry context on retries)
|
|
408
697
|
// Check if previous outcome file exists for retry context
|
|
@@ -424,10 +713,17 @@ async function executeSingleProject(projectPath, projectName, options) {
|
|
|
424
713
|
dependencyIds,
|
|
425
714
|
dependencyOutcomes,
|
|
426
715
|
});
|
|
427
|
-
//
|
|
716
|
+
// Capture HEAD hash before execution for commit verification
|
|
717
|
+
const preExecutionHead = isGitRepo(worktreeCwd) ? getHeadCommitHash(worktreeCwd) : null;
|
|
718
|
+
const commitContext = preExecutionHead ? {
|
|
719
|
+
preExecutionHead,
|
|
720
|
+
expectedPrefix: `RAF[${projectNumber}:${task.id}]`,
|
|
721
|
+
outcomeFilePath,
|
|
722
|
+
} : undefined;
|
|
723
|
+
// Run Claude (use worktree root as cwd if in worktree mode)
|
|
428
724
|
const result = verbose
|
|
429
|
-
? await claudeRunner.runVerbose(prompt, { timeout })
|
|
430
|
-
: await claudeRunner.run(prompt, { timeout });
|
|
725
|
+
? await claudeRunner.runVerbose(prompt, { timeout, outcomeFilePath, commitContext, cwd: worktreeCwd })
|
|
726
|
+
: await claudeRunner.run(prompt, { timeout, outcomeFilePath, commitContext, cwd: worktreeCwd });
|
|
431
727
|
lastOutput = result.output;
|
|
432
728
|
// Parse result
|
|
433
729
|
const parsed = parseOutput(result.output);
|
|
@@ -533,7 +829,7 @@ Task completed. No detailed report provided.
|
|
|
533
829
|
}
|
|
534
830
|
projectManager.saveOutcome(projectPath, task.id, outcomeContent);
|
|
535
831
|
if (verbose) {
|
|
536
|
-
logger.success(` Task ${
|
|
832
|
+
logger.success(` Task ${taskLabel} completed (${elapsedFormatted})`);
|
|
537
833
|
}
|
|
538
834
|
else {
|
|
539
835
|
// Minimal mode: show completed task line
|
|
@@ -544,16 +840,16 @@ Task completed. No detailed report provided.
|
|
|
544
840
|
else {
|
|
545
841
|
// Stash any uncommitted changes on complete failure
|
|
546
842
|
let stashName;
|
|
547
|
-
if (hasUncommittedChanges()) {
|
|
843
|
+
if (hasUncommittedChanges(worktreeCwd)) {
|
|
548
844
|
const projectNum = extractProjectNumber(projectPath) ?? '000';
|
|
549
845
|
stashName = `raf-${projectNum}-task-${task.id}-failed`;
|
|
550
|
-
const stashed = stashChanges(stashName);
|
|
846
|
+
const stashed = stashChanges(stashName, worktreeCwd);
|
|
551
847
|
if (verbose && stashed) {
|
|
552
|
-
logger.info(` Changes stashed as: ${stashName}`);
|
|
848
|
+
logger.info(` Changes for task ${taskLabel} stashed as: ${stashName}`);
|
|
553
849
|
}
|
|
554
850
|
}
|
|
555
851
|
if (verbose) {
|
|
556
|
-
logger.error(` Task ${
|
|
852
|
+
logger.error(` Task ${taskLabel} failed: ${failureReason} (${elapsedFormatted})`);
|
|
557
853
|
logger.info(' Analyzing failure...');
|
|
558
854
|
}
|
|
559
855
|
else {
|
|
@@ -659,31 +955,4 @@ ${stashName ? `- Stash: ${stashName}` : ''}
|
|
|
659
955
|
retryHistory: projectRetryHistory,
|
|
660
956
|
};
|
|
661
957
|
}
|
|
662
|
-
function printMultiProjectSummary(results, verbose) {
|
|
663
|
-
logger.newline();
|
|
664
|
-
if (verbose) {
|
|
665
|
-
logger.info('=== Multi-Project Summary ===');
|
|
666
|
-
logger.newline();
|
|
667
|
-
for (const result of results) {
|
|
668
|
-
const statusSymbol = result.success ? SYMBOLS.completed : SYMBOLS.failed;
|
|
669
|
-
const statusText = result.success
|
|
670
|
-
? `Completed (${result.tasksCompleted}/${result.totalTasks} tasks)`
|
|
671
|
-
: result.error
|
|
672
|
-
? `Error: ${result.error}`
|
|
673
|
-
: `Failed (${result.tasksCompleted}/${result.totalTasks} tasks)`;
|
|
674
|
-
logger.info(`${statusSymbol} ${result.projectName}: ${statusText}`);
|
|
675
|
-
}
|
|
676
|
-
const completed = results.filter((r) => r.success).length;
|
|
677
|
-
const failed = results.length - completed;
|
|
678
|
-
logger.newline();
|
|
679
|
-
logger.info(`Total: ${completed} completed, ${failed} failed`);
|
|
680
|
-
}
|
|
681
|
-
else {
|
|
682
|
-
// Minimal multi-project summary: just show each project result
|
|
683
|
-
for (const result of results) {
|
|
684
|
-
const symbol = result.success ? SYMBOLS.completed : SYMBOLS.failed;
|
|
685
|
-
logger.info(`${symbol} ${result.projectName}`);
|
|
686
|
-
}
|
|
687
|
-
}
|
|
688
|
-
}
|
|
689
958
|
//# sourceMappingURL=do.js.map
|