@camaradesuk/git-worktree-tools 1.10.0 → 1.11.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/package.json +12 -3
- 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
package/dist/lib/git.test.js
DELETED
|
@@ -1,608 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
-
import { spawnSync, execSync, spawn, } from 'child_process';
|
|
3
|
-
import * as path from 'path';
|
|
4
|
-
import { EventEmitter } from 'stream';
|
|
5
|
-
import * as git from './git.js';
|
|
6
|
-
// Mock child_process
|
|
7
|
-
vi.mock('child_process', () => ({
|
|
8
|
-
spawnSync: vi.fn(),
|
|
9
|
-
execSync: vi.fn(),
|
|
10
|
-
spawn: vi.fn(),
|
|
11
|
-
}));
|
|
12
|
-
const mockSpawnSync = vi.mocked(spawnSync);
|
|
13
|
-
const mockExecSync = vi.mocked(execSync);
|
|
14
|
-
const mockSpawn = vi.mocked(spawn);
|
|
15
|
-
/**
|
|
16
|
-
* Helper to create a successful spawnSync result
|
|
17
|
-
*/
|
|
18
|
-
function mockSpawnSuccess(stdout) {
|
|
19
|
-
return {
|
|
20
|
-
status: 0,
|
|
21
|
-
signal: null,
|
|
22
|
-
output: ['', stdout, ''],
|
|
23
|
-
pid: 123,
|
|
24
|
-
stdout,
|
|
25
|
-
stderr: '',
|
|
26
|
-
error: undefined,
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Helper to create a failed spawnSync result
|
|
31
|
-
*/
|
|
32
|
-
function mockSpawnFailure(stderr) {
|
|
33
|
-
return {
|
|
34
|
-
status: 1,
|
|
35
|
-
signal: null,
|
|
36
|
-
output: ['', '', stderr],
|
|
37
|
-
pid: 123,
|
|
38
|
-
stdout: '',
|
|
39
|
-
stderr,
|
|
40
|
-
error: undefined,
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
describe('git', () => {
|
|
44
|
-
beforeEach(() => {
|
|
45
|
-
vi.clearAllMocks();
|
|
46
|
-
});
|
|
47
|
-
describe('exec', () => {
|
|
48
|
-
it('executes git command and returns output with trailing whitespace trimmed', () => {
|
|
49
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('output with trailing whitespace \n'));
|
|
50
|
-
const result = git.exec(['status']);
|
|
51
|
-
// Leading whitespace is preserved (important for git status), trailing is trimmed
|
|
52
|
-
expect(result).toBe('output with trailing whitespace');
|
|
53
|
-
expect(mockSpawnSync).toHaveBeenCalledWith('git', ['status'], expect.any(Object));
|
|
54
|
-
});
|
|
55
|
-
it('preserves leading whitespace in output', () => {
|
|
56
|
-
// Leading spaces are significant in git status --porcelain output
|
|
57
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess(' M file.txt\n'));
|
|
58
|
-
const result = git.exec(['status', '--porcelain']);
|
|
59
|
-
expect(result).toBe(' M file.txt');
|
|
60
|
-
});
|
|
61
|
-
it('passes cwd option correctly', () => {
|
|
62
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('output'));
|
|
63
|
-
git.exec(['status'], { cwd: '/some/path' });
|
|
64
|
-
expect(mockSpawnSync).toHaveBeenCalledWith('git', ['status'], expect.objectContaining({ cwd: '/some/path' }));
|
|
65
|
-
});
|
|
66
|
-
it('throws error with stderr message on failure', () => {
|
|
67
|
-
mockSpawnSync.mockReturnValue(mockSpawnFailure('fatal: not a git repository'));
|
|
68
|
-
expect(() => git.exec(['status'])).toThrow('Git command failed');
|
|
69
|
-
});
|
|
70
|
-
});
|
|
71
|
-
describe('execSafe', () => {
|
|
72
|
-
it('returns output on success', () => {
|
|
73
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('output'));
|
|
74
|
-
const result = git.execSafe(['status']);
|
|
75
|
-
expect(result).toBe('output');
|
|
76
|
-
});
|
|
77
|
-
it('returns null on failure', () => {
|
|
78
|
-
mockSpawnSync.mockReturnValue(mockSpawnFailure('Command failed'));
|
|
79
|
-
const result = git.execSafe(['status']);
|
|
80
|
-
expect(result).toBeNull();
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
describe('getRepoRoot', () => {
|
|
84
|
-
it('returns normalized path from git rev-parse', () => {
|
|
85
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('/home/user/repo\n'));
|
|
86
|
-
const result = git.getRepoRoot();
|
|
87
|
-
expect(result).toContain('repo');
|
|
88
|
-
expect(mockSpawnSync).toHaveBeenCalledWith('git', ['rev-parse', '--show-toplevel'], expect.any(Object));
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
describe('getRepoName', () => {
|
|
92
|
-
it('extracts name from SSH remote URL', () => {
|
|
93
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('git@github.com:org/my-repo.git'));
|
|
94
|
-
const result = git.getRepoName('/repo');
|
|
95
|
-
expect(result).toBe('my-repo');
|
|
96
|
-
});
|
|
97
|
-
it('extracts name from HTTPS remote URL', () => {
|
|
98
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('https://github.com/org/my-repo.git'));
|
|
99
|
-
const result = git.getRepoName('/repo');
|
|
100
|
-
expect(result).toBe('my-repo');
|
|
101
|
-
});
|
|
102
|
-
it('extracts name from URL without .git suffix', () => {
|
|
103
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('https://github.com/org/my-repo'));
|
|
104
|
-
const result = git.getRepoName('/repo');
|
|
105
|
-
expect(result).toBe('my-repo');
|
|
106
|
-
});
|
|
107
|
-
it('falls back to directory name when no remote', () => {
|
|
108
|
-
mockSpawnSync.mockReturnValue(mockSpawnFailure('No remote'));
|
|
109
|
-
const result = git.getRepoName('/home/user/my-project');
|
|
110
|
-
expect(result).toBe('my-project');
|
|
111
|
-
});
|
|
112
|
-
it('extracts name from Unix local path with .git suffix', () => {
|
|
113
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('/path/to/my-repo.git'));
|
|
114
|
-
const result = git.getRepoName('/repo');
|
|
115
|
-
expect(result).toBe('my-repo');
|
|
116
|
-
});
|
|
117
|
-
it('extracts name from Windows local path with .git suffix', () => {
|
|
118
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('C:\\Users\\test\\repos\\my-repo.git'));
|
|
119
|
-
const result = git.getRepoName('/repo');
|
|
120
|
-
expect(result).toBe('my-repo');
|
|
121
|
-
});
|
|
122
|
-
it('extracts name from Windows local path without .git suffix', () => {
|
|
123
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('C:\\Users\\test\\repos\\my-repo'));
|
|
124
|
-
const result = git.getRepoName('/repo');
|
|
125
|
-
expect(result).toBe('my-repo');
|
|
126
|
-
});
|
|
127
|
-
it('extracts name from Windows short path format', () => {
|
|
128
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('C:\\Users\\RUNNER~1\\AppData\\Local\\Temp\\main-repo.git'));
|
|
129
|
-
const result = git.getRepoName('/repo');
|
|
130
|
-
expect(result).toBe('main-repo');
|
|
131
|
-
});
|
|
132
|
-
});
|
|
133
|
-
describe('getCurrentBranch', () => {
|
|
134
|
-
it('returns branch name', () => {
|
|
135
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('feature/my-branch'));
|
|
136
|
-
const result = git.getCurrentBranch();
|
|
137
|
-
expect(result).toBe('feature/my-branch');
|
|
138
|
-
});
|
|
139
|
-
it('returns null for detached HEAD', () => {
|
|
140
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('HEAD'));
|
|
141
|
-
const result = git.getCurrentBranch();
|
|
142
|
-
expect(result).toBeNull();
|
|
143
|
-
});
|
|
144
|
-
});
|
|
145
|
-
describe('isDetachedHead', () => {
|
|
146
|
-
it('returns true when in detached HEAD state', () => {
|
|
147
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('HEAD'));
|
|
148
|
-
expect(git.isDetachedHead()).toBe(true);
|
|
149
|
-
});
|
|
150
|
-
it('returns false when on a branch', () => {
|
|
151
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('main'));
|
|
152
|
-
expect(git.isDetachedHead()).toBe(false);
|
|
153
|
-
});
|
|
154
|
-
});
|
|
155
|
-
describe('getWorkingTreeStatus', () => {
|
|
156
|
-
it('returns clean for empty status', () => {
|
|
157
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess(''));
|
|
158
|
-
expect(git.getWorkingTreeStatus()).toBe('clean');
|
|
159
|
-
});
|
|
160
|
-
it('returns staged_only for staged changes', () => {
|
|
161
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('M file.txt'));
|
|
162
|
-
expect(git.getWorkingTreeStatus()).toBe('staged_only');
|
|
163
|
-
});
|
|
164
|
-
it('returns unstaged_only for unstaged changes', () => {
|
|
165
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess(' M file.txt'));
|
|
166
|
-
expect(git.getWorkingTreeStatus()).toBe('unstaged_only');
|
|
167
|
-
});
|
|
168
|
-
it('returns unstaged_only for untracked files', () => {
|
|
169
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('?? newfile.txt'));
|
|
170
|
-
expect(git.getWorkingTreeStatus()).toBe('unstaged_only');
|
|
171
|
-
});
|
|
172
|
-
it('returns both for staged and unstaged changes', () => {
|
|
173
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('MM file.txt'));
|
|
174
|
-
expect(git.getWorkingTreeStatus()).toBe('both');
|
|
175
|
-
});
|
|
176
|
-
it('returns both for staged changes and untracked files', () => {
|
|
177
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('M staged.txt\n?? untracked.txt'));
|
|
178
|
-
expect(git.getWorkingTreeStatus()).toBe('both');
|
|
179
|
-
});
|
|
180
|
-
});
|
|
181
|
-
describe('getStagedFiles', () => {
|
|
182
|
-
it('returns list of staged files', () => {
|
|
183
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('file1.txt\nfile2.txt\n'));
|
|
184
|
-
const result = git.getStagedFiles();
|
|
185
|
-
expect(result).toEqual(['file1.txt', 'file2.txt']);
|
|
186
|
-
});
|
|
187
|
-
it('returns empty array when nothing staged', () => {
|
|
188
|
-
mockSpawnSync.mockReturnValue(mockSpawnFailure('No staged files'));
|
|
189
|
-
const result = git.getStagedFiles();
|
|
190
|
-
expect(result).toEqual([]);
|
|
191
|
-
});
|
|
192
|
-
});
|
|
193
|
-
describe('getUnstagedFiles', () => {
|
|
194
|
-
it('returns list of unstaged and untracked files', () => {
|
|
195
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess(' M modified.txt\n?? untracked.txt'));
|
|
196
|
-
const result = git.getUnstagedFiles();
|
|
197
|
-
expect(result).toEqual(['modified.txt', 'untracked.txt']);
|
|
198
|
-
});
|
|
199
|
-
it('excludes staged-only files', () => {
|
|
200
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('M staged.txt\n M both.txt'));
|
|
201
|
-
const result = git.getUnstagedFiles();
|
|
202
|
-
expect(result).toEqual(['both.txt']);
|
|
203
|
-
});
|
|
204
|
-
it('returns empty array when working tree is clean', () => {
|
|
205
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess(''));
|
|
206
|
-
const result = git.getUnstagedFiles();
|
|
207
|
-
expect(result).toEqual([]);
|
|
208
|
-
});
|
|
209
|
-
});
|
|
210
|
-
describe('listWorktrees', () => {
|
|
211
|
-
it('parses worktree list porcelain output', () => {
|
|
212
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('worktree /home/user/repo\n' +
|
|
213
|
-
'HEAD abc123def456\n' +
|
|
214
|
-
'branch refs/heads/main\n' +
|
|
215
|
-
'\n' +
|
|
216
|
-
'worktree /home/user/repo.pr42\n' +
|
|
217
|
-
'HEAD def456abc123\n' +
|
|
218
|
-
'branch refs/heads/feature/test\n' +
|
|
219
|
-
'\n'));
|
|
220
|
-
const result = git.listWorktrees();
|
|
221
|
-
expect(result).toHaveLength(2);
|
|
222
|
-
expect(result[0]).toEqual({
|
|
223
|
-
path: '/home/user/repo',
|
|
224
|
-
commit: 'abc123def456',
|
|
225
|
-
branch: 'main',
|
|
226
|
-
isMain: true,
|
|
227
|
-
isBare: false,
|
|
228
|
-
isLocked: false,
|
|
229
|
-
isPrunable: false,
|
|
230
|
-
});
|
|
231
|
-
expect(result[1]).toEqual({
|
|
232
|
-
path: '/home/user/repo.pr42',
|
|
233
|
-
commit: 'def456abc123',
|
|
234
|
-
branch: 'feature/test',
|
|
235
|
-
isMain: false,
|
|
236
|
-
isBare: false,
|
|
237
|
-
isLocked: false,
|
|
238
|
-
isPrunable: false,
|
|
239
|
-
});
|
|
240
|
-
});
|
|
241
|
-
it('handles bare repository', () => {
|
|
242
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('worktree /home/user/repo.git\n' + 'bare\n' + '\n'));
|
|
243
|
-
const result = git.listWorktrees();
|
|
244
|
-
expect(result[0].isBare).toBe(true);
|
|
245
|
-
expect(result[0].isMain).toBe(true);
|
|
246
|
-
});
|
|
247
|
-
it('handles locked and prunable worktrees', () => {
|
|
248
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('worktree /home/user/repo.pr1\n' +
|
|
249
|
-
'HEAD abc123\n' +
|
|
250
|
-
'branch refs/heads/test\n' +
|
|
251
|
-
'locked\n' +
|
|
252
|
-
'prunable\n' +
|
|
253
|
-
'\n'));
|
|
254
|
-
const result = git.listWorktrees();
|
|
255
|
-
expect(result[0].isLocked).toBe(true);
|
|
256
|
-
expect(result[0].isPrunable).toBe(true);
|
|
257
|
-
});
|
|
258
|
-
it('handles detached HEAD in worktree', () => {
|
|
259
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('worktree /home/user/repo\n' + 'HEAD abc123\n' + 'detached\n' + '\n'));
|
|
260
|
-
const result = git.listWorktrees();
|
|
261
|
-
expect(result[0].branch).toBeNull();
|
|
262
|
-
});
|
|
263
|
-
});
|
|
264
|
-
describe('getCommitRelationship', () => {
|
|
265
|
-
it('returns same when HEAD equals base', () => {
|
|
266
|
-
mockSpawnSync
|
|
267
|
-
.mockReturnValueOnce(mockSpawnSuccess('abc123')) // getHeadCommit
|
|
268
|
-
.mockReturnValueOnce(mockSpawnSuccess('abc123')); // getRefCommit
|
|
269
|
-
const result = git.getCommitRelationship('main');
|
|
270
|
-
expect(result).toBe('same');
|
|
271
|
-
});
|
|
272
|
-
it('returns divergent when base branch does not exist', () => {
|
|
273
|
-
mockSpawnSync
|
|
274
|
-
.mockReturnValueOnce(mockSpawnSuccess('abc123')) // getHeadCommit
|
|
275
|
-
.mockReturnValueOnce(mockSpawnFailure('unknown revision')); // getRefCommit fails
|
|
276
|
-
const result = git.getCommitRelationship('main');
|
|
277
|
-
expect(result).toBe('divergent');
|
|
278
|
-
});
|
|
279
|
-
});
|
|
280
|
-
describe('getCommitsAhead', () => {
|
|
281
|
-
it('returns list of commits ahead of base', () => {
|
|
282
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('abc123 First commit\ndef456 Second commit'));
|
|
283
|
-
const result = git.getCommitsAhead('main');
|
|
284
|
-
expect(result).toEqual(['abc123 First commit', 'def456 Second commit']);
|
|
285
|
-
});
|
|
286
|
-
it('returns empty array when not ahead', () => {
|
|
287
|
-
mockSpawnSync.mockReturnValue(mockSpawnFailure('No commits'));
|
|
288
|
-
const result = git.getCommitsAhead('main');
|
|
289
|
-
expect(result).toEqual([]);
|
|
290
|
-
});
|
|
291
|
-
});
|
|
292
|
-
describe('addWorktree', () => {
|
|
293
|
-
it('creates worktree with existing branch', () => {
|
|
294
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess(''));
|
|
295
|
-
git.addWorktree('/path/to/worktree', 'feature-branch');
|
|
296
|
-
expect(mockSpawnSync).toHaveBeenCalledWith('git', ['worktree', 'add', '/path/to/worktree', 'feature-branch'], expect.any(Object));
|
|
297
|
-
});
|
|
298
|
-
it('creates worktree with new branch', () => {
|
|
299
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess(''));
|
|
300
|
-
git.addWorktree('/path/to/worktree', 'new-branch', { createBranch: true });
|
|
301
|
-
expect(mockSpawnSync).toHaveBeenCalledWith('git', ['worktree', 'add', '-b', 'new-branch', '/path/to/worktree'], expect.any(Object));
|
|
302
|
-
});
|
|
303
|
-
it('creates worktree with new branch from start point', () => {
|
|
304
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess(''));
|
|
305
|
-
git.addWorktree('/path/to/worktree', 'new-branch', {
|
|
306
|
-
createBranch: true,
|
|
307
|
-
startPoint: 'origin/main',
|
|
308
|
-
});
|
|
309
|
-
expect(mockSpawnSync).toHaveBeenCalledWith('git', ['worktree', 'add', '-b', 'new-branch', '/path/to/worktree', 'origin/main'], expect.any(Object));
|
|
310
|
-
});
|
|
311
|
-
});
|
|
312
|
-
describe('removeWorktree', () => {
|
|
313
|
-
it('removes worktree', () => {
|
|
314
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess(''));
|
|
315
|
-
git.removeWorktree('/path/to/worktree');
|
|
316
|
-
expect(mockSpawnSync).toHaveBeenCalledWith('git', ['worktree', 'remove', '/path/to/worktree'], expect.any(Object));
|
|
317
|
-
});
|
|
318
|
-
it('force removes worktree', () => {
|
|
319
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess(''));
|
|
320
|
-
git.removeWorktree('/path/to/worktree', { force: true });
|
|
321
|
-
expect(mockSpawnSync).toHaveBeenCalledWith('git', ['worktree', 'remove', '--force', '/path/to/worktree'], expect.any(Object));
|
|
322
|
-
});
|
|
323
|
-
});
|
|
324
|
-
describe('createBranch', () => {
|
|
325
|
-
it('creates branch from HEAD', () => {
|
|
326
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess(''));
|
|
327
|
-
git.createBranch('new-branch');
|
|
328
|
-
expect(mockSpawnSync).toHaveBeenCalledWith('git', ['branch', 'new-branch'], expect.any(Object));
|
|
329
|
-
});
|
|
330
|
-
it('creates branch from start point', () => {
|
|
331
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess(''));
|
|
332
|
-
git.createBranch('new-branch', 'origin/main');
|
|
333
|
-
expect(mockSpawnSync).toHaveBeenCalledWith('git', ['branch', 'new-branch', 'origin/main'], expect.any(Object));
|
|
334
|
-
});
|
|
335
|
-
});
|
|
336
|
-
describe('deleteBranch', () => {
|
|
337
|
-
it('deletes branch with -d flag', () => {
|
|
338
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess(''));
|
|
339
|
-
git.deleteBranch('old-branch');
|
|
340
|
-
expect(mockSpawnSync).toHaveBeenCalledWith('git', ['branch', '-d', 'old-branch'], expect.any(Object));
|
|
341
|
-
});
|
|
342
|
-
it('force deletes branch with -D flag', () => {
|
|
343
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess(''));
|
|
344
|
-
git.deleteBranch('old-branch', { force: true });
|
|
345
|
-
expect(mockSpawnSync).toHaveBeenCalledWith('git', ['branch', '-D', 'old-branch'], expect.any(Object));
|
|
346
|
-
});
|
|
347
|
-
});
|
|
348
|
-
describe('commit', () => {
|
|
349
|
-
it('creates commit with message', () => {
|
|
350
|
-
mockSpawnSync
|
|
351
|
-
.mockReturnValueOnce(mockSpawnSuccess('')) // commit
|
|
352
|
-
.mockReturnValueOnce(mockSpawnSuccess('abc123')); // getHeadCommit
|
|
353
|
-
const result = git.commit({ message: 'Test commit' });
|
|
354
|
-
expect(mockSpawnSync).toHaveBeenCalledWith('git', ['commit', '-m', 'Test commit'], expect.any(Object));
|
|
355
|
-
expect(result).toBe('abc123');
|
|
356
|
-
});
|
|
357
|
-
it('creates commit with all flag', () => {
|
|
358
|
-
mockSpawnSync
|
|
359
|
-
.mockReturnValueOnce(mockSpawnSuccess(''))
|
|
360
|
-
.mockReturnValueOnce(mockSpawnSuccess('abc123'));
|
|
361
|
-
git.commit({ message: 'Test commit', all: true });
|
|
362
|
-
expect(mockSpawnSync).toHaveBeenCalledWith('git', ['commit', '-a', '-m', 'Test commit'], expect.any(Object));
|
|
363
|
-
});
|
|
364
|
-
it('creates empty commit when allowed', () => {
|
|
365
|
-
mockSpawnSync
|
|
366
|
-
.mockReturnValueOnce(mockSpawnSuccess(''))
|
|
367
|
-
.mockReturnValueOnce(mockSpawnSuccess('abc123'));
|
|
368
|
-
git.commit({ message: 'Empty commit', allowEmpty: true });
|
|
369
|
-
expect(mockSpawnSync).toHaveBeenCalledWith('git', ['commit', '--allow-empty', '-m', 'Empty commit'], expect.any(Object));
|
|
370
|
-
});
|
|
371
|
-
});
|
|
372
|
-
describe('push', () => {
|
|
373
|
-
it('pushes to remote', () => {
|
|
374
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess(''));
|
|
375
|
-
git.push();
|
|
376
|
-
expect(mockSpawnSync).toHaveBeenCalledWith('git', ['push'], expect.any(Object));
|
|
377
|
-
});
|
|
378
|
-
it('pushes with upstream flag', () => {
|
|
379
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess(''));
|
|
380
|
-
git.push({ setUpstream: true, remote: 'origin', branch: 'feature' });
|
|
381
|
-
expect(mockSpawnSync).toHaveBeenCalledWith('git', ['push', '-u', 'origin', 'feature'], expect.any(Object));
|
|
382
|
-
});
|
|
383
|
-
it('force pushes', () => {
|
|
384
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess(''));
|
|
385
|
-
git.push({ force: true });
|
|
386
|
-
expect(mockSpawnSync).toHaveBeenCalledWith('git', ['push', '--force'], expect.any(Object));
|
|
387
|
-
});
|
|
388
|
-
});
|
|
389
|
-
describe('stash', () => {
|
|
390
|
-
it('creates stash and returns reference', () => {
|
|
391
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('Saved working directory'));
|
|
392
|
-
const result = git.stash();
|
|
393
|
-
expect(result).toBe('stash@{0}');
|
|
394
|
-
});
|
|
395
|
-
it('returns null when nothing to stash', () => {
|
|
396
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('No local changes to save'));
|
|
397
|
-
const result = git.stash();
|
|
398
|
-
expect(result).toBeNull();
|
|
399
|
-
});
|
|
400
|
-
it('stashes with keep-index flag', () => {
|
|
401
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('Saved'));
|
|
402
|
-
git.stash({ keepIndex: true });
|
|
403
|
-
expect(mockSpawnSync).toHaveBeenCalledWith('git', ['stash', 'push', '--keep-index'], expect.any(Object));
|
|
404
|
-
});
|
|
405
|
-
it('stashes with message', () => {
|
|
406
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('Saved'));
|
|
407
|
-
git.stash({ message: 'WIP: feature' });
|
|
408
|
-
expect(mockSpawnSync).toHaveBeenCalledWith('git', ['stash', 'push', '-m', 'WIP: feature'], expect.any(Object));
|
|
409
|
-
});
|
|
410
|
-
it('stashes untracked files', () => {
|
|
411
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('Saved'));
|
|
412
|
-
git.stash({ includeUntracked: true });
|
|
413
|
-
expect(mockSpawnSync).toHaveBeenCalledWith('git', ['stash', 'push', '--include-untracked'], expect.any(Object));
|
|
414
|
-
});
|
|
415
|
-
});
|
|
416
|
-
describe('branchExists', () => {
|
|
417
|
-
it('returns true when branch exists', () => {
|
|
418
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('abc123'));
|
|
419
|
-
expect(git.branchExists('main')).toBe(true);
|
|
420
|
-
});
|
|
421
|
-
it('returns false when branch does not exist', () => {
|
|
422
|
-
mockSpawnSync.mockReturnValue(mockSpawnFailure('unknown revision'));
|
|
423
|
-
expect(git.branchExists('nonexistent')).toBe(false);
|
|
424
|
-
});
|
|
425
|
-
});
|
|
426
|
-
describe('remoteBranchExists', () => {
|
|
427
|
-
it('returns true when remote branch exists', () => {
|
|
428
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('abc123'));
|
|
429
|
-
expect(git.remoteBranchExists('main')).toBe(true);
|
|
430
|
-
});
|
|
431
|
-
it('returns false when remote branch does not exist', () => {
|
|
432
|
-
mockSpawnSync.mockReturnValue(mockSpawnFailure('unknown revision'));
|
|
433
|
-
expect(git.remoteBranchExists('nonexistent')).toBe(false);
|
|
434
|
-
});
|
|
435
|
-
it('checks specific remote', () => {
|
|
436
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('abc123'));
|
|
437
|
-
git.remoteBranchExists('main', 'upstream');
|
|
438
|
-
expect(mockSpawnSync).toHaveBeenCalledWith('git', ['rev-parse', '--verify', 'refs/remotes/upstream/main'], expect.any(Object));
|
|
439
|
-
});
|
|
440
|
-
});
|
|
441
|
-
describe('getMainWorktreeRoot', () => {
|
|
442
|
-
it('returns repo root when in main worktree', () => {
|
|
443
|
-
// Use path.join to create platform-appropriate paths
|
|
444
|
-
const repoPath = path.join('/home', 'user', 'repo');
|
|
445
|
-
const gitDir = path.join(repoPath, '.git');
|
|
446
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess(gitDir));
|
|
447
|
-
const result = git.getMainWorktreeRoot(repoPath);
|
|
448
|
-
expect(result).toBe(path.resolve(repoPath));
|
|
449
|
-
});
|
|
450
|
-
it('returns main worktree root when in linked worktree', () => {
|
|
451
|
-
const mainRepo = path.join('/home', 'user', 'main-repo');
|
|
452
|
-
const worktreeGitDir = path.join(mainRepo, '.git', 'worktrees', 'feature-branch');
|
|
453
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess(worktreeGitDir));
|
|
454
|
-
const result = git.getMainWorktreeRoot(path.join('/home', 'user', 'main-repo.pr42'));
|
|
455
|
-
expect(result).toBe(path.resolve(mainRepo));
|
|
456
|
-
});
|
|
457
|
-
it('falls back to getRepoRoot when commonDir is null', () => {
|
|
458
|
-
const fallbackPath = path.join('/fallback', 'root');
|
|
459
|
-
// First call (git-common-dir) fails, second call (show-toplevel) succeeds
|
|
460
|
-
mockSpawnSync
|
|
461
|
-
.mockReturnValueOnce(mockSpawnFailure('failed'))
|
|
462
|
-
.mockReturnValueOnce(mockSpawnSuccess(fallbackPath));
|
|
463
|
-
const result = git.getMainWorktreeRoot();
|
|
464
|
-
expect(result).toContain('fallback');
|
|
465
|
-
});
|
|
466
|
-
});
|
|
467
|
-
describe('isGitIgnored', () => {
|
|
468
|
-
it('returns true when file is ignored', () => {
|
|
469
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess('node_modules/'));
|
|
470
|
-
expect(git.isGitIgnored('node_modules/')).toBe(true);
|
|
471
|
-
});
|
|
472
|
-
it('returns false when file is not ignored', () => {
|
|
473
|
-
mockSpawnSync.mockReturnValue(mockSpawnFailure('no output for unignored files'));
|
|
474
|
-
expect(git.isGitIgnored('src/index.ts')).toBe(false);
|
|
475
|
-
});
|
|
476
|
-
it('returns false when check-ignore returns empty', () => {
|
|
477
|
-
mockSpawnSync.mockReturnValue(mockSpawnSuccess(''));
|
|
478
|
-
expect(git.isGitIgnored('src/index.ts')).toBe(false);
|
|
479
|
-
});
|
|
480
|
-
});
|
|
481
|
-
describe('checkGitInstalled', () => {
|
|
482
|
-
it('returns true when git is installed', () => {
|
|
483
|
-
mockExecSync.mockReturnValue('git version 2.39.0');
|
|
484
|
-
expect(git.checkGitInstalled()).toBe(true);
|
|
485
|
-
});
|
|
486
|
-
it('returns false when git is not installed', () => {
|
|
487
|
-
mockExecSync.mockImplementation(() => {
|
|
488
|
-
throw new Error('command not found: git');
|
|
489
|
-
});
|
|
490
|
-
expect(git.checkGitInstalled()).toBe(false);
|
|
491
|
-
});
|
|
492
|
-
});
|
|
493
|
-
// ============================================================================
|
|
494
|
-
// Async function tests
|
|
495
|
-
// ============================================================================
|
|
496
|
-
/**
|
|
497
|
-
* Helper to create a mock child process for async spawn
|
|
498
|
-
*/
|
|
499
|
-
function createMockChildProcess(stdout, stderr, exitCode) {
|
|
500
|
-
const child = new EventEmitter();
|
|
501
|
-
// Create mock readable streams
|
|
502
|
-
const mockStdout = new EventEmitter();
|
|
503
|
-
const mockStderr = new EventEmitter();
|
|
504
|
-
child.stdout = mockStdout;
|
|
505
|
-
child.stderr = mockStderr;
|
|
506
|
-
// Emit data and close event on next tick
|
|
507
|
-
process.nextTick(() => {
|
|
508
|
-
if (stdout) {
|
|
509
|
-
child.stdout?.emit('data', Buffer.from(stdout));
|
|
510
|
-
}
|
|
511
|
-
if (stderr) {
|
|
512
|
-
child.stderr?.emit('data', Buffer.from(stderr));
|
|
513
|
-
}
|
|
514
|
-
child.emit('close', exitCode);
|
|
515
|
-
});
|
|
516
|
-
return child;
|
|
517
|
-
}
|
|
518
|
-
describe('execAsync', () => {
|
|
519
|
-
it('executes git command and returns output', async () => {
|
|
520
|
-
mockSpawn.mockReturnValue(createMockChildProcess('output\n', '', 0));
|
|
521
|
-
const result = await git.execAsync(['status']);
|
|
522
|
-
expect(result).toBe('output');
|
|
523
|
-
expect(mockSpawn).toHaveBeenCalledWith('git', ['status'], expect.any(Object));
|
|
524
|
-
});
|
|
525
|
-
it('rejects on non-zero exit code', async () => {
|
|
526
|
-
mockSpawn.mockReturnValue(createMockChildProcess('', 'fatal: error', 1));
|
|
527
|
-
await expect(git.execAsync(['invalid'])).rejects.toThrow('Git command failed');
|
|
528
|
-
});
|
|
529
|
-
it('rejects on spawn error', async () => {
|
|
530
|
-
const child = new EventEmitter();
|
|
531
|
-
child.stdout = new EventEmitter();
|
|
532
|
-
child.stderr = new EventEmitter();
|
|
533
|
-
mockSpawn.mockReturnValue(child);
|
|
534
|
-
const promise = git.execAsync(['status']);
|
|
535
|
-
process.nextTick(() => {
|
|
536
|
-
child.emit('error', new Error('spawn failed'));
|
|
537
|
-
});
|
|
538
|
-
await expect(promise).rejects.toThrow('spawn failed');
|
|
539
|
-
});
|
|
540
|
-
it('passes cwd option correctly', async () => {
|
|
541
|
-
mockSpawn.mockReturnValue(createMockChildProcess('output', '', 0));
|
|
542
|
-
await git.execAsync(['status'], { cwd: '/some/path' });
|
|
543
|
-
expect(mockSpawn).toHaveBeenCalledWith('git', ['status'], expect.objectContaining({ cwd: '/some/path' }));
|
|
544
|
-
});
|
|
545
|
-
});
|
|
546
|
-
describe('fetchAsync', () => {
|
|
547
|
-
it('fetches from remote', async () => {
|
|
548
|
-
mockSpawn.mockReturnValue(createMockChildProcess('', '', 0));
|
|
549
|
-
await git.fetchAsync('origin');
|
|
550
|
-
expect(mockSpawn).toHaveBeenCalledWith('git', ['fetch', 'origin'], expect.any(Object));
|
|
551
|
-
});
|
|
552
|
-
it('uses default remote', async () => {
|
|
553
|
-
mockSpawn.mockReturnValue(createMockChildProcess('', '', 0));
|
|
554
|
-
await git.fetchAsync();
|
|
555
|
-
expect(mockSpawn).toHaveBeenCalledWith('git', ['fetch', 'origin'], expect.any(Object));
|
|
556
|
-
});
|
|
557
|
-
});
|
|
558
|
-
describe('addWorktreeAsync', () => {
|
|
559
|
-
it('creates worktree with existing branch', async () => {
|
|
560
|
-
mockSpawn.mockReturnValue(createMockChildProcess('', '', 0));
|
|
561
|
-
await git.addWorktreeAsync('/path/to/worktree', 'feature-branch');
|
|
562
|
-
expect(mockSpawn).toHaveBeenCalledWith('git', ['worktree', 'add', '/path/to/worktree', 'feature-branch'], expect.any(Object));
|
|
563
|
-
});
|
|
564
|
-
it('creates worktree with new branch', async () => {
|
|
565
|
-
mockSpawn.mockReturnValue(createMockChildProcess('', '', 0));
|
|
566
|
-
await git.addWorktreeAsync('/path/to/worktree', 'new-branch', { createBranch: true });
|
|
567
|
-
expect(mockSpawn).toHaveBeenCalledWith('git', ['worktree', 'add', '-b', 'new-branch', '/path/to/worktree'], expect.any(Object));
|
|
568
|
-
});
|
|
569
|
-
it('creates worktree with new branch from start point', async () => {
|
|
570
|
-
mockSpawn.mockReturnValue(createMockChildProcess('', '', 0));
|
|
571
|
-
await git.addWorktreeAsync('/path/to/worktree', 'new-branch', {
|
|
572
|
-
createBranch: true,
|
|
573
|
-
startPoint: 'origin/main',
|
|
574
|
-
});
|
|
575
|
-
expect(mockSpawn).toHaveBeenCalledWith('git', ['worktree', 'add', '-b', 'new-branch', '/path/to/worktree', 'origin/main'], expect.any(Object));
|
|
576
|
-
});
|
|
577
|
-
});
|
|
578
|
-
describe('removeWorktreeAsync', () => {
|
|
579
|
-
it('removes worktree', async () => {
|
|
580
|
-
mockSpawn.mockReturnValue(createMockChildProcess('', '', 0));
|
|
581
|
-
await git.removeWorktreeAsync('/path/to/worktree');
|
|
582
|
-
expect(mockSpawn).toHaveBeenCalledWith('git', ['worktree', 'remove', '/path/to/worktree'], expect.any(Object));
|
|
583
|
-
});
|
|
584
|
-
it('force removes worktree', async () => {
|
|
585
|
-
mockSpawn.mockReturnValue(createMockChildProcess('', '', 0));
|
|
586
|
-
await git.removeWorktreeAsync('/path/to/worktree', { force: true });
|
|
587
|
-
expect(mockSpawn).toHaveBeenCalledWith('git', ['worktree', 'remove', '--force', '/path/to/worktree'], expect.any(Object));
|
|
588
|
-
});
|
|
589
|
-
});
|
|
590
|
-
describe('pushAsync', () => {
|
|
591
|
-
it('pushes to remote', async () => {
|
|
592
|
-
mockSpawn.mockReturnValue(createMockChildProcess('', '', 0));
|
|
593
|
-
await git.pushAsync();
|
|
594
|
-
expect(mockSpawn).toHaveBeenCalledWith('git', ['push'], expect.any(Object));
|
|
595
|
-
});
|
|
596
|
-
it('pushes with upstream flag', async () => {
|
|
597
|
-
mockSpawn.mockReturnValue(createMockChildProcess('', '', 0));
|
|
598
|
-
await git.pushAsync({ setUpstream: true, remote: 'origin', branch: 'feature' });
|
|
599
|
-
expect(mockSpawn).toHaveBeenCalledWith('git', ['push', '-u', 'origin', 'feature'], expect.any(Object));
|
|
600
|
-
});
|
|
601
|
-
it('force pushes', async () => {
|
|
602
|
-
mockSpawn.mockReturnValue(createMockChildProcess('', '', 0));
|
|
603
|
-
await git.pushAsync({ force: true });
|
|
604
|
-
expect(mockSpawn).toHaveBeenCalledWith('git', ['push', '--force'], expect.any(Object));
|
|
605
|
-
});
|
|
606
|
-
});
|
|
607
|
-
});
|
|
608
|
-
//# sourceMappingURL=git.test.js.map
|