@waoooo/claude-skills 1.0.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 (264) hide show
  1. package/README.md +48 -0
  2. package/package.json +28 -0
  3. package/registry.json +431 -0
  4. package/skills/acceptance-review/SKILL.md +537 -0
  5. package/skills/all-plan/SKILL.md +19 -0
  6. package/skills/all-plan/references/flow.md +750 -0
  7. package/skills/api-docs-generate/SKILL.md +204 -0
  8. package/skills/api-docs-generate/assets/templates/api.mdx +140 -0
  9. package/skills/api-docs-generate/scripts/generate-api-docs.ts +308 -0
  10. package/skills/ask/SKILL.md +42 -0
  11. package/skills/autonew/SKILL.md +34 -0
  12. package/skills/capability-analyze/SKILL.md +300 -0
  13. package/skills/capability-analyze/scripts/analyze-capabilities.ts +531 -0
  14. package/skills/capability-docs-generate/SKILL.md +155 -0
  15. package/skills/capability-docs-generate/assets/templates/capability.mdx +271 -0
  16. package/skills/capability-docs-generate/scripts/generate-capability-docs.ts +358 -0
  17. package/skills/capability-tree-query/SKILL.md +112 -0
  18. package/skills/capability-tree-query/scripts/build-capability-tree.ts +402 -0
  19. package/skills/changelog-generator/SKILL.md +104 -0
  20. package/skills/continue/SKILL.md +39 -0
  21. package/skills/continue/agents/openai.yaml +3 -0
  22. package/skills/creating-skills/SKILL.md +158 -0
  23. package/skills/creating-skills/references/official_best_practices.md +128 -0
  24. package/skills/creating-skills/references/skill_examples.md +199 -0
  25. package/skills/docx/LICENSE.txt +30 -0
  26. package/skills/docx/SKILL.md +197 -0
  27. package/skills/docx/docx-js.md +350 -0
  28. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  29. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  30. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  31. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  32. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  33. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  34. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  35. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  36. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  37. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  38. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  39. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  40. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  41. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  42. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  43. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  44. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  45. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  46. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  47. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  48. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  49. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  50. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  51. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  52. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  53. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  54. package/skills/docx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  55. package/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  56. package/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  57. package/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  58. package/skills/docx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  59. package/skills/docx/ooxml/schemas/mce/mc.xsd +75 -0
  60. package/skills/docx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
  61. package/skills/docx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
  62. package/skills/docx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
  63. package/skills/docx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
  64. package/skills/docx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
  65. package/skills/docx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  66. package/skills/docx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
  67. package/skills/docx/ooxml/scripts/pack.py +159 -0
  68. package/skills/docx/ooxml/scripts/unpack.py +29 -0
  69. package/skills/docx/ooxml/scripts/validate.py +69 -0
  70. package/skills/docx/ooxml/scripts/validation/__init__.py +15 -0
  71. package/skills/docx/ooxml/scripts/validation/base.py +951 -0
  72. package/skills/docx/ooxml/scripts/validation/docx.py +274 -0
  73. package/skills/docx/ooxml/scripts/validation/pptx.py +315 -0
  74. package/skills/docx/ooxml/scripts/validation/redlining.py +279 -0
  75. package/skills/docx/ooxml.md +610 -0
  76. package/skills/docx/scripts/__init__.py +1 -0
  77. package/skills/docx/scripts/document.py +1276 -0
  78. package/skills/docx/scripts/templates/comments.xml +3 -0
  79. package/skills/docx/scripts/templates/commentsExtended.xml +3 -0
  80. package/skills/docx/scripts/templates/commentsExtensible.xml +3 -0
  81. package/skills/docx/scripts/templates/commentsIds.xml +3 -0
  82. package/skills/docx/scripts/templates/people.xml +3 -0
  83. package/skills/docx/scripts/utilities.py +374 -0
  84. package/skills/git-branch-create/SKILL.md +170 -0
  85. package/skills/git-branch-merge/SKILL.md +176 -0
  86. package/skills/git-commit/SKILL.md +56 -0
  87. package/skills/git-commit/references/commit_examples.md +311 -0
  88. package/skills/github-actions-trigger/SKILL.md +367 -0
  89. package/skills/github-issue-create/SKILL.md +294 -0
  90. package/skills/github-pr-creation/SKILL.md +137 -0
  91. package/skills/github-pr-creation/references/pr_templates.md +187 -0
  92. package/skills/github-pr-merge/SKILL.md +112 -0
  93. package/skills/github-pr-review/SKILL.md +110 -0
  94. package/skills/github-pr-review/references/severity_guide.md +168 -0
  95. package/skills/job-create/SKILL.md +294 -0
  96. package/skills/job-create/scripts/create-job.ts +105 -0
  97. package/skills/job-workflow/SKILL.md +212 -0
  98. package/skills/keyword-extract/SKILL.md +229 -0
  99. package/skills/mcp-builder/LICENSE.txt +202 -0
  100. package/skills/mcp-builder/SKILL.md +236 -0
  101. package/skills/mcp-builder/reference/evaluation.md +602 -0
  102. package/skills/mcp-builder/reference/mcp_best_practices.md +249 -0
  103. package/skills/mcp-builder/reference/node_mcp_server.md +970 -0
  104. package/skills/mcp-builder/reference/python_mcp_server.md +719 -0
  105. package/skills/mcp-builder/scripts/connections.py +151 -0
  106. package/skills/mcp-builder/scripts/evaluation.py +373 -0
  107. package/skills/mcp-builder/scripts/example_evaluation.xml +22 -0
  108. package/skills/mcp-builder/scripts/requirements.txt +2 -0
  109. package/skills/mdx-to-openspec/SKILL.md +827 -0
  110. package/skills/mdx-to-openspec/scripts/mdx-to-openspec.ts +320 -0
  111. package/skills/mounted/SKILL.md +20 -0
  112. package/skills/multi-model-review/SKILL.md +459 -0
  113. package/skills/notion-automation/SKILL.md +215 -0
  114. package/skills/openspec-review/SKILL.md +513 -0
  115. package/skills/pdf/LICENSE.txt +30 -0
  116. package/skills/pdf/SKILL.md +294 -0
  117. package/skills/pdf/forms.md +205 -0
  118. package/skills/pdf/reference.md +612 -0
  119. package/skills/pdf/scripts/check_bounding_boxes.py +70 -0
  120. package/skills/pdf/scripts/check_bounding_boxes_test.py +226 -0
  121. package/skills/pdf/scripts/check_fillable_fields.py +12 -0
  122. package/skills/pdf/scripts/convert_pdf_to_images.py +35 -0
  123. package/skills/pdf/scripts/create_validation_image.py +41 -0
  124. package/skills/pdf/scripts/extract_form_field_info.py +152 -0
  125. package/skills/pdf/scripts/fill_fillable_fields.py +114 -0
  126. package/skills/pdf/scripts/fill_pdf_form_with_annotations.py +108 -0
  127. package/skills/pend/SKILL.md +33 -0
  128. package/skills/ping/SKILL.md +39 -0
  129. package/skills/pptx/LICENSE.txt +30 -0
  130. package/skills/pptx/SKILL.md +484 -0
  131. package/skills/pptx/html2pptx.md +625 -0
  132. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
  133. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
  134. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
  135. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
  136. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
  137. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
  138. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
  139. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
  140. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
  141. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
  142. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
  143. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
  144. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
  145. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
  146. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
  147. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
  148. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
  149. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
  150. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
  151. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
  152. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
  153. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
  154. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
  155. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
  156. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
  157. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
  158. package/skills/pptx/ooxml/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
  159. package/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
  160. package/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
  161. package/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
  162. package/skills/pptx/ooxml/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
  163. package/skills/pptx/ooxml/schemas/mce/mc.xsd +75 -0
  164. package/skills/pptx/ooxml/schemas/microsoft/wml-2010.xsd +560 -0
  165. package/skills/pptx/ooxml/schemas/microsoft/wml-2012.xsd +67 -0
  166. package/skills/pptx/ooxml/schemas/microsoft/wml-2018.xsd +14 -0
  167. package/skills/pptx/ooxml/schemas/microsoft/wml-cex-2018.xsd +20 -0
  168. package/skills/pptx/ooxml/schemas/microsoft/wml-cid-2016.xsd +13 -0
  169. package/skills/pptx/ooxml/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
  170. package/skills/pptx/ooxml/schemas/microsoft/wml-symex-2015.xsd +8 -0
  171. package/skills/pptx/ooxml/scripts/pack.py +159 -0
  172. package/skills/pptx/ooxml/scripts/unpack.py +29 -0
  173. package/skills/pptx/ooxml/scripts/validate.py +69 -0
  174. package/skills/pptx/ooxml/scripts/validation/__init__.py +15 -0
  175. package/skills/pptx/ooxml/scripts/validation/base.py +951 -0
  176. package/skills/pptx/ooxml/scripts/validation/docx.py +274 -0
  177. package/skills/pptx/ooxml/scripts/validation/pptx.py +315 -0
  178. package/skills/pptx/ooxml/scripts/validation/redlining.py +279 -0
  179. package/skills/pptx/ooxml.md +427 -0
  180. package/skills/pptx/scripts/html2pptx.js +979 -0
  181. package/skills/pptx/scripts/inventory.py +1020 -0
  182. package/skills/pptx/scripts/rearrange.py +231 -0
  183. package/skills/pptx/scripts/replace.py +385 -0
  184. package/skills/pptx/scripts/thumbnail.py +450 -0
  185. package/skills/progress-update/SKILL.md +394 -0
  186. package/skills/progress-update/scripts/update-progress.ts +221 -0
  187. package/skills/release-automation/SKILL.md +306 -0
  188. package/skills/requirement-parse/SKILL.md +212 -0
  189. package/skills/requirement-parse/scripts/infer-builder-config.ts +346 -0
  190. package/skills/requirement-parse/scripts/merge-requirements.ts +228 -0
  191. package/skills/requirement-parse/scripts/parse-docs.ts +206 -0
  192. package/skills/requirement-parse/scripts/parse-openspec.ts +168 -0
  193. package/skills/roadmap-docs-generate/SKILL.md +483 -0
  194. package/skills/roadmap-docs-generate/assets/templates/ROADMAP.mdx +75 -0
  195. package/skills/roadmap-docs-generate/assets/templates/ROADMAP.mdx.template +330 -0
  196. package/skills/roadmap-docs-generate/assets/templates/TODO.mdx +56 -0
  197. package/skills/roadmap-docs-generate/assets/templates/TODO.mdx.template +363 -0
  198. package/skills/roadmap-docs-generate/scripts/json-to-mdx.ts +445 -0
  199. package/skills/roadmap-docs-generate/scripts/json-to-mdx.ts.backup +411 -0
  200. package/skills/roadmap-generate/SKILL.md +396 -0
  201. package/skills/roadmap-generate/scripts/generate-roadmap.ts +496 -0
  202. package/skills/skill-creator/LICENSE.txt +202 -0
  203. package/skills/skill-creator/SKILL.md +356 -0
  204. package/skills/skill-creator/references/output-patterns.md +82 -0
  205. package/skills/skill-creator/references/workflows.md +28 -0
  206. package/skills/skill-creator/scripts/init_skill.py +303 -0
  207. package/skills/skill-creator/scripts/package_skill.py +110 -0
  208. package/skills/skill-creator/scripts/quick_validate.py +95 -0
  209. package/skills/spec-generate/SKILL.md +408 -0
  210. package/skills/spec-generate/scripts/generate-specs.ts +538 -0
  211. package/skills/spec-generate/scripts/generate-tasks.ts +174 -0
  212. package/skills/specs-review/SKILL.md +370 -0
  213. package/skills/task-execute/SKILL.md +399 -0
  214. package/skills/task-update-status/SKILL.md +349 -0
  215. package/skills/task-update-status/scripts/update-task-status.ts +192 -0
  216. package/skills/task-verify/SKILL.md +407 -0
  217. package/skills/ui-ux-pro-max/SKILL.md +386 -0
  218. package/skills/ui-ux-pro-max/data/charts.csv +26 -0
  219. package/skills/ui-ux-pro-max/data/colors.csv +97 -0
  220. package/skills/ui-ux-pro-max/data/icons.csv +101 -0
  221. package/skills/ui-ux-pro-max/data/landing.csv +31 -0
  222. package/skills/ui-ux-pro-max/data/products.csv +97 -0
  223. package/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
  224. package/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -0
  225. package/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  226. package/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  227. package/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
  228. package/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  229. package/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  230. package/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  231. package/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  232. package/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
  233. package/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
  234. package/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  235. package/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  236. package/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  237. package/skills/ui-ux-pro-max/data/styles.csv +68 -0
  238. package/skills/ui-ux-pro-max/data/typography.csv +58 -0
  239. package/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
  240. package/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  241. package/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
  242. package/skills/ui-ux-pro-max/scripts/core.py +253 -0
  243. package/skills/ui-ux-pro-max/scripts/design_system.py +1067 -0
  244. package/skills/ui-ux-pro-max/scripts/search.py +114 -0
  245. package/skills/vercel-automation/SKILL.md +226 -0
  246. package/skills/webapp-testing/LICENSE.txt +202 -0
  247. package/skills/webapp-testing/SKILL.md +96 -0
  248. package/skills/webapp-testing/examples/console_logging.py +35 -0
  249. package/skills/webapp-testing/examples/element_discovery.py +40 -0
  250. package/skills/webapp-testing/examples/static_html_automation.py +33 -0
  251. package/skills/webapp-testing/scripts/with_server.py +106 -0
  252. package/skills/worktree-manager/SKILL.md +725 -0
  253. package/skills/worktree-manager/config.json +15 -0
  254. package/skills/worktree-manager/scripts/allocate-ports.sh +100 -0
  255. package/skills/worktree-manager/scripts/cleanup.sh +185 -0
  256. package/skills/worktree-manager/scripts/launch-agent.sh +155 -0
  257. package/skills/worktree-manager/scripts/register.sh +125 -0
  258. package/skills/worktree-manager/scripts/release-ports.sh +48 -0
  259. package/skills/worktree-manager/scripts/status.sh +169 -0
  260. package/skills/worktree-manager/scripts/sync.sh +168 -0
  261. package/skills/worktree-manager/templates/worktree.json +23 -0
  262. package/skills/xlsx/LICENSE.txt +30 -0
  263. package/skills/xlsx/SKILL.md +289 -0
  264. package/skills/xlsx/recalc.py +178 -0
@@ -0,0 +1,15 @@
1
+ {
2
+ "terminal": "ghostty",
3
+ "shell": "fish",
4
+ "claudeCommand": "cc",
5
+ "portPool": {
6
+ "start": 8100,
7
+ "end": 8199
8
+ },
9
+ "portsPerWorktree": 2,
10
+ "worktreeBase": "~/.archon/worktrees",
11
+ "registryPath": "~/.claude/worktree-registry.json",
12
+ "defaultCopyDirs": [".agents", ".env.example", ".env"],
13
+ "healthCheckTimeout": 30,
14
+ "healthCheckRetries": 6
15
+ }
@@ -0,0 +1,100 @@
1
+ #!/bin/bash
2
+ # allocate-ports.sh - Allocate N unused ports from global pool
3
+ #
4
+ # Usage: ./allocate-ports.sh <count>
5
+ #
6
+ # Returns: Space-separated list of port numbers
7
+ # Example: ./allocate-ports.sh 2 → "8100 8101"
8
+ #
9
+ # Also updates the registry to mark ports as allocated
10
+
11
+ set -e
12
+
13
+ COUNT="${1:-2}"
14
+
15
+ # Validate input
16
+ if ! [[ "$COUNT" =~ ^[0-9]+$ ]] || [ "$COUNT" -lt 1 ]; then
17
+ echo "Error: Count must be a positive integer" >&2
18
+ exit 1
19
+ fi
20
+
21
+ # Find config and registry
22
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
23
+ CONFIG_FILE="$SCRIPT_DIR/../config.json"
24
+ REGISTRY="${HOME}/.claude/worktree-registry.json"
25
+
26
+ # Load port pool from config
27
+ if [ -f "$CONFIG_FILE" ] && command -v jq &> /dev/null; then
28
+ PORT_START=$(jq -r '.portPool.start // 8100' "$CONFIG_FILE")
29
+ PORT_END=$(jq -r '.portPool.end // 8199' "$CONFIG_FILE")
30
+ else
31
+ PORT_START=8100
32
+ PORT_END=8199
33
+ fi
34
+
35
+ # Check jq is available
36
+ if ! command -v jq &> /dev/null; then
37
+ echo "Error: jq is required. Install with: brew install jq" >&2
38
+ exit 1
39
+ fi
40
+
41
+ # Initialize registry if it doesn't exist
42
+ if [ ! -f "$REGISTRY" ]; then
43
+ mkdir -p "$(dirname "$REGISTRY")"
44
+ cat > "$REGISTRY" << EOF
45
+ {
46
+ "worktrees": [],
47
+ "portPool": {
48
+ "start": $PORT_START,
49
+ "end": $PORT_END,
50
+ "allocated": []
51
+ }
52
+ }
53
+ EOF
54
+ fi
55
+
56
+ # Get currently allocated ports from registry
57
+ ALLOCATED_PORTS=$(jq -r '.portPool.allocated // [] | .[]' "$REGISTRY" 2>/dev/null || echo "")
58
+
59
+ # Function to check if port is in use (by system or in registry)
60
+ is_port_available() {
61
+ local port=$1
62
+
63
+ # Check if in registry's allocated list
64
+ if echo "$ALLOCATED_PORTS" | grep -q "^${port}$"; then
65
+ return 1
66
+ fi
67
+
68
+ # Check if port is actually in use by system
69
+ if lsof -i :"$port" &>/dev/null; then
70
+ return 1
71
+ fi
72
+
73
+ return 0
74
+ }
75
+
76
+ # Find available ports
77
+ FOUND_PORTS=()
78
+ for ((port=PORT_START; port<=PORT_END; port++)); do
79
+ if is_port_available "$port"; then
80
+ FOUND_PORTS+=("$port")
81
+ if [ ${#FOUND_PORTS[@]} -eq "$COUNT" ]; then
82
+ break
83
+ fi
84
+ fi
85
+ done
86
+
87
+ # Check if we found enough ports
88
+ if [ ${#FOUND_PORTS[@]} -lt "$COUNT" ]; then
89
+ echo "Error: Could not find $COUNT available ports in range $PORT_START-$PORT_END" >&2
90
+ echo "Found only: ${FOUND_PORTS[*]}" >&2
91
+ exit 1
92
+ fi
93
+
94
+ # Update registry with newly allocated ports
95
+ TMP=$(mktemp)
96
+ PORTS_JSON=$(printf '%s\n' "${FOUND_PORTS[@]}" | jq -R 'tonumber' | jq -s .)
97
+ jq ".portPool.allocated = ((.portPool.allocated // []) + $PORTS_JSON | unique | sort_by(.))" "$REGISTRY" > "$TMP" && mv "$TMP" "$REGISTRY"
98
+
99
+ # Output the ports (space-separated)
100
+ echo "${FOUND_PORTS[*]}"
@@ -0,0 +1,185 @@
1
+ #!/bin/bash
2
+ # cleanup.sh - Full cleanup of a worktree (ports, directory, registry, optionally branch)
3
+ #
4
+ # Usage: ./cleanup.sh <project> <branch> [--delete-branch]
5
+ # ./cleanup.sh --merged [--delete-branch]
6
+ #
7
+ # Examples:
8
+ # ./cleanup.sh obsidian-ai-agent feature/auth # Cleanup worktree only
9
+ # ./cleanup.sh obsidian-ai-agent feature/auth --delete-branch # Also delete git branch
10
+ # ./cleanup.sh --merged # Cleanup all merged worktrees
11
+ # ./cleanup.sh --merged --delete-branch # Also delete branches
12
+ #
13
+ # This script:
14
+ # 1. Kills processes on allocated ports
15
+ # 2. Removes the worktree directory
16
+ # 3. Prunes git worktree references
17
+ # 4. Removes entry from global registry
18
+ # 5. Releases ports back to pool
19
+ # 6. Optionally deletes local and remote git branches
20
+
21
+ set -e
22
+
23
+ REGISTRY="${HOME}/.claude/worktree-registry.json"
24
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
25
+
26
+ # Handle --merged mode
27
+ if [ "$1" = "--merged" ]; then
28
+ DELETE_BRANCH="${2:-}"
29
+
30
+ echo "Finding worktrees with merged PRs..."
31
+ echo "─────────────────────────────────────────────────────────"
32
+
33
+ CLEANED=0
34
+ SKIPPED=0
35
+
36
+ while IFS= read -r entry; do
37
+ [ -z "$entry" ] && continue
38
+
39
+ PROJECT=$(echo "$entry" | jq -r '.project')
40
+ BRANCH=$(echo "$entry" | jq -r '.branch')
41
+
42
+ # Check PR status
43
+ PR_INFO=$(gh pr list --head "$BRANCH" --state all --json number,state --limit 1 2>/dev/null || echo "[]")
44
+ PR_STATE=$(echo "$PR_INFO" | jq -r '.[0].state // "NONE"')
45
+ PR_NUM=$(echo "$PR_INFO" | jq -r '.[0].number // "?"')
46
+
47
+ if [ "$PR_STATE" = "MERGED" ]; then
48
+ echo ""
49
+ echo "Found merged: $PROJECT / $BRANCH (PR #$PR_NUM)"
50
+ "$SCRIPT_DIR/cleanup.sh" "$PROJECT" "$BRANCH" $DELETE_BRANCH
51
+ CLEANED=$((CLEANED + 1))
52
+ else
53
+ SKIPPED=$((SKIPPED + 1))
54
+ fi
55
+
56
+ done < <(jq -c '.worktrees[]' "$REGISTRY" 2>/dev/null)
57
+
58
+ echo ""
59
+ echo "─────────────────────────────────────────────────────────"
60
+ echo "Cleaned: $CLEANED worktrees"
61
+ echo "Skipped: $SKIPPED worktrees (not merged)"
62
+ exit 0
63
+ fi
64
+
65
+ PROJECT="$1"
66
+ BRANCH="$2"
67
+ DELETE_BRANCH="${3:-}"
68
+
69
+ if [ -z "$PROJECT" ] || [ -z "$BRANCH" ]; then
70
+ echo "Usage: $0 <project> <branch> [--delete-branch]"
71
+ echo " $0 --merged [--delete-branch]"
72
+ exit 1
73
+ fi
74
+
75
+ # Check jq is available
76
+ if ! command -v jq &> /dev/null; then
77
+ echo "Error: jq is required. Install with: brew install jq"
78
+ exit 1
79
+ fi
80
+
81
+ # Check if registry exists
82
+ if [ ! -f "$REGISTRY" ]; then
83
+ echo "Error: No registry found at: $REGISTRY"
84
+ exit 1
85
+ fi
86
+
87
+ echo "Cleaning up: $PROJECT / $BRANCH"
88
+ echo "─────────────────────────────────────────────────────────"
89
+
90
+ # Find worktree entry in registry
91
+ ENTRY=$(jq -c ".worktrees[] | select(.project == \"$PROJECT\" and .branch == \"$BRANCH\")" "$REGISTRY" 2>/dev/null || echo "")
92
+
93
+ if [ -z "$ENTRY" ]; then
94
+ echo "Warning: Worktree not found in registry"
95
+ echo "Attempting cleanup based on project/branch names..."
96
+ fi
97
+
98
+ # Get details from entry (or defaults)
99
+ if [ -n "$ENTRY" ]; then
100
+ WORKTREE_PATH=$(echo "$ENTRY" | jq -r '.worktreePath')
101
+ REPO_PATH=$(echo "$ENTRY" | jq -r '.repoPath')
102
+ PORTS=$(echo "$ENTRY" | jq -r '.ports[]' 2>/dev/null || echo "")
103
+ else
104
+ # Construct default path
105
+ BRANCH_SLUG=$(echo "$BRANCH" | tr '/' '-')
106
+ WORKTREE_PATH="$HOME/tmp/worktrees/$PROJECT/$BRANCH_SLUG"
107
+ REPO_PATH=""
108
+ PORTS=""
109
+ fi
110
+
111
+ # Step 1: Kill processes on ports
112
+ if [ -n "$PORTS" ]; then
113
+ echo "Killing processes on allocated ports..."
114
+ for PORT in $PORTS; do
115
+ if lsof -ti:"$PORT" &>/dev/null; then
116
+ lsof -ti:"$PORT" | xargs kill -9 2>/dev/null && echo " Killed process on port $PORT" || echo " Failed to kill on port $PORT"
117
+ else
118
+ echo " Port $PORT: no process"
119
+ fi
120
+ done
121
+ else
122
+ echo "No ports registered, skipping port cleanup"
123
+ fi
124
+
125
+ # Step 2: Remove worktree directory
126
+ if [ -d "$WORKTREE_PATH" ]; then
127
+ echo "Removing worktree directory: $WORKTREE_PATH"
128
+
129
+ # Try to find the main repo to run git worktree remove
130
+ if [ -n "$REPO_PATH" ] && [ -d "$REPO_PATH" ]; then
131
+ cd "$REPO_PATH"
132
+ git worktree remove "$WORKTREE_PATH" --force 2>/dev/null && echo " Removed via git worktree" || {
133
+ echo " Git worktree remove failed, removing directory directly..."
134
+ rm -rf "$WORKTREE_PATH" && echo " Removed directory"
135
+ }
136
+ else
137
+ # Just remove the directory
138
+ rm -rf "$WORKTREE_PATH" && echo " Removed directory"
139
+ fi
140
+ else
141
+ echo "Worktree directory not found: $WORKTREE_PATH"
142
+ fi
143
+
144
+ # Step 3: Prune stale worktree references
145
+ if [ -n "$REPO_PATH" ] && [ -d "$REPO_PATH" ]; then
146
+ echo "Pruning stale git worktree references..."
147
+ cd "$REPO_PATH"
148
+ git worktree prune 2>/dev/null && echo " Pruned" || echo " Prune skipped"
149
+ fi
150
+
151
+ # Step 4: Remove from registry and release ports
152
+ echo "Updating global registry..."
153
+ TMP=$(mktemp)
154
+
155
+ # Remove worktree entry
156
+ jq "del(.worktrees[] | select(.project == \"$PROJECT\" and .branch == \"$BRANCH\"))" "$REGISTRY" > "$TMP"
157
+
158
+ # Release ports from allocated pool
159
+ if [ -n "$PORTS" ]; then
160
+ for PORT in $PORTS; do
161
+ jq ".portPool.allocated = (.portPool.allocated | map(select(. != $PORT)))" "$TMP" > "${TMP}.2" && mv "${TMP}.2" "$TMP"
162
+ done
163
+ echo " Released ports: $PORTS"
164
+ fi
165
+
166
+ mv "$TMP" "$REGISTRY"
167
+ echo " Registry updated"
168
+
169
+ # Step 5: Delete git branches (if requested)
170
+ if [ "$DELETE_BRANCH" = "--delete-branch" ]; then
171
+ if [ -n "$REPO_PATH" ] && [ -d "$REPO_PATH" ]; then
172
+ cd "$REPO_PATH"
173
+
174
+ echo "Deleting local branch: $BRANCH"
175
+ git branch -D "$BRANCH" 2>/dev/null && echo " Deleted local branch" || echo " Local branch not found or is current branch"
176
+
177
+ echo "Deleting remote branch: $BRANCH"
178
+ git push origin --delete "$BRANCH" 2>/dev/null && echo " Deleted remote branch" || echo " Remote branch not found or already deleted"
179
+ else
180
+ echo "Cannot delete branches: original repo path not found"
181
+ fi
182
+ fi
183
+
184
+ echo "─────────────────────────────────────────────────────────"
185
+ echo "✅ Cleanup complete: $PROJECT / $BRANCH"
@@ -0,0 +1,155 @@
1
+ #!/bin/bash
2
+ # launch-agent.sh - Launch Claude Code in a new Ghostty terminal for a worktree
3
+ #
4
+ # Usage: ./launch-agent.sh <worktree-path> [task-description]
5
+ #
6
+ # Examples:
7
+ # ./launch-agent.sh ~/tmp/worktrees/my-project/feature-auth
8
+ # ./launch-agent.sh ~/tmp/worktrees/my-project/feature-auth "Implement OAuth login"
9
+
10
+ set -e
11
+
12
+ WORKTREE_PATH="$1"
13
+ TASK="$2"
14
+
15
+ # Validate input
16
+ if [ -z "$WORKTREE_PATH" ]; then
17
+ echo "Error: Worktree path required"
18
+ echo "Usage: $0 <worktree-path> [task-description]"
19
+ exit 1
20
+ fi
21
+
22
+ # Find script directory and config
23
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
24
+ CONFIG_FILE="$SCRIPT_DIR/../config.json"
25
+
26
+ # Load config (with defaults)
27
+ if [ -f "$CONFIG_FILE" ] && command -v jq &> /dev/null; then
28
+ TERMINAL=$(jq -r '.terminal // "ghostty"' "$CONFIG_FILE")
29
+ SHELL_CMD=$(jq -r '.shell // "fish"' "$CONFIG_FILE")
30
+ CLAUDE_CMD=$(jq -r '.claudeCommand // "cc"' "$CONFIG_FILE")
31
+ else
32
+ TERMINAL="ghostty"
33
+ SHELL_CMD="fish"
34
+ CLAUDE_CMD="cc"
35
+ fi
36
+
37
+ # Note: CLAUDE_CMD (default "cc") is configurable in config.json
38
+ # It runs inside the target shell (fish) which should have the alias defined
39
+ # Falls back to "claude" if the alias/command fails
40
+
41
+ # Expand ~ in path
42
+ WORKTREE_PATH="${WORKTREE_PATH/#\~/$HOME}"
43
+
44
+ # Convert to absolute path if relative
45
+ if [[ "$WORKTREE_PATH" != /* ]]; then
46
+ WORKTREE_PATH="$(pwd)/$WORKTREE_PATH"
47
+ fi
48
+
49
+ # Verify worktree exists
50
+ if [ ! -d "$WORKTREE_PATH" ]; then
51
+ echo "Error: Worktree directory does not exist: $WORKTREE_PATH"
52
+ exit 1
53
+ fi
54
+
55
+ # Verify it's a git worktree (has .git file or directory)
56
+ if [ ! -e "$WORKTREE_PATH/.git" ]; then
57
+ echo "Error: Not a git worktree: $WORKTREE_PATH"
58
+ exit 1
59
+ fi
60
+
61
+ # Get branch name
62
+ BRANCH=$(cd "$WORKTREE_PATH" && git branch --show-current 2>/dev/null || basename "$WORKTREE_PATH")
63
+
64
+ # Get project name from path
65
+ PROJECT=$(basename "$(dirname "$WORKTREE_PATH")")
66
+
67
+ # Build the command to run in the new terminal
68
+ # Use configured command (cc) - fish syntax compatible
69
+ # For fish: use 'or' instead of '||' for fallback, and avoid subshells
70
+ if [ "$SHELL_CMD" = "fish" ]; then
71
+ if [ -n "$TASK" ]; then
72
+ INNER_CMD="cd '$WORKTREE_PATH'; and echo '🌳 Worktree: $PROJECT / $BRANCH'; and echo '📋 Task: $TASK'; and echo ''; and $CLAUDE_CMD; or claude"
73
+ else
74
+ INNER_CMD="cd '$WORKTREE_PATH'; and echo '🌳 Worktree: $PROJECT / $BRANCH'; and echo ''; and $CLAUDE_CMD; or claude"
75
+ fi
76
+ else
77
+ # bash/zsh syntax
78
+ if [ -n "$TASK" ]; then
79
+ INNER_CMD="cd '$WORKTREE_PATH' && echo '🌳 Worktree: $PROJECT / $BRANCH' && echo '📋 Task: $TASK' && echo '' && ($CLAUDE_CMD || claude)"
80
+ else
81
+ INNER_CMD="cd '$WORKTREE_PATH' && echo '🌳 Worktree: $PROJECT / $BRANCH' && echo '' && ($CLAUDE_CMD || claude)"
82
+ fi
83
+ fi
84
+
85
+ # Launch based on terminal type
86
+ case "$TERMINAL" in
87
+ ghostty)
88
+ if ! command -v ghostty &> /dev/null && [ ! -d "/Applications/Ghostty.app" ]; then
89
+ echo "Error: Ghostty not found"
90
+ exit 1
91
+ fi
92
+ # Launch Ghostty with the command
93
+ open -na "Ghostty.app" --args -e "$SHELL_CMD" -c "$INNER_CMD"
94
+ ;;
95
+
96
+ iterm2|iterm)
97
+ osascript <<EOF
98
+ tell application "iTerm2"
99
+ create window with default profile
100
+ tell current session of current window
101
+ write text "cd '$WORKTREE_PATH' && $CLAUDE_CMD"
102
+ end tell
103
+ end tell
104
+ EOF
105
+ ;;
106
+
107
+ tmux)
108
+ if ! command -v tmux &> /dev/null; then
109
+ echo "Error: tmux not found"
110
+ exit 1
111
+ fi
112
+ SESSION_NAME="wt-$PROJECT-$(echo "$BRANCH" | tr '/' '-')"
113
+ tmux new-session -d -s "$SESSION_NAME" -c "$WORKTREE_PATH" "$SHELL_CMD -c '$CLAUDE_CMD'"
114
+ echo " tmux session: $SESSION_NAME (attach with: tmux attach -t $SESSION_NAME)"
115
+ ;;
116
+
117
+ wezterm)
118
+ if ! command -v wezterm &> /dev/null; then
119
+ echo "Error: WezTerm not found"
120
+ exit 1
121
+ fi
122
+ wezterm start --cwd "$WORKTREE_PATH" -- "$SHELL_CMD" -c "$INNER_CMD"
123
+ ;;
124
+
125
+ kitty)
126
+ if ! command -v kitty &> /dev/null; then
127
+ echo "Error: Kitty not found"
128
+ exit 1
129
+ fi
130
+ kitty --detach --directory "$WORKTREE_PATH" "$SHELL_CMD" -c "$INNER_CMD"
131
+ ;;
132
+
133
+ alacritty)
134
+ if ! command -v alacritty &> /dev/null; then
135
+ echo "Error: Alacritty not found"
136
+ exit 1
137
+ fi
138
+ alacritty --working-directory "$WORKTREE_PATH" -e "$SHELL_CMD" -c "$INNER_CMD" &
139
+ ;;
140
+
141
+ *)
142
+ echo "Error: Unknown terminal type: $TERMINAL"
143
+ echo "Supported: ghostty, iterm2, tmux, wezterm, kitty, alacritty"
144
+ exit 1
145
+ ;;
146
+ esac
147
+
148
+ echo "✅ Launched Claude Code agent"
149
+ echo " Terminal: $TERMINAL"
150
+ echo " Project: $PROJECT"
151
+ echo " Branch: $BRANCH"
152
+ echo " Path: $WORKTREE_PATH"
153
+ if [ -n "$TASK" ]; then
154
+ echo " Task: $TASK"
155
+ fi
@@ -0,0 +1,125 @@
1
+ #!/bin/bash
2
+ # register.sh - Register a worktree in the global registry
3
+ #
4
+ # Usage: ./register.sh <project> <branch> <branch-slug> <worktree-path> <repo-path> <ports> [task]
5
+ #
6
+ # Arguments:
7
+ # project - Project name (e.g., "obsidian-ai-agent")
8
+ # branch - Full branch name (e.g., "feature/auth")
9
+ # branch-slug - Slugified branch (e.g., "feature-auth")
10
+ # worktree-path - Full path to worktree
11
+ # repo-path - Full path to original repo
12
+ # ports - Comma-separated ports (e.g., "8100,8101")
13
+ # task - Optional task description
14
+ #
15
+ # Example:
16
+ # ./register.sh obsidian-ai-agent feature/auth feature-auth \
17
+ # ~/tmp/worktrees/obsidian-ai-agent/feature-auth \
18
+ # ~/Projects/obsidian-ai-agent \
19
+ # 8100,8101 "Implement OAuth"
20
+
21
+ set -e
22
+
23
+ PROJECT="$1"
24
+ BRANCH="$2"
25
+ BRANCH_SLUG="$3"
26
+ WORKTREE_PATH="$4"
27
+ REPO_PATH="$5"
28
+ PORTS="$6"
29
+ TASK="${7:-}"
30
+
31
+ # Validate inputs
32
+ if [ -z "$PROJECT" ] || [ -z "$BRANCH" ] || [ -z "$BRANCH_SLUG" ] || [ -z "$WORKTREE_PATH" ] || [ -z "$REPO_PATH" ] || [ -z "$PORTS" ]; then
33
+ echo "Usage: $0 <project> <branch> <branch-slug> <worktree-path> <repo-path> <ports> [task]"
34
+ exit 1
35
+ fi
36
+
37
+ REGISTRY="${HOME}/.claude/worktree-registry.json"
38
+
39
+ # Check jq is available
40
+ if ! command -v jq &> /dev/null; then
41
+ echo "Error: jq is required. Install with: brew install jq"
42
+ exit 1
43
+ fi
44
+
45
+ # Expand ~ in paths
46
+ WORKTREE_PATH="${WORKTREE_PATH/#\~/$HOME}"
47
+ REPO_PATH="${REPO_PATH/#\~/$HOME}"
48
+
49
+ # Initialize registry if it doesn't exist
50
+ if [ ! -f "$REGISTRY" ]; then
51
+ mkdir -p "$(dirname "$REGISTRY")"
52
+ cat > "$REGISTRY" << 'EOF'
53
+ {
54
+ "worktrees": [],
55
+ "portPool": {
56
+ "start": 8100,
57
+ "end": 8199,
58
+ "allocated": []
59
+ }
60
+ }
61
+ EOF
62
+ fi
63
+
64
+ # Check if already registered - release old ports before updating
65
+ if jq -e ".worktrees[] | select(.project == \"$PROJECT\" and .branch == \"$BRANCH\")" "$REGISTRY" > /dev/null 2>&1; then
66
+ echo "Warning: Worktree already registered, updating..."
67
+
68
+ # Get old ports to release them
69
+ OLD_PORTS=$(jq -r ".worktrees[] | select(.project == \"$PROJECT\" and .branch == \"$BRANCH\") | .ports[]" "$REGISTRY" 2>/dev/null || echo "")
70
+
71
+ TMP=$(mktemp)
72
+ # Remove old entry
73
+ jq "del(.worktrees[] | select(.project == \"$PROJECT\" and .branch == \"$BRANCH\"))" "$REGISTRY" > "$TMP"
74
+
75
+ # Release old ports from pool
76
+ if [ -n "$OLD_PORTS" ]; then
77
+ for OLD_PORT in $OLD_PORTS; do
78
+ jq ".portPool.allocated = (.portPool.allocated | map(select(. != $OLD_PORT)))" "$TMP" > "${TMP}.2" && mv "${TMP}.2" "$TMP"
79
+ done
80
+ echo " Released old ports: $OLD_PORTS"
81
+ fi
82
+
83
+ mv "$TMP" "$REGISTRY"
84
+ fi
85
+
86
+ # Parse ports into JSON array
87
+ PORTS_JSON=$(echo "$PORTS" | tr ',' '\n' | jq -R 'tonumber' | jq -s .)
88
+
89
+ # Format task
90
+ if [ -n "$TASK" ]; then
91
+ TASK_JSON="\"$TASK\""
92
+ else
93
+ TASK_JSON="null"
94
+ fi
95
+
96
+ # Generate UUID
97
+ UUID=$(uuidgen 2>/dev/null || cat /proc/sys/kernel/random/uuid 2>/dev/null || echo "wt-$(date +%s)-$$")
98
+
99
+ # Add entry
100
+ TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
101
+ TMP=$(mktemp)
102
+ jq ".worktrees += [{
103
+ \"id\": \"$UUID\",
104
+ \"project\": \"$PROJECT\",
105
+ \"repoPath\": \"$REPO_PATH\",
106
+ \"branch\": \"$BRANCH\",
107
+ \"branchSlug\": \"$BRANCH_SLUG\",
108
+ \"worktreePath\": \"$WORKTREE_PATH\",
109
+ \"ports\": $PORTS_JSON,
110
+ \"createdAt\": \"$TIMESTAMP\",
111
+ \"validatedAt\": null,
112
+ \"agentLaunchedAt\": null,
113
+ \"task\": $TASK_JSON,
114
+ \"prNumber\": null,
115
+ \"status\": \"active\"
116
+ }]" "$REGISTRY" > "$TMP" && mv "$TMP" "$REGISTRY"
117
+
118
+ echo "✅ Registered worktree:"
119
+ echo " Project: $PROJECT"
120
+ echo " Branch: $BRANCH"
121
+ echo " Path: $WORKTREE_PATH"
122
+ echo " Ports: $PORTS"
123
+ if [ -n "$TASK" ]; then
124
+ echo " Task: $TASK"
125
+ fi
@@ -0,0 +1,48 @@
1
+ #!/bin/bash
2
+ # release-ports.sh - Release ports back to the global pool
3
+ #
4
+ # Usage: ./release-ports.sh <port1> [port2] [port3] ...
5
+ #
6
+ # Example: ./release-ports.sh 8100 8101
7
+
8
+ set -e
9
+
10
+ if [ $# -eq 0 ]; then
11
+ echo "Usage: $0 <port1> [port2] [port3] ..."
12
+ exit 1
13
+ fi
14
+
15
+ REGISTRY="${HOME}/.claude/worktree-registry.json"
16
+
17
+ # Check jq is available
18
+ if ! command -v jq &> /dev/null; then
19
+ echo "Error: jq is required. Install with: brew install jq"
20
+ exit 1
21
+ fi
22
+
23
+ # Check if registry exists
24
+ if [ ! -f "$REGISTRY" ]; then
25
+ echo "No registry found, nothing to release"
26
+ exit 0
27
+ fi
28
+
29
+ TMP=$(mktemp)
30
+ cp "$REGISTRY" "$TMP"
31
+
32
+ RELEASED=()
33
+ for PORT in "$@"; do
34
+ if [[ "$PORT" =~ ^[0-9]+$ ]]; then
35
+ jq ".portPool.allocated = (.portPool.allocated | map(select(. != $PORT)))" "$TMP" > "${TMP}.2" && mv "${TMP}.2" "$TMP"
36
+ RELEASED+=("$PORT")
37
+ else
38
+ echo "Warning: Invalid port number: $PORT" >&2
39
+ fi
40
+ done
41
+
42
+ mv "$TMP" "$REGISTRY"
43
+
44
+ if [ ${#RELEASED[@]} -gt 0 ]; then
45
+ echo "Released ports: ${RELEASED[*]}"
46
+ else
47
+ echo "No ports released"
48
+ fi