@camaradesuk/git-worktree-tools 1.3.0 → 1.4.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 +290 -3
- package/dist/api/clean.d.ts +65 -0
- package/dist/api/clean.d.ts.map +1 -0
- package/dist/api/clean.js +209 -0
- package/dist/api/clean.js.map +1 -0
- package/dist/api/create.d.ts +88 -0
- package/dist/api/create.d.ts.map +1 -0
- package/dist/api/create.js +370 -0
- package/dist/api/create.js.map +1 -0
- package/dist/api/index.d.ts +15 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +19 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/list.d.ts +74 -0
- package/dist/api/list.d.ts.map +1 -0
- package/dist/api/list.js +80 -0
- package/dist/api/list.js.map +1 -0
- package/dist/api/state.d.ts +43 -0
- package/dist/api/state.d.ts.map +1 -0
- package/dist/api/state.js +70 -0
- package/dist/api/state.js.map +1 -0
- package/dist/cli/cleanpr.js +171 -28
- package/dist/cli/cleanpr.js.map +1 -1
- package/dist/cli/cleanpr.test.js +459 -7
- package/dist/cli/cleanpr.test.js.map +1 -1
- package/dist/cli/newpr.js +189 -28
- package/dist/cli/newpr.js.map +1 -1
- package/dist/cli/newpr.test.js +349 -0
- package/dist/cli/newpr.test.js.map +1 -1
- package/dist/cli/wtconfig.d.ts +14 -0
- package/dist/cli/wtconfig.d.ts.map +1 -0
- package/dist/cli/wtconfig.js +948 -0
- package/dist/cli/wtconfig.js.map +1 -0
- package/dist/cli/wtconfig.test.d.ts +5 -0
- package/dist/cli/wtconfig.test.d.ts.map +1 -0
- package/dist/cli/wtconfig.test.js +1281 -0
- package/dist/cli/wtconfig.test.js.map +1 -0
- package/dist/cli/wtlink.js +5 -0
- package/dist/cli/wtlink.js.map +1 -1
- package/dist/cli/wtstate.d.ts +8 -0
- package/dist/cli/wtstate.d.ts.map +1 -0
- package/dist/cli/wtstate.js +83 -0
- package/dist/cli/wtstate.js.map +1 -0
- package/dist/cli/wtstate.test.d.ts +5 -0
- package/dist/cli/wtstate.test.d.ts.map +1 -0
- package/dist/cli/wtstate.test.js +193 -0
- package/dist/cli/wtstate.test.js.map +1 -0
- package/dist/e2e/cleanpr/cleanpr.e2e.test.d.ts +2 -0
- package/dist/e2e/cleanpr/cleanpr.e2e.test.d.ts.map +1 -0
- package/dist/e2e/cleanpr/cleanpr.e2e.test.js +326 -0
- package/dist/e2e/cleanpr/cleanpr.e2e.test.js.map +1 -0
- package/dist/e2e/helpers/cli-runner.d.ts +103 -0
- package/dist/e2e/helpers/cli-runner.d.ts.map +1 -0
- package/dist/e2e/helpers/cli-runner.js +200 -0
- package/dist/e2e/helpers/cli-runner.js.map +1 -0
- package/dist/e2e/helpers/gh-mock.d.ts +87 -0
- package/dist/e2e/helpers/gh-mock.d.ts.map +1 -0
- package/dist/e2e/helpers/gh-mock.js +384 -0
- package/dist/e2e/helpers/gh-mock.js.map +1 -0
- package/dist/e2e/helpers/index.d.ts +12 -0
- package/dist/e2e/helpers/index.d.ts.map +1 -0
- package/dist/e2e/helpers/index.js +16 -0
- package/dist/e2e/helpers/index.js.map +1 -0
- package/dist/e2e/helpers/pty-wrapper.d.ts +118 -0
- package/dist/e2e/helpers/pty-wrapper.d.ts.map +1 -0
- package/dist/e2e/helpers/pty-wrapper.js +276 -0
- package/dist/e2e/helpers/pty-wrapper.js.map +1 -0
- package/dist/e2e/helpers/scenario-harness.d.ts +55 -0
- package/dist/e2e/helpers/scenario-harness.d.ts.map +1 -0
- package/dist/e2e/helpers/scenario-harness.js +360 -0
- package/dist/e2e/helpers/scenario-harness.js.map +1 -0
- package/dist/e2e/helpers/test-context.d.ts +120 -0
- package/dist/e2e/helpers/test-context.d.ts.map +1 -0
- package/dist/e2e/helpers/test-context.js +263 -0
- package/dist/e2e/helpers/test-context.js.map +1 -0
- package/dist/e2e/lswt/lswt.e2e.test.d.ts +2 -0
- package/dist/e2e/lswt/lswt.e2e.test.d.ts.map +1 -0
- package/dist/e2e/lswt/lswt.e2e.test.js +328 -0
- package/dist/e2e/lswt/lswt.e2e.test.js.map +1 -0
- package/dist/e2e/newpr/newpr.e2e.test.d.ts +2 -0
- package/dist/e2e/newpr/newpr.e2e.test.d.ts.map +1 -0
- package/dist/e2e/newpr/newpr.e2e.test.js +286 -0
- package/dist/e2e/newpr/newpr.e2e.test.js.map +1 -0
- package/dist/e2e/newpr/scenarios.e2e.test.d.ts +2 -0
- package/dist/e2e/newpr/scenarios.e2e.test.d.ts.map +1 -0
- package/dist/e2e/newpr/scenarios.e2e.test.js +426 -0
- package/dist/e2e/newpr/scenarios.e2e.test.js.map +1 -0
- package/dist/e2e/workflows/pr-lifecycle.e2e.test.d.ts +2 -0
- package/dist/e2e/workflows/pr-lifecycle.e2e.test.d.ts.map +1 -0
- package/dist/e2e/workflows/pr-lifecycle.e2e.test.js +298 -0
- package/dist/e2e/workflows/pr-lifecycle.e2e.test.js.map +1 -0
- package/dist/e2e/wtlink/wtlink.e2e.test.d.ts +2 -0
- package/dist/e2e/wtlink/wtlink.e2e.test.d.ts.map +1 -0
- package/dist/e2e/wtlink/wtlink.e2e.test.js +364 -0
- package/dist/e2e/wtlink/wtlink.e2e.test.js.map +1 -0
- package/dist/index.d.ts +15 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/ai/base-provider.d.ts +58 -0
- package/dist/lib/ai/base-provider.d.ts.map +1 -0
- package/dist/lib/ai/base-provider.js +246 -0
- package/dist/lib/ai/base-provider.js.map +1 -0
- package/dist/lib/ai/base-provider.test.d.ts +7 -0
- package/dist/lib/ai/base-provider.test.d.ts.map +1 -0
- package/dist/lib/ai/base-provider.test.js +320 -0
- package/dist/lib/ai/base-provider.test.js.map +1 -0
- package/dist/lib/ai/cli-provider.d.ts +87 -0
- package/dist/lib/ai/cli-provider.d.ts.map +1 -0
- package/dist/lib/ai/cli-provider.js +280 -0
- package/dist/lib/ai/cli-provider.js.map +1 -0
- package/dist/lib/ai/cli-provider.test.d.ts +5 -0
- package/dist/lib/ai/cli-provider.test.d.ts.map +1 -0
- package/dist/lib/ai/cli-provider.test.js +462 -0
- package/dist/lib/ai/cli-provider.test.js.map +1 -0
- package/dist/lib/ai/fallback-provider.d.ts +20 -0
- package/dist/lib/ai/fallback-provider.d.ts.map +1 -0
- package/dist/lib/ai/fallback-provider.js +125 -0
- package/dist/lib/ai/fallback-provider.js.map +1 -0
- package/dist/lib/ai/fallback-provider.test.d.ts +7 -0
- package/dist/lib/ai/fallback-provider.test.d.ts.map +1 -0
- package/dist/lib/ai/fallback-provider.test.js +165 -0
- package/dist/lib/ai/fallback-provider.test.js.map +1 -0
- package/dist/lib/ai/generation-service.d.ts +44 -0
- package/dist/lib/ai/generation-service.d.ts.map +1 -0
- package/dist/lib/ai/generation-service.js +107 -0
- package/dist/lib/ai/generation-service.js.map +1 -0
- package/dist/lib/ai/generation-service.test.d.ts +7 -0
- package/dist/lib/ai/generation-service.test.d.ts.map +1 -0
- package/dist/lib/ai/generation-service.test.js +213 -0
- package/dist/lib/ai/generation-service.test.js.map +1 -0
- package/dist/lib/ai/index.d.ts +19 -0
- package/dist/lib/ai/index.d.ts.map +1 -0
- package/dist/lib/ai/index.js +22 -0
- package/dist/lib/ai/index.js.map +1 -0
- package/dist/lib/ai/provider-manager.d.ts +109 -0
- package/dist/lib/ai/provider-manager.d.ts.map +1 -0
- package/dist/lib/ai/provider-manager.js +270 -0
- package/dist/lib/ai/provider-manager.js.map +1 -0
- package/dist/lib/ai/provider-manager.test.d.ts +5 -0
- package/dist/lib/ai/provider-manager.test.d.ts.map +1 -0
- package/dist/lib/ai/provider-manager.test.js +312 -0
- package/dist/lib/ai/provider-manager.test.js.map +1 -0
- package/dist/lib/ai/types.d.ts +166 -0
- package/dist/lib/ai/types.d.ts.map +1 -0
- package/dist/lib/ai/types.js +19 -0
- package/dist/lib/ai/types.js.map +1 -0
- package/dist/lib/cleanpr/args.d.ts.map +1 -1
- package/dist/lib/cleanpr/args.js +18 -0
- package/dist/lib/cleanpr/args.js.map +1 -1
- package/dist/lib/cleanpr/args.test.js +88 -11
- package/dist/lib/cleanpr/args.test.js.map +1 -1
- package/dist/lib/cleanpr/cleanup.d.ts +2 -0
- package/dist/lib/cleanpr/cleanup.d.ts.map +1 -1
- package/dist/lib/cleanpr/cleanup.js +30 -2
- package/dist/lib/cleanpr/cleanup.js.map +1 -1
- package/dist/lib/cleanpr/cleanup.test.js +37 -5
- package/dist/lib/cleanpr/cleanup.test.js.map +1 -1
- package/dist/lib/cleanpr/types.d.ts +10 -0
- package/dist/lib/cleanpr/types.d.ts.map +1 -1
- package/dist/lib/cleanpr/worktree-info.test.js +72 -1
- package/dist/lib/cleanpr/worktree-info.test.js.map +1 -1
- package/dist/lib/config.d.ts +170 -1
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +129 -2
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/config.test.js +406 -2
- package/dist/lib/config.test.js.map +1 -1
- package/dist/lib/hooks/executor.d.ts +35 -0
- package/dist/lib/hooks/executor.d.ts.map +1 -0
- package/dist/lib/hooks/executor.js +401 -0
- package/dist/lib/hooks/executor.js.map +1 -0
- package/dist/lib/hooks/executor.test.d.ts +5 -0
- package/dist/lib/hooks/executor.test.d.ts.map +1 -0
- package/dist/lib/hooks/executor.test.js +648 -0
- package/dist/lib/hooks/executor.test.js.map +1 -0
- package/dist/lib/hooks/index.d.ts +25 -0
- package/dist/lib/hooks/index.d.ts.map +1 -0
- package/dist/lib/hooks/index.js +26 -0
- package/dist/lib/hooks/index.js.map +1 -0
- package/dist/lib/hooks/templates.d.ts +74 -0
- package/dist/lib/hooks/templates.d.ts.map +1 -0
- package/dist/lib/hooks/templates.js +270 -0
- package/dist/lib/hooks/templates.js.map +1 -0
- package/dist/lib/hooks/templates.test.d.ts +5 -0
- package/dist/lib/hooks/templates.test.d.ts.map +1 -0
- package/dist/lib/hooks/templates.test.js +163 -0
- package/dist/lib/hooks/templates.test.js.map +1 -0
- package/dist/lib/hooks/types.d.ts +161 -0
- package/dist/lib/hooks/types.d.ts.map +1 -0
- package/dist/lib/hooks/types.js +73 -0
- package/dist/lib/hooks/types.js.map +1 -0
- package/dist/lib/hooks/types.test.d.ts +5 -0
- package/dist/lib/hooks/types.test.d.ts.map +1 -0
- package/dist/lib/hooks/types.test.js +132 -0
- package/dist/lib/hooks/types.test.js.map +1 -0
- package/dist/lib/json-output.d.ts +172 -0
- package/dist/lib/json-output.d.ts.map +1 -0
- package/dist/lib/json-output.js +134 -0
- package/dist/lib/json-output.js.map +1 -0
- package/dist/lib/json-output.test.d.ts +5 -0
- package/dist/lib/json-output.test.d.ts.map +1 -0
- package/dist/lib/json-output.test.js +259 -0
- package/dist/lib/json-output.test.js.map +1 -0
- package/dist/lib/lswt/action-executors.test.js +6 -0
- package/dist/lib/lswt/action-executors.test.js.map +1 -1
- package/dist/lib/newpr/action-deps.d.ts +15 -0
- package/dist/lib/newpr/action-deps.d.ts.map +1 -0
- package/dist/lib/newpr/action-deps.js +22 -0
- package/dist/lib/newpr/action-deps.js.map +1 -0
- package/dist/lib/newpr/args.d.ts.map +1 -1
- package/dist/lib/newpr/args.js +56 -0
- package/dist/lib/newpr/args.js.map +1 -1
- package/dist/lib/newpr/hook-runner.d.ts +80 -0
- package/dist/lib/newpr/hook-runner.d.ts.map +1 -0
- package/dist/lib/newpr/hook-runner.js +182 -0
- package/dist/lib/newpr/hook-runner.js.map +1 -0
- package/dist/lib/newpr/hook-runner.test.d.ts +7 -0
- package/dist/lib/newpr/hook-runner.test.d.ts.map +1 -0
- package/dist/lib/newpr/hook-runner.test.js +301 -0
- package/dist/lib/newpr/hook-runner.test.js.map +1 -0
- package/dist/lib/newpr/index.d.ts +3 -0
- package/dist/lib/newpr/index.d.ts.map +1 -1
- package/dist/lib/newpr/index.js +3 -0
- package/dist/lib/newpr/index.js.map +1 -1
- package/dist/lib/newpr/types.d.ts +9 -0
- package/dist/lib/newpr/types.d.ts.map +1 -1
- package/dist/lib/wtconfig/config-manager.d.ts +72 -0
- package/dist/lib/wtconfig/config-manager.d.ts.map +1 -0
- package/dist/lib/wtconfig/config-manager.js +408 -0
- package/dist/lib/wtconfig/config-manager.js.map +1 -0
- package/dist/lib/wtconfig/config-manager.test.d.ts +5 -0
- package/dist/lib/wtconfig/config-manager.test.d.ts.map +1 -0
- package/dist/lib/wtconfig/config-manager.test.js +501 -0
- package/dist/lib/wtconfig/config-manager.test.js.map +1 -0
- package/dist/lib/wtconfig/environment.d.ts +23 -0
- package/dist/lib/wtconfig/environment.d.ts.map +1 -0
- package/dist/lib/wtconfig/environment.js +238 -0
- package/dist/lib/wtconfig/environment.js.map +1 -0
- package/dist/lib/wtconfig/environment.test.d.ts +5 -0
- package/dist/lib/wtconfig/environment.test.d.ts.map +1 -0
- package/dist/lib/wtconfig/environment.test.js +246 -0
- package/dist/lib/wtconfig/environment.test.js.map +1 -0
- package/dist/lib/wtconfig/index.d.ts +7 -0
- package/dist/lib/wtconfig/index.d.ts.map +1 -0
- package/dist/lib/wtconfig/index.js +8 -0
- package/dist/lib/wtconfig/index.js.map +1 -0
- package/dist/lib/wtconfig/types.d.ts +97 -0
- package/dist/lib/wtconfig/types.d.ts.map +1 -0
- package/dist/lib/wtconfig/types.js +5 -0
- package/dist/lib/wtconfig/types.js.map +1 -0
- package/dist/lib/wtstate/analyze.d.ts +13 -0
- package/dist/lib/wtstate/analyze.d.ts.map +1 -0
- package/dist/lib/wtstate/analyze.js +165 -0
- package/dist/lib/wtstate/analyze.js.map +1 -0
- package/dist/lib/wtstate/analyze.test.d.ts +5 -0
- package/dist/lib/wtstate/analyze.test.d.ts.map +1 -0
- package/dist/lib/wtstate/analyze.test.js +282 -0
- package/dist/lib/wtstate/analyze.test.js.map +1 -0
- package/dist/lib/wtstate/args.d.ts +17 -0
- package/dist/lib/wtstate/args.d.ts.map +1 -0
- package/dist/lib/wtstate/args.js +91 -0
- package/dist/lib/wtstate/args.js.map +1 -0
- package/dist/lib/wtstate/args.test.d.ts +5 -0
- package/dist/lib/wtstate/args.test.d.ts.map +1 -0
- package/dist/lib/wtstate/args.test.js +120 -0
- package/dist/lib/wtstate/args.test.js.map +1 -0
- package/dist/lib/wtstate/index.d.ts +7 -0
- package/dist/lib/wtstate/index.d.ts.map +1 -0
- package/dist/lib/wtstate/index.js +8 -0
- package/dist/lib/wtstate/index.js.map +1 -0
- package/dist/lib/wtstate/types.d.ts +64 -0
- package/dist/lib/wtstate/types.d.ts.map +1 -0
- package/dist/lib/wtstate/types.js +5 -0
- package/dist/lib/wtstate/types.js.map +1 -0
- package/dist/mcp/server.d.ts +14 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +339 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/server.test.d.ts +9 -0
- package/dist/mcp/server.test.d.ts.map +1 -0
- package/dist/mcp/server.test.js +390 -0
- package/dist/mcp/server.test.js.map +1 -0
- package/package.json +8 -2
package/README.md
CHANGED
|
@@ -41,6 +41,12 @@ cleanpr
|
|
|
41
41
|
|
|
42
42
|
# Manage shared config files between worktrees
|
|
43
43
|
wtlink
|
|
44
|
+
|
|
45
|
+
# Query git state (for AI agents)
|
|
46
|
+
wtstate --json
|
|
47
|
+
|
|
48
|
+
# Configure settings with interactive wizard
|
|
49
|
+
wtconfig init
|
|
44
50
|
```
|
|
45
51
|
|
|
46
52
|
## Commands
|
|
@@ -205,15 +211,204 @@ The manifest lives in your repository root and tracks which files to share:
|
|
|
205
211
|
- `dist/`, `build/` — Build artifacts should be separate per worktree
|
|
206
212
|
- `.git/` — Never link git internals
|
|
207
213
|
|
|
214
|
+
### wtstate
|
|
215
|
+
|
|
216
|
+
Query the current git state for AI agents and automation. Returns structured information about the repository state, available actions, and recommended next steps.
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
wtstate # Human-readable output
|
|
220
|
+
wtstate --json # Machine-readable JSON output
|
|
221
|
+
wtstate --verbose # Include file lists and commit details
|
|
222
|
+
wtstate --base dev # Specify base branch (default: main)
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
**JSON output includes:**
|
|
226
|
+
|
|
227
|
+
- `scenario` — Current git state scenario (e.g., `main_staged_same`, `branch_with_changes`)
|
|
228
|
+
- `scenarioDescription` — Human-readable description
|
|
229
|
+
- `currentBranch` — Current branch name (null if detached HEAD)
|
|
230
|
+
- `baseBranch` — Base branch for comparison
|
|
231
|
+
- `worktreeType` — Type: `main_worktree`, `pr_worktree`, or `other`
|
|
232
|
+
- `hasChanges`, `hasStagedChanges`, `hasUnstagedChanges` — Change flags
|
|
233
|
+
- `localCommits` — List of local commits not in origin
|
|
234
|
+
- `availableActions` — Actions available for this scenario
|
|
235
|
+
- `recommendedAction` — Suggested action to take
|
|
236
|
+
|
|
237
|
+
### wtconfig
|
|
238
|
+
|
|
239
|
+
Configuration management with an interactive setup wizard.
|
|
240
|
+
|
|
241
|
+
```bash
|
|
242
|
+
wtconfig init # Run interactive setup wizard
|
|
243
|
+
wtconfig show # Show current configuration
|
|
244
|
+
wtconfig set <key> <val> # Set a configuration value
|
|
245
|
+
wtconfig get <key> # Get a configuration value
|
|
246
|
+
wtconfig edit # Open config in default editor
|
|
247
|
+
wtconfig validate # Validate configuration
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
**Setup wizard detects:**
|
|
251
|
+
|
|
252
|
+
- Operating system and installed tools
|
|
253
|
+
- Git configuration (version, user, email)
|
|
254
|
+
- GitHub CLI authentication
|
|
255
|
+
- Available AI tools (Claude Code, Gemini CLI, Ollama)
|
|
256
|
+
- Package manager (npm, pnpm, yarn, bun)
|
|
257
|
+
- IDE availability (VS Code, Cursor)
|
|
258
|
+
|
|
259
|
+
**Configuration locations:**
|
|
260
|
+
|
|
261
|
+
- **Global:** `~/.worktreerc` (applies to all repos)
|
|
262
|
+
- **Repository:** `.worktreerc` or `.worktreerc.json` (repo-specific)
|
|
263
|
+
|
|
264
|
+
Repository config overrides global settings.
|
|
265
|
+
|
|
266
|
+
**Example AI workflow:**
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
# 1. Query state
|
|
270
|
+
STATE=$(wtstate --json)
|
|
271
|
+
|
|
272
|
+
# 2. Extract recommended action
|
|
273
|
+
ACTION=$(echo $STATE | jq -r '.data.recommendedAction')
|
|
274
|
+
|
|
275
|
+
# 3. Execute with chosen action
|
|
276
|
+
newpr "Add feature" --non-interactive --action=$ACTION --json
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
## AI Tool Integration
|
|
280
|
+
|
|
281
|
+
All commands support `--json` for machine-readable output, enabling integration with AI CLI tools like Claude Code, Gemini CLI, and Codex.
|
|
282
|
+
|
|
283
|
+
> **Comprehensive Guide:** See [docs/AI-TOOLING.md](docs/AI-TOOLING.md) for detailed documentation including programmatic API, error codes, lifecycle hooks, and integration examples.
|
|
284
|
+
|
|
285
|
+
### Quick Start for AI Agents
|
|
286
|
+
|
|
287
|
+
The recommended workflow is a three-step "look before you leap" pattern:
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
# 1. Query current git state
|
|
291
|
+
STATE=$(wtstate --json)
|
|
292
|
+
|
|
293
|
+
# 2. Extract recommended action
|
|
294
|
+
ACTION=$(echo $STATE | jq -r '.data.recommendedAction')
|
|
295
|
+
|
|
296
|
+
# 3. Execute with the chosen action
|
|
297
|
+
newpr "Add feature X" --non-interactive --action=$ACTION --json
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
### Non-Interactive Mode
|
|
301
|
+
|
|
302
|
+
```bash
|
|
303
|
+
# Create PR without prompts
|
|
304
|
+
newpr "Feature X" --non-interactive --json
|
|
305
|
+
newpr "Fix bug" --non-interactive --action=commit_staged --json
|
|
306
|
+
|
|
307
|
+
# Clean PRs with dry-run preview
|
|
308
|
+
cleanpr --all --dry-run --json
|
|
309
|
+
cleanpr --all --json
|
|
310
|
+
|
|
311
|
+
# Link configs without prompts
|
|
312
|
+
wtlink link --yes --json
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
### JSON Output Schema
|
|
316
|
+
|
|
317
|
+
All commands return consistent JSON:
|
|
318
|
+
|
|
319
|
+
```typescript
|
|
320
|
+
interface CommandResult<T> {
|
|
321
|
+
success: boolean; // Whether the command succeeded
|
|
322
|
+
command: string; // Command name (e.g., "newpr", "cleanpr")
|
|
323
|
+
timestamp: string; // ISO 8601 timestamp
|
|
324
|
+
data?: T; // Command-specific data (on success)
|
|
325
|
+
error?: {
|
|
326
|
+
// Error details (on failure)
|
|
327
|
+
code: string; // Machine-readable error code
|
|
328
|
+
message: string; // Human-readable message
|
|
329
|
+
};
|
|
330
|
+
warnings?: string[]; // Non-fatal warnings
|
|
331
|
+
}
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
### Structured Error Codes
|
|
335
|
+
|
|
336
|
+
Error codes enable programmatic error handling:
|
|
337
|
+
|
|
338
|
+
| Code | Description |
|
|
339
|
+
| ---------------------- | ---------------------------- |
|
|
340
|
+
| `NOT_GIT_REPO` | Not inside a git repository |
|
|
341
|
+
| `GH_NOT_AUTHENTICATED` | GitHub CLI not authenticated |
|
|
342
|
+
| `INVALID_ACTION` | Invalid action for scenario |
|
|
343
|
+
| `HOOK_FAILED` | Lifecycle hook failed |
|
|
344
|
+
| `USER_CANCELLED` | Operation cancelled |
|
|
345
|
+
| `PR_CREATE_FAILED` | Failed to create PR |
|
|
346
|
+
|
|
347
|
+
See [docs/AI-TOOLING.md](docs/AI-TOOLING.md#structured-error-codes) for the complete list.
|
|
348
|
+
|
|
349
|
+
### Available Actions for `--action` Flag
|
|
350
|
+
|
|
351
|
+
| Action | Description |
|
|
352
|
+
| ---------------------------- | ------------------------------------------ |
|
|
353
|
+
| `empty_commit` | Create empty initial commit |
|
|
354
|
+
| `commit_staged` | Commit staged changes to new branch |
|
|
355
|
+
| `commit_all` | Stage all and commit to new branch |
|
|
356
|
+
| `stash_and_empty` | Stash changes, create empty commit |
|
|
357
|
+
| `use_commits` | Use local commits (branch from HEAD) |
|
|
358
|
+
| `push_then_branch` | Push to main first, then create branch |
|
|
359
|
+
| `use_commits_and_commit_all` | Include commits + commit uncommitted |
|
|
360
|
+
| `use_commits_and_stash` | Include commits, stash uncommitted |
|
|
361
|
+
| `create_pr_for_branch` | Create PR for existing branch |
|
|
362
|
+
| `pr_for_branch_commit_all` | Create PR for branch, commit changes first |
|
|
363
|
+
| `pr_for_branch_stash` | Create PR for branch, stash changes |
|
|
364
|
+
| `branch_from_detached` | Create branch from detached HEAD |
|
|
365
|
+
|
|
366
|
+
### Programmatic API
|
|
367
|
+
|
|
368
|
+
For deeper integration, use the programmatic API:
|
|
369
|
+
|
|
370
|
+
```typescript
|
|
371
|
+
import {
|
|
372
|
+
queryState,
|
|
373
|
+
listWorktrees,
|
|
374
|
+
cleanWorktrees,
|
|
375
|
+
createPr,
|
|
376
|
+
} from '@camaradesuk/git-worktree-tools';
|
|
377
|
+
|
|
378
|
+
// Query git state
|
|
379
|
+
const state = queryState({ baseBranch: 'main' });
|
|
380
|
+
if (state.success) {
|
|
381
|
+
console.log(`Scenario: ${state.data.scenario}`);
|
|
382
|
+
console.log(`Recommended: ${state.data.recommendedAction}`);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// Create PR
|
|
386
|
+
const result = await createPr({
|
|
387
|
+
description: 'Add dark mode',
|
|
388
|
+
action: 'commit_staged',
|
|
389
|
+
draft: true,
|
|
390
|
+
});
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
See [docs/AI-TOOLING.md](docs/AI-TOOLING.md#programmatic-api) for complete API documentation.
|
|
394
|
+
|
|
208
395
|
## Configuration
|
|
209
396
|
|
|
210
|
-
Create a `.worktreerc` file in your repository root:
|
|
397
|
+
Create a `.worktreerc` file in your repository root, or use `wtconfig init` to generate one interactively:
|
|
211
398
|
|
|
212
399
|
```json
|
|
213
400
|
{
|
|
214
|
-
"sharedRepos": ["cluster-gitops", "infrastructure"],
|
|
215
401
|
"baseBranch": "main",
|
|
216
|
-
"draftPr": true
|
|
402
|
+
"draftPr": true,
|
|
403
|
+
"branchPrefix": "feat",
|
|
404
|
+
"ai": {
|
|
405
|
+
"provider": "auto",
|
|
406
|
+
"branchName": true,
|
|
407
|
+
"prDescription": true
|
|
408
|
+
},
|
|
409
|
+
"hooks": {
|
|
410
|
+
"post-worktree": "npm install"
|
|
411
|
+
}
|
|
217
412
|
}
|
|
218
413
|
```
|
|
219
414
|
|
|
@@ -228,6 +423,96 @@ Create a `.worktreerc` file in your repository root:
|
|
|
228
423
|
| `worktreeParent` | string | `".."` | Parent directory for worktrees |
|
|
229
424
|
| `branchPrefix` | string | `"feat"` | Prefix for auto-generated branch names |
|
|
230
425
|
| `preferredEditor` | string | `"vscode"` | Editor for lswt interactive: "vscode", "cursor", or "auto" |
|
|
426
|
+
| `ai` | object | `{}` | AI content generation settings (see below) |
|
|
427
|
+
| `hooks` | object | `{}` | Lifecycle hook commands (see below) |
|
|
428
|
+
|
|
429
|
+
### AI Content Generation
|
|
430
|
+
|
|
431
|
+
Enable AI-powered content generation for branch names and PR descriptions:
|
|
432
|
+
|
|
433
|
+
```json
|
|
434
|
+
{
|
|
435
|
+
"ai": {
|
|
436
|
+
"provider": "auto", // "auto" | "claude" | "gemini" | "openai" | "ollama" | "none"
|
|
437
|
+
"branchName": true, // Generate smart branch names from description
|
|
438
|
+
"prTitle": true, // Generate PR titles
|
|
439
|
+
"prDescription": true // Generate PR descriptions from changes
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
When `provider` is `"auto"`, the tool detects available AI tools in order: Claude Code → Gemini CLI → Ollama → OpenAI API.
|
|
445
|
+
|
|
446
|
+
### Lifecycle Hooks
|
|
447
|
+
|
|
448
|
+
Run custom commands at various points in the `newpr` workflow:
|
|
449
|
+
|
|
450
|
+
```json
|
|
451
|
+
{
|
|
452
|
+
"hooks": {
|
|
453
|
+
"post-worktree": "npm install",
|
|
454
|
+
"post-pr": ["echo 'PR created!'", "./notify-team.sh"],
|
|
455
|
+
"pre-branch": {
|
|
456
|
+
"command": "npm test",
|
|
457
|
+
"failOnError": true
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
**Available hooks:**
|
|
464
|
+
|
|
465
|
+
| Hook | Description | Critical |
|
|
466
|
+
| --------------- | ------------------------- | -------- |
|
|
467
|
+
| `pre-analyze` | Before git state analysis | Yes |
|
|
468
|
+
| `post-analyze` | After state analysis | No |
|
|
469
|
+
| `pre-branch` | Before branch creation | Yes |
|
|
470
|
+
| `post-branch` | After branch creation | No |
|
|
471
|
+
| `pre-commit` | Before initial commit | Yes |
|
|
472
|
+
| `post-commit` | After initial commit | No |
|
|
473
|
+
| `pre-push` | Before push to origin | Yes |
|
|
474
|
+
| `post-push` | After push to origin | No |
|
|
475
|
+
| `pre-pr` | Before PR creation | Yes |
|
|
476
|
+
| `post-pr` | After PR creation | No |
|
|
477
|
+
| `pre-worktree` | Before worktree creation | Yes |
|
|
478
|
+
| `post-worktree` | After worktree creation | No |
|
|
479
|
+
| `cleanup` | On error (for rollback) | No |
|
|
480
|
+
|
|
481
|
+
**Critical hooks** abort the workflow if they fail. Non-critical hooks show a warning but continue.
|
|
482
|
+
|
|
483
|
+
**Hook definition formats:**
|
|
484
|
+
|
|
485
|
+
```json
|
|
486
|
+
{
|
|
487
|
+
"hooks": {
|
|
488
|
+
// Simple command
|
|
489
|
+
"post-worktree": "npm install",
|
|
490
|
+
|
|
491
|
+
// Multiple commands (run in sequence)
|
|
492
|
+
"post-pr": ["echo 'Done!'", "./scripts/notify.sh"],
|
|
493
|
+
|
|
494
|
+
// Complex definition
|
|
495
|
+
"pre-commit": {
|
|
496
|
+
"command": "npm test",
|
|
497
|
+
"timeout": 60000,
|
|
498
|
+
"failOnError": true,
|
|
499
|
+
"if": "exists:package.json"
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
**Hook context variables** (available as environment variables):
|
|
506
|
+
|
|
507
|
+
| Variable | Description |
|
|
508
|
+
| ------------------ | ------------------ |
|
|
509
|
+
| `WT_BRANCH_NAME` | New branch name |
|
|
510
|
+
| `WT_PR_NUMBER` | PR number |
|
|
511
|
+
| `WT_PR_URL` | PR URL |
|
|
512
|
+
| `WT_WORKTREE_PATH` | New worktree path |
|
|
513
|
+
| `WT_REPO_ROOT` | Main repo root |
|
|
514
|
+
| `WT_BASE_BRANCH` | Base branch (main) |
|
|
515
|
+
| `WT_DESCRIPTION` | PR description |
|
|
231
516
|
|
|
232
517
|
> **Note:** File syncing between worktrees is managed by `wtlink` using its own `.wtlinkrc` manifest. See the [wtlink section](#wtlink) for details.
|
|
233
518
|
|
|
@@ -285,6 +570,8 @@ npm test
|
|
|
285
570
|
npm link
|
|
286
571
|
```
|
|
287
572
|
|
|
573
|
+
See [docs/DEVELOPMENT.md](docs/DEVELOPMENT.md) for detailed local development instructions, including how to test CLI commands without affecting your global install.
|
|
574
|
+
|
|
288
575
|
## License
|
|
289
576
|
|
|
290
577
|
MIT
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clean worktrees API - Clean up merged/closed PR worktrees
|
|
3
|
+
*
|
|
4
|
+
* Wraps the cleanpr module to provide a clean programmatic interface.
|
|
5
|
+
*/
|
|
6
|
+
import { type CommandResult, type CleanprResultData, type CleanprDryRunData } from '../lib/json-output.js';
|
|
7
|
+
/**
|
|
8
|
+
* Information about a cleaned worktree
|
|
9
|
+
*/
|
|
10
|
+
export interface CleanedWorktree {
|
|
11
|
+
/** PR number */
|
|
12
|
+
prNumber: number;
|
|
13
|
+
/** Branch name */
|
|
14
|
+
branch: string | null;
|
|
15
|
+
/** Worktree path that was removed */
|
|
16
|
+
path: string;
|
|
17
|
+
/** PR state: 'MERGED', 'CLOSED', etc. */
|
|
18
|
+
prState: string;
|
|
19
|
+
/** Whether local branch was deleted */
|
|
20
|
+
localBranchDeleted: boolean;
|
|
21
|
+
/** Whether remote branch was deleted */
|
|
22
|
+
remoteBranchDeleted: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Options for cleaning worktrees
|
|
26
|
+
*/
|
|
27
|
+
export interface CleanWorktreesOptions {
|
|
28
|
+
/** Specific PR number to clean (null = clean all cleanable) */
|
|
29
|
+
prNumber?: number | null;
|
|
30
|
+
/** Force remove even if PR is still open */
|
|
31
|
+
force?: boolean;
|
|
32
|
+
/** Also delete remote branches */
|
|
33
|
+
deleteRemote?: boolean;
|
|
34
|
+
/** Dry run - show what would be cleaned without doing it */
|
|
35
|
+
dryRun?: boolean;
|
|
36
|
+
/** Working directory (defaults to current directory) */
|
|
37
|
+
cwd?: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Result data for cleanWorktrees
|
|
41
|
+
*/
|
|
42
|
+
export type CleanWorktreesResultData = CleanprResultData | CleanprDryRunData;
|
|
43
|
+
/**
|
|
44
|
+
* Result type for cleanWorktrees
|
|
45
|
+
*/
|
|
46
|
+
export type CleanWorktreesResult = CommandResult<CleanWorktreesResultData>;
|
|
47
|
+
/**
|
|
48
|
+
* Clean up worktrees for merged or closed PRs
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* import { cleanWorktrees } from '@camaradesuk/git-worktree-tools/api';
|
|
53
|
+
*
|
|
54
|
+
* // Clean all merged/closed PRs
|
|
55
|
+
* const result = await cleanWorktrees({ deleteRemote: true });
|
|
56
|
+
*
|
|
57
|
+
* // Clean a specific PR
|
|
58
|
+
* const result = await cleanWorktrees({ prNumber: 42, force: true });
|
|
59
|
+
*
|
|
60
|
+
* // Dry run
|
|
61
|
+
* const result = await cleanWorktrees({ dryRun: true });
|
|
62
|
+
* ```
|
|
63
|
+
*/
|
|
64
|
+
export declare function cleanWorktrees(options?: CleanWorktreesOptions): Promise<CleanWorktreesResult>;
|
|
65
|
+
//# sourceMappingURL=clean.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clean.d.ts","sourceRoot":"","sources":["../../src/api/clean.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAiBH,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EAIvB,MAAM,uBAAuB,CAAC;AAI/B;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,gBAAgB;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB;IAClB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,kBAAkB,EAAE,OAAO,CAAC;IAC5B,wCAAwC;IACxC,mBAAmB,EAAE,OAAO,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,kCAAkC;IAClC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,wDAAwD;IACxD,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG,iBAAiB,GAAG,iBAAiB,CAAC;AAE7E;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,aAAa,CAAC,wBAAwB,CAAC,CAAC;AA2C3E;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,cAAc,CAClC,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,oBAAoB,CAAC,CAyK/B"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clean worktrees API - Clean up merged/closed PR worktrees
|
|
3
|
+
*
|
|
4
|
+
* Wraps the cleanpr module to provide a clean programmatic interface.
|
|
5
|
+
*/
|
|
6
|
+
import { execSync } from 'child_process';
|
|
7
|
+
import * as path from 'path';
|
|
8
|
+
import { gatherPrWorktreeInfo, createDefaultDeps, getCleanableWorktrees, findWorktreeByPrNumber, cleanWorktree, cleanWorktrees as cleanWorktreesBatch, summarizeResults, } from '../lib/cleanpr/index.js';
|
|
9
|
+
import { loadConfig } from '../lib/config.js';
|
|
10
|
+
import { createSuccessResult, createErrorResult, ErrorCode, } from '../lib/json-output.js';
|
|
11
|
+
import * as git from '../lib/git.js';
|
|
12
|
+
import * as github from '../lib/github.js';
|
|
13
|
+
/**
|
|
14
|
+
* Create cleanup dependencies using real git operations
|
|
15
|
+
*/
|
|
16
|
+
function createCleanupDeps(repoRoot) {
|
|
17
|
+
return {
|
|
18
|
+
removeWorktree: (wtPath, force) => {
|
|
19
|
+
git.removeWorktree(wtPath, { force });
|
|
20
|
+
},
|
|
21
|
+
deleteLocalBranch: (branch) => {
|
|
22
|
+
try {
|
|
23
|
+
execSync(`git branch -D "${branch}"`, {
|
|
24
|
+
cwd: repoRoot,
|
|
25
|
+
encoding: 'utf-8',
|
|
26
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
27
|
+
});
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
deleteRemoteBranch: (branch) => {
|
|
35
|
+
try {
|
|
36
|
+
execSync(`git push origin --delete "${branch}"`, {
|
|
37
|
+
cwd: repoRoot,
|
|
38
|
+
encoding: 'utf-8',
|
|
39
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
40
|
+
});
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
pruneWorktrees: () => {
|
|
48
|
+
git.pruneWorktrees();
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Clean up worktrees for merged or closed PRs
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* ```typescript
|
|
57
|
+
* import { cleanWorktrees } from '@camaradesuk/git-worktree-tools/api';
|
|
58
|
+
*
|
|
59
|
+
* // Clean all merged/closed PRs
|
|
60
|
+
* const result = await cleanWorktrees({ deleteRemote: true });
|
|
61
|
+
*
|
|
62
|
+
* // Clean a specific PR
|
|
63
|
+
* const result = await cleanWorktrees({ prNumber: 42, force: true });
|
|
64
|
+
*
|
|
65
|
+
* // Dry run
|
|
66
|
+
* const result = await cleanWorktrees({ dryRun: true });
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
export async function cleanWorktrees(options = {}) {
|
|
70
|
+
const { prNumber = null, force = false, deleteRemote = false, dryRun = false, cwd } = options;
|
|
71
|
+
try {
|
|
72
|
+
// Verify prerequisites
|
|
73
|
+
if (!github.isGhInstalled()) {
|
|
74
|
+
return createErrorResult('cleanpr', ErrorCode.GH_NOT_INSTALLED, 'GitHub CLI (gh) is required for PR status checking');
|
|
75
|
+
}
|
|
76
|
+
// Verify we're in a git repo
|
|
77
|
+
const repoRoot = git.getRepoRoot(cwd);
|
|
78
|
+
if (!repoRoot) {
|
|
79
|
+
return createErrorResult('cleanpr', ErrorCode.NOT_GIT_REPO, 'Not in a git repository');
|
|
80
|
+
}
|
|
81
|
+
// Load configuration
|
|
82
|
+
const config = loadConfig(repoRoot);
|
|
83
|
+
// Gather worktree info
|
|
84
|
+
const gatherDeps = createDefaultDeps();
|
|
85
|
+
const worktrees = await gatherPrWorktreeInfo(repoRoot, config.worktreePattern, gatherDeps);
|
|
86
|
+
// Build clean options
|
|
87
|
+
const cleanOptions = {
|
|
88
|
+
force,
|
|
89
|
+
deleteRemote,
|
|
90
|
+
dryRun,
|
|
91
|
+
all: prNumber === null,
|
|
92
|
+
json: true,
|
|
93
|
+
interactive: false, // API is never interactive
|
|
94
|
+
};
|
|
95
|
+
// Handle specific PR number
|
|
96
|
+
if (prNumber !== null) {
|
|
97
|
+
const target = findWorktreeByPrNumber(worktrees, prNumber);
|
|
98
|
+
if (!target) {
|
|
99
|
+
const pattern = config.worktreePattern
|
|
100
|
+
.replace('{repo}', path.basename(repoRoot))
|
|
101
|
+
.replace('{number}', String(prNumber));
|
|
102
|
+
const expectedPath = path.join(path.dirname(repoRoot), pattern);
|
|
103
|
+
return createErrorResult('cleanpr', ErrorCode.PR_NOT_FOUND, `No worktree found for PR #${prNumber}`, {
|
|
104
|
+
expectedPath,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
if (dryRun) {
|
|
108
|
+
const data = {
|
|
109
|
+
wouldClean: [
|
|
110
|
+
{
|
|
111
|
+
prNumber: target.prNumber,
|
|
112
|
+
branch: target.branch,
|
|
113
|
+
path: target.path,
|
|
114
|
+
prState: target.prState,
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
totalWouldClean: 1,
|
|
118
|
+
};
|
|
119
|
+
return createSuccessResult('cleanpr', data);
|
|
120
|
+
}
|
|
121
|
+
const deps = createCleanupDeps(repoRoot);
|
|
122
|
+
const result = cleanWorktree(target, cleanOptions, deps);
|
|
123
|
+
if (result.success) {
|
|
124
|
+
// Infer branch deletion status based on options and whether worktree had a branch
|
|
125
|
+
const hadBranch = target.branch !== null;
|
|
126
|
+
const data = {
|
|
127
|
+
cleaned: [
|
|
128
|
+
{
|
|
129
|
+
prNumber: target.prNumber,
|
|
130
|
+
branch: target.branch,
|
|
131
|
+
path: target.path,
|
|
132
|
+
prState: target.prState,
|
|
133
|
+
localBranchDeleted: hadBranch,
|
|
134
|
+
remoteBranchDeleted: hadBranch && deleteRemote,
|
|
135
|
+
},
|
|
136
|
+
],
|
|
137
|
+
skipped: [],
|
|
138
|
+
totalCleaned: 1,
|
|
139
|
+
totalSkipped: 0,
|
|
140
|
+
};
|
|
141
|
+
return createSuccessResult('cleanpr', data);
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
return createErrorResult('cleanpr', ErrorCode.OPERATION_FAILED, result.message);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
// Clean all cleanable worktrees
|
|
148
|
+
const cleanable = getCleanableWorktrees(worktrees);
|
|
149
|
+
if (cleanable.length === 0) {
|
|
150
|
+
const data = {
|
|
151
|
+
cleaned: [],
|
|
152
|
+
skipped: [],
|
|
153
|
+
totalCleaned: 0,
|
|
154
|
+
totalSkipped: 0,
|
|
155
|
+
};
|
|
156
|
+
return createSuccessResult('cleanpr', data);
|
|
157
|
+
}
|
|
158
|
+
if (dryRun) {
|
|
159
|
+
const data = {
|
|
160
|
+
wouldClean: cleanable.map((w) => ({
|
|
161
|
+
prNumber: w.prNumber,
|
|
162
|
+
branch: w.branch,
|
|
163
|
+
path: w.path,
|
|
164
|
+
prState: w.prState,
|
|
165
|
+
})),
|
|
166
|
+
totalWouldClean: cleanable.length,
|
|
167
|
+
};
|
|
168
|
+
return createSuccessResult('cleanpr', data);
|
|
169
|
+
}
|
|
170
|
+
const deps = createCleanupDeps(repoRoot);
|
|
171
|
+
const results = cleanWorktreesBatch(cleanable, cleanOptions, deps);
|
|
172
|
+
const summary = summarizeResults(results);
|
|
173
|
+
const cleaned = [];
|
|
174
|
+
const skipped = [];
|
|
175
|
+
for (let i = 0; i < cleanable.length; i++) {
|
|
176
|
+
const wt = cleanable[i];
|
|
177
|
+
const result = results[i];
|
|
178
|
+
if (result.success) {
|
|
179
|
+
const hadBranch = wt.branch !== null;
|
|
180
|
+
cleaned.push({
|
|
181
|
+
prNumber: wt.prNumber,
|
|
182
|
+
branch: wt.branch,
|
|
183
|
+
path: wt.path,
|
|
184
|
+
prState: wt.prState,
|
|
185
|
+
localBranchDeleted: hadBranch,
|
|
186
|
+
remoteBranchDeleted: hadBranch && deleteRemote,
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
skipped.push({
|
|
191
|
+
prNumber: wt.prNumber,
|
|
192
|
+
reason: result.message,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
const data = {
|
|
197
|
+
cleaned,
|
|
198
|
+
skipped,
|
|
199
|
+
totalCleaned: summary.cleaned,
|
|
200
|
+
totalSkipped: summary.total - summary.cleaned,
|
|
201
|
+
};
|
|
202
|
+
return createSuccessResult('cleanpr', data);
|
|
203
|
+
}
|
|
204
|
+
catch (error) {
|
|
205
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
206
|
+
return createErrorResult('cleanpr', ErrorCode.UNKNOWN_ERROR, message);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
//# sourceMappingURL=clean.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clean.js","sourceRoot":"","sources":["../../src/api/clean.ts"],"names":[],"mappings":"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"}
|