@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.
Files changed (284) hide show
  1. package/README.md +290 -3
  2. package/dist/api/clean.d.ts +65 -0
  3. package/dist/api/clean.d.ts.map +1 -0
  4. package/dist/api/clean.js +209 -0
  5. package/dist/api/clean.js.map +1 -0
  6. package/dist/api/create.d.ts +88 -0
  7. package/dist/api/create.d.ts.map +1 -0
  8. package/dist/api/create.js +370 -0
  9. package/dist/api/create.js.map +1 -0
  10. package/dist/api/index.d.ts +15 -0
  11. package/dist/api/index.d.ts.map +1 -0
  12. package/dist/api/index.js +19 -0
  13. package/dist/api/index.js.map +1 -0
  14. package/dist/api/list.d.ts +74 -0
  15. package/dist/api/list.d.ts.map +1 -0
  16. package/dist/api/list.js +80 -0
  17. package/dist/api/list.js.map +1 -0
  18. package/dist/api/state.d.ts +43 -0
  19. package/dist/api/state.d.ts.map +1 -0
  20. package/dist/api/state.js +70 -0
  21. package/dist/api/state.js.map +1 -0
  22. package/dist/cli/cleanpr.js +171 -28
  23. package/dist/cli/cleanpr.js.map +1 -1
  24. package/dist/cli/cleanpr.test.js +459 -7
  25. package/dist/cli/cleanpr.test.js.map +1 -1
  26. package/dist/cli/newpr.js +189 -28
  27. package/dist/cli/newpr.js.map +1 -1
  28. package/dist/cli/newpr.test.js +349 -0
  29. package/dist/cli/newpr.test.js.map +1 -1
  30. package/dist/cli/wtconfig.d.ts +14 -0
  31. package/dist/cli/wtconfig.d.ts.map +1 -0
  32. package/dist/cli/wtconfig.js +948 -0
  33. package/dist/cli/wtconfig.js.map +1 -0
  34. package/dist/cli/wtconfig.test.d.ts +5 -0
  35. package/dist/cli/wtconfig.test.d.ts.map +1 -0
  36. package/dist/cli/wtconfig.test.js +1281 -0
  37. package/dist/cli/wtconfig.test.js.map +1 -0
  38. package/dist/cli/wtlink.js +5 -0
  39. package/dist/cli/wtlink.js.map +1 -1
  40. package/dist/cli/wtstate.d.ts +8 -0
  41. package/dist/cli/wtstate.d.ts.map +1 -0
  42. package/dist/cli/wtstate.js +83 -0
  43. package/dist/cli/wtstate.js.map +1 -0
  44. package/dist/cli/wtstate.test.d.ts +5 -0
  45. package/dist/cli/wtstate.test.d.ts.map +1 -0
  46. package/dist/cli/wtstate.test.js +193 -0
  47. package/dist/cli/wtstate.test.js.map +1 -0
  48. package/dist/e2e/cleanpr/cleanpr.e2e.test.d.ts +2 -0
  49. package/dist/e2e/cleanpr/cleanpr.e2e.test.d.ts.map +1 -0
  50. package/dist/e2e/cleanpr/cleanpr.e2e.test.js +326 -0
  51. package/dist/e2e/cleanpr/cleanpr.e2e.test.js.map +1 -0
  52. package/dist/e2e/helpers/cli-runner.d.ts +103 -0
  53. package/dist/e2e/helpers/cli-runner.d.ts.map +1 -0
  54. package/dist/e2e/helpers/cli-runner.js +200 -0
  55. package/dist/e2e/helpers/cli-runner.js.map +1 -0
  56. package/dist/e2e/helpers/gh-mock.d.ts +87 -0
  57. package/dist/e2e/helpers/gh-mock.d.ts.map +1 -0
  58. package/dist/e2e/helpers/gh-mock.js +384 -0
  59. package/dist/e2e/helpers/gh-mock.js.map +1 -0
  60. package/dist/e2e/helpers/index.d.ts +12 -0
  61. package/dist/e2e/helpers/index.d.ts.map +1 -0
  62. package/dist/e2e/helpers/index.js +16 -0
  63. package/dist/e2e/helpers/index.js.map +1 -0
  64. package/dist/e2e/helpers/pty-wrapper.d.ts +118 -0
  65. package/dist/e2e/helpers/pty-wrapper.d.ts.map +1 -0
  66. package/dist/e2e/helpers/pty-wrapper.js +276 -0
  67. package/dist/e2e/helpers/pty-wrapper.js.map +1 -0
  68. package/dist/e2e/helpers/scenario-harness.d.ts +55 -0
  69. package/dist/e2e/helpers/scenario-harness.d.ts.map +1 -0
  70. package/dist/e2e/helpers/scenario-harness.js +360 -0
  71. package/dist/e2e/helpers/scenario-harness.js.map +1 -0
  72. package/dist/e2e/helpers/test-context.d.ts +120 -0
  73. package/dist/e2e/helpers/test-context.d.ts.map +1 -0
  74. package/dist/e2e/helpers/test-context.js +263 -0
  75. package/dist/e2e/helpers/test-context.js.map +1 -0
  76. package/dist/e2e/lswt/lswt.e2e.test.d.ts +2 -0
  77. package/dist/e2e/lswt/lswt.e2e.test.d.ts.map +1 -0
  78. package/dist/e2e/lswt/lswt.e2e.test.js +328 -0
  79. package/dist/e2e/lswt/lswt.e2e.test.js.map +1 -0
  80. package/dist/e2e/newpr/newpr.e2e.test.d.ts +2 -0
  81. package/dist/e2e/newpr/newpr.e2e.test.d.ts.map +1 -0
  82. package/dist/e2e/newpr/newpr.e2e.test.js +286 -0
  83. package/dist/e2e/newpr/newpr.e2e.test.js.map +1 -0
  84. package/dist/e2e/newpr/scenarios.e2e.test.d.ts +2 -0
  85. package/dist/e2e/newpr/scenarios.e2e.test.d.ts.map +1 -0
  86. package/dist/e2e/newpr/scenarios.e2e.test.js +426 -0
  87. package/dist/e2e/newpr/scenarios.e2e.test.js.map +1 -0
  88. package/dist/e2e/workflows/pr-lifecycle.e2e.test.d.ts +2 -0
  89. package/dist/e2e/workflows/pr-lifecycle.e2e.test.d.ts.map +1 -0
  90. package/dist/e2e/workflows/pr-lifecycle.e2e.test.js +298 -0
  91. package/dist/e2e/workflows/pr-lifecycle.e2e.test.js.map +1 -0
  92. package/dist/e2e/wtlink/wtlink.e2e.test.d.ts +2 -0
  93. package/dist/e2e/wtlink/wtlink.e2e.test.d.ts.map +1 -0
  94. package/dist/e2e/wtlink/wtlink.e2e.test.js +364 -0
  95. package/dist/e2e/wtlink/wtlink.e2e.test.js.map +1 -0
  96. package/dist/index.d.ts +15 -1
  97. package/dist/index.d.ts.map +1 -1
  98. package/dist/index.js +14 -0
  99. package/dist/index.js.map +1 -1
  100. package/dist/lib/ai/base-provider.d.ts +58 -0
  101. package/dist/lib/ai/base-provider.d.ts.map +1 -0
  102. package/dist/lib/ai/base-provider.js +246 -0
  103. package/dist/lib/ai/base-provider.js.map +1 -0
  104. package/dist/lib/ai/base-provider.test.d.ts +7 -0
  105. package/dist/lib/ai/base-provider.test.d.ts.map +1 -0
  106. package/dist/lib/ai/base-provider.test.js +320 -0
  107. package/dist/lib/ai/base-provider.test.js.map +1 -0
  108. package/dist/lib/ai/cli-provider.d.ts +87 -0
  109. package/dist/lib/ai/cli-provider.d.ts.map +1 -0
  110. package/dist/lib/ai/cli-provider.js +280 -0
  111. package/dist/lib/ai/cli-provider.js.map +1 -0
  112. package/dist/lib/ai/cli-provider.test.d.ts +5 -0
  113. package/dist/lib/ai/cli-provider.test.d.ts.map +1 -0
  114. package/dist/lib/ai/cli-provider.test.js +462 -0
  115. package/dist/lib/ai/cli-provider.test.js.map +1 -0
  116. package/dist/lib/ai/fallback-provider.d.ts +20 -0
  117. package/dist/lib/ai/fallback-provider.d.ts.map +1 -0
  118. package/dist/lib/ai/fallback-provider.js +125 -0
  119. package/dist/lib/ai/fallback-provider.js.map +1 -0
  120. package/dist/lib/ai/fallback-provider.test.d.ts +7 -0
  121. package/dist/lib/ai/fallback-provider.test.d.ts.map +1 -0
  122. package/dist/lib/ai/fallback-provider.test.js +165 -0
  123. package/dist/lib/ai/fallback-provider.test.js.map +1 -0
  124. package/dist/lib/ai/generation-service.d.ts +44 -0
  125. package/dist/lib/ai/generation-service.d.ts.map +1 -0
  126. package/dist/lib/ai/generation-service.js +107 -0
  127. package/dist/lib/ai/generation-service.js.map +1 -0
  128. package/dist/lib/ai/generation-service.test.d.ts +7 -0
  129. package/dist/lib/ai/generation-service.test.d.ts.map +1 -0
  130. package/dist/lib/ai/generation-service.test.js +213 -0
  131. package/dist/lib/ai/generation-service.test.js.map +1 -0
  132. package/dist/lib/ai/index.d.ts +19 -0
  133. package/dist/lib/ai/index.d.ts.map +1 -0
  134. package/dist/lib/ai/index.js +22 -0
  135. package/dist/lib/ai/index.js.map +1 -0
  136. package/dist/lib/ai/provider-manager.d.ts +109 -0
  137. package/dist/lib/ai/provider-manager.d.ts.map +1 -0
  138. package/dist/lib/ai/provider-manager.js +270 -0
  139. package/dist/lib/ai/provider-manager.js.map +1 -0
  140. package/dist/lib/ai/provider-manager.test.d.ts +5 -0
  141. package/dist/lib/ai/provider-manager.test.d.ts.map +1 -0
  142. package/dist/lib/ai/provider-manager.test.js +312 -0
  143. package/dist/lib/ai/provider-manager.test.js.map +1 -0
  144. package/dist/lib/ai/types.d.ts +166 -0
  145. package/dist/lib/ai/types.d.ts.map +1 -0
  146. package/dist/lib/ai/types.js +19 -0
  147. package/dist/lib/ai/types.js.map +1 -0
  148. package/dist/lib/cleanpr/args.d.ts.map +1 -1
  149. package/dist/lib/cleanpr/args.js +18 -0
  150. package/dist/lib/cleanpr/args.js.map +1 -1
  151. package/dist/lib/cleanpr/args.test.js +88 -11
  152. package/dist/lib/cleanpr/args.test.js.map +1 -1
  153. package/dist/lib/cleanpr/cleanup.d.ts +2 -0
  154. package/dist/lib/cleanpr/cleanup.d.ts.map +1 -1
  155. package/dist/lib/cleanpr/cleanup.js +30 -2
  156. package/dist/lib/cleanpr/cleanup.js.map +1 -1
  157. package/dist/lib/cleanpr/cleanup.test.js +37 -5
  158. package/dist/lib/cleanpr/cleanup.test.js.map +1 -1
  159. package/dist/lib/cleanpr/types.d.ts +10 -0
  160. package/dist/lib/cleanpr/types.d.ts.map +1 -1
  161. package/dist/lib/cleanpr/worktree-info.test.js +72 -1
  162. package/dist/lib/cleanpr/worktree-info.test.js.map +1 -1
  163. package/dist/lib/config.d.ts +170 -1
  164. package/dist/lib/config.d.ts.map +1 -1
  165. package/dist/lib/config.js +129 -2
  166. package/dist/lib/config.js.map +1 -1
  167. package/dist/lib/config.test.js +406 -2
  168. package/dist/lib/config.test.js.map +1 -1
  169. package/dist/lib/hooks/executor.d.ts +35 -0
  170. package/dist/lib/hooks/executor.d.ts.map +1 -0
  171. package/dist/lib/hooks/executor.js +401 -0
  172. package/dist/lib/hooks/executor.js.map +1 -0
  173. package/dist/lib/hooks/executor.test.d.ts +5 -0
  174. package/dist/lib/hooks/executor.test.d.ts.map +1 -0
  175. package/dist/lib/hooks/executor.test.js +648 -0
  176. package/dist/lib/hooks/executor.test.js.map +1 -0
  177. package/dist/lib/hooks/index.d.ts +25 -0
  178. package/dist/lib/hooks/index.d.ts.map +1 -0
  179. package/dist/lib/hooks/index.js +26 -0
  180. package/dist/lib/hooks/index.js.map +1 -0
  181. package/dist/lib/hooks/templates.d.ts +74 -0
  182. package/dist/lib/hooks/templates.d.ts.map +1 -0
  183. package/dist/lib/hooks/templates.js +270 -0
  184. package/dist/lib/hooks/templates.js.map +1 -0
  185. package/dist/lib/hooks/templates.test.d.ts +5 -0
  186. package/dist/lib/hooks/templates.test.d.ts.map +1 -0
  187. package/dist/lib/hooks/templates.test.js +163 -0
  188. package/dist/lib/hooks/templates.test.js.map +1 -0
  189. package/dist/lib/hooks/types.d.ts +161 -0
  190. package/dist/lib/hooks/types.d.ts.map +1 -0
  191. package/dist/lib/hooks/types.js +73 -0
  192. package/dist/lib/hooks/types.js.map +1 -0
  193. package/dist/lib/hooks/types.test.d.ts +5 -0
  194. package/dist/lib/hooks/types.test.d.ts.map +1 -0
  195. package/dist/lib/hooks/types.test.js +132 -0
  196. package/dist/lib/hooks/types.test.js.map +1 -0
  197. package/dist/lib/json-output.d.ts +172 -0
  198. package/dist/lib/json-output.d.ts.map +1 -0
  199. package/dist/lib/json-output.js +134 -0
  200. package/dist/lib/json-output.js.map +1 -0
  201. package/dist/lib/json-output.test.d.ts +5 -0
  202. package/dist/lib/json-output.test.d.ts.map +1 -0
  203. package/dist/lib/json-output.test.js +259 -0
  204. package/dist/lib/json-output.test.js.map +1 -0
  205. package/dist/lib/lswt/action-executors.test.js +6 -0
  206. package/dist/lib/lswt/action-executors.test.js.map +1 -1
  207. package/dist/lib/newpr/action-deps.d.ts +15 -0
  208. package/dist/lib/newpr/action-deps.d.ts.map +1 -0
  209. package/dist/lib/newpr/action-deps.js +22 -0
  210. package/dist/lib/newpr/action-deps.js.map +1 -0
  211. package/dist/lib/newpr/args.d.ts.map +1 -1
  212. package/dist/lib/newpr/args.js +56 -0
  213. package/dist/lib/newpr/args.js.map +1 -1
  214. package/dist/lib/newpr/hook-runner.d.ts +80 -0
  215. package/dist/lib/newpr/hook-runner.d.ts.map +1 -0
  216. package/dist/lib/newpr/hook-runner.js +182 -0
  217. package/dist/lib/newpr/hook-runner.js.map +1 -0
  218. package/dist/lib/newpr/hook-runner.test.d.ts +7 -0
  219. package/dist/lib/newpr/hook-runner.test.d.ts.map +1 -0
  220. package/dist/lib/newpr/hook-runner.test.js +301 -0
  221. package/dist/lib/newpr/hook-runner.test.js.map +1 -0
  222. package/dist/lib/newpr/index.d.ts +3 -0
  223. package/dist/lib/newpr/index.d.ts.map +1 -1
  224. package/dist/lib/newpr/index.js +3 -0
  225. package/dist/lib/newpr/index.js.map +1 -1
  226. package/dist/lib/newpr/types.d.ts +9 -0
  227. package/dist/lib/newpr/types.d.ts.map +1 -1
  228. package/dist/lib/wtconfig/config-manager.d.ts +72 -0
  229. package/dist/lib/wtconfig/config-manager.d.ts.map +1 -0
  230. package/dist/lib/wtconfig/config-manager.js +408 -0
  231. package/dist/lib/wtconfig/config-manager.js.map +1 -0
  232. package/dist/lib/wtconfig/config-manager.test.d.ts +5 -0
  233. package/dist/lib/wtconfig/config-manager.test.d.ts.map +1 -0
  234. package/dist/lib/wtconfig/config-manager.test.js +501 -0
  235. package/dist/lib/wtconfig/config-manager.test.js.map +1 -0
  236. package/dist/lib/wtconfig/environment.d.ts +23 -0
  237. package/dist/lib/wtconfig/environment.d.ts.map +1 -0
  238. package/dist/lib/wtconfig/environment.js +238 -0
  239. package/dist/lib/wtconfig/environment.js.map +1 -0
  240. package/dist/lib/wtconfig/environment.test.d.ts +5 -0
  241. package/dist/lib/wtconfig/environment.test.d.ts.map +1 -0
  242. package/dist/lib/wtconfig/environment.test.js +246 -0
  243. package/dist/lib/wtconfig/environment.test.js.map +1 -0
  244. package/dist/lib/wtconfig/index.d.ts +7 -0
  245. package/dist/lib/wtconfig/index.d.ts.map +1 -0
  246. package/dist/lib/wtconfig/index.js +8 -0
  247. package/dist/lib/wtconfig/index.js.map +1 -0
  248. package/dist/lib/wtconfig/types.d.ts +97 -0
  249. package/dist/lib/wtconfig/types.d.ts.map +1 -0
  250. package/dist/lib/wtconfig/types.js +5 -0
  251. package/dist/lib/wtconfig/types.js.map +1 -0
  252. package/dist/lib/wtstate/analyze.d.ts +13 -0
  253. package/dist/lib/wtstate/analyze.d.ts.map +1 -0
  254. package/dist/lib/wtstate/analyze.js +165 -0
  255. package/dist/lib/wtstate/analyze.js.map +1 -0
  256. package/dist/lib/wtstate/analyze.test.d.ts +5 -0
  257. package/dist/lib/wtstate/analyze.test.d.ts.map +1 -0
  258. package/dist/lib/wtstate/analyze.test.js +282 -0
  259. package/dist/lib/wtstate/analyze.test.js.map +1 -0
  260. package/dist/lib/wtstate/args.d.ts +17 -0
  261. package/dist/lib/wtstate/args.d.ts.map +1 -0
  262. package/dist/lib/wtstate/args.js +91 -0
  263. package/dist/lib/wtstate/args.js.map +1 -0
  264. package/dist/lib/wtstate/args.test.d.ts +5 -0
  265. package/dist/lib/wtstate/args.test.d.ts.map +1 -0
  266. package/dist/lib/wtstate/args.test.js +120 -0
  267. package/dist/lib/wtstate/args.test.js.map +1 -0
  268. package/dist/lib/wtstate/index.d.ts +7 -0
  269. package/dist/lib/wtstate/index.d.ts.map +1 -0
  270. package/dist/lib/wtstate/index.js +8 -0
  271. package/dist/lib/wtstate/index.js.map +1 -0
  272. package/dist/lib/wtstate/types.d.ts +64 -0
  273. package/dist/lib/wtstate/types.d.ts.map +1 -0
  274. package/dist/lib/wtstate/types.js +5 -0
  275. package/dist/lib/wtstate/types.js.map +1 -0
  276. package/dist/mcp/server.d.ts +14 -0
  277. package/dist/mcp/server.d.ts.map +1 -0
  278. package/dist/mcp/server.js +339 -0
  279. package/dist/mcp/server.js.map +1 -0
  280. package/dist/mcp/server.test.d.ts +9 -0
  281. package/dist/mcp/server.test.d.ts.map +1 -0
  282. package/dist/mcp/server.test.js +390 -0
  283. package/dist/mcp/server.test.js.map +1 -0
  284. 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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"}