@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,714 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
-
import * as fs from 'fs';
|
|
3
|
-
import * as path from 'path';
|
|
4
|
-
import * as os from 'os';
|
|
5
|
-
import { getAllFiles, getAllDirectories, getFileDecision, getFolderStates, getFolderStateBreakdown, isItemVisible, buildFileTree, findNodeByPath, getHierarchicalViewItems, getFlatViewItems, getVisibleItems, getDisplayItems, isCommonIgnoreDir, COMMON_IGNORE_DIRS, groupByTopDirectory, executeVimCommand, run, } from './manage-manifest.js';
|
|
6
|
-
// Mock git module
|
|
7
|
-
vi.mock('../git.js', () => ({
|
|
8
|
-
checkGitInstalled: vi.fn().mockReturnValue(true),
|
|
9
|
-
getRepoRoot: vi.fn().mockReturnValue('/mock/repo'),
|
|
10
|
-
getMainWorktreeRoot: vi.fn().mockReturnValue('/mock/main-worktree'),
|
|
11
|
-
isGitIgnored: vi.fn().mockReturnValue(true),
|
|
12
|
-
exec: vi.fn(),
|
|
13
|
-
}));
|
|
14
|
-
// Mock inquirer
|
|
15
|
-
vi.mock('inquirer', () => ({
|
|
16
|
-
default: {
|
|
17
|
-
prompt: vi.fn(),
|
|
18
|
-
},
|
|
19
|
-
}));
|
|
20
|
-
// Mock console methods
|
|
21
|
-
const mockConsoleLog = vi.spyOn(console, 'log').mockImplementation(() => { });
|
|
22
|
-
vi.spyOn(console, 'error').mockImplementation(() => { });
|
|
23
|
-
vi.spyOn(console, 'clear').mockImplementation(() => { });
|
|
24
|
-
import * as git from '../git.js';
|
|
25
|
-
describe('wtlink/manage-manifest pure functions', () => {
|
|
26
|
-
// Helper to create a simple file tree
|
|
27
|
-
const createSimpleTree = () => ({
|
|
28
|
-
path: '',
|
|
29
|
-
isDirectory: true,
|
|
30
|
-
children: [
|
|
31
|
-
{
|
|
32
|
-
path: 'src',
|
|
33
|
-
isDirectory: true,
|
|
34
|
-
children: [
|
|
35
|
-
{ path: 'src/index.ts', isDirectory: false, children: [] },
|
|
36
|
-
{ path: 'src/utils.ts', isDirectory: false, children: [] },
|
|
37
|
-
],
|
|
38
|
-
},
|
|
39
|
-
{ path: 'config.json', isDirectory: false, children: [] },
|
|
40
|
-
],
|
|
41
|
-
});
|
|
42
|
-
describe('getAllFiles', () => {
|
|
43
|
-
it('returns single file for non-directory node', () => {
|
|
44
|
-
const node = { path: 'file.ts', isDirectory: false, children: [] };
|
|
45
|
-
expect(getAllFiles(node)).toEqual(['file.ts']);
|
|
46
|
-
});
|
|
47
|
-
it('returns all nested files for directory', () => {
|
|
48
|
-
const tree = createSimpleTree();
|
|
49
|
-
const files = getAllFiles(tree);
|
|
50
|
-
expect(files).toContain('src/index.ts');
|
|
51
|
-
expect(files).toContain('src/utils.ts');
|
|
52
|
-
expect(files).toContain('config.json');
|
|
53
|
-
expect(files).toHaveLength(3);
|
|
54
|
-
});
|
|
55
|
-
it('returns empty array for empty directory', () => {
|
|
56
|
-
const node = { path: 'empty', isDirectory: true, children: [] };
|
|
57
|
-
expect(getAllFiles(node)).toEqual([]);
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
describe('getAllDirectories', () => {
|
|
61
|
-
it('returns empty array for file node', () => {
|
|
62
|
-
const node = { path: 'file.ts', isDirectory: false, children: [] };
|
|
63
|
-
expect(getAllDirectories(node)).toEqual([]);
|
|
64
|
-
});
|
|
65
|
-
it('returns all nested directories', () => {
|
|
66
|
-
const tree = {
|
|
67
|
-
path: '',
|
|
68
|
-
isDirectory: true,
|
|
69
|
-
children: [
|
|
70
|
-
{
|
|
71
|
-
path: 'src',
|
|
72
|
-
isDirectory: true,
|
|
73
|
-
children: [{ path: 'src/lib', isDirectory: true, children: [] }],
|
|
74
|
-
},
|
|
75
|
-
{ path: 'config', isDirectory: true, children: [] },
|
|
76
|
-
],
|
|
77
|
-
};
|
|
78
|
-
const dirs = getAllDirectories(tree);
|
|
79
|
-
expect(dirs.map((d) => d.path)).toContain('src');
|
|
80
|
-
expect(dirs.map((d) => d.path)).toContain('src/lib');
|
|
81
|
-
expect(dirs.map((d) => d.path)).toContain('config');
|
|
82
|
-
expect(dirs).toHaveLength(3);
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
describe('getFileDecision', () => {
|
|
86
|
-
it('returns decision from map when present', () => {
|
|
87
|
-
const decisions = new Map([['file.ts', 'add']]);
|
|
88
|
-
expect(getFileDecision(decisions, 'file.ts')).toBe('add');
|
|
89
|
-
});
|
|
90
|
-
it('returns undecided when file not in map', () => {
|
|
91
|
-
const decisions = new Map();
|
|
92
|
-
expect(getFileDecision(decisions, 'unknown.ts')).toBe('undecided');
|
|
93
|
-
});
|
|
94
|
-
it('handles all decision types', () => {
|
|
95
|
-
const decisions = new Map([
|
|
96
|
-
['add.ts', 'add'],
|
|
97
|
-
['comment.ts', 'comment'],
|
|
98
|
-
['skip.ts', 'skip'],
|
|
99
|
-
]);
|
|
100
|
-
expect(getFileDecision(decisions, 'add.ts')).toBe('add');
|
|
101
|
-
expect(getFileDecision(decisions, 'comment.ts')).toBe('comment');
|
|
102
|
-
expect(getFileDecision(decisions, 'skip.ts')).toBe('skip');
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
describe('getFolderStates', () => {
|
|
106
|
-
it('returns single state for file', () => {
|
|
107
|
-
const node = { path: 'file.ts', isDirectory: false, children: [] };
|
|
108
|
-
const decisions = new Map([['file.ts', 'add']]);
|
|
109
|
-
expect(getFolderStates(node, decisions)).toEqual(new Set(['add']));
|
|
110
|
-
});
|
|
111
|
-
it('returns undecided for file not in decisions', () => {
|
|
112
|
-
const node = { path: 'file.ts', isDirectory: false, children: [] };
|
|
113
|
-
const decisions = new Map();
|
|
114
|
-
expect(getFolderStates(node, decisions)).toEqual(new Set(['undecided']));
|
|
115
|
-
});
|
|
116
|
-
it('returns all states for mixed folder', () => {
|
|
117
|
-
const tree = createSimpleTree();
|
|
118
|
-
const srcNode = tree.children[0];
|
|
119
|
-
const decisions = new Map([
|
|
120
|
-
['src/index.ts', 'add'],
|
|
121
|
-
['src/utils.ts', 'skip'],
|
|
122
|
-
]);
|
|
123
|
-
const states = getFolderStates(srcNode, decisions);
|
|
124
|
-
expect(states.has('add')).toBe(true);
|
|
125
|
-
expect(states.has('skip')).toBe(true);
|
|
126
|
-
expect(states.has('undecided')).toBe(false);
|
|
127
|
-
});
|
|
128
|
-
it('includes undecided for partially decided folder', () => {
|
|
129
|
-
const tree = createSimpleTree();
|
|
130
|
-
const srcNode = tree.children[0];
|
|
131
|
-
const decisions = new Map([['src/index.ts', 'add']]);
|
|
132
|
-
const states = getFolderStates(srcNode, decisions);
|
|
133
|
-
expect(states.has('add')).toBe(true);
|
|
134
|
-
expect(states.has('undecided')).toBe(true);
|
|
135
|
-
});
|
|
136
|
-
});
|
|
137
|
-
describe('getFolderStateBreakdown', () => {
|
|
138
|
-
it('returns correct counts for folder', () => {
|
|
139
|
-
const tree = createSimpleTree();
|
|
140
|
-
const decisions = new Map([
|
|
141
|
-
['src/index.ts', 'add'],
|
|
142
|
-
['src/utils.ts', 'comment'],
|
|
143
|
-
['config.json', 'skip'],
|
|
144
|
-
]);
|
|
145
|
-
const breakdown = getFolderStateBreakdown(tree, decisions);
|
|
146
|
-
expect(breakdown).toEqual({ add: 1, comment: 1, skip: 1, undecided: 0 });
|
|
147
|
-
});
|
|
148
|
-
it('counts undecided files', () => {
|
|
149
|
-
const tree = createSimpleTree();
|
|
150
|
-
const decisions = new Map([['src/index.ts', 'add']]);
|
|
151
|
-
const breakdown = getFolderStateBreakdown(tree, decisions);
|
|
152
|
-
expect(breakdown.add).toBe(1);
|
|
153
|
-
expect(breakdown.undecided).toBe(2);
|
|
154
|
-
});
|
|
155
|
-
});
|
|
156
|
-
describe('isItemVisible', () => {
|
|
157
|
-
it('returns false when no filters active', () => {
|
|
158
|
-
const item = {
|
|
159
|
-
path: 'file.ts',
|
|
160
|
-
isDirectory: false,
|
|
161
|
-
states: new Set(['add']),
|
|
162
|
-
};
|
|
163
|
-
expect(isItemVisible(item, new Set())).toBe(false);
|
|
164
|
-
});
|
|
165
|
-
it('returns true when item state matches filter', () => {
|
|
166
|
-
const item = {
|
|
167
|
-
path: 'file.ts',
|
|
168
|
-
isDirectory: false,
|
|
169
|
-
states: new Set(['add']),
|
|
170
|
-
};
|
|
171
|
-
expect(isItemVisible(item, new Set(['add']))).toBe(true);
|
|
172
|
-
});
|
|
173
|
-
it('returns true when any state matches', () => {
|
|
174
|
-
const item = {
|
|
175
|
-
path: 'folder',
|
|
176
|
-
isDirectory: true,
|
|
177
|
-
states: new Set(['add', 'skip']),
|
|
178
|
-
};
|
|
179
|
-
expect(isItemVisible(item, new Set(['add']))).toBe(true);
|
|
180
|
-
expect(isItemVisible(item, new Set(['skip']))).toBe(true);
|
|
181
|
-
});
|
|
182
|
-
it('returns false when no state matches', () => {
|
|
183
|
-
const item = {
|
|
184
|
-
path: 'file.ts',
|
|
185
|
-
isDirectory: false,
|
|
186
|
-
states: new Set(['add']),
|
|
187
|
-
};
|
|
188
|
-
expect(isItemVisible(item, new Set(['skip', 'comment']))).toBe(false);
|
|
189
|
-
});
|
|
190
|
-
});
|
|
191
|
-
describe('buildFileTree', () => {
|
|
192
|
-
it('builds tree from flat file list', () => {
|
|
193
|
-
const files = ['src/index.ts', 'src/lib/utils.ts', 'config.json'];
|
|
194
|
-
const tree = buildFileTree(files);
|
|
195
|
-
expect(tree.path).toBe('');
|
|
196
|
-
expect(tree.isDirectory).toBe(true);
|
|
197
|
-
expect(tree.children).toHaveLength(2); // src, config.json
|
|
198
|
-
});
|
|
199
|
-
it('handles empty file list', () => {
|
|
200
|
-
const tree = buildFileTree([]);
|
|
201
|
-
expect(tree.path).toBe('');
|
|
202
|
-
expect(tree.isDirectory).toBe(true);
|
|
203
|
-
expect(tree.children).toHaveLength(0);
|
|
204
|
-
});
|
|
205
|
-
it('creates proper hierarchy', () => {
|
|
206
|
-
const files = ['a/b/c/file.ts'];
|
|
207
|
-
const tree = buildFileTree(files);
|
|
208
|
-
// Navigate down the tree
|
|
209
|
-
expect(tree.children).toHaveLength(1);
|
|
210
|
-
const a = tree.children[0];
|
|
211
|
-
expect(a.path).toBe('a');
|
|
212
|
-
expect(a.isDirectory).toBe(true);
|
|
213
|
-
const b = a.children[0];
|
|
214
|
-
expect(b.path).toBe('a/b');
|
|
215
|
-
expect(b.isDirectory).toBe(true);
|
|
216
|
-
const c = b.children[0];
|
|
217
|
-
expect(c.path).toBe('a/b/c');
|
|
218
|
-
expect(c.isDirectory).toBe(true);
|
|
219
|
-
const file = c.children[0];
|
|
220
|
-
expect(file.path).toBe('a/b/c/file.ts');
|
|
221
|
-
expect(file.isDirectory).toBe(false);
|
|
222
|
-
});
|
|
223
|
-
});
|
|
224
|
-
describe('findNodeByPath', () => {
|
|
225
|
-
it('finds root node', () => {
|
|
226
|
-
const tree = createSimpleTree();
|
|
227
|
-
const found = findNodeByPath(tree, '');
|
|
228
|
-
expect(found).toBe(tree);
|
|
229
|
-
});
|
|
230
|
-
it('finds nested directory', () => {
|
|
231
|
-
const tree = createSimpleTree();
|
|
232
|
-
const found = findNodeByPath(tree, 'src');
|
|
233
|
-
expect(found?.path).toBe('src');
|
|
234
|
-
expect(found?.isDirectory).toBe(true);
|
|
235
|
-
});
|
|
236
|
-
it('finds nested file', () => {
|
|
237
|
-
const tree = createSimpleTree();
|
|
238
|
-
const found = findNodeByPath(tree, 'src/index.ts');
|
|
239
|
-
expect(found?.path).toBe('src/index.ts');
|
|
240
|
-
expect(found?.isDirectory).toBe(false);
|
|
241
|
-
});
|
|
242
|
-
it('returns null for non-existent path', () => {
|
|
243
|
-
const tree = createSimpleTree();
|
|
244
|
-
expect(findNodeByPath(tree, 'nonexistent')).toBeNull();
|
|
245
|
-
});
|
|
246
|
-
});
|
|
247
|
-
describe('getHierarchicalViewItems', () => {
|
|
248
|
-
it('returns root children when navigation stack empty', () => {
|
|
249
|
-
const tree = createSimpleTree();
|
|
250
|
-
const decisions = new Map();
|
|
251
|
-
const items = getHierarchicalViewItems(tree, [], decisions);
|
|
252
|
-
expect(items).toHaveLength(2); // src folder and config.json
|
|
253
|
-
});
|
|
254
|
-
it('returns folder children when navigated', () => {
|
|
255
|
-
const tree = createSimpleTree();
|
|
256
|
-
const decisions = new Map();
|
|
257
|
-
const items = getHierarchicalViewItems(tree, ['src'], decisions);
|
|
258
|
-
expect(items).toHaveLength(2); // index.ts and utils.ts
|
|
259
|
-
expect(items.every((i) => i.path.startsWith('src/'))).toBe(true);
|
|
260
|
-
});
|
|
261
|
-
it('sorts folders before files', () => {
|
|
262
|
-
const tree = createSimpleTree();
|
|
263
|
-
const decisions = new Map();
|
|
264
|
-
const items = getHierarchicalViewItems(tree, [], decisions);
|
|
265
|
-
// src folder should come before config.json file
|
|
266
|
-
const srcIndex = items.findIndex((i) => i.path === 'src');
|
|
267
|
-
const configIndex = items.findIndex((i) => i.path === 'config.json');
|
|
268
|
-
expect(srcIndex).toBeLessThan(configIndex);
|
|
269
|
-
});
|
|
270
|
-
});
|
|
271
|
-
describe('getFlatViewItems', () => {
|
|
272
|
-
it('returns all directories and files', () => {
|
|
273
|
-
const tree = createSimpleTree();
|
|
274
|
-
const decisions = new Map();
|
|
275
|
-
const items = getFlatViewItems(tree, decisions);
|
|
276
|
-
// Should have 1 directory (src) and 3 files
|
|
277
|
-
expect(items.some((i) => i.path === 'src' && i.isDirectory)).toBe(true);
|
|
278
|
-
expect(items.some((i) => i.path === 'src/index.ts')).toBe(true);
|
|
279
|
-
expect(items.some((i) => i.path === 'src/utils.ts')).toBe(true);
|
|
280
|
-
expect(items.some((i) => i.path === 'config.json')).toBe(true);
|
|
281
|
-
});
|
|
282
|
-
it('sorts alphabetically', () => {
|
|
283
|
-
const tree = createSimpleTree();
|
|
284
|
-
const decisions = new Map();
|
|
285
|
-
const items = getFlatViewItems(tree, decisions);
|
|
286
|
-
const paths = items.map((i) => i.path);
|
|
287
|
-
const sorted = [...paths].sort();
|
|
288
|
-
expect(paths).toEqual(sorted);
|
|
289
|
-
});
|
|
290
|
-
});
|
|
291
|
-
describe('getVisibleItems', () => {
|
|
292
|
-
it('filters items based on active filters', () => {
|
|
293
|
-
const tree = createSimpleTree();
|
|
294
|
-
const decisions = new Map([
|
|
295
|
-
['src/index.ts', 'add'],
|
|
296
|
-
['src/utils.ts', 'skip'],
|
|
297
|
-
['config.json', 'add'],
|
|
298
|
-
]);
|
|
299
|
-
const state = {
|
|
300
|
-
fileTree: tree,
|
|
301
|
-
decisions,
|
|
302
|
-
viewMode: 'flat',
|
|
303
|
-
activeFilters: new Set(['add']),
|
|
304
|
-
showHelp: false,
|
|
305
|
-
navigationStack: [],
|
|
306
|
-
cursorIndex: 0,
|
|
307
|
-
scrollOffset: 0,
|
|
308
|
-
};
|
|
309
|
-
const items = getVisibleItems(state);
|
|
310
|
-
// Should show items with 'add' state - src folder (contains add), src/index.ts, config.json
|
|
311
|
-
expect(items.some((i) => i.path === 'src/index.ts')).toBe(true);
|
|
312
|
-
expect(items.some((i) => i.path === 'config.json')).toBe(true);
|
|
313
|
-
expect(items.some((i) => i.path === 'src/utils.ts')).toBe(false);
|
|
314
|
-
});
|
|
315
|
-
it('shows nothing when no filters active', () => {
|
|
316
|
-
const tree = createSimpleTree();
|
|
317
|
-
const state = {
|
|
318
|
-
fileTree: tree,
|
|
319
|
-
decisions: new Map(),
|
|
320
|
-
viewMode: 'flat',
|
|
321
|
-
activeFilters: new Set(),
|
|
322
|
-
showHelp: false,
|
|
323
|
-
navigationStack: [],
|
|
324
|
-
cursorIndex: 0,
|
|
325
|
-
scrollOffset: 0,
|
|
326
|
-
};
|
|
327
|
-
const items = getVisibleItems(state);
|
|
328
|
-
expect(items).toHaveLength(0);
|
|
329
|
-
});
|
|
330
|
-
});
|
|
331
|
-
describe('getDisplayItems', () => {
|
|
332
|
-
it('adds back navigation in hierarchical mode when navigated', () => {
|
|
333
|
-
const tree = createSimpleTree();
|
|
334
|
-
const state = {
|
|
335
|
-
fileTree: tree,
|
|
336
|
-
decisions: new Map(),
|
|
337
|
-
viewMode: 'hierarchical',
|
|
338
|
-
activeFilters: new Set(['undecided']),
|
|
339
|
-
showHelp: false,
|
|
340
|
-
navigationStack: ['src'],
|
|
341
|
-
cursorIndex: 0,
|
|
342
|
-
scrollOffset: 0,
|
|
343
|
-
};
|
|
344
|
-
const items = getDisplayItems(state);
|
|
345
|
-
expect(items[0].path).toBe('..');
|
|
346
|
-
});
|
|
347
|
-
it('does not add back navigation at root', () => {
|
|
348
|
-
const tree = createSimpleTree();
|
|
349
|
-
const state = {
|
|
350
|
-
fileTree: tree,
|
|
351
|
-
decisions: new Map(),
|
|
352
|
-
viewMode: 'hierarchical',
|
|
353
|
-
activeFilters: new Set(['undecided']),
|
|
354
|
-
showHelp: false,
|
|
355
|
-
navigationStack: [],
|
|
356
|
-
cursorIndex: 0,
|
|
357
|
-
scrollOffset: 0,
|
|
358
|
-
};
|
|
359
|
-
const items = getDisplayItems(state);
|
|
360
|
-
expect(items[0]?.path).not.toBe('..');
|
|
361
|
-
});
|
|
362
|
-
it('does not add back navigation in flat mode', () => {
|
|
363
|
-
const tree = createSimpleTree();
|
|
364
|
-
const state = {
|
|
365
|
-
fileTree: tree,
|
|
366
|
-
decisions: new Map(),
|
|
367
|
-
viewMode: 'flat',
|
|
368
|
-
activeFilters: new Set(['undecided']),
|
|
369
|
-
showHelp: false,
|
|
370
|
-
navigationStack: ['src'],
|
|
371
|
-
cursorIndex: 0,
|
|
372
|
-
scrollOffset: 0,
|
|
373
|
-
};
|
|
374
|
-
const items = getDisplayItems(state);
|
|
375
|
-
expect(items.every((i) => i.path !== '..')).toBe(true);
|
|
376
|
-
});
|
|
377
|
-
});
|
|
378
|
-
describe('isCommonIgnoreDir', () => {
|
|
379
|
-
it('returns true for common ignore directories', () => {
|
|
380
|
-
expect(isCommonIgnoreDir('node_modules')).toBe(true);
|
|
381
|
-
expect(isCommonIgnoreDir('.git')).toBe(true);
|
|
382
|
-
expect(isCommonIgnoreDir('dist')).toBe(true);
|
|
383
|
-
expect(isCommonIgnoreDir('coverage')).toBe(true);
|
|
384
|
-
});
|
|
385
|
-
it('returns true for nested ignore directories', () => {
|
|
386
|
-
expect(isCommonIgnoreDir('src/node_modules')).toBe(true);
|
|
387
|
-
expect(isCommonIgnoreDir('packages/lib/dist')).toBe(true);
|
|
388
|
-
});
|
|
389
|
-
it('returns false for regular directories', () => {
|
|
390
|
-
expect(isCommonIgnoreDir('src')).toBe(false);
|
|
391
|
-
expect(isCommonIgnoreDir('lib')).toBe(false);
|
|
392
|
-
expect(isCommonIgnoreDir('components')).toBe(false);
|
|
393
|
-
});
|
|
394
|
-
});
|
|
395
|
-
describe('COMMON_IGNORE_DIRS', () => {
|
|
396
|
-
it('contains expected directories', () => {
|
|
397
|
-
expect(COMMON_IGNORE_DIRS).toContain('node_modules');
|
|
398
|
-
expect(COMMON_IGNORE_DIRS).toContain('.git');
|
|
399
|
-
expect(COMMON_IGNORE_DIRS).toContain('dist');
|
|
400
|
-
expect(COMMON_IGNORE_DIRS).toContain('build');
|
|
401
|
-
expect(COMMON_IGNORE_DIRS).toContain('coverage');
|
|
402
|
-
});
|
|
403
|
-
});
|
|
404
|
-
describe('groupByTopDirectory', () => {
|
|
405
|
-
it('groups files by top-level directory', () => {
|
|
406
|
-
const files = ['src/index.ts', 'src/utils.ts', 'lib/helper.ts', 'config.json'];
|
|
407
|
-
const groups = groupByTopDirectory(files);
|
|
408
|
-
expect(groups.get('src')).toBe(2);
|
|
409
|
-
expect(groups.get('lib')).toBe(1);
|
|
410
|
-
expect(groups.get('.')).toBe(1); // root level files
|
|
411
|
-
});
|
|
412
|
-
it('handles empty file list', () => {
|
|
413
|
-
const groups = groupByTopDirectory([]);
|
|
414
|
-
expect(groups.size).toBe(0);
|
|
415
|
-
});
|
|
416
|
-
it('handles root-level files only', () => {
|
|
417
|
-
const files = ['file1.ts', 'file2.ts', 'file3.ts'];
|
|
418
|
-
const groups = groupByTopDirectory(files);
|
|
419
|
-
expect(groups.get('.')).toBe(3);
|
|
420
|
-
expect(groups.size).toBe(1);
|
|
421
|
-
});
|
|
422
|
-
it('handles deeply nested files', () => {
|
|
423
|
-
const files = ['a/b/c/d/file.ts', 'a/b/x/file.ts', 'a/other.ts'];
|
|
424
|
-
const groups = groupByTopDirectory(files);
|
|
425
|
-
// All should be grouped under 'a'
|
|
426
|
-
expect(groups.get('a')).toBe(3);
|
|
427
|
-
});
|
|
428
|
-
it('sorts groups by count descending', () => {
|
|
429
|
-
const files = ['lib/a.ts', 'src/a.ts', 'src/b.ts', 'src/c.ts', 'config.json', 'other.json'];
|
|
430
|
-
const groups = groupByTopDirectory(files);
|
|
431
|
-
const entries = [...groups.entries()];
|
|
432
|
-
// src (3) should come before . (2) should come before lib (1)
|
|
433
|
-
expect(entries[0][0]).toBe('src');
|
|
434
|
-
expect(entries[0][1]).toBe(3);
|
|
435
|
-
expect(entries[1][0]).toBe('.');
|
|
436
|
-
expect(entries[1][1]).toBe(2);
|
|
437
|
-
expect(entries[2][0]).toBe('lib');
|
|
438
|
-
expect(entries[2][1]).toBe(1);
|
|
439
|
-
});
|
|
440
|
-
});
|
|
441
|
-
describe('executeVimCommand', () => {
|
|
442
|
-
it('returns "quit" for :q command', () => {
|
|
443
|
-
expect(executeVimCommand('q')).toBe('quit');
|
|
444
|
-
});
|
|
445
|
-
it('returns "force-quit" for :q! command', () => {
|
|
446
|
-
expect(executeVimCommand('q!')).toBe('force-quit');
|
|
447
|
-
});
|
|
448
|
-
it('returns "save" for :w command', () => {
|
|
449
|
-
expect(executeVimCommand('w')).toBe('save');
|
|
450
|
-
});
|
|
451
|
-
it('returns "save-quit" for :wq command', () => {
|
|
452
|
-
expect(executeVimCommand('wq')).toBe('save-quit');
|
|
453
|
-
});
|
|
454
|
-
it('returns "save-quit" for :x command', () => {
|
|
455
|
-
expect(executeVimCommand('x')).toBe('save-quit');
|
|
456
|
-
});
|
|
457
|
-
it('returns null for unknown commands', () => {
|
|
458
|
-
expect(executeVimCommand('unknown')).toBeNull();
|
|
459
|
-
expect(executeVimCommand('help')).toBeNull();
|
|
460
|
-
expect(executeVimCommand('exit')).toBeNull();
|
|
461
|
-
expect(executeVimCommand('')).toBeNull();
|
|
462
|
-
});
|
|
463
|
-
it('handles whitespace in commands', () => {
|
|
464
|
-
expect(executeVimCommand(' q ')).toBe('quit');
|
|
465
|
-
expect(executeVimCommand('\tq\t')).toBe('quit');
|
|
466
|
-
expect(executeVimCommand(' wq ')).toBe('save-quit');
|
|
467
|
-
expect(executeVimCommand(' w ')).toBe('save');
|
|
468
|
-
});
|
|
469
|
-
it('is case-insensitive', () => {
|
|
470
|
-
expect(executeVimCommand('Q')).toBe('quit');
|
|
471
|
-
expect(executeVimCommand('Q!')).toBe('force-quit');
|
|
472
|
-
expect(executeVimCommand('W')).toBe('save');
|
|
473
|
-
expect(executeVimCommand('WQ')).toBe('save-quit');
|
|
474
|
-
expect(executeVimCommand('X')).toBe('save-quit');
|
|
475
|
-
expect(executeVimCommand('Wq')).toBe('save-quit');
|
|
476
|
-
expect(executeVimCommand('wQ')).toBe('save-quit');
|
|
477
|
-
});
|
|
478
|
-
it('returns null for partial matches', () => {
|
|
479
|
-
expect(executeVimCommand('qa')).toBeNull();
|
|
480
|
-
expect(executeVimCommand('wqa')).toBeNull();
|
|
481
|
-
expect(executeVimCommand('q!!')).toBeNull();
|
|
482
|
-
expect(executeVimCommand('write')).toBeNull();
|
|
483
|
-
expect(executeVimCommand('quit')).toBeNull();
|
|
484
|
-
});
|
|
485
|
-
it('handles edge cases', () => {
|
|
486
|
-
// Just the bang should not be valid
|
|
487
|
-
expect(executeVimCommand('!')).toBeNull();
|
|
488
|
-
// Just whitespace
|
|
489
|
-
expect(executeVimCommand(' ')).toBeNull();
|
|
490
|
-
});
|
|
491
|
-
});
|
|
492
|
-
describe('getDisplayItems - edge cases', () => {
|
|
493
|
-
it('does not add back navigation when not showing undecided only', () => {
|
|
494
|
-
const tree = createSimpleTree();
|
|
495
|
-
const state = {
|
|
496
|
-
fileTree: tree,
|
|
497
|
-
decisions: new Map(),
|
|
498
|
-
viewMode: 'hierarchical',
|
|
499
|
-
activeFilters: new Set(['undecided', 'add']), // Multiple filters
|
|
500
|
-
showHelp: false,
|
|
501
|
-
navigationStack: ['src'],
|
|
502
|
-
cursorIndex: 0,
|
|
503
|
-
scrollOffset: 0,
|
|
504
|
-
};
|
|
505
|
-
const items = getDisplayItems(state);
|
|
506
|
-
// Should not have back navigation because not showing undecided only
|
|
507
|
-
expect(items.every((i) => i.path !== '..')).toBe(true);
|
|
508
|
-
});
|
|
509
|
-
});
|
|
510
|
-
});
|
|
511
|
-
// Mock child_process for getIgnoredFiles
|
|
512
|
-
vi.mock('child_process', async (importOriginal) => {
|
|
513
|
-
const actual = await importOriginal();
|
|
514
|
-
return {
|
|
515
|
-
...actual,
|
|
516
|
-
execSync: vi.fn().mockReturnValue(''),
|
|
517
|
-
};
|
|
518
|
-
});
|
|
519
|
-
import { execSync } from 'child_process';
|
|
520
|
-
describe('wtlink/manage-manifest TUI functions', () => {
|
|
521
|
-
let tempDir;
|
|
522
|
-
let gitRoot;
|
|
523
|
-
let mainWorktreeRoot;
|
|
524
|
-
let manifestPath;
|
|
525
|
-
beforeEach(() => {
|
|
526
|
-
vi.clearAllMocks();
|
|
527
|
-
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'manage-manifest-test-'));
|
|
528
|
-
gitRoot = path.join(tempDir, 'worktree');
|
|
529
|
-
mainWorktreeRoot = path.join(tempDir, 'main');
|
|
530
|
-
fs.mkdirSync(gitRoot, { recursive: true });
|
|
531
|
-
fs.mkdirSync(mainWorktreeRoot, { recursive: true });
|
|
532
|
-
manifestPath = path.join(mainWorktreeRoot, '.wtlink');
|
|
533
|
-
// Set up git mocks
|
|
534
|
-
vi.mocked(git.getRepoRoot).mockReturnValue(gitRoot);
|
|
535
|
-
vi.mocked(git.getMainWorktreeRoot).mockReturnValue(mainWorktreeRoot);
|
|
536
|
-
vi.mocked(git.isGitIgnored).mockReturnValue(true);
|
|
537
|
-
vi.mocked(execSync).mockReturnValue(Buffer.from(''));
|
|
538
|
-
});
|
|
539
|
-
afterEach(() => {
|
|
540
|
-
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
541
|
-
vi.clearAllMocks();
|
|
542
|
-
});
|
|
543
|
-
describe('run', () => {
|
|
544
|
-
it('should report manifest is up to date when no changes needed', async () => {
|
|
545
|
-
// Create empty manifest and no ignored files
|
|
546
|
-
fs.writeFileSync(manifestPath, '');
|
|
547
|
-
// Mock git ls-files to return empty (no ignored files)
|
|
548
|
-
vi.mocked(execSync).mockReturnValue(Buffer.from(''));
|
|
549
|
-
const argv = {
|
|
550
|
-
nonInteractive: true,
|
|
551
|
-
clean: false,
|
|
552
|
-
dryRun: false,
|
|
553
|
-
manifestFile: '.wtlink',
|
|
554
|
-
backup: false,
|
|
555
|
-
verbose: false,
|
|
556
|
-
};
|
|
557
|
-
await run(argv);
|
|
558
|
-
expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('up to date'));
|
|
559
|
-
});
|
|
560
|
-
it('should handle deleted entries in clean mode', async () => {
|
|
561
|
-
// Create manifest with entry that doesn't exist in filesystem
|
|
562
|
-
fs.writeFileSync(manifestPath, 'deleted-file.txt');
|
|
563
|
-
// Mock git ls-files to return empty (no new ignored files)
|
|
564
|
-
vi.mocked(execSync).mockReturnValue(Buffer.from(''));
|
|
565
|
-
const argv = {
|
|
566
|
-
nonInteractive: true,
|
|
567
|
-
clean: true,
|
|
568
|
-
dryRun: false,
|
|
569
|
-
manifestFile: '.wtlink',
|
|
570
|
-
backup: false,
|
|
571
|
-
verbose: false,
|
|
572
|
-
};
|
|
573
|
-
await run(argv);
|
|
574
|
-
// In clean mode, deleted entries should be removed
|
|
575
|
-
expect(mockConsoleLog).toHaveBeenCalled();
|
|
576
|
-
});
|
|
577
|
-
it('should handle dry-run mode without modifying manifest', async () => {
|
|
578
|
-
const originalContent = 'existing-file.txt';
|
|
579
|
-
fs.writeFileSync(manifestPath, originalContent);
|
|
580
|
-
// Create the existing file in worktree
|
|
581
|
-
fs.writeFileSync(path.join(gitRoot, 'existing-file.txt'), 'content');
|
|
582
|
-
// Mock new ignored file
|
|
583
|
-
vi.mocked(execSync).mockReturnValue(Buffer.from('new-ignored-file.txt'));
|
|
584
|
-
const argv = {
|
|
585
|
-
nonInteractive: true,
|
|
586
|
-
clean: false,
|
|
587
|
-
dryRun: true,
|
|
588
|
-
manifestFile: '.wtlink',
|
|
589
|
-
backup: false,
|
|
590
|
-
verbose: false,
|
|
591
|
-
};
|
|
592
|
-
await run(argv);
|
|
593
|
-
// Manifest should not be modified in dry-run mode
|
|
594
|
-
const finalContent = fs.readFileSync(manifestPath, 'utf-8');
|
|
595
|
-
expect(finalContent).toBe(originalContent);
|
|
596
|
-
});
|
|
597
|
-
it('should handle tracked entries warning in clean mode', async () => {
|
|
598
|
-
// Create manifest with an entry that is now tracked (not ignored)
|
|
599
|
-
fs.writeFileSync(manifestPath, 'now-tracked.txt');
|
|
600
|
-
fs.writeFileSync(path.join(gitRoot, 'now-tracked.txt'), 'content');
|
|
601
|
-
// Mock file as not ignored (tracked by git)
|
|
602
|
-
vi.mocked(git.isGitIgnored).mockReturnValue(false);
|
|
603
|
-
vi.mocked(execSync).mockReturnValue(Buffer.from(''));
|
|
604
|
-
const argv = {
|
|
605
|
-
nonInteractive: true,
|
|
606
|
-
clean: true,
|
|
607
|
-
dryRun: false,
|
|
608
|
-
manifestFile: '.wtlink',
|
|
609
|
-
backup: false,
|
|
610
|
-
verbose: false,
|
|
611
|
-
};
|
|
612
|
-
await run(argv);
|
|
613
|
-
// Should show warning about tracked files
|
|
614
|
-
expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('TRACKED'));
|
|
615
|
-
});
|
|
616
|
-
it('should create backup when backup option is enabled and manifest changes', async () => {
|
|
617
|
-
// Create manifest with a deleted entry (file doesn't exist)
|
|
618
|
-
const originalContent = 'deleted-file.txt';
|
|
619
|
-
fs.writeFileSync(manifestPath, originalContent);
|
|
620
|
-
// Mock no new ignored files, file doesn't exist so it's "deleted"
|
|
621
|
-
vi.mocked(execSync).mockReturnValue(Buffer.from(''));
|
|
622
|
-
const argv = {
|
|
623
|
-
nonInteractive: true,
|
|
624
|
-
clean: true, // clean mode will remove deleted entries
|
|
625
|
-
dryRun: false,
|
|
626
|
-
manifestFile: '.wtlink',
|
|
627
|
-
backup: true,
|
|
628
|
-
verbose: false,
|
|
629
|
-
};
|
|
630
|
-
await run(argv);
|
|
631
|
-
// Backup file should be created when manifest is modified
|
|
632
|
-
const backupPath = manifestPath + '.bak';
|
|
633
|
-
if (fs.existsSync(backupPath)) {
|
|
634
|
-
expect(fs.readFileSync(backupPath, 'utf-8')).toBe(originalContent);
|
|
635
|
-
}
|
|
636
|
-
// If backup wasn't created, it means manifest wasn't modified - that's also valid
|
|
637
|
-
});
|
|
638
|
-
it('should add new ignored files as commented in non-interactive mode', async () => {
|
|
639
|
-
// Create empty manifest
|
|
640
|
-
fs.writeFileSync(manifestPath, '');
|
|
641
|
-
// Mock new ignored files
|
|
642
|
-
vi.mocked(execSync).mockReturnValue(Buffer.from('new-file.txt\nconfig.json'));
|
|
643
|
-
const argv = {
|
|
644
|
-
nonInteractive: true,
|
|
645
|
-
clean: false,
|
|
646
|
-
dryRun: false,
|
|
647
|
-
manifestFile: '.wtlink',
|
|
648
|
-
backup: false,
|
|
649
|
-
verbose: false,
|
|
650
|
-
};
|
|
651
|
-
await run(argv);
|
|
652
|
-
// New files should be added as commented
|
|
653
|
-
const content = fs.readFileSync(manifestPath, 'utf-8');
|
|
654
|
-
expect(content).toContain('# new-file.txt');
|
|
655
|
-
expect(content).toContain('# config.json');
|
|
656
|
-
});
|
|
657
|
-
it('should show verbose output when verbose flag is set', async () => {
|
|
658
|
-
// Create empty manifest
|
|
659
|
-
fs.writeFileSync(manifestPath, '');
|
|
660
|
-
// Mock many new ignored files
|
|
661
|
-
const files = Array.from({ length: 100 }, (_, i) => `file${i}.txt`).join('\n');
|
|
662
|
-
vi.mocked(execSync).mockReturnValue(Buffer.from(files));
|
|
663
|
-
const argv = {
|
|
664
|
-
nonInteractive: true,
|
|
665
|
-
clean: false,
|
|
666
|
-
dryRun: true,
|
|
667
|
-
manifestFile: '.wtlink',
|
|
668
|
-
backup: false,
|
|
669
|
-
verbose: true, // verbose mode
|
|
670
|
-
};
|
|
671
|
-
await run(argv);
|
|
672
|
-
// With verbose mode, should see individual file names logged
|
|
673
|
-
expect(mockConsoleLog).toHaveBeenCalled();
|
|
674
|
-
});
|
|
675
|
-
it('should show summary for large file sets in dry-run without verbose', async () => {
|
|
676
|
-
// Create empty manifest
|
|
677
|
-
fs.writeFileSync(manifestPath, '');
|
|
678
|
-
// Mock many new ignored files in src/ directory
|
|
679
|
-
const files = Array.from({ length: 100 }, (_, i) => `src/file${i}.txt`).join('\n');
|
|
680
|
-
vi.mocked(execSync).mockReturnValue(Buffer.from(files));
|
|
681
|
-
const argv = {
|
|
682
|
-
nonInteractive: true,
|
|
683
|
-
clean: false,
|
|
684
|
-
dryRun: true,
|
|
685
|
-
manifestFile: '.wtlink',
|
|
686
|
-
backup: false,
|
|
687
|
-
verbose: false, // no verbose
|
|
688
|
-
};
|
|
689
|
-
await run(argv);
|
|
690
|
-
// Should show summary instead of full list
|
|
691
|
-
expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('100'));
|
|
692
|
-
});
|
|
693
|
-
it('should handle git ls-files error gracefully', async () => {
|
|
694
|
-
// Create empty manifest
|
|
695
|
-
fs.writeFileSync(manifestPath, '');
|
|
696
|
-
// Mock git ls-files to throw error
|
|
697
|
-
vi.mocked(execSync).mockImplementation(() => {
|
|
698
|
-
throw new Error('Git command failed');
|
|
699
|
-
});
|
|
700
|
-
const argv = {
|
|
701
|
-
nonInteractive: true,
|
|
702
|
-
clean: false,
|
|
703
|
-
dryRun: false,
|
|
704
|
-
manifestFile: '.wtlink',
|
|
705
|
-
backup: false,
|
|
706
|
-
verbose: false,
|
|
707
|
-
};
|
|
708
|
-
await run(argv);
|
|
709
|
-
// Should show warning and continue
|
|
710
|
-
expect(mockConsoleLog).toHaveBeenCalledWith(expect.stringContaining('up to date'));
|
|
711
|
-
});
|
|
712
|
-
});
|
|
713
|
-
});
|
|
714
|
-
//# sourceMappingURL=manage-manifest.test.js.map
|