@camaradesuk/git-worktree-tools 1.10.0 → 1.12.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/README.md +4 -4
- package/dist/lib/config.d.ts +2 -1
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +11 -0
- package/dist/lib/config.js.map +1 -1
- package/package.json +12 -3
- package/schemas/worktreerc.schema.json +1 -1
- package/dist/api/list.test.d.ts +0 -5
- package/dist/api/list.test.d.ts.map +0 -1
- package/dist/api/list.test.js +0 -390
- package/dist/api/list.test.js.map +0 -1
- package/dist/cli/cleanpr.test.d.ts +0 -2
- package/dist/cli/cleanpr.test.d.ts.map +0 -1
- package/dist/cli/cleanpr.test.js +0 -954
- package/dist/cli/cleanpr.test.js.map +0 -1
- package/dist/cli/lswt.test.d.ts +0 -2
- package/dist/cli/lswt.test.d.ts.map +0 -1
- package/dist/cli/lswt.test.js +0 -376
- package/dist/cli/lswt.test.js.map +0 -1
- package/dist/cli/newpr.test.d.ts +0 -2
- package/dist/cli/newpr.test.d.ts.map +0 -1
- package/dist/cli/newpr.test.js +0 -1182
- package/dist/cli/newpr.test.js.map +0 -1
- package/dist/cli/prs.test.d.ts +0 -8
- package/dist/cli/prs.test.d.ts.map +0 -1
- package/dist/cli/prs.test.js +0 -463
- package/dist/cli/prs.test.js.map +0 -1
- package/dist/cli/wt/clean.test.d.ts +0 -8
- package/dist/cli/wt/clean.test.d.ts.map +0 -1
- package/dist/cli/wt/clean.test.js +0 -624
- package/dist/cli/wt/clean.test.js.map +0 -1
- package/dist/cli/wt/completion.test.d.ts +0 -5
- package/dist/cli/wt/completion.test.d.ts.map +0 -1
- package/dist/cli/wt/completion.test.js +0 -275
- package/dist/cli/wt/completion.test.js.map +0 -1
- package/dist/cli/wt/config.test.d.ts +0 -7
- package/dist/cli/wt/config.test.d.ts.map +0 -1
- package/dist/cli/wt/config.test.js +0 -440
- package/dist/cli/wt/config.test.js.map +0 -1
- package/dist/cli/wt/entry.test.d.ts +0 -8
- package/dist/cli/wt/entry.test.d.ts.map +0 -1
- package/dist/cli/wt/entry.test.js +0 -201
- package/dist/cli/wt/entry.test.js.map +0 -1
- package/dist/cli/wt/init.test.d.ts +0 -5
- package/dist/cli/wt/init.test.d.ts.map +0 -1
- package/dist/cli/wt/init.test.js +0 -165
- package/dist/cli/wt/init.test.js.map +0 -1
- package/dist/cli/wt/init.unit.test.d.ts +0 -5
- package/dist/cli/wt/init.unit.test.d.ts.map +0 -1
- package/dist/cli/wt/init.unit.test.js +0 -432
- package/dist/cli/wt/init.unit.test.js.map +0 -1
- package/dist/cli/wt/interactive-menu.test.d.ts +0 -12
- package/dist/cli/wt/interactive-menu.test.d.ts.map +0 -1
- package/dist/cli/wt/interactive-menu.test.js +0 -796
- package/dist/cli/wt/interactive-menu.test.js.map +0 -1
- package/dist/cli/wt/list.test.d.ts +0 -10
- package/dist/cli/wt/list.test.d.ts.map +0 -1
- package/dist/cli/wt/list.test.js +0 -157
- package/dist/cli/wt/list.test.js.map +0 -1
- package/dist/cli/wt/prs.test.d.ts +0 -5
- package/dist/cli/wt/prs.test.d.ts.map +0 -1
- package/dist/cli/wt/prs.test.js +0 -410
- package/dist/cli/wt/prs.test.js.map +0 -1
- package/dist/cli/wt/run-command.test.d.ts +0 -5
- package/dist/cli/wt/run-command.test.d.ts.map +0 -1
- package/dist/cli/wt/run-command.test.js +0 -88
- package/dist/cli/wt/run-command.test.js.map +0 -1
- package/dist/cli/wt/state.test.d.ts +0 -9
- package/dist/cli/wt/state.test.d.ts.map +0 -1
- package/dist/cli/wt/state.test.js +0 -127
- package/dist/cli/wt/state.test.js.map +0 -1
- package/dist/cli/wt/wt.test.d.ts +0 -8
- package/dist/cli/wt/wt.test.d.ts.map +0 -1
- package/dist/cli/wt/wt.test.js +0 -739
- package/dist/cli/wt/wt.test.js.map +0 -1
- package/dist/cli/wt.unit.test.d.ts +0 -7
- package/dist/cli/wt.unit.test.d.ts.map +0 -1
- package/dist/cli/wt.unit.test.js +0 -160
- package/dist/cli/wt.unit.test.js.map +0 -1
- package/dist/cli/wtconfig.test.d.ts +0 -5
- package/dist/cli/wtconfig.test.d.ts.map +0 -1
- package/dist/cli/wtconfig.test.js +0 -1289
- package/dist/cli/wtconfig.test.js.map +0 -1
- package/dist/cli/wtlink.test.d.ts +0 -2
- package/dist/cli/wtlink.test.d.ts.map +0 -1
- package/dist/cli/wtlink.test.js +0 -249
- package/dist/cli/wtlink.test.js.map +0 -1
- package/dist/cli/wtstate.test.d.ts +0 -5
- package/dist/cli/wtstate.test.d.ts.map +0 -1
- package/dist/cli/wtstate.test.js +0 -193
- package/dist/cli/wtstate.test.js.map +0 -1
- package/dist/e2e/cleanpr/cleanpr.e2e.test.d.ts +0 -2
- package/dist/e2e/cleanpr/cleanpr.e2e.test.d.ts.map +0 -1
- package/dist/e2e/cleanpr/cleanpr.e2e.test.js +0 -326
- package/dist/e2e/cleanpr/cleanpr.e2e.test.js.map +0 -1
- package/dist/e2e/cli.e2e.test.d.ts +0 -2
- package/dist/e2e/cli.e2e.test.d.ts.map +0 -1
- package/dist/e2e/cli.e2e.test.js +0 -417
- package/dist/e2e/cli.e2e.test.js.map +0 -1
- package/dist/e2e/lswt/lswt.e2e.test.d.ts +0 -2
- package/dist/e2e/lswt/lswt.e2e.test.d.ts.map +0 -1
- package/dist/e2e/lswt/lswt.e2e.test.js +0 -361
- package/dist/e2e/lswt/lswt.e2e.test.js.map +0 -1
- package/dist/e2e/newpr/newpr.e2e.test.d.ts +0 -2
- package/dist/e2e/newpr/newpr.e2e.test.d.ts.map +0 -1
- package/dist/e2e/newpr/newpr.e2e.test.js +0 -286
- package/dist/e2e/newpr/newpr.e2e.test.js.map +0 -1
- package/dist/e2e/newpr/scenarios.e2e.test.d.ts +0 -2
- package/dist/e2e/newpr/scenarios.e2e.test.d.ts.map +0 -1
- package/dist/e2e/newpr/scenarios.e2e.test.js +0 -426
- package/dist/e2e/newpr/scenarios.e2e.test.js.map +0 -1
- package/dist/e2e/newpr-full-flow.e2e.test.d.ts +0 -2
- package/dist/e2e/newpr-full-flow.e2e.test.d.ts.map +0 -1
- package/dist/e2e/newpr-full-flow.e2e.test.js +0 -280
- package/dist/e2e/newpr-full-flow.e2e.test.js.map +0 -1
- package/dist/e2e/prs/prs.e2e.test.d.ts +0 -7
- package/dist/e2e/prs/prs.e2e.test.d.ts.map +0 -1
- package/dist/e2e/prs/prs.e2e.test.js +0 -606
- package/dist/e2e/prs/prs.e2e.test.js.map +0 -1
- package/dist/e2e/workflows/pr-lifecycle.e2e.test.d.ts +0 -2
- package/dist/e2e/workflows/pr-lifecycle.e2e.test.d.ts.map +0 -1
- package/dist/e2e/workflows/pr-lifecycle.e2e.test.js +0 -298
- package/dist/e2e/workflows/pr-lifecycle.e2e.test.js.map +0 -1
- package/dist/e2e/wt/interactive-menu.e2e.test.d.ts +0 -8
- package/dist/e2e/wt/interactive-menu.e2e.test.d.ts.map +0 -1
- package/dist/e2e/wt/interactive-menu.e2e.test.js +0 -583
- package/dist/e2e/wt/interactive-menu.e2e.test.js.map +0 -1
- package/dist/e2e/wt/wt.e2e.test.d.ts +0 -9
- package/dist/e2e/wt/wt.e2e.test.d.ts.map +0 -1
- package/dist/e2e/wt/wt.e2e.test.js +0 -597
- package/dist/e2e/wt/wt.e2e.test.js.map +0 -1
- package/dist/e2e/wtlink/wtlink.e2e.test.d.ts +0 -2
- package/dist/e2e/wtlink/wtlink.e2e.test.d.ts.map +0 -1
- package/dist/e2e/wtlink/wtlink.e2e.test.js +0 -416
- package/dist/e2e/wtlink/wtlink.e2e.test.js.map +0 -1
- package/dist/integration/git.integration.test.d.ts +0 -2
- package/dist/integration/git.integration.test.d.ts.map +0 -1
- package/dist/integration/git.integration.test.js +0 -336
- package/dist/integration/git.integration.test.js.map +0 -1
- package/dist/integration/lswt-remote-pr.integration.test.d.ts +0 -2
- package/dist/integration/lswt-remote-pr.integration.test.d.ts.map +0 -1
- package/dist/integration/lswt-remote-pr.integration.test.js +0 -222
- package/dist/integration/lswt-remote-pr.integration.test.js.map +0 -1
- package/dist/integration/newpr-branchfrom-head.integration.test.d.ts +0 -2
- package/dist/integration/newpr-branchfrom-head.integration.test.d.ts.map +0 -1
- package/dist/integration/newpr-branchfrom-head.integration.test.js +0 -498
- package/dist/integration/newpr-branchfrom-head.integration.test.js.map +0 -1
- package/dist/integration/newpr.integration.test.d.ts +0 -2
- package/dist/integration/newpr.integration.test.d.ts.map +0 -1
- package/dist/integration/newpr.integration.test.js +0 -460
- package/dist/integration/newpr.integration.test.js.map +0 -1
- package/dist/integration/prs.integration.test.d.ts +0 -8
- package/dist/integration/prs.integration.test.d.ts.map +0 -1
- package/dist/integration/prs.integration.test.js +0 -478
- package/dist/integration/prs.integration.test.js.map +0 -1
- package/dist/lib/ai/base-provider.test.d.ts +0 -7
- package/dist/lib/ai/base-provider.test.d.ts.map +0 -1
- package/dist/lib/ai/base-provider.test.js +0 -319
- package/dist/lib/ai/base-provider.test.js.map +0 -1
- package/dist/lib/ai/cli-provider.test.d.ts +0 -5
- package/dist/lib/ai/cli-provider.test.d.ts.map +0 -1
- package/dist/lib/ai/cli-provider.test.js +0 -460
- package/dist/lib/ai/cli-provider.test.js.map +0 -1
- package/dist/lib/ai/fallback-provider.test.d.ts +0 -7
- package/dist/lib/ai/fallback-provider.test.d.ts.map +0 -1
- package/dist/lib/ai/fallback-provider.test.js +0 -165
- package/dist/lib/ai/fallback-provider.test.js.map +0 -1
- package/dist/lib/ai/generation-service.test.d.ts +0 -7
- package/dist/lib/ai/generation-service.test.d.ts.map +0 -1
- package/dist/lib/ai/generation-service.test.js +0 -213
- package/dist/lib/ai/generation-service.test.js.map +0 -1
- package/dist/lib/ai/provider-manager.test.d.ts +0 -5
- package/dist/lib/ai/provider-manager.test.d.ts.map +0 -1
- package/dist/lib/ai/provider-manager.test.js +0 -312
- package/dist/lib/ai/provider-manager.test.js.map +0 -1
- package/dist/lib/ai/repo-docs.test.d.ts +0 -5
- package/dist/lib/ai/repo-docs.test.d.ts.map +0 -1
- package/dist/lib/ai/repo-docs.test.js +0 -357
- package/dist/lib/ai/repo-docs.test.js.map +0 -1
- package/dist/lib/cleanpr/args.test.d.ts +0 -2
- package/dist/lib/cleanpr/args.test.d.ts.map +0 -1
- package/dist/lib/cleanpr/args.test.js +0 -269
- package/dist/lib/cleanpr/args.test.js.map +0 -1
- package/dist/lib/cleanpr/cleanup.test.d.ts +0 -2
- package/dist/lib/cleanpr/cleanup.test.d.ts.map +0 -1
- package/dist/lib/cleanpr/cleanup.test.js +0 -296
- package/dist/lib/cleanpr/cleanup.test.js.map +0 -1
- package/dist/lib/cleanpr/worktree-info.test.d.ts +0 -2
- package/dist/lib/cleanpr/worktree-info.test.d.ts.map +0 -1
- package/dist/lib/cleanpr/worktree-info.test.js +0 -228
- package/dist/lib/cleanpr/worktree-info.test.js.map +0 -1
- package/dist/lib/colors.test.d.ts +0 -2
- package/dist/lib/colors.test.d.ts.map +0 -1
- package/dist/lib/colors.test.js +0 -142
- package/dist/lib/colors.test.js.map +0 -1
- package/dist/lib/config-editor.test.d.ts +0 -11
- package/dist/lib/config-editor.test.d.ts.map +0 -1
- package/dist/lib/config-editor.test.js +0 -526
- package/dist/lib/config-editor.test.js.map +0 -1
- package/dist/lib/config-migration/detector.test.d.ts +0 -5
- package/dist/lib/config-migration/detector.test.d.ts.map +0 -1
- package/dist/lib/config-migration/detector.test.js +0 -201
- package/dist/lib/config-migration/detector.test.js.map +0 -1
- package/dist/lib/config-migration/reporter.test.d.ts +0 -5
- package/dist/lib/config-migration/reporter.test.d.ts.map +0 -1
- package/dist/lib/config-migration/reporter.test.js +0 -305
- package/dist/lib/config-migration/reporter.test.js.map +0 -1
- package/dist/lib/config-migration/runner.test.d.ts +0 -5
- package/dist/lib/config-migration/runner.test.d.ts.map +0 -1
- package/dist/lib/config-migration/runner.test.js +0 -235
- package/dist/lib/config-migration/runner.test.js.map +0 -1
- package/dist/lib/config-validation.test.d.ts +0 -5
- package/dist/lib/config-validation.test.d.ts.map +0 -1
- package/dist/lib/config-validation.test.js +0 -423
- package/dist/lib/config-validation.test.js.map +0 -1
- package/dist/lib/config.test.d.ts +0 -2
- package/dist/lib/config.test.d.ts.map +0 -1
- package/dist/lib/config.test.js +0 -554
- package/dist/lib/config.test.js.map +0 -1
- package/dist/lib/constants.test.d.ts +0 -5
- package/dist/lib/constants.test.d.ts.map +0 -1
- package/dist/lib/constants.test.js +0 -180
- package/dist/lib/constants.test.js.map +0 -1
- package/dist/lib/deprecation.test.d.ts +0 -2
- package/dist/lib/deprecation.test.d.ts.map +0 -1
- package/dist/lib/deprecation.test.js +0 -71
- package/dist/lib/deprecation.test.js.map +0 -1
- package/dist/lib/errors.test.d.ts +0 -2
- package/dist/lib/errors.test.d.ts.map +0 -1
- package/dist/lib/errors.test.js +0 -117
- package/dist/lib/errors.test.js.map +0 -1
- package/dist/lib/git.test.d.ts +0 -2
- package/dist/lib/git.test.d.ts.map +0 -1
- package/dist/lib/git.test.js +0 -608
- package/dist/lib/git.test.js.map +0 -1
- package/dist/lib/github.test.d.ts +0 -2
- package/dist/lib/github.test.d.ts.map +0 -1
- package/dist/lib/github.test.js +0 -441
- package/dist/lib/github.test.js.map +0 -1
- package/dist/lib/global-check.test.d.ts +0 -5
- package/dist/lib/global-check.test.d.ts.map +0 -1
- package/dist/lib/global-check.test.js +0 -150
- package/dist/lib/global-check.test.js.map +0 -1
- package/dist/lib/global-config.test.d.ts +0 -5
- package/dist/lib/global-config.test.d.ts.map +0 -1
- package/dist/lib/global-config.test.js +0 -282
- package/dist/lib/global-config.test.js.map +0 -1
- package/dist/lib/hooks/confirmation.test.d.ts +0 -7
- package/dist/lib/hooks/confirmation.test.d.ts.map +0 -1
- package/dist/lib/hooks/confirmation.test.js +0 -300
- package/dist/lib/hooks/confirmation.test.js.map +0 -1
- package/dist/lib/hooks/executor.test.d.ts +0 -5
- package/dist/lib/hooks/executor.test.d.ts.map +0 -1
- package/dist/lib/hooks/executor.test.js +0 -648
- package/dist/lib/hooks/executor.test.js.map +0 -1
- package/dist/lib/hooks/templates.test.d.ts +0 -5
- package/dist/lib/hooks/templates.test.d.ts.map +0 -1
- package/dist/lib/hooks/templates.test.js +0 -163
- package/dist/lib/hooks/templates.test.js.map +0 -1
- package/dist/lib/hooks/types.test.d.ts +0 -5
- package/dist/lib/hooks/types.test.d.ts.map +0 -1
- package/dist/lib/hooks/types.test.js +0 -132
- package/dist/lib/hooks/types.test.js.map +0 -1
- package/dist/lib/json-output.test.d.ts +0 -5
- package/dist/lib/json-output.test.d.ts.map +0 -1
- package/dist/lib/json-output.test.js +0 -261
- package/dist/lib/json-output.test.js.map +0 -1
- package/dist/lib/logger.test.d.ts +0 -14
- package/dist/lib/logger.test.d.ts.map +0 -1
- package/dist/lib/logger.test.js +0 -692
- package/dist/lib/logger.test.js.map +0 -1
- package/dist/lib/lswt/action-executors.test.d.ts +0 -2
- package/dist/lib/lswt/action-executors.test.d.ts.map +0 -1
- package/dist/lib/lswt/action-executors.test.js +0 -1127
- package/dist/lib/lswt/action-executors.test.js.map +0 -1
- package/dist/lib/lswt/actions.test.d.ts +0 -2
- package/dist/lib/lswt/actions.test.d.ts.map +0 -1
- package/dist/lib/lswt/actions.test.js +0 -497
- package/dist/lib/lswt/actions.test.js.map +0 -1
- package/dist/lib/lswt/args.test.d.ts +0 -2
- package/dist/lib/lswt/args.test.d.ts.map +0 -1
- package/dist/lib/lswt/args.test.js +0 -195
- package/dist/lib/lswt/args.test.js.map +0 -1
- package/dist/lib/lswt/environment.test.d.ts +0 -2
- package/dist/lib/lswt/environment.test.d.ts.map +0 -1
- package/dist/lib/lswt/environment.test.js +0 -544
- package/dist/lib/lswt/environment.test.js.map +0 -1
- package/dist/lib/lswt/formatters.test.d.ts +0 -2
- package/dist/lib/lswt/formatters.test.d.ts.map +0 -1
- package/dist/lib/lswt/formatters.test.js +0 -323
- package/dist/lib/lswt/formatters.test.js.map +0 -1
- package/dist/lib/lswt/fuzzy-search.test.d.ts +0 -5
- package/dist/lib/lswt/fuzzy-search.test.d.ts.map +0 -1
- package/dist/lib/lswt/fuzzy-search.test.js +0 -207
- package/dist/lib/lswt/fuzzy-search.test.js.map +0 -1
- package/dist/lib/lswt/interactive.test.d.ts +0 -2
- package/dist/lib/lswt/interactive.test.d.ts.map +0 -1
- package/dist/lib/lswt/interactive.test.js +0 -771
- package/dist/lib/lswt/interactive.test.js.map +0 -1
- package/dist/lib/lswt/table.test.d.ts +0 -5
- package/dist/lib/lswt/table.test.d.ts.map +0 -1
- package/dist/lib/lswt/table.test.js +0 -262
- package/dist/lib/lswt/table.test.js.map +0 -1
- package/dist/lib/lswt/worktree-info.test.d.ts +0 -2
- package/dist/lib/lswt/worktree-info.test.d.ts.map +0 -1
- package/dist/lib/lswt/worktree-info.test.js +0 -484
- package/dist/lib/lswt/worktree-info.test.js.map +0 -1
- package/dist/lib/newpr/action-deps.test.d.ts +0 -5
- package/dist/lib/newpr/action-deps.test.d.ts.map +0 -1
- package/dist/lib/newpr/action-deps.test.js +0 -111
- package/dist/lib/newpr/action-deps.test.js.map +0 -1
- package/dist/lib/newpr/actions.test.d.ts +0 -2
- package/dist/lib/newpr/actions.test.d.ts.map +0 -1
- package/dist/lib/newpr/actions.test.js +0 -254
- package/dist/lib/newpr/actions.test.js.map +0 -1
- package/dist/lib/newpr/args.test.d.ts +0 -2
- package/dist/lib/newpr/args.test.d.ts.map +0 -1
- package/dist/lib/newpr/args.test.js +0 -479
- package/dist/lib/newpr/args.test.js.map +0 -1
- package/dist/lib/newpr/hook-runner.test.d.ts +0 -7
- package/dist/lib/newpr/hook-runner.test.d.ts.map +0 -1
- package/dist/lib/newpr/hook-runner.test.js +0 -422
- package/dist/lib/newpr/hook-runner.test.js.map +0 -1
- package/dist/lib/newpr/plan-generator.test.d.ts +0 -7
- package/dist/lib/newpr/plan-generator.test.d.ts.map +0 -1
- package/dist/lib/newpr/plan-generator.test.js +0 -387
- package/dist/lib/newpr/plan-generator.test.js.map +0 -1
- package/dist/lib/newpr/scenario-handler.test.d.ts +0 -2
- package/dist/lib/newpr/scenario-handler.test.d.ts.map +0 -1
- package/dist/lib/newpr/scenario-handler.test.js +0 -256
- package/dist/lib/newpr/scenario-handler.test.js.map +0 -1
- package/dist/lib/prompts.test.d.ts +0 -2
- package/dist/lib/prompts.test.d.ts.map +0 -1
- package/dist/lib/prompts.test.js +0 -807
- package/dist/lib/prompts.test.js.map +0 -1
- package/dist/lib/prs/actions.test.d.ts +0 -5
- package/dist/lib/prs/actions.test.d.ts.map +0 -1
- package/dist/lib/prs/actions.test.js +0 -356
- package/dist/lib/prs/actions.test.js.map +0 -1
- package/dist/lib/prs/command.test.d.ts +0 -11
- package/dist/lib/prs/command.test.d.ts.map +0 -1
- package/dist/lib/prs/command.test.js +0 -409
- package/dist/lib/prs/command.test.js.map +0 -1
- package/dist/lib/prs/data.test.d.ts +0 -5
- package/dist/lib/prs/data.test.d.ts.map +0 -1
- package/dist/lib/prs/data.test.js +0 -417
- package/dist/lib/prs/data.test.js.map +0 -1
- package/dist/lib/prs/details.test.d.ts +0 -5
- package/dist/lib/prs/details.test.d.ts.map +0 -1
- package/dist/lib/prs/details.test.js +0 -325
- package/dist/lib/prs/details.test.js.map +0 -1
- package/dist/lib/prs/filters.test.d.ts +0 -5
- package/dist/lib/prs/filters.test.d.ts.map +0 -1
- package/dist/lib/prs/filters.test.js +0 -312
- package/dist/lib/prs/filters.test.js.map +0 -1
- package/dist/lib/prs/formatters.test.d.ts +0 -2
- package/dist/lib/prs/formatters.test.d.ts.map +0 -1
- package/dist/lib/prs/formatters.test.js +0 -387
- package/dist/lib/prs/formatters.test.js.map +0 -1
- package/dist/lib/prs/interactive.test.d.ts +0 -5
- package/dist/lib/prs/interactive.test.d.ts.map +0 -1
- package/dist/lib/prs/interactive.test.js +0 -517
- package/dist/lib/prs/interactive.test.js.map +0 -1
- package/dist/lib/schema.test.d.ts +0 -10
- package/dist/lib/schema.test.d.ts.map +0 -1
- package/dist/lib/schema.test.js +0 -309
- package/dist/lib/schema.test.js.map +0 -1
- package/dist/lib/state-detection.test.d.ts +0 -2
- package/dist/lib/state-detection.test.d.ts.map +0 -1
- package/dist/lib/state-detection.test.js +0 -451
- package/dist/lib/state-detection.test.js.map +0 -1
- package/dist/lib/ui/error.test.d.ts +0 -2
- package/dist/lib/ui/error.test.d.ts.map +0 -1
- package/dist/lib/ui/error.test.js +0 -143
- package/dist/lib/ui/error.test.js.map +0 -1
- package/dist/lib/ui/output.test.d.ts +0 -2
- package/dist/lib/ui/output.test.d.ts.map +0 -1
- package/dist/lib/ui/output.test.js +0 -59
- package/dist/lib/ui/output.test.js.map +0 -1
- package/dist/lib/ui/status.test.d.ts +0 -2
- package/dist/lib/ui/status.test.d.ts.map +0 -1
- package/dist/lib/ui/status.test.js +0 -158
- package/dist/lib/ui/status.test.js.map +0 -1
- package/dist/lib/ui/table.test.d.ts +0 -2
- package/dist/lib/ui/table.test.d.ts.map +0 -1
- package/dist/lib/ui/table.test.js +0 -115
- package/dist/lib/ui/table.test.js.map +0 -1
- package/dist/lib/ui/theme.test.d.ts +0 -2
- package/dist/lib/ui/theme.test.d.ts.map +0 -1
- package/dist/lib/ui/theme.test.js +0 -76
- package/dist/lib/ui/theme.test.js.map +0 -1
- package/dist/lib/wtconfig/config-manager.test.d.ts +0 -5
- package/dist/lib/wtconfig/config-manager.test.d.ts.map +0 -1
- package/dist/lib/wtconfig/config-manager.test.js +0 -501
- package/dist/lib/wtconfig/config-manager.test.js.map +0 -1
- package/dist/lib/wtconfig/environment.test.d.ts +0 -5
- package/dist/lib/wtconfig/environment.test.d.ts.map +0 -1
- package/dist/lib/wtconfig/environment.test.js +0 -285
- package/dist/lib/wtconfig/environment.test.js.map +0 -1
- package/dist/lib/wtlink/config-manifest.test.d.ts +0 -2
- package/dist/lib/wtlink/config-manifest.test.d.ts.map +0 -1
- package/dist/lib/wtlink/config-manifest.test.js +0 -486
- package/dist/lib/wtlink/config-manifest.test.js.map +0 -1
- package/dist/lib/wtlink/link-configs.test.d.ts +0 -2
- package/dist/lib/wtlink/link-configs.test.d.ts.map +0 -1
- package/dist/lib/wtlink/link-configs.test.js +0 -612
- package/dist/lib/wtlink/link-configs.test.js.map +0 -1
- package/dist/lib/wtlink/main-menu.test.d.ts +0 -5
- package/dist/lib/wtlink/main-menu.test.d.ts.map +0 -1
- package/dist/lib/wtlink/main-menu.test.js +0 -126
- package/dist/lib/wtlink/main-menu.test.js.map +0 -1
- package/dist/lib/wtlink/manage-manifest.test.d.ts +0 -2
- package/dist/lib/wtlink/manage-manifest.test.d.ts.map +0 -1
- package/dist/lib/wtlink/manage-manifest.test.js +0 -714
- package/dist/lib/wtlink/manage-manifest.test.js.map +0 -1
- package/dist/lib/wtlink/validate-manifest.test.d.ts +0 -2
- package/dist/lib/wtlink/validate-manifest.test.d.ts.map +0 -1
- package/dist/lib/wtlink/validate-manifest.test.js +0 -220
- package/dist/lib/wtlink/validate-manifest.test.js.map +0 -1
- package/dist/lib/wtstate/analyze.test.d.ts +0 -5
- package/dist/lib/wtstate/analyze.test.d.ts.map +0 -1
- package/dist/lib/wtstate/analyze.test.js +0 -282
- package/dist/lib/wtstate/analyze.test.js.map +0 -1
- package/dist/lib/wtstate/args.test.d.ts +0 -5
- package/dist/lib/wtstate/args.test.d.ts.map +0 -1
- package/dist/lib/wtstate/args.test.js +0 -120
- package/dist/lib/wtstate/args.test.js.map +0 -1
- package/dist/mcp/server.test.d.ts +0 -9
- package/dist/mcp/server.test.d.ts.map +0 -1
- package/dist/mcp/server.test.js +0 -550
- package/dist/mcp/server.test.js.map +0 -1
|
@@ -1,771 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
-
import { formatWorktreeChoiceWithColors, formatTypeBadgeWithColors, formatStatusWithColors, runInteractiveMode, getActionForShortcut, getBadgeText, computeMaxBadgeWidth, } from './interactive.js';
|
|
3
|
-
// Mock git
|
|
4
|
-
vi.mock('../git.js', () => ({
|
|
5
|
-
getRepoRoot: vi.fn(),
|
|
6
|
-
}));
|
|
7
|
-
// Mock config
|
|
8
|
-
vi.mock('../config.js', () => ({
|
|
9
|
-
loadConfig: vi.fn().mockReturnValue({}),
|
|
10
|
-
}));
|
|
11
|
-
// Mock environment
|
|
12
|
-
vi.mock('./environment.js', () => ({
|
|
13
|
-
detectEnvironment: vi.fn(() => ({
|
|
14
|
-
hasVscode: true,
|
|
15
|
-
hasCursor: false,
|
|
16
|
-
defaultEditor: 'vscode',
|
|
17
|
-
platform: 'linux',
|
|
18
|
-
isInteractive: true,
|
|
19
|
-
shell: '/bin/bash',
|
|
20
|
-
gitVersion: { major: 2, minor: 39, patch: 0, raw: 'git version 2.39.0' },
|
|
21
|
-
})),
|
|
22
|
-
}));
|
|
23
|
-
// Mock actions
|
|
24
|
-
vi.mock('./actions.js', () => ({
|
|
25
|
-
buildActionMenu: vi.fn(() => [
|
|
26
|
-
{ name: 'Open in editor', value: 'open_editor', shortcut: 'e' },
|
|
27
|
-
{ name: 'Exit', value: 'exit', shortcut: 'q' },
|
|
28
|
-
]),
|
|
29
|
-
formatShortcutLegend: vi.fn(() => '[e] editor [q] exit'),
|
|
30
|
-
}));
|
|
31
|
-
// Mock action-executors
|
|
32
|
-
vi.mock('./action-executors.js', () => ({
|
|
33
|
-
executeAction: vi.fn().mockResolvedValue({ success: true }),
|
|
34
|
-
createDefaultExecutorDeps: vi.fn().mockReturnValue({}),
|
|
35
|
-
}));
|
|
36
|
-
// Mock worktree-info
|
|
37
|
-
vi.mock('./worktree-info.js', () => ({
|
|
38
|
-
gatherWorktreeInfo: vi.fn().mockResolvedValue([]),
|
|
39
|
-
createDefaultDeps: vi.fn().mockReturnValue({}),
|
|
40
|
-
}));
|
|
41
|
-
import * as git from '../git.js';
|
|
42
|
-
import { executeAction } from './action-executors.js';
|
|
43
|
-
import { gatherWorktreeInfo } from './worktree-info.js';
|
|
44
|
-
describe('lswt/interactive', () => {
|
|
45
|
-
// Helper to create mock interactive deps
|
|
46
|
-
const createMockDeps = (overrides = {}) => ({
|
|
47
|
-
selectWorktree: vi.fn().mockResolvedValue({ worktree: null, action: null }),
|
|
48
|
-
selectAction: vi.fn().mockResolvedValue('exit'),
|
|
49
|
-
pressEnterToContinue: vi.fn().mockResolvedValue(undefined),
|
|
50
|
-
...overrides,
|
|
51
|
-
});
|
|
52
|
-
const makeWorktree = (overrides = {}) => ({
|
|
53
|
-
path: '/home/user/repo',
|
|
54
|
-
name: 'repo',
|
|
55
|
-
branch: 'main',
|
|
56
|
-
commit: 'abc123',
|
|
57
|
-
type: 'main',
|
|
58
|
-
prNumber: null,
|
|
59
|
-
prState: null,
|
|
60
|
-
isDraft: null,
|
|
61
|
-
hasChanges: false,
|
|
62
|
-
...overrides,
|
|
63
|
-
});
|
|
64
|
-
describe('formatTypeBadgeWithColors', () => {
|
|
65
|
-
it('formats main worktree badge', () => {
|
|
66
|
-
const worktree = makeWorktree({ type: 'main' });
|
|
67
|
-
const badgeWidth = computeMaxBadgeWidth([worktree]);
|
|
68
|
-
const result = formatTypeBadgeWithColors(worktree, badgeWidth);
|
|
69
|
-
expect(result).toContain('[main]');
|
|
70
|
-
});
|
|
71
|
-
it('formats PR worktree badge', () => {
|
|
72
|
-
const worktree = makeWorktree({
|
|
73
|
-
type: 'pr',
|
|
74
|
-
prNumber: 42,
|
|
75
|
-
prState: 'OPEN',
|
|
76
|
-
});
|
|
77
|
-
const badgeWidth = computeMaxBadgeWidth([worktree]);
|
|
78
|
-
const result = formatTypeBadgeWithColors(worktree, badgeWidth);
|
|
79
|
-
expect(result).toContain('[PR #42]');
|
|
80
|
-
});
|
|
81
|
-
it('formats draft PR badge with DRAFT indicator', () => {
|
|
82
|
-
const worktree = makeWorktree({
|
|
83
|
-
type: 'pr',
|
|
84
|
-
prNumber: 42,
|
|
85
|
-
prState: 'OPEN',
|
|
86
|
-
isDraft: true,
|
|
87
|
-
});
|
|
88
|
-
const badgeWidth = computeMaxBadgeWidth([worktree]);
|
|
89
|
-
const result = formatTypeBadgeWithColors(worktree, badgeWidth);
|
|
90
|
-
expect(result).toContain('DRAFT');
|
|
91
|
-
expect(result).toContain('#42');
|
|
92
|
-
});
|
|
93
|
-
it('formats branch worktree badge', () => {
|
|
94
|
-
const worktree = makeWorktree({
|
|
95
|
-
type: 'branch',
|
|
96
|
-
branch: 'feature-branch',
|
|
97
|
-
});
|
|
98
|
-
const badgeWidth = computeMaxBadgeWidth([worktree]);
|
|
99
|
-
const result = formatTypeBadgeWithColors(worktree, badgeWidth);
|
|
100
|
-
expect(result).toContain('[branch]');
|
|
101
|
-
});
|
|
102
|
-
it('formats detached worktree badge', () => {
|
|
103
|
-
const worktree = makeWorktree({
|
|
104
|
-
type: 'detached',
|
|
105
|
-
branch: null,
|
|
106
|
-
});
|
|
107
|
-
const badgeWidth = computeMaxBadgeWidth([worktree]);
|
|
108
|
-
const result = formatTypeBadgeWithColors(worktree, badgeWidth);
|
|
109
|
-
expect(result).toContain('[detached]');
|
|
110
|
-
});
|
|
111
|
-
it('formats remote PR worktree badge', () => {
|
|
112
|
-
const worktree = makeWorktree({
|
|
113
|
-
type: 'remote_pr',
|
|
114
|
-
prNumber: 42,
|
|
115
|
-
prState: 'OPEN',
|
|
116
|
-
});
|
|
117
|
-
const badgeWidth = computeMaxBadgeWidth([worktree]);
|
|
118
|
-
const result = formatTypeBadgeWithColors(worktree, badgeWidth);
|
|
119
|
-
expect(result).toContain('[PR #42 REMOTE]');
|
|
120
|
-
});
|
|
121
|
-
it('formats remote PR draft worktree badge', () => {
|
|
122
|
-
const worktree = makeWorktree({
|
|
123
|
-
type: 'remote_pr',
|
|
124
|
-
prNumber: 42,
|
|
125
|
-
prState: 'OPEN',
|
|
126
|
-
isDraft: true,
|
|
127
|
-
});
|
|
128
|
-
const badgeWidth = computeMaxBadgeWidth([worktree]);
|
|
129
|
-
const result = formatTypeBadgeWithColors(worktree, badgeWidth);
|
|
130
|
-
expect(result).toContain('REMOTE');
|
|
131
|
-
expect(result).toContain('DRAFT');
|
|
132
|
-
expect(result).toContain('#42');
|
|
133
|
-
});
|
|
134
|
-
});
|
|
135
|
-
describe('formatStatusWithColors', () => {
|
|
136
|
-
it('returns empty string when no status info', () => {
|
|
137
|
-
const worktree = makeWorktree({
|
|
138
|
-
type: 'branch',
|
|
139
|
-
prState: null,
|
|
140
|
-
hasChanges: false,
|
|
141
|
-
});
|
|
142
|
-
const result = formatStatusWithColors(worktree);
|
|
143
|
-
expect(result).toBe('');
|
|
144
|
-
});
|
|
145
|
-
it('shows OPEN status for open PRs', () => {
|
|
146
|
-
const worktree = makeWorktree({
|
|
147
|
-
type: 'pr',
|
|
148
|
-
prNumber: 1,
|
|
149
|
-
prState: 'OPEN',
|
|
150
|
-
});
|
|
151
|
-
const result = formatStatusWithColors(worktree);
|
|
152
|
-
expect(result).toContain('OPEN');
|
|
153
|
-
});
|
|
154
|
-
it('shows MERGED status for merged PRs', () => {
|
|
155
|
-
const worktree = makeWorktree({
|
|
156
|
-
type: 'pr',
|
|
157
|
-
prNumber: 1,
|
|
158
|
-
prState: 'MERGED',
|
|
159
|
-
});
|
|
160
|
-
const result = formatStatusWithColors(worktree);
|
|
161
|
-
expect(result).toContain('MERGED');
|
|
162
|
-
});
|
|
163
|
-
it('shows CLOSED status for closed PRs', () => {
|
|
164
|
-
const worktree = makeWorktree({
|
|
165
|
-
type: 'pr',
|
|
166
|
-
prNumber: 1,
|
|
167
|
-
prState: 'CLOSED',
|
|
168
|
-
});
|
|
169
|
-
const result = formatStatusWithColors(worktree);
|
|
170
|
-
expect(result).toContain('CLOSED');
|
|
171
|
-
});
|
|
172
|
-
it('shows has changes indicator', () => {
|
|
173
|
-
const worktree = makeWorktree({
|
|
174
|
-
type: 'branch',
|
|
175
|
-
hasChanges: true,
|
|
176
|
-
});
|
|
177
|
-
const result = formatStatusWithColors(worktree);
|
|
178
|
-
expect(result).toContain('has changes');
|
|
179
|
-
});
|
|
180
|
-
it('shows clean status for main worktree without changes', () => {
|
|
181
|
-
const worktree = makeWorktree({
|
|
182
|
-
type: 'main',
|
|
183
|
-
hasChanges: false,
|
|
184
|
-
});
|
|
185
|
-
const result = formatStatusWithColors(worktree);
|
|
186
|
-
expect(result).toContain('clean');
|
|
187
|
-
});
|
|
188
|
-
it('shows both PR state and changes', () => {
|
|
189
|
-
const worktree = makeWorktree({
|
|
190
|
-
type: 'pr',
|
|
191
|
-
prNumber: 1,
|
|
192
|
-
prState: 'OPEN',
|
|
193
|
-
hasChanges: true,
|
|
194
|
-
});
|
|
195
|
-
const result = formatStatusWithColors(worktree);
|
|
196
|
-
expect(result).toContain('OPEN');
|
|
197
|
-
expect(result).toContain('has changes');
|
|
198
|
-
});
|
|
199
|
-
});
|
|
200
|
-
describe('getBadgeText', () => {
|
|
201
|
-
it('returns [main] for main worktree', () => {
|
|
202
|
-
const worktree = makeWorktree({ type: 'main' });
|
|
203
|
-
expect(getBadgeText(worktree)).toBe('[main]');
|
|
204
|
-
});
|
|
205
|
-
it('returns [PR #N] for PR worktree', () => {
|
|
206
|
-
const worktree = makeWorktree({ type: 'pr', prNumber: 42 });
|
|
207
|
-
expect(getBadgeText(worktree)).toBe('[PR #42]');
|
|
208
|
-
});
|
|
209
|
-
it('returns [PR #N DRAFT] for draft PR worktree', () => {
|
|
210
|
-
const worktree = makeWorktree({ type: 'pr', prNumber: 42, isDraft: true });
|
|
211
|
-
expect(getBadgeText(worktree)).toBe('[PR #42 DRAFT]');
|
|
212
|
-
});
|
|
213
|
-
it('returns [PR #N REMOTE] for remote PR worktree', () => {
|
|
214
|
-
const worktree = makeWorktree({ type: 'remote_pr', prNumber: 42 });
|
|
215
|
-
expect(getBadgeText(worktree)).toBe('[PR #42 REMOTE]');
|
|
216
|
-
});
|
|
217
|
-
it('returns [PR #N REMOTE DRAFT] for remote draft PR worktree', () => {
|
|
218
|
-
const worktree = makeWorktree({ type: 'remote_pr', prNumber: 42, isDraft: true });
|
|
219
|
-
expect(getBadgeText(worktree)).toBe('[PR #42 REMOTE DRAFT]');
|
|
220
|
-
});
|
|
221
|
-
it('returns [branch] for branch worktree', () => {
|
|
222
|
-
const worktree = makeWorktree({ type: 'branch' });
|
|
223
|
-
expect(getBadgeText(worktree)).toBe('[branch]');
|
|
224
|
-
});
|
|
225
|
-
it('returns [detached] for detached worktree', () => {
|
|
226
|
-
const worktree = makeWorktree({ type: 'detached' });
|
|
227
|
-
expect(getBadgeText(worktree)).toBe('[detached]');
|
|
228
|
-
});
|
|
229
|
-
it('handles large PR numbers correctly', () => {
|
|
230
|
-
const worktree = makeWorktree({ type: 'pr', prNumber: 12345 });
|
|
231
|
-
expect(getBadgeText(worktree)).toBe('[PR #12345]');
|
|
232
|
-
});
|
|
233
|
-
});
|
|
234
|
-
describe('computeMaxBadgeWidth', () => {
|
|
235
|
-
it('returns sensible default for empty array', () => {
|
|
236
|
-
expect(computeMaxBadgeWidth([])).toBe(12);
|
|
237
|
-
});
|
|
238
|
-
it('computes width based on longest badge', () => {
|
|
239
|
-
const worktrees = [
|
|
240
|
-
makeWorktree({ type: 'main' }), // [main] = 6
|
|
241
|
-
makeWorktree({ type: 'pr', prNumber: 42 }), // [PR #42] = 8
|
|
242
|
-
];
|
|
243
|
-
// Max is 8 + 2 padding = 10
|
|
244
|
-
expect(computeMaxBadgeWidth(worktrees)).toBe(10);
|
|
245
|
-
});
|
|
246
|
-
it('handles large PR numbers in width calculation', () => {
|
|
247
|
-
const worktrees = [
|
|
248
|
-
makeWorktree({ type: 'main' }), // [main] = 6
|
|
249
|
-
makeWorktree({ type: 'pr', prNumber: 99999 }), // [PR #99999] = 11
|
|
250
|
-
];
|
|
251
|
-
// Max is 11 + 2 padding = 13
|
|
252
|
-
expect(computeMaxBadgeWidth(worktrees)).toBe(13);
|
|
253
|
-
});
|
|
254
|
-
it('handles remote PRs in width calculation', () => {
|
|
255
|
-
const worktrees = [
|
|
256
|
-
makeWorktree({ type: 'main' }), // [main] = 6
|
|
257
|
-
makeWorktree({ type: 'remote_pr', prNumber: 42, isDraft: true }), // [PR #42 REMOTE DRAFT] = 21
|
|
258
|
-
];
|
|
259
|
-
// Max is 21 + 2 padding = 23
|
|
260
|
-
expect(computeMaxBadgeWidth(worktrees)).toBe(23);
|
|
261
|
-
});
|
|
262
|
-
});
|
|
263
|
-
describe('formatWorktreeChoiceWithColors', () => {
|
|
264
|
-
it('includes type badge', () => {
|
|
265
|
-
const worktree = makeWorktree({ type: 'main' });
|
|
266
|
-
const badgeWidth = computeMaxBadgeWidth([worktree]);
|
|
267
|
-
const result = formatWorktreeChoiceWithColors(worktree, badgeWidth);
|
|
268
|
-
expect(result).toContain('[main]');
|
|
269
|
-
});
|
|
270
|
-
it('includes branch name', () => {
|
|
271
|
-
const worktree = makeWorktree({
|
|
272
|
-
type: 'branch',
|
|
273
|
-
branch: 'feature-xyz',
|
|
274
|
-
});
|
|
275
|
-
const badgeWidth = computeMaxBadgeWidth([worktree]);
|
|
276
|
-
const result = formatWorktreeChoiceWithColors(worktree, badgeWidth);
|
|
277
|
-
expect(result).toContain('feature-xyz');
|
|
278
|
-
});
|
|
279
|
-
it('shows (detached) for detached worktrees', () => {
|
|
280
|
-
const worktree = makeWorktree({
|
|
281
|
-
type: 'detached',
|
|
282
|
-
branch: null,
|
|
283
|
-
});
|
|
284
|
-
const badgeWidth = computeMaxBadgeWidth([worktree]);
|
|
285
|
-
const result = formatWorktreeChoiceWithColors(worktree, badgeWidth);
|
|
286
|
-
expect(result).toContain('(detached)');
|
|
287
|
-
});
|
|
288
|
-
it('includes status for PR worktrees', () => {
|
|
289
|
-
const worktree = makeWorktree({
|
|
290
|
-
type: 'pr',
|
|
291
|
-
prNumber: 42,
|
|
292
|
-
prState: 'OPEN',
|
|
293
|
-
branch: 'feat/something',
|
|
294
|
-
});
|
|
295
|
-
const badgeWidth = computeMaxBadgeWidth([worktree]);
|
|
296
|
-
const result = formatWorktreeChoiceWithColors(worktree, badgeWidth);
|
|
297
|
-
expect(result).toContain('[PR #42]');
|
|
298
|
-
expect(result).toContain('feat/something');
|
|
299
|
-
expect(result).toContain('OPEN');
|
|
300
|
-
});
|
|
301
|
-
it('includes draft indicator for draft PRs', () => {
|
|
302
|
-
const worktree = makeWorktree({
|
|
303
|
-
type: 'pr',
|
|
304
|
-
prNumber: 42,
|
|
305
|
-
prState: 'OPEN',
|
|
306
|
-
isDraft: true,
|
|
307
|
-
branch: 'feat/something',
|
|
308
|
-
});
|
|
309
|
-
const badgeWidth = computeMaxBadgeWidth([worktree]);
|
|
310
|
-
const result = formatWorktreeChoiceWithColors(worktree, badgeWidth);
|
|
311
|
-
expect(result).toContain('DRAFT');
|
|
312
|
-
});
|
|
313
|
-
it('includes has changes indicator', () => {
|
|
314
|
-
const worktree = makeWorktree({
|
|
315
|
-
type: 'branch',
|
|
316
|
-
branch: 'feature',
|
|
317
|
-
hasChanges: true,
|
|
318
|
-
});
|
|
319
|
-
const badgeWidth = computeMaxBadgeWidth([worktree]);
|
|
320
|
-
const result = formatWorktreeChoiceWithColors(worktree, badgeWidth);
|
|
321
|
-
expect(result).toContain('has changes');
|
|
322
|
-
});
|
|
323
|
-
it('shows PR title for remote PRs instead of branch', () => {
|
|
324
|
-
const worktree = makeWorktree({
|
|
325
|
-
type: 'remote_pr',
|
|
326
|
-
prNumber: 42,
|
|
327
|
-
prState: 'OPEN',
|
|
328
|
-
branch: 'feat/some-long-branch-name',
|
|
329
|
-
prTitle: 'Add amazing new feature',
|
|
330
|
-
});
|
|
331
|
-
const badgeWidth = computeMaxBadgeWidth([worktree]);
|
|
332
|
-
const result = formatWorktreeChoiceWithColors(worktree, badgeWidth);
|
|
333
|
-
expect(result).toContain('Add amazing new feature');
|
|
334
|
-
expect(result).toContain('[PR #42 REMOTE]');
|
|
335
|
-
});
|
|
336
|
-
it('truncates long PR titles for remote PRs', () => {
|
|
337
|
-
const worktree = makeWorktree({
|
|
338
|
-
type: 'remote_pr',
|
|
339
|
-
prNumber: 42,
|
|
340
|
-
prState: 'OPEN',
|
|
341
|
-
branch: 'feat/feature',
|
|
342
|
-
prTitle: 'This is a very long pull request title that should be truncated for display',
|
|
343
|
-
});
|
|
344
|
-
const badgeWidth = computeMaxBadgeWidth([worktree]);
|
|
345
|
-
const result = formatWorktreeChoiceWithColors(worktree, badgeWidth);
|
|
346
|
-
// Title should be truncated to 30 chars with ...
|
|
347
|
-
expect(result).toContain('...');
|
|
348
|
-
});
|
|
349
|
-
it('shows OPEN status for remote PRs', () => {
|
|
350
|
-
const worktree = makeWorktree({
|
|
351
|
-
type: 'remote_pr',
|
|
352
|
-
prNumber: 42,
|
|
353
|
-
prState: 'OPEN',
|
|
354
|
-
prTitle: 'New feature',
|
|
355
|
-
});
|
|
356
|
-
const badgeWidth = computeMaxBadgeWidth([worktree]);
|
|
357
|
-
const result = formatWorktreeChoiceWithColors(worktree, badgeWidth);
|
|
358
|
-
expect(result).toContain('OPEN');
|
|
359
|
-
});
|
|
360
|
-
it('includes draft indicator for remote PR drafts', () => {
|
|
361
|
-
const worktree = makeWorktree({
|
|
362
|
-
type: 'remote_pr',
|
|
363
|
-
prNumber: 42,
|
|
364
|
-
prState: 'OPEN',
|
|
365
|
-
isDraft: true,
|
|
366
|
-
prTitle: 'Draft feature',
|
|
367
|
-
});
|
|
368
|
-
const badgeWidth = computeMaxBadgeWidth([worktree]);
|
|
369
|
-
const result = formatWorktreeChoiceWithColors(worktree, badgeWidth);
|
|
370
|
-
expect(result).toContain('DRAFT');
|
|
371
|
-
});
|
|
372
|
-
});
|
|
373
|
-
describe('getActionForShortcut', () => {
|
|
374
|
-
// Basic shortcut mapping tests
|
|
375
|
-
it('returns open_editor for "e" shortcut on regular worktrees', () => {
|
|
376
|
-
const worktree = makeWorktree({ type: 'main' });
|
|
377
|
-
expect(getActionForShortcut('e', worktree)).toBe('open_editor');
|
|
378
|
-
});
|
|
379
|
-
it('returns open_terminal for "t" shortcut', () => {
|
|
380
|
-
const worktree = makeWorktree({ type: 'branch' });
|
|
381
|
-
expect(getActionForShortcut('t', worktree)).toBe('open_terminal');
|
|
382
|
-
});
|
|
383
|
-
it('returns copy_path for "c" shortcut', () => {
|
|
384
|
-
const worktree = makeWorktree({ type: 'main' });
|
|
385
|
-
expect(getActionForShortcut('c', worktree)).toBe('copy_path');
|
|
386
|
-
});
|
|
387
|
-
it('returns show_details for "d" shortcut', () => {
|
|
388
|
-
const worktree = makeWorktree({ type: 'main' });
|
|
389
|
-
expect(getActionForShortcut('d', worktree)).toBe('show_details');
|
|
390
|
-
});
|
|
391
|
-
it('returns link_configs for "l" shortcut', () => {
|
|
392
|
-
const worktree = makeWorktree({ type: 'main' });
|
|
393
|
-
expect(getActionForShortcut('l', worktree)).toBe('link_configs');
|
|
394
|
-
});
|
|
395
|
-
it('returns exit for "q" shortcut', () => {
|
|
396
|
-
const worktree = makeWorktree({ type: 'main' });
|
|
397
|
-
expect(getActionForShortcut('q', worktree)).toBe('exit');
|
|
398
|
-
});
|
|
399
|
-
it('returns null for unknown shortcut keys', () => {
|
|
400
|
-
const worktree = makeWorktree({ type: 'main' });
|
|
401
|
-
expect(getActionForShortcut('x', worktree)).toBeNull();
|
|
402
|
-
expect(getActionForShortcut('z', worktree)).toBeNull();
|
|
403
|
-
expect(getActionForShortcut('1', worktree)).toBeNull();
|
|
404
|
-
});
|
|
405
|
-
// "p" key behavior tests
|
|
406
|
-
describe('"p" key behavior', () => {
|
|
407
|
-
it('returns open_pr_url for "p" on PR worktree', () => {
|
|
408
|
-
const worktree = makeWorktree({ type: 'pr', prNumber: 42, prState: 'OPEN' });
|
|
409
|
-
expect(getActionForShortcut('p', worktree)).toBe('open_pr_url');
|
|
410
|
-
});
|
|
411
|
-
it('returns create_pr for "p" on branch worktree', () => {
|
|
412
|
-
const worktree = makeWorktree({ type: 'branch', branch: 'feature' });
|
|
413
|
-
expect(getActionForShortcut('p', worktree)).toBe('create_pr');
|
|
414
|
-
});
|
|
415
|
-
it('returns open_pr_url for "p" on remote_pr worktree', () => {
|
|
416
|
-
const worktree = makeWorktree({ type: 'remote_pr', prNumber: 42, prState: 'OPEN' });
|
|
417
|
-
expect(getActionForShortcut('p', worktree)).toBe('open_pr_url');
|
|
418
|
-
});
|
|
419
|
-
it('returns null for "p" on main worktree', () => {
|
|
420
|
-
const worktree = makeWorktree({ type: 'main' });
|
|
421
|
-
expect(getActionForShortcut('p', worktree)).toBeNull();
|
|
422
|
-
});
|
|
423
|
-
it('returns null for "p" on detached worktree', () => {
|
|
424
|
-
const worktree = makeWorktree({ type: 'detached' });
|
|
425
|
-
expect(getActionForShortcut('p', worktree)).toBeNull();
|
|
426
|
-
});
|
|
427
|
-
});
|
|
428
|
-
// "w" key behavior tests (checkout_pr - only for remote_pr)
|
|
429
|
-
describe('"w" key behavior (checkout_pr)', () => {
|
|
430
|
-
it('returns checkout_pr for "w" on remote_pr worktree', () => {
|
|
431
|
-
const worktree = makeWorktree({ type: 'remote_pr', prNumber: 42, prState: 'OPEN' });
|
|
432
|
-
expect(getActionForShortcut('w', worktree)).toBe('checkout_pr');
|
|
433
|
-
});
|
|
434
|
-
it('returns null for "w" on main worktree', () => {
|
|
435
|
-
const worktree = makeWorktree({ type: 'main' });
|
|
436
|
-
expect(getActionForShortcut('w', worktree)).toBeNull();
|
|
437
|
-
});
|
|
438
|
-
it('returns null for "w" on branch worktree', () => {
|
|
439
|
-
const worktree = makeWorktree({ type: 'branch' });
|
|
440
|
-
expect(getActionForShortcut('w', worktree)).toBeNull();
|
|
441
|
-
});
|
|
442
|
-
it('returns null for "w" on pr worktree', () => {
|
|
443
|
-
const worktree = makeWorktree({ type: 'pr', prNumber: 42, prState: 'OPEN' });
|
|
444
|
-
expect(getActionForShortcut('w', worktree)).toBeNull();
|
|
445
|
-
});
|
|
446
|
-
it('returns null for "w" on detached worktree', () => {
|
|
447
|
-
const worktree = makeWorktree({ type: 'detached' });
|
|
448
|
-
expect(getActionForShortcut('w', worktree)).toBeNull();
|
|
449
|
-
});
|
|
450
|
-
});
|
|
451
|
-
// "r" key behavior tests (remove_worktree)
|
|
452
|
-
describe('"r" key behavior (remove_worktree)', () => {
|
|
453
|
-
it('returns remove_worktree for "r" on branch worktree', () => {
|
|
454
|
-
const worktree = makeWorktree({ type: 'branch' });
|
|
455
|
-
expect(getActionForShortcut('r', worktree)).toBe('remove_worktree');
|
|
456
|
-
});
|
|
457
|
-
it('returns remove_worktree for "r" on pr worktree', () => {
|
|
458
|
-
const worktree = makeWorktree({ type: 'pr', prNumber: 42, prState: 'OPEN' });
|
|
459
|
-
expect(getActionForShortcut('r', worktree)).toBe('remove_worktree');
|
|
460
|
-
});
|
|
461
|
-
it('returns remove_worktree for "r" on detached worktree', () => {
|
|
462
|
-
const worktree = makeWorktree({ type: 'detached' });
|
|
463
|
-
expect(getActionForShortcut('r', worktree)).toBe('remove_worktree');
|
|
464
|
-
});
|
|
465
|
-
it('returns null for "r" on main worktree', () => {
|
|
466
|
-
const worktree = makeWorktree({ type: 'main' });
|
|
467
|
-
expect(getActionForShortcut('r', worktree)).toBeNull();
|
|
468
|
-
});
|
|
469
|
-
});
|
|
470
|
-
// Remote PR limited actions tests
|
|
471
|
-
describe('remote_pr limited actions', () => {
|
|
472
|
-
it('returns null for "e" (open_editor) on remote_pr', () => {
|
|
473
|
-
const worktree = makeWorktree({ type: 'remote_pr', prNumber: 42, prState: 'OPEN' });
|
|
474
|
-
expect(getActionForShortcut('e', worktree)).toBeNull();
|
|
475
|
-
});
|
|
476
|
-
it('returns null for "t" (open_terminal) on remote_pr', () => {
|
|
477
|
-
const worktree = makeWorktree({ type: 'remote_pr', prNumber: 42, prState: 'OPEN' });
|
|
478
|
-
expect(getActionForShortcut('t', worktree)).toBeNull();
|
|
479
|
-
});
|
|
480
|
-
it('returns null for "c" (copy_path) on remote_pr', () => {
|
|
481
|
-
const worktree = makeWorktree({ type: 'remote_pr', prNumber: 42, prState: 'OPEN' });
|
|
482
|
-
expect(getActionForShortcut('c', worktree)).toBeNull();
|
|
483
|
-
});
|
|
484
|
-
it('returns null for "l" (link_configs) on remote_pr', () => {
|
|
485
|
-
const worktree = makeWorktree({ type: 'remote_pr', prNumber: 42, prState: 'OPEN' });
|
|
486
|
-
expect(getActionForShortcut('l', worktree)).toBeNull();
|
|
487
|
-
});
|
|
488
|
-
it('returns null for "r" (remove_worktree) on remote_pr', () => {
|
|
489
|
-
const worktree = makeWorktree({ type: 'remote_pr', prNumber: 42, prState: 'OPEN' });
|
|
490
|
-
expect(getActionForShortcut('r', worktree)).toBeNull();
|
|
491
|
-
});
|
|
492
|
-
it('allows "w" (checkout_pr) on remote_pr', () => {
|
|
493
|
-
const worktree = makeWorktree({ type: 'remote_pr', prNumber: 42, prState: 'OPEN' });
|
|
494
|
-
expect(getActionForShortcut('w', worktree)).toBe('checkout_pr');
|
|
495
|
-
});
|
|
496
|
-
it('allows "p" (open_pr_url) on remote_pr', () => {
|
|
497
|
-
const worktree = makeWorktree({ type: 'remote_pr', prNumber: 42, prState: 'OPEN' });
|
|
498
|
-
expect(getActionForShortcut('p', worktree)).toBe('open_pr_url');
|
|
499
|
-
});
|
|
500
|
-
it('allows "d" (show_details) on remote_pr', () => {
|
|
501
|
-
const worktree = makeWorktree({ type: 'remote_pr', prNumber: 42, prState: 'OPEN' });
|
|
502
|
-
expect(getActionForShortcut('d', worktree)).toBe('show_details');
|
|
503
|
-
});
|
|
504
|
-
it('allows "q" (exit) on remote_pr', () => {
|
|
505
|
-
const worktree = makeWorktree({ type: 'remote_pr', prNumber: 42, prState: 'OPEN' });
|
|
506
|
-
expect(getActionForShortcut('q', worktree)).toBe('exit');
|
|
507
|
-
});
|
|
508
|
-
});
|
|
509
|
-
});
|
|
510
|
-
describe('runInteractiveMode', () => {
|
|
511
|
-
const defaultOptions = {
|
|
512
|
-
showStatus: false,
|
|
513
|
-
json: false,
|
|
514
|
-
verbose: false,
|
|
515
|
-
};
|
|
516
|
-
beforeEach(() => {
|
|
517
|
-
vi.clearAllMocks();
|
|
518
|
-
// Mock console methods
|
|
519
|
-
vi.spyOn(console, 'clear').mockImplementation(() => { });
|
|
520
|
-
vi.spyOn(console, 'log').mockImplementation(() => { });
|
|
521
|
-
vi.spyOn(console, 'error').mockImplementation(() => { });
|
|
522
|
-
});
|
|
523
|
-
afterEach(() => {
|
|
524
|
-
vi.restoreAllMocks();
|
|
525
|
-
});
|
|
526
|
-
it('returns early with error when not in git repository', async () => {
|
|
527
|
-
vi.mocked(git.getRepoRoot).mockReturnValue(null);
|
|
528
|
-
const deps = createMockDeps();
|
|
529
|
-
await runInteractiveMode([makeWorktree()], defaultOptions, deps);
|
|
530
|
-
expect(console.error).toHaveBeenCalled();
|
|
531
|
-
});
|
|
532
|
-
it('returns early when no worktrees provided', async () => {
|
|
533
|
-
vi.mocked(git.getRepoRoot).mockReturnValue('/home/user/repo');
|
|
534
|
-
const deps = createMockDeps();
|
|
535
|
-
await runInteractiveMode([], defaultOptions, deps);
|
|
536
|
-
expect(console.log).toHaveBeenCalledWith(expect.stringContaining('No worktrees found'));
|
|
537
|
-
});
|
|
538
|
-
it('exits when user selects exit from worktree list', async () => {
|
|
539
|
-
vi.mocked(git.getRepoRoot).mockReturnValue('/home/user/repo');
|
|
540
|
-
const deps = createMockDeps({
|
|
541
|
-
selectWorktree: vi.fn().mockResolvedValue({ worktree: null, action: null }),
|
|
542
|
-
});
|
|
543
|
-
await runInteractiveMode([makeWorktree()], defaultOptions, deps);
|
|
544
|
-
expect(console.log).toHaveBeenCalledWith(expect.stringContaining('Goodbye'));
|
|
545
|
-
});
|
|
546
|
-
it('exits when user selects exit action', async () => {
|
|
547
|
-
vi.mocked(git.getRepoRoot).mockReturnValue('/home/user/repo');
|
|
548
|
-
const worktree = makeWorktree();
|
|
549
|
-
const deps = createMockDeps({
|
|
550
|
-
selectWorktree: vi.fn().mockResolvedValue({ worktree, action: null }),
|
|
551
|
-
selectAction: vi.fn().mockResolvedValue('exit'),
|
|
552
|
-
});
|
|
553
|
-
await runInteractiveMode([worktree], defaultOptions, deps);
|
|
554
|
-
expect(console.log).toHaveBeenCalledWith(expect.stringContaining('Goodbye'));
|
|
555
|
-
});
|
|
556
|
-
it('continues loop when user selects back action', async () => {
|
|
557
|
-
vi.mocked(git.getRepoRoot).mockReturnValue('/home/user/repo');
|
|
558
|
-
const worktree = makeWorktree();
|
|
559
|
-
const selectWorktreeMock = vi
|
|
560
|
-
.fn()
|
|
561
|
-
.mockResolvedValueOnce({ worktree, action: null }) // First loop - select worktree
|
|
562
|
-
.mockResolvedValueOnce({ worktree: null, action: null }); // Second loop - exit
|
|
563
|
-
const deps = createMockDeps({
|
|
564
|
-
selectWorktree: selectWorktreeMock,
|
|
565
|
-
selectAction: vi.fn().mockResolvedValue('back'),
|
|
566
|
-
});
|
|
567
|
-
await runInteractiveMode([worktree], defaultOptions, deps);
|
|
568
|
-
// selectWorktree should be called 2 times (first loop, then exit)
|
|
569
|
-
expect(selectWorktreeMock).toHaveBeenCalledTimes(2);
|
|
570
|
-
});
|
|
571
|
-
it('executes action and shows success message', async () => {
|
|
572
|
-
vi.mocked(git.getRepoRoot).mockReturnValue('/home/user/repo');
|
|
573
|
-
const worktree = makeWorktree();
|
|
574
|
-
vi.mocked(executeAction).mockResolvedValueOnce({
|
|
575
|
-
success: true,
|
|
576
|
-
message: 'Copied to clipboard',
|
|
577
|
-
});
|
|
578
|
-
const selectWorktreeMock = vi
|
|
579
|
-
.fn()
|
|
580
|
-
.mockResolvedValueOnce({ worktree, action: null })
|
|
581
|
-
.mockResolvedValueOnce({ worktree: null, action: null });
|
|
582
|
-
const deps = createMockDeps({
|
|
583
|
-
selectWorktree: selectWorktreeMock,
|
|
584
|
-
selectAction: vi.fn().mockResolvedValue('copy_path'),
|
|
585
|
-
});
|
|
586
|
-
await runInteractiveMode([worktree], defaultOptions, deps);
|
|
587
|
-
expect(executeAction).toHaveBeenCalled();
|
|
588
|
-
expect(console.log).toHaveBeenCalledWith(expect.stringContaining('Copied to clipboard'));
|
|
589
|
-
});
|
|
590
|
-
it('shows error message on failed action', async () => {
|
|
591
|
-
vi.mocked(git.getRepoRoot).mockReturnValue('/home/user/repo');
|
|
592
|
-
const worktree = makeWorktree();
|
|
593
|
-
vi.mocked(executeAction).mockResolvedValueOnce({
|
|
594
|
-
success: false,
|
|
595
|
-
message: 'Failed to copy',
|
|
596
|
-
});
|
|
597
|
-
const selectWorktreeMock = vi
|
|
598
|
-
.fn()
|
|
599
|
-
.mockResolvedValueOnce({ worktree, action: null })
|
|
600
|
-
.mockResolvedValueOnce({ worktree: null, action: null });
|
|
601
|
-
const deps = createMockDeps({
|
|
602
|
-
selectWorktree: selectWorktreeMock,
|
|
603
|
-
selectAction: vi.fn().mockResolvedValue('copy_path'),
|
|
604
|
-
});
|
|
605
|
-
await runInteractiveMode([worktree], defaultOptions, deps);
|
|
606
|
-
expect(console.log).toHaveBeenCalledWith(expect.stringContaining('Failed to copy'));
|
|
607
|
-
});
|
|
608
|
-
it('refreshes worktree list when action returns shouldRefresh', async () => {
|
|
609
|
-
vi.mocked(git.getRepoRoot).mockReturnValue('/home/user/repo');
|
|
610
|
-
const worktree = makeWorktree();
|
|
611
|
-
const newWorktree = makeWorktree({ name: 'updated' });
|
|
612
|
-
vi.mocked(executeAction).mockResolvedValueOnce({
|
|
613
|
-
success: true,
|
|
614
|
-
message: 'Worktree removed',
|
|
615
|
-
shouldRefresh: true,
|
|
616
|
-
});
|
|
617
|
-
vi.mocked(gatherWorktreeInfo).mockResolvedValueOnce([newWorktree]);
|
|
618
|
-
const selectWorktreeMock = vi
|
|
619
|
-
.fn()
|
|
620
|
-
.mockResolvedValueOnce({ worktree, action: null })
|
|
621
|
-
.mockResolvedValueOnce({ worktree: null, action: null });
|
|
622
|
-
const deps = createMockDeps({
|
|
623
|
-
selectWorktree: selectWorktreeMock,
|
|
624
|
-
selectAction: vi.fn().mockResolvedValue('remove_worktree'),
|
|
625
|
-
});
|
|
626
|
-
await runInteractiveMode([worktree], defaultOptions, deps);
|
|
627
|
-
expect(gatherWorktreeInfo).toHaveBeenCalled();
|
|
628
|
-
});
|
|
629
|
-
it('exits when refresh results in no remaining worktrees', async () => {
|
|
630
|
-
vi.mocked(git.getRepoRoot).mockReturnValue('/home/user/repo');
|
|
631
|
-
const worktree = makeWorktree();
|
|
632
|
-
vi.mocked(executeAction).mockResolvedValueOnce({
|
|
633
|
-
success: true,
|
|
634
|
-
message: 'Worktree removed',
|
|
635
|
-
shouldRefresh: true,
|
|
636
|
-
});
|
|
637
|
-
// After refresh, no worktrees remain
|
|
638
|
-
vi.mocked(gatherWorktreeInfo).mockResolvedValueOnce([]);
|
|
639
|
-
const deps = createMockDeps({
|
|
640
|
-
selectWorktree: vi.fn().mockResolvedValue({ worktree, action: null }),
|
|
641
|
-
selectAction: vi.fn().mockResolvedValue('remove_worktree'),
|
|
642
|
-
});
|
|
643
|
-
await runInteractiveMode([worktree], defaultOptions, deps);
|
|
644
|
-
expect(console.log).toHaveBeenCalledWith(expect.stringContaining('No worktrees remaining'));
|
|
645
|
-
});
|
|
646
|
-
it('exits immediately when action returns shouldExit', async () => {
|
|
647
|
-
vi.mocked(git.getRepoRoot).mockReturnValue('/home/user/repo');
|
|
648
|
-
const worktree = makeWorktree();
|
|
649
|
-
vi.mocked(executeAction).mockResolvedValueOnce({
|
|
650
|
-
success: true,
|
|
651
|
-
shouldExit: true,
|
|
652
|
-
});
|
|
653
|
-
const selectWorktreeMock = vi.fn().mockResolvedValue({ worktree, action: null });
|
|
654
|
-
const deps = createMockDeps({
|
|
655
|
-
selectWorktree: selectWorktreeMock,
|
|
656
|
-
selectAction: vi.fn().mockResolvedValue('open_editor'),
|
|
657
|
-
});
|
|
658
|
-
await runInteractiveMode([worktree], defaultOptions, deps);
|
|
659
|
-
// selectWorktree should only be called once since shouldExit is true
|
|
660
|
-
expect(selectWorktreeMock).toHaveBeenCalledTimes(1);
|
|
661
|
-
});
|
|
662
|
-
it('handles worktree header display correctly', async () => {
|
|
663
|
-
vi.mocked(git.getRepoRoot).mockReturnValue('/home/user/repo');
|
|
664
|
-
const worktrees = [
|
|
665
|
-
makeWorktree({ path: '/home/user/repo', type: 'main' }),
|
|
666
|
-
makeWorktree({
|
|
667
|
-
path: '/home/user/repo.pr1',
|
|
668
|
-
type: 'pr',
|
|
669
|
-
prNumber: 1,
|
|
670
|
-
prState: 'OPEN',
|
|
671
|
-
hasChanges: true,
|
|
672
|
-
}),
|
|
673
|
-
];
|
|
674
|
-
const deps = createMockDeps({
|
|
675
|
-
selectWorktree: vi.fn().mockResolvedValue({ worktree: null, action: null }),
|
|
676
|
-
});
|
|
677
|
-
await runInteractiveMode(worktrees, defaultOptions, deps);
|
|
678
|
-
// Should display header with worktree count
|
|
679
|
-
expect(console.log).toHaveBeenCalledWith(expect.stringContaining('2 worktrees'));
|
|
680
|
-
});
|
|
681
|
-
it('displays PR count in header', async () => {
|
|
682
|
-
vi.mocked(git.getRepoRoot).mockReturnValue('/home/user/repo');
|
|
683
|
-
const worktrees = [
|
|
684
|
-
makeWorktree({ type: 'main' }),
|
|
685
|
-
makeWorktree({ type: 'pr', prNumber: 1, prState: 'OPEN' }),
|
|
686
|
-
makeWorktree({ type: 'pr', prNumber: 2, prState: 'MERGED' }),
|
|
687
|
-
];
|
|
688
|
-
const deps = createMockDeps({
|
|
689
|
-
selectWorktree: vi.fn().mockResolvedValue({ worktree: null, action: null }),
|
|
690
|
-
});
|
|
691
|
-
await runInteractiveMode(worktrees, defaultOptions, deps);
|
|
692
|
-
expect(console.log).toHaveBeenCalledWith(expect.stringContaining('2 local PRs'));
|
|
693
|
-
});
|
|
694
|
-
it('displays changes count in header', async () => {
|
|
695
|
-
vi.mocked(git.getRepoRoot).mockReturnValue('/home/user/repo');
|
|
696
|
-
const worktrees = [
|
|
697
|
-
makeWorktree({ type: 'main', hasChanges: true }),
|
|
698
|
-
makeWorktree({ type: 'branch', hasChanges: true }),
|
|
699
|
-
];
|
|
700
|
-
const deps = createMockDeps({
|
|
701
|
-
selectWorktree: vi.fn().mockResolvedValue({ worktree: null, action: null }),
|
|
702
|
-
});
|
|
703
|
-
await runInteractiveMode(worktrees, defaultOptions, deps);
|
|
704
|
-
expect(console.log).toHaveBeenCalledWith(expect.stringContaining('2 with changes'));
|
|
705
|
-
});
|
|
706
|
-
it('displays remote PR count in header', async () => {
|
|
707
|
-
vi.mocked(git.getRepoRoot).mockReturnValue('/home/user/repo');
|
|
708
|
-
const worktrees = [
|
|
709
|
-
makeWorktree({ type: 'main' }),
|
|
710
|
-
makeWorktree({ type: 'pr', prNumber: 1, prState: 'OPEN' }),
|
|
711
|
-
makeWorktree({ type: 'remote_pr', prNumber: 10, prState: 'OPEN', prTitle: 'Remote PR 1' }),
|
|
712
|
-
makeWorktree({ type: 'remote_pr', prNumber: 20, prState: 'OPEN', prTitle: 'Remote PR 2' }),
|
|
713
|
-
makeWorktree({ type: 'remote_pr', prNumber: 30, prState: 'OPEN', prTitle: 'Remote PR 3' }),
|
|
714
|
-
];
|
|
715
|
-
const deps = createMockDeps({
|
|
716
|
-
selectWorktree: vi.fn().mockResolvedValue({ worktree: null, action: null }),
|
|
717
|
-
});
|
|
718
|
-
await runInteractiveMode(worktrees, defaultOptions, deps);
|
|
719
|
-
expect(console.log).toHaveBeenCalledWith(expect.stringContaining('3 remote PRs'));
|
|
720
|
-
});
|
|
721
|
-
it('shows worktree shortcut in header when remote PRs are present', async () => {
|
|
722
|
-
vi.mocked(git.getRepoRoot).mockReturnValue('/home/user/repo');
|
|
723
|
-
const worktrees = [
|
|
724
|
-
makeWorktree({ type: 'main' }),
|
|
725
|
-
makeWorktree({ type: 'remote_pr', prNumber: 42, prState: 'OPEN', prTitle: 'Remote PR' }),
|
|
726
|
-
];
|
|
727
|
-
const deps = createMockDeps({
|
|
728
|
-
selectWorktree: vi.fn().mockResolvedValue({ worktree: null, action: null }),
|
|
729
|
-
});
|
|
730
|
-
await runInteractiveMode(worktrees, defaultOptions, deps);
|
|
731
|
-
expect(console.log).toHaveBeenCalledWith(expect.stringContaining('[w]'));
|
|
732
|
-
});
|
|
733
|
-
it('displays correct local worktree count (excluding remote PRs)', async () => {
|
|
734
|
-
vi.mocked(git.getRepoRoot).mockReturnValue('/home/user/repo');
|
|
735
|
-
const worktrees = [
|
|
736
|
-
makeWorktree({ type: 'main' }),
|
|
737
|
-
makeWorktree({ type: 'pr', prNumber: 1, prState: 'OPEN' }),
|
|
738
|
-
makeWorktree({ type: 'remote_pr', prNumber: 10, prState: 'OPEN', prTitle: 'Remote PR' }),
|
|
739
|
-
];
|
|
740
|
-
const deps = createMockDeps({
|
|
741
|
-
selectWorktree: vi.fn().mockResolvedValue({ worktree: null, action: null }),
|
|
742
|
-
});
|
|
743
|
-
await runInteractiveMode(worktrees, defaultOptions, deps);
|
|
744
|
-
// Should show "2 worktrees" (main + local PR), not 3
|
|
745
|
-
expect(console.log).toHaveBeenCalledWith(expect.stringContaining('2 worktrees'));
|
|
746
|
-
});
|
|
747
|
-
it('executes shortcut action directly when provided with selection', async () => {
|
|
748
|
-
vi.mocked(git.getRepoRoot).mockReturnValue('/home/user/repo');
|
|
749
|
-
const worktree = makeWorktree();
|
|
750
|
-
vi.mocked(executeAction).mockResolvedValueOnce({
|
|
751
|
-
success: true,
|
|
752
|
-
shouldExit: true,
|
|
753
|
-
});
|
|
754
|
-
// Simulate shortcut key press - returns both worktree and action
|
|
755
|
-
const selectActionMock = vi.fn();
|
|
756
|
-
const deps = createMockDeps({
|
|
757
|
-
selectWorktree: vi.fn().mockResolvedValue({ worktree, action: 'open_editor' }),
|
|
758
|
-
selectAction: selectActionMock,
|
|
759
|
-
});
|
|
760
|
-
await runInteractiveMode([worktree], defaultOptions, deps);
|
|
761
|
-
// executeAction should be called with the shortcut action as first arg
|
|
762
|
-
expect(executeAction).toHaveBeenCalled();
|
|
763
|
-
const callArgs = vi.mocked(executeAction).mock.calls[0];
|
|
764
|
-
expect(callArgs[0]).toBe('open_editor');
|
|
765
|
-
expect(callArgs[1]).toEqual(worktree);
|
|
766
|
-
// selectAction should NOT be called since action was provided via shortcut
|
|
767
|
-
expect(selectActionMock).not.toHaveBeenCalled();
|
|
768
|
-
});
|
|
769
|
-
});
|
|
770
|
-
});
|
|
771
|
-
//# sourceMappingURL=interactive.test.js.map
|