rafcode 1.3.2 → 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/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 +384 -123
- 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 +2 -2
- package/dist/core/claude-runner.d.ts.map +1 -1
- package/dist/core/git.d.ts +15 -6
- package/dist/core/git.d.ts.map +1 -1
- package/dist/core/git.js +53 -20
- 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/prompts/amend.d.ts +1 -0
- package/dist/prompts/amend.d.ts.map +1 -1
- package/dist/prompts/amend.js +14 -10
- package/dist/prompts/amend.js.map +1 -1
- package/dist/prompts/execution.d.ts.map +1 -1
- package/dist/prompts/execution.js +4 -2
- 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 +9 -8
- 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 +454 -134
- 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 +2 -2
- package/src/core/git.ts +57 -21
- 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/prompts/amend.ts +15 -9
- package/src/prompts/execution.ts +4 -2
- package/src/prompts/planning.ts +10 -8
- 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 +9 -9
- 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 +5 -5
- 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 +103 -103
- 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/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/RAF/{019-verbose-chronicle → aaaabt-verbose-chronicle}/decisions.md +0 -0
- /package/RAF/{019-verbose-chronicle → aaaabt-verbose-chronicle}/input.md +0 -0
- /package/RAF/{019-verbose-chronicle/outcomes/001-amend-iteration-references.md → aaaabt-verbose-chronicle/outcomes/01-amend-iteration-references.md} +0 -0
- /package/RAF/{019-verbose-chronicle/outcomes/002-verbose-task-name-display.md → aaaabt-verbose-chronicle/outcomes/02-verbose-task-name-display.md} +0 -0
- /package/RAF/{019-verbose-chronicle/outcomes/003-verbose-streaming-fix.md → aaaabt-verbose-chronicle/outcomes/03-verbose-streaming-fix.md} +0 -0
- /package/RAF/{019-verbose-chronicle/outcomes/004-commit-verification-before-halt.md → aaaabt-verbose-chronicle/outcomes/04-commit-verification-before-halt.md} +0 -0
- /package/RAF/{019-verbose-chronicle/plans/001-amend-iteration-references.md → aaaabt-verbose-chronicle/plans/01-amend-iteration-references.md} +0 -0
- /package/RAF/{019-verbose-chronicle/plans/002-verbose-task-name-display.md → aaaabt-verbose-chronicle/plans/02-verbose-task-name-display.md} +0 -0
- /package/RAF/{019-verbose-chronicle/plans/003-verbose-streaming-fix.md → aaaabt-verbose-chronicle/plans/03-verbose-streaming-fix.md} +0 -0
- /package/RAF/{019-verbose-chronicle/plans/004-commit-verification-before-halt.md → aaaabt-verbose-chronicle/plans/04-commit-verification-before-halt.md} +0 -0
package/src/commands/status.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
1
3
|
import { Command } from 'commander';
|
|
2
|
-
import { getRafDir, resolveProjectIdentifier, extractProjectName } from '../utils/paths.js';
|
|
4
|
+
import { getRafDir, resolveProjectIdentifier, extractProjectName, extractProjectNumber, resolveProjectIdentifierWithDetails, formatProjectNumber } from '../utils/paths.js';
|
|
3
5
|
import { logger } from '../utils/logger.js';
|
|
4
6
|
import type { StatusCommandOptions } from '../types/config.js';
|
|
5
7
|
import {
|
|
@@ -7,8 +9,16 @@ import {
|
|
|
7
9
|
getDerivedStats,
|
|
8
10
|
discoverProjects,
|
|
9
11
|
type DerivedTaskStatus,
|
|
12
|
+
type DerivedProjectState,
|
|
13
|
+
type DerivedStats,
|
|
10
14
|
} from '../core/state-derivation.js';
|
|
11
15
|
import { SYMBOLS, formatProgressBar, type TaskStatus } from '../utils/terminal-symbols.js';
|
|
16
|
+
import {
|
|
17
|
+
getRepoRoot,
|
|
18
|
+
getRepoBasename,
|
|
19
|
+
listWorktreeProjects,
|
|
20
|
+
computeWorktreePath,
|
|
21
|
+
} from '../core/worktree.js';
|
|
12
22
|
|
|
13
23
|
/** Maximum number of projects to display in status list */
|
|
14
24
|
const MAX_DISPLAYED_PROJECTS = 10;
|
|
@@ -16,7 +26,7 @@ const MAX_DISPLAYED_PROJECTS = 10;
|
|
|
16
26
|
export function createStatusCommand(): Command {
|
|
17
27
|
const command = new Command('status')
|
|
18
28
|
.description('Show status of a project or list all projects')
|
|
19
|
-
.argument('[identifier]', 'Project identifier:
|
|
29
|
+
.argument('[identifier]', 'Project identifier: ID (00j3k1), name (my-project), or folder (00j3k1-my-project)')
|
|
20
30
|
.option('--json', 'Output as JSON')
|
|
21
31
|
.action(async (identifier?: string, options?: StatusCommandOptions) => {
|
|
22
32
|
await runStatusCommand(identifier, options);
|
|
@@ -25,53 +35,220 @@ export function createStatusCommand(): Command {
|
|
|
25
35
|
return command;
|
|
26
36
|
}
|
|
27
37
|
|
|
38
|
+
/** Resolved worktree context for status display */
|
|
39
|
+
interface WorktreeContext {
|
|
40
|
+
repoBasename: string;
|
|
41
|
+
rafRelativePath: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/** A worktree project with its derived state */
|
|
45
|
+
interface WorktreeProjectInfo {
|
|
46
|
+
folder: string;
|
|
47
|
+
projectPath: string;
|
|
48
|
+
state: DerivedProjectState;
|
|
49
|
+
stats: DerivedStats;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Attempt to discover the worktree context (repo basename and RAF relative path).
|
|
54
|
+
* Returns null if not in a git repo.
|
|
55
|
+
*/
|
|
56
|
+
function getWorktreeContext(rafDir: string): WorktreeContext | null {
|
|
57
|
+
const repoRoot = getRepoRoot();
|
|
58
|
+
if (!repoRoot) return null;
|
|
59
|
+
|
|
60
|
+
const repoBasename = getRepoBasename();
|
|
61
|
+
if (!repoBasename) return null;
|
|
62
|
+
|
|
63
|
+
const rafRelativePath = path.relative(repoRoot, rafDir);
|
|
64
|
+
return { repoBasename, rafRelativePath };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Discover all worktree projects with their state.
|
|
69
|
+
* Returns only projects that have valid project directories.
|
|
70
|
+
*/
|
|
71
|
+
function discoverWorktreeProjectStates(ctx: WorktreeContext): WorktreeProjectInfo[] {
|
|
72
|
+
const wtProjects = listWorktreeProjects(ctx.repoBasename);
|
|
73
|
+
const results: WorktreeProjectInfo[] = [];
|
|
74
|
+
|
|
75
|
+
for (const folder of wtProjects) {
|
|
76
|
+
const wtPath = computeWorktreePath(ctx.repoBasename, folder);
|
|
77
|
+
const wtProjectPath = path.join(wtPath, ctx.rafRelativePath, folder);
|
|
78
|
+
|
|
79
|
+
if (!fs.existsSync(wtProjectPath)) continue;
|
|
80
|
+
|
|
81
|
+
try {
|
|
82
|
+
const state = deriveProjectState(wtProjectPath);
|
|
83
|
+
const stats = getDerivedStats(state);
|
|
84
|
+
results.push({ folder, projectPath: wtProjectPath, state, stats });
|
|
85
|
+
} catch {
|
|
86
|
+
// Skip projects that fail to derive state
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return results;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Check if two project states differ (different task counts or different statuses).
|
|
95
|
+
*/
|
|
96
|
+
function projectStatesDiffer(mainState: DerivedProjectState, wtState: DerivedProjectState): boolean {
|
|
97
|
+
if (mainState.tasks.length !== wtState.tasks.length) return true;
|
|
98
|
+
|
|
99
|
+
for (let i = 0; i < mainState.tasks.length; i++) {
|
|
100
|
+
const mainTask = mainState.tasks[i];
|
|
101
|
+
const wtTask = wtState.tasks[i];
|
|
102
|
+
if (mainTask && wtTask && mainTask.status !== wtTask.status) return true;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return false;
|
|
106
|
+
}
|
|
107
|
+
|
|
28
108
|
async function runStatusCommand(
|
|
29
109
|
identifier?: string,
|
|
30
110
|
options?: StatusCommandOptions
|
|
31
111
|
): Promise<void> {
|
|
32
112
|
const rafDir = getRafDir();
|
|
113
|
+
const wtCtx = getWorktreeContext(rafDir);
|
|
33
114
|
|
|
34
115
|
if (!identifier) {
|
|
35
|
-
|
|
36
|
-
await listAllProjects(rafDir, options);
|
|
116
|
+
await listAllProjects(rafDir, options, wtCtx);
|
|
37
117
|
return;
|
|
38
118
|
}
|
|
39
119
|
|
|
40
|
-
// Show specific project - resolve
|
|
41
|
-
const
|
|
120
|
+
// Show specific project - resolve in main repo
|
|
121
|
+
const mainProjectPath = resolveProjectIdentifier(rafDir, identifier);
|
|
42
122
|
|
|
43
|
-
|
|
123
|
+
// Resolve in worktree
|
|
124
|
+
let wtProject: WorktreeProjectInfo | null = null;
|
|
125
|
+
if (wtCtx) {
|
|
126
|
+
const wtProjects = discoverWorktreeProjectStates(wtCtx);
|
|
127
|
+
for (const wp of wtProjects) {
|
|
128
|
+
// Match by folder name against main project, or resolve identifier in worktree
|
|
129
|
+
if (mainProjectPath && path.basename(mainProjectPath) === wp.folder) {
|
|
130
|
+
wtProject = wp;
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
// Try matching by identifier if not found via main project
|
|
134
|
+
if (!mainProjectPath) {
|
|
135
|
+
const wtRafDir = path.join(computeWorktreePath(wtCtx.repoBasename, wp.folder), wtCtx.rafRelativePath);
|
|
136
|
+
const resolved = resolveProjectIdentifierWithDetails(wtRafDir, identifier);
|
|
137
|
+
if (resolved.path) {
|
|
138
|
+
wtProject = wp;
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if (!mainProjectPath && !wtProject) {
|
|
44
146
|
logger.error(`Project not found: ${identifier}`);
|
|
45
147
|
process.exit(1);
|
|
46
148
|
}
|
|
47
149
|
|
|
48
|
-
// Derive state
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
150
|
+
// Derive main repo state (if exists)
|
|
151
|
+
let mainState: DerivedProjectState | null = null;
|
|
152
|
+
let mainStats: DerivedStats | null = null;
|
|
153
|
+
let projectName: string;
|
|
154
|
+
|
|
155
|
+
if (mainProjectPath) {
|
|
156
|
+
mainState = deriveProjectState(mainProjectPath);
|
|
157
|
+
mainStats = getDerivedStats(mainState);
|
|
158
|
+
projectName = extractProjectName(mainProjectPath) ?? identifier;
|
|
159
|
+
} else {
|
|
160
|
+
projectName = extractProjectName(wtProject!.folder) ?? identifier;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Determine if we need to show both views
|
|
164
|
+
const showBoth = mainState && wtProject && projectStatesDiffer(mainState, wtProject.state);
|
|
165
|
+
const worktreeOnly = !mainState && wtProject;
|
|
53
166
|
|
|
54
167
|
if (options?.json) {
|
|
55
|
-
|
|
168
|
+
const jsonData: Record<string, unknown> = {
|
|
169
|
+
projectName,
|
|
170
|
+
status: mainState?.status ?? wtProject!.state.status,
|
|
171
|
+
state: mainState ?? wtProject!.state,
|
|
172
|
+
stats: mainStats ?? wtProject!.stats,
|
|
173
|
+
};
|
|
174
|
+
if (wtProject) {
|
|
175
|
+
jsonData.worktree = {
|
|
176
|
+
folder: wtProject.folder,
|
|
177
|
+
projectPath: wtProject.projectPath,
|
|
178
|
+
status: wtProject.state.status,
|
|
179
|
+
state: wtProject.state,
|
|
180
|
+
stats: wtProject.stats,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
console.log(JSON.stringify(jsonData, null, 2));
|
|
56
184
|
return;
|
|
57
185
|
}
|
|
58
186
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
187
|
+
if (showBoth) {
|
|
188
|
+
// Show both main and worktree states
|
|
189
|
+
logger.info(`${SYMBOLS.project} ${projectName}`);
|
|
62
190
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
191
|
+
const mainTaskStatuses: TaskStatus[] = mainState!.tasks.map((t) => derivedStatusToTaskStatus(t.status));
|
|
192
|
+
const mainProgressBar = formatProgressBar(mainTaskStatuses);
|
|
193
|
+
logger.info(` Main: ${mainProgressBar} (${mainStats!.completed}/${mainStats!.total})`);
|
|
194
|
+
|
|
195
|
+
const wtTaskStatuses: TaskStatus[] = wtProject!.state.tasks.map((t) => derivedStatusToTaskStatus(t.status));
|
|
196
|
+
const wtProgressBar = formatProgressBar(wtTaskStatuses);
|
|
197
|
+
logger.info(` Worktree: ${wtProgressBar} (${wtProject!.stats.completed}/${wtProject!.stats.total})`);
|
|
198
|
+
} else if (worktreeOnly) {
|
|
199
|
+
// Show worktree only
|
|
200
|
+
const taskStatuses: TaskStatus[] = wtProject!.state.tasks.map((t) => derivedStatusToTaskStatus(t.status));
|
|
201
|
+
const progressBar = formatProgressBar(taskStatuses);
|
|
202
|
+
logger.info(`${SYMBOLS.project} ${projectName}`);
|
|
203
|
+
logger.info(`${progressBar} (${wtProject!.stats.completed}/${wtProject!.stats.total})`);
|
|
204
|
+
} else {
|
|
205
|
+
// Show main only (no worktree, or worktree is identical)
|
|
206
|
+
const taskStatuses: TaskStatus[] = mainState!.tasks.map((t) => derivedStatusToTaskStatus(t.status));
|
|
207
|
+
const progressBar = formatProgressBar(taskStatuses);
|
|
208
|
+
logger.info(`${SYMBOLS.project} ${projectName}`);
|
|
209
|
+
logger.info(`${progressBar} (${mainStats!.completed}/${mainStats!.total})`);
|
|
210
|
+
}
|
|
66
211
|
}
|
|
67
212
|
|
|
68
213
|
async function listAllProjects(
|
|
69
214
|
rafDir: string,
|
|
70
|
-
options?: StatusCommandOptions
|
|
215
|
+
options?: StatusCommandOptions,
|
|
216
|
+
wtCtx?: WorktreeContext | null
|
|
71
217
|
): Promise<void> {
|
|
72
218
|
const allProjects = discoverProjects(rafDir);
|
|
73
219
|
|
|
74
|
-
|
|
220
|
+
// Discover worktree projects
|
|
221
|
+
const wtProjectInfos = wtCtx ? discoverWorktreeProjectStates(wtCtx) : [];
|
|
222
|
+
|
|
223
|
+
// Build a set of main repo folder names for fast lookup
|
|
224
|
+
const mainFolderNames = new Set(allProjects.map((p) => path.basename(p.path)));
|
|
225
|
+
|
|
226
|
+
// Determine which worktree projects to show:
|
|
227
|
+
// - Worktree-only projects (no main repo counterpart) are always shown
|
|
228
|
+
// - Worktree projects that differ from main repo counterpart are shown
|
|
229
|
+
const worktreeToShow: WorktreeProjectInfo[] = [];
|
|
230
|
+
for (const wp of wtProjectInfos) {
|
|
231
|
+
if (!mainFolderNames.has(wp.folder)) {
|
|
232
|
+
// Worktree-only project
|
|
233
|
+
worktreeToShow.push(wp);
|
|
234
|
+
} else {
|
|
235
|
+
// Has main repo counterpart - check if they differ
|
|
236
|
+
const mainProject = allProjects.find((p) => path.basename(p.path) === wp.folder);
|
|
237
|
+
if (mainProject) {
|
|
238
|
+
try {
|
|
239
|
+
const mainState = deriveProjectState(mainProject.path);
|
|
240
|
+
if (projectStatesDiffer(mainState, wp.state)) {
|
|
241
|
+
worktreeToShow.push(wp);
|
|
242
|
+
}
|
|
243
|
+
} catch {
|
|
244
|
+
// If we can't derive main state, show the worktree project
|
|
245
|
+
worktreeToShow.push(wp);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
if (allProjects.length === 0 && worktreeToShow.length === 0) {
|
|
75
252
|
logger.info('No projects found.');
|
|
76
253
|
return;
|
|
77
254
|
}
|
|
@@ -91,39 +268,69 @@ async function listAllProjects(
|
|
|
91
268
|
return { ...p, status: null, state: null, stats: null };
|
|
92
269
|
}
|
|
93
270
|
});
|
|
94
|
-
|
|
271
|
+
|
|
272
|
+
const jsonData: Record<string, unknown> = { projects: projectsWithState };
|
|
273
|
+
if (worktreeToShow.length > 0) {
|
|
274
|
+
jsonData.worktrees = worktreeToShow.map((wp) => ({
|
|
275
|
+
folder: wp.folder,
|
|
276
|
+
projectPath: wp.projectPath,
|
|
277
|
+
status: wp.state.status,
|
|
278
|
+
state: wp.state,
|
|
279
|
+
stats: wp.stats,
|
|
280
|
+
}));
|
|
281
|
+
}
|
|
282
|
+
console.log(JSON.stringify(jsonData, null, 2));
|
|
95
283
|
return;
|
|
96
284
|
}
|
|
97
285
|
|
|
98
|
-
//
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
286
|
+
// Display main repo projects
|
|
287
|
+
if (allProjects.length > 0) {
|
|
288
|
+
// Truncate to last N projects if needed (projects are sorted by number ascending)
|
|
289
|
+
const totalProjects = allProjects.length;
|
|
290
|
+
const hiddenCount = Math.max(0, totalProjects - MAX_DISPLAYED_PROJECTS);
|
|
291
|
+
const displayedProjects = hiddenCount > 0
|
|
292
|
+
? allProjects.slice(-MAX_DISPLAYED_PROJECTS)
|
|
293
|
+
: allProjects;
|
|
294
|
+
|
|
295
|
+
// Show truncation indicator at top if there are hidden projects
|
|
296
|
+
if (hiddenCount > 0) {
|
|
297
|
+
logger.dim(`... and ${hiddenCount} more project${hiddenCount === 1 ? '' : 's'}`);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
for (const project of displayedProjects) {
|
|
301
|
+
try {
|
|
302
|
+
const state = deriveProjectState(project.path);
|
|
303
|
+
const stats = getDerivedStats(state);
|
|
104
304
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
305
|
+
// Convert derived task statuses to TaskStatus for progress bar
|
|
306
|
+
const taskStatuses: TaskStatus[] = state.tasks.map((t) => derivedStatusToTaskStatus(t.status));
|
|
307
|
+
const progressBar = formatProgressBar(taskStatuses);
|
|
308
|
+
|
|
309
|
+
// Format: "00j3k1 my-project ✓✓●○○ (2/5)"
|
|
310
|
+
const projectNumber = formatProjectNumber(project.number);
|
|
311
|
+
const counts = `(${stats.completed}/${stats.total})`;
|
|
312
|
+
logger.info(`${projectNumber} ${project.name} ${progressBar} ${counts}`);
|
|
313
|
+
} catch {
|
|
314
|
+
// Failed to derive state - show minimal info
|
|
315
|
+
const projectNumber = formatProjectNumber(project.number);
|
|
316
|
+
logger.info(`${projectNumber} ${project.name}`);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
108
319
|
}
|
|
109
320
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
321
|
+
// Display worktree projects section
|
|
322
|
+
if (worktreeToShow.length > 0) {
|
|
323
|
+
logger.newline();
|
|
324
|
+
logger.info('Worktrees:');
|
|
325
|
+
for (const wp of worktreeToShow) {
|
|
326
|
+
const projectNumber = extractProjectNumber(wp.folder) ?? '???';
|
|
327
|
+
const projectName = extractProjectName(wp.folder) ?? wp.folder;
|
|
114
328
|
|
|
115
|
-
|
|
116
|
-
const taskStatuses: TaskStatus[] = state.tasks.map((t) => derivedStatusToTaskStatus(t.status));
|
|
329
|
+
const taskStatuses: TaskStatus[] = wp.state.tasks.map((t) => derivedStatusToTaskStatus(t.status));
|
|
117
330
|
const progressBar = formatProgressBar(taskStatuses);
|
|
331
|
+
const counts = `(${wp.stats.completed}/${wp.stats.total})`;
|
|
118
332
|
|
|
119
|
-
|
|
120
|
-
const projectNumber = String(project.number).padStart(3, '0');
|
|
121
|
-
const counts = `(${stats.completed}/${stats.total})`;
|
|
122
|
-
logger.info(`${projectNumber} ${project.name} ${progressBar} ${counts}`);
|
|
123
|
-
} catch {
|
|
124
|
-
// Failed to derive state - show minimal info
|
|
125
|
-
const projectNumber = String(project.number).padStart(3, '0');
|
|
126
|
-
logger.info(`${projectNumber} ${project.name}`);
|
|
333
|
+
logger.info(` ${projectNumber} ${projectName} ${progressBar} ${counts}`);
|
|
127
334
|
}
|
|
128
335
|
}
|
|
129
336
|
}
|
|
@@ -45,7 +45,7 @@ export interface ClaudeRunnerOptions {
|
|
|
45
45
|
commitContext?: {
|
|
46
46
|
/** HEAD commit hash recorded before task execution began. */
|
|
47
47
|
preExecutionHead: string;
|
|
48
|
-
/** Expected commit message prefix (e.g., "RAF[005:
|
|
48
|
+
/** Expected commit message prefix (e.g., "RAF[005:01]"). */
|
|
49
49
|
expectedPrefix: string;
|
|
50
50
|
/** Path to the outcome file that should be committed. */
|
|
51
51
|
outcomeFilePath: string;
|
|
@@ -104,7 +104,7 @@ export const OUTCOME_POLL_INTERVAL_MS = 5_000;
|
|
|
104
104
|
export interface CommitContext {
|
|
105
105
|
/** HEAD commit hash recorded before task execution began. */
|
|
106
106
|
preExecutionHead: string;
|
|
107
|
-
/** Expected commit message prefix (e.g., "RAF[005:
|
|
107
|
+
/** Expected commit message prefix (e.g., "RAF[005:01]"). */
|
|
108
108
|
expectedPrefix: string;
|
|
109
109
|
/** Path to the outcome file that should be committed. */
|
|
110
110
|
outcomeFilePath: string;
|
package/src/core/git.ts
CHANGED
|
@@ -12,9 +12,9 @@ export interface GitStatus {
|
|
|
12
12
|
/**
|
|
13
13
|
* Check if we're in a git repository.
|
|
14
14
|
*/
|
|
15
|
-
export function isGitRepo(): boolean {
|
|
15
|
+
export function isGitRepo(cwd?: string): boolean {
|
|
16
16
|
try {
|
|
17
|
-
execSync('git rev-parse --is-inside-work-tree', { encoding: 'utf-8', stdio: 'pipe' });
|
|
17
|
+
execSync('git rev-parse --is-inside-work-tree', { encoding: 'utf-8', stdio: 'pipe', ...(cwd ? { cwd } : {}) });
|
|
18
18
|
return true;
|
|
19
19
|
} catch {
|
|
20
20
|
return false;
|
|
@@ -58,9 +58,9 @@ export function getGitStatus(): GitStatus {
|
|
|
58
58
|
/**
|
|
59
59
|
* Check if there are uncommitted changes.
|
|
60
60
|
*/
|
|
61
|
-
export function hasUncommittedChanges(): boolean {
|
|
61
|
+
export function hasUncommittedChanges(cwd?: string): boolean {
|
|
62
62
|
try {
|
|
63
|
-
const status = execSync('git status --porcelain', { encoding: 'utf-8', stdio: 'pipe' });
|
|
63
|
+
const status = execSync('git status --porcelain', { encoding: 'utf-8', stdio: 'pipe', ...(cwd ? { cwd } : {}) });
|
|
64
64
|
return status.trim().length > 0;
|
|
65
65
|
} catch {
|
|
66
66
|
return false;
|
|
@@ -141,16 +141,16 @@ export function getChangedFiles(): string[] {
|
|
|
141
141
|
|
|
142
142
|
/**
|
|
143
143
|
* Stash uncommitted changes with a descriptive name.
|
|
144
|
-
* @param name - Name for the stash (e.g., "raf-001-task-
|
|
144
|
+
* @param name - Name for the stash (e.g., "raf-001-task-03-failed")
|
|
145
145
|
* @returns true if stash was created, false otherwise
|
|
146
146
|
*/
|
|
147
|
-
export function stashChanges(name: string): boolean {
|
|
148
|
-
if (!isGitRepo()) {
|
|
147
|
+
export function stashChanges(name: string, cwd?: string): boolean {
|
|
148
|
+
if (!isGitRepo(cwd)) {
|
|
149
149
|
logger.warn('Not in a git repository, skipping stash');
|
|
150
150
|
return false;
|
|
151
151
|
}
|
|
152
152
|
|
|
153
|
-
if (!hasUncommittedChanges()) {
|
|
153
|
+
if (!hasUncommittedChanges(cwd)) {
|
|
154
154
|
logger.debug('No uncommitted changes to stash');
|
|
155
155
|
return false;
|
|
156
156
|
}
|
|
@@ -159,6 +159,7 @@ export function stashChanges(name: string): boolean {
|
|
|
159
159
|
execSync(`git stash push -m "${name.replace(/"/g, '\\"')}"`, {
|
|
160
160
|
encoding: 'utf-8',
|
|
161
161
|
stdio: 'pipe',
|
|
162
|
+
...(cwd ? { cwd } : {}),
|
|
162
163
|
});
|
|
163
164
|
return true;
|
|
164
165
|
} catch (error) {
|
|
@@ -171,9 +172,9 @@ export function stashChanges(name: string): boolean {
|
|
|
171
172
|
* Get the current HEAD commit hash.
|
|
172
173
|
* Returns null if not in a git repo or HEAD doesn't exist.
|
|
173
174
|
*/
|
|
174
|
-
export function getHeadCommitHash(): string | null {
|
|
175
|
+
export function getHeadCommitHash(cwd?: string): string | null {
|
|
175
176
|
try {
|
|
176
|
-
return execSync('git rev-parse HEAD', { encoding: 'utf-8', stdio: 'pipe' }).trim() || null;
|
|
177
|
+
return execSync('git rev-parse HEAD', { encoding: 'utf-8', stdio: 'pipe', ...(cwd ? { cwd } : {}) }).trim() || null;
|
|
177
178
|
} catch {
|
|
178
179
|
return null;
|
|
179
180
|
}
|
|
@@ -214,13 +215,20 @@ export function isFileCommittedInHead(filePath: string): boolean {
|
|
|
214
215
|
/**
|
|
215
216
|
* Commit planning artifacts (input.md and decisions.md) for a project.
|
|
216
217
|
* Uses commit message format: RAF[NNN] Plan: project-name
|
|
218
|
+
* For amendments: RAF[NNN] Amend: project-name
|
|
217
219
|
*
|
|
218
220
|
* @param projectPath - Full path to the project folder (e.g., /path/to/RAF/017-decision-vault)
|
|
221
|
+
* @param options - Optional settings
|
|
222
|
+
* @param options.cwd - Working directory for git commands (worktree support)
|
|
223
|
+
* @param options.additionalFiles - Extra file paths to stage (e.g., plan files for amend)
|
|
224
|
+
* @param options.isAmend - Use "Amend:" prefix instead of "Plan:" in commit message
|
|
219
225
|
* @returns Promise that resolves when commit is complete (or fails silently)
|
|
220
226
|
*/
|
|
221
|
-
export async function commitPlanningArtifacts(projectPath: string): Promise<void> {
|
|
227
|
+
export async function commitPlanningArtifacts(projectPath: string, options?: { cwd?: string; additionalFiles?: string[]; isAmend?: boolean }): Promise<void> {
|
|
228
|
+
const execCwd = options?.cwd;
|
|
229
|
+
|
|
222
230
|
// Check if we're in a git repository
|
|
223
|
-
if (!isGitRepo()) {
|
|
231
|
+
if (!isGitRepo(execCwd)) {
|
|
224
232
|
logger.warn('Not in a git repository, skipping planning artifacts commit');
|
|
225
233
|
return;
|
|
226
234
|
}
|
|
@@ -234,25 +242,52 @@ export async function commitPlanningArtifacts(projectPath: string): Promise<void
|
|
|
234
242
|
return;
|
|
235
243
|
}
|
|
236
244
|
|
|
237
|
-
// Build file paths
|
|
245
|
+
// Build absolute file paths
|
|
238
246
|
const inputFile = path.join(projectPath, 'input.md');
|
|
239
247
|
const decisionsFile = path.join(projectPath, 'decisions.md');
|
|
240
248
|
|
|
241
249
|
// Build commit message
|
|
242
|
-
const
|
|
250
|
+
const prefix = options?.isAmend ? 'Amend' : 'Plan';
|
|
251
|
+
const commitMessage = `RAF[${projectNumber}] ${prefix}: ${projectName}`;
|
|
252
|
+
|
|
253
|
+
// Build list of files to stage (absolute paths)
|
|
254
|
+
const absoluteFiles = [inputFile, decisionsFile, ...(options?.additionalFiles ?? [])];
|
|
255
|
+
|
|
256
|
+
// Convert to relative paths when cwd is provided (worktree mode).
|
|
257
|
+
// Git resolves paths relative to the working directory. Using relative paths
|
|
258
|
+
// avoids issues with symlink resolution (e.g., /tmp → /private/tmp on macOS)
|
|
259
|
+
// that can cause absolute paths to not match git's internal worktree paths.
|
|
260
|
+
const filesToStage = execCwd
|
|
261
|
+
? absoluteFiles.map(f => path.relative(execCwd, f))
|
|
262
|
+
: absoluteFiles;
|
|
263
|
+
|
|
264
|
+
// Stage each file individually so one missing file doesn't block the others
|
|
265
|
+
let stagedCount = 0;
|
|
266
|
+
for (const file of filesToStage) {
|
|
267
|
+
try {
|
|
268
|
+
execSync(`git add -- "${file}"`, {
|
|
269
|
+
encoding: 'utf-8',
|
|
270
|
+
stdio: 'pipe',
|
|
271
|
+
...(execCwd ? { cwd: execCwd } : {}),
|
|
272
|
+
});
|
|
273
|
+
stagedCount++;
|
|
274
|
+
} catch (error) {
|
|
275
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
276
|
+
logger.warn(`Failed to stage ${file}: ${msg}`);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
243
279
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
encoding: 'utf-8',
|
|
249
|
-
stdio: 'pipe',
|
|
250
|
-
});
|
|
280
|
+
if (stagedCount === 0) {
|
|
281
|
+
logger.debug('No files were staged for planning artifacts commit');
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
251
284
|
|
|
285
|
+
try {
|
|
252
286
|
// Check if there's anything staged to commit
|
|
253
287
|
const stagedStatus = execSync('git diff --cached --name-only', {
|
|
254
288
|
encoding: 'utf-8',
|
|
255
289
|
stdio: 'pipe',
|
|
290
|
+
...(execCwd ? { cwd: execCwd } : {}),
|
|
256
291
|
}).trim();
|
|
257
292
|
|
|
258
293
|
if (!stagedStatus) {
|
|
@@ -264,6 +299,7 @@ export async function commitPlanningArtifacts(projectPath: string): Promise<void
|
|
|
264
299
|
execSync(`git commit -m "${commitMessage.replace(/"/g, '\\"')}"`, {
|
|
265
300
|
encoding: 'utf-8',
|
|
266
301
|
stdio: 'pipe',
|
|
302
|
+
...(execCwd ? { cwd: execCwd } : {}),
|
|
267
303
|
});
|
|
268
304
|
|
|
269
305
|
logger.debug(`Committed planning artifacts: ${commitMessage}`);
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
getDecisionsPath,
|
|
12
12
|
getInputPath,
|
|
13
13
|
listProjects,
|
|
14
|
+
TASK_ID_PATTERN,
|
|
14
15
|
} from '../utils/paths.js';
|
|
15
16
|
import { sanitizeProjectName } from '../utils/validation.js';
|
|
16
17
|
import { logger } from '../utils/logger.js';
|
|
@@ -145,7 +146,7 @@ export class ProjectManager {
|
|
|
145
146
|
const files = fs.readdirSync(outcomesDir).filter((f) => f.endsWith('.md')).sort();
|
|
146
147
|
|
|
147
148
|
for (const file of files) {
|
|
148
|
-
const match = file.match(
|
|
149
|
+
const match = file.match(new RegExp(`^(${TASK_ID_PATTERN})-`));
|
|
149
150
|
if (match && match[1]) {
|
|
150
151
|
const content = fs.readFileSync(path.join(outcomesDir, file), 'utf-8');
|
|
151
152
|
outcomes.push({ taskId: match[1], content });
|