@fifine/aim-studio 0.0.1

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 (289) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +159 -0
  3. package/bin/aim.js +3 -0
  4. package/dist/cli/index.d.ts +3 -0
  5. package/dist/cli/index.d.ts.map +1 -0
  6. package/dist/cli/index.js +89 -0
  7. package/dist/cli/index.js.map +1 -0
  8. package/dist/commands/init.d.ts +13 -0
  9. package/dist/commands/init.d.ts.map +1 -0
  10. package/dist/commands/init.js +513 -0
  11. package/dist/commands/init.js.map +1 -0
  12. package/dist/commands/update.d.ts +27 -0
  13. package/dist/commands/update.d.ts.map +1 -0
  14. package/dist/commands/update.js +1275 -0
  15. package/dist/commands/update.js.map +1 -0
  16. package/dist/configurators/claude.d.ts +32 -0
  17. package/dist/configurators/claude.d.ts.map +1 -0
  18. package/dist/configurators/claude.js +98 -0
  19. package/dist/configurators/claude.js.map +1 -0
  20. package/dist/configurators/index.d.ts +51 -0
  21. package/dist/configurators/index.d.ts.map +1 -0
  22. package/dist/configurators/index.js +113 -0
  23. package/dist/configurators/index.js.map +1 -0
  24. package/dist/configurators/shared.d.ts +12 -0
  25. package/dist/configurators/shared.d.ts.map +1 -0
  26. package/dist/configurators/shared.js +21 -0
  27. package/dist/configurators/shared.js.map +1 -0
  28. package/dist/configurators/workflow.d.ts +28 -0
  29. package/dist/configurators/workflow.d.ts.map +1 -0
  30. package/dist/configurators/workflow.js +147 -0
  31. package/dist/configurators/workflow.js.map +1 -0
  32. package/dist/constants/paths.d.ts +68 -0
  33. package/dist/constants/paths.d.ts.map +1 -0
  34. package/dist/constants/paths.js +77 -0
  35. package/dist/constants/paths.js.map +1 -0
  36. package/dist/constants/version.d.ts +9 -0
  37. package/dist/constants/version.d.ts.map +1 -0
  38. package/dist/constants/version.js +15 -0
  39. package/dist/constants/version.js.map +1 -0
  40. package/dist/index.d.ts +9 -0
  41. package/dist/index.d.ts.map +1 -0
  42. package/dist/index.js +9 -0
  43. package/dist/index.js.map +1 -0
  44. package/dist/migrations/index.d.ts +54 -0
  45. package/dist/migrations/index.d.ts.map +1 -0
  46. package/dist/migrations/index.js +160 -0
  47. package/dist/migrations/index.js.map +1 -0
  48. package/dist/migrations/manifests/0.0.1.json +9 -0
  49. package/dist/migrations/manifests/0.1.9.json +30 -0
  50. package/dist/migrations/manifests/0.2.0.json +49 -0
  51. package/dist/migrations/manifests/0.2.12.json +9 -0
  52. package/dist/migrations/manifests/0.2.13.json +9 -0
  53. package/dist/migrations/manifests/0.2.14.json +175 -0
  54. package/dist/migrations/manifests/0.2.15.json +33 -0
  55. package/dist/migrations/manifests/0.3.0-beta.0.json +278 -0
  56. package/dist/migrations/manifests/0.3.0-beta.1.json +9 -0
  57. package/dist/migrations/manifests/0.3.0-beta.10.json +9 -0
  58. package/dist/migrations/manifests/0.3.0-beta.11.json +9 -0
  59. package/dist/migrations/manifests/0.3.0-beta.12.json +9 -0
  60. package/dist/migrations/manifests/0.3.0-beta.13.json +9 -0
  61. package/dist/migrations/manifests/0.3.0-beta.14.json +9 -0
  62. package/dist/migrations/manifests/0.3.0-beta.15.json +9 -0
  63. package/dist/migrations/manifests/0.3.0-beta.16.json +9 -0
  64. package/dist/migrations/manifests/0.3.0-beta.2.json +9 -0
  65. package/dist/migrations/manifests/0.3.0-beta.3.json +9 -0
  66. package/dist/migrations/manifests/0.3.0-beta.4.json +9 -0
  67. package/dist/migrations/manifests/0.3.0-beta.5.json +9 -0
  68. package/dist/migrations/manifests/0.3.0-beta.6.json +9 -0
  69. package/dist/migrations/manifests/0.3.0-beta.7.json +11 -0
  70. package/dist/migrations/manifests/0.3.0-beta.8.json +9 -0
  71. package/dist/migrations/manifests/0.3.0-beta.9.json +9 -0
  72. package/dist/migrations/manifests/0.3.0-rc.0.json +9 -0
  73. package/dist/migrations/manifests/0.3.0-rc.1.json +9 -0
  74. package/dist/migrations/manifests/0.3.0-rc.2.json +9 -0
  75. package/dist/templates/CLAUDE.md +71 -0
  76. package/dist/templates/aim/gitignore.txt +29 -0
  77. package/dist/templates/aim/index.d.ts +49 -0
  78. package/dist/templates/aim/index.d.ts.map +1 -0
  79. package/dist/templates/aim/index.js +92 -0
  80. package/dist/templates/aim/index.js.map +1 -0
  81. package/dist/templates/aim/scripts/__init__.py +5 -0
  82. package/dist/templates/aim/scripts/add_session.py +392 -0
  83. package/dist/templates/aim/scripts/common/__init__.py +80 -0
  84. package/dist/templates/aim/scripts/common/cli_adapter.py +435 -0
  85. package/dist/templates/aim/scripts/common/developer.py +190 -0
  86. package/dist/templates/aim/scripts/common/git_context.py +383 -0
  87. package/dist/templates/aim/scripts/common/paths.py +347 -0
  88. package/dist/templates/aim/scripts/common/phase.py +253 -0
  89. package/dist/templates/aim/scripts/common/registry.py +366 -0
  90. package/dist/templates/aim/scripts/common/task_queue.py +255 -0
  91. package/dist/templates/aim/scripts/common/task_utils.py +178 -0
  92. package/dist/templates/aim/scripts/common/worktree.py +219 -0
  93. package/dist/templates/aim/scripts/create_bootstrap.py +290 -0
  94. package/dist/templates/aim/scripts/get_context.py +16 -0
  95. package/dist/templates/aim/scripts/get_developer.py +26 -0
  96. package/dist/templates/aim/scripts/init_developer.py +51 -0
  97. package/dist/templates/aim/scripts/multi_agent/__init__.py +5 -0
  98. package/dist/templates/aim/scripts/multi_agent/cleanup.py +403 -0
  99. package/dist/templates/aim/scripts/multi_agent/create_pr.py +329 -0
  100. package/dist/templates/aim/scripts/multi_agent/plan.py +233 -0
  101. package/dist/templates/aim/scripts/multi_agent/start.py +461 -0
  102. package/dist/templates/aim/scripts/multi_agent/status.py +817 -0
  103. package/dist/templates/aim/scripts/task.py +1068 -0
  104. package/dist/templates/aim/scripts-shell-archive/add-session.sh +384 -0
  105. package/dist/templates/aim/scripts-shell-archive/common/developer.sh +129 -0
  106. package/dist/templates/aim/scripts-shell-archive/common/git-context.sh +263 -0
  107. package/dist/templates/aim/scripts-shell-archive/common/paths.sh +208 -0
  108. package/dist/templates/aim/scripts-shell-archive/common/phase.sh +150 -0
  109. package/dist/templates/aim/scripts-shell-archive/common/registry.sh +247 -0
  110. package/dist/templates/aim/scripts-shell-archive/common/task-queue.sh +142 -0
  111. package/dist/templates/aim/scripts-shell-archive/common/task-utils.sh +151 -0
  112. package/dist/templates/aim/scripts-shell-archive/common/worktree.sh +128 -0
  113. package/dist/templates/aim/scripts-shell-archive/create-bootstrap.sh +299 -0
  114. package/dist/templates/aim/scripts-shell-archive/get-context.sh +7 -0
  115. package/dist/templates/aim/scripts-shell-archive/get-developer.sh +15 -0
  116. package/dist/templates/aim/scripts-shell-archive/init-developer.sh +34 -0
  117. package/dist/templates/aim/scripts-shell-archive/multi-agent/cleanup.sh +396 -0
  118. package/dist/templates/aim/scripts-shell-archive/multi-agent/create-pr.sh +241 -0
  119. package/dist/templates/aim/scripts-shell-archive/multi-agent/plan.sh +207 -0
  120. package/dist/templates/aim/scripts-shell-archive/multi-agent/start.sh +317 -0
  121. package/dist/templates/aim/scripts-shell-archive/multi-agent/status.sh +828 -0
  122. package/dist/templates/aim/scripts-shell-archive/task.sh +1204 -0
  123. package/dist/templates/aim/tasks/.gitkeep +0 -0
  124. package/dist/templates/aim/workflow.md +258 -0
  125. package/dist/templates/aim/worktree.yaml +47 -0
  126. package/dist/templates/claude/agents/check.md +122 -0
  127. package/dist/templates/claude/agents/debug.md +106 -0
  128. package/dist/templates/claude/agents/dispatch.md +230 -0
  129. package/dist/templates/claude/agents/implement.md +96 -0
  130. package/dist/templates/claude/agents/plan.md +396 -0
  131. package/dist/templates/claude/agents/research.md +120 -0
  132. package/dist/templates/claude/agents/story.md +53 -0
  133. package/dist/templates/claude/commands/aim/before-backend-dev.md +13 -0
  134. package/dist/templates/claude/commands/aim/before-frontend-dev.md +13 -0
  135. package/dist/templates/claude/commands/aim/break-loop.md +153 -0
  136. package/dist/templates/claude/commands/aim/check-backend.md +13 -0
  137. package/dist/templates/claude/commands/aim/check-cross-layer.md +153 -0
  138. package/dist/templates/claude/commands/aim/check-frontend.md +13 -0
  139. package/dist/templates/claude/commands/aim/check-story.md +59 -0
  140. package/dist/templates/claude/commands/aim/create-command.md +154 -0
  141. package/dist/templates/claude/commands/aim/export.md +187 -0
  142. package/dist/templates/claude/commands/aim/finish-work.md +104 -0
  143. package/dist/templates/claude/commands/aim/integrate-skill.md +219 -0
  144. package/dist/templates/claude/commands/aim/onboard.md +358 -0
  145. package/dist/templates/claude/commands/aim/parallel.md +217 -0
  146. package/dist/templates/claude/commands/aim/portrait.md +170 -0
  147. package/dist/templates/claude/commands/aim/record-session.md +92 -0
  148. package/dist/templates/claude/commands/aim/start.md +112 -0
  149. package/dist/templates/claude/commands/aim/story.md +140 -0
  150. package/dist/templates/claude/commands/aim/update-spec.md +285 -0
  151. package/dist/templates/claude/commands/aim/visualize.md +182 -0
  152. package/dist/templates/claude/commands/trellis/before-backend-dev.md +13 -0
  153. package/dist/templates/claude/commands/trellis/before-frontend-dev.md +13 -0
  154. package/dist/templates/claude/commands/trellis/break-loop.md +125 -0
  155. package/dist/templates/claude/commands/trellis/check-backend.md +13 -0
  156. package/dist/templates/claude/commands/trellis/check-cross-layer.md +153 -0
  157. package/dist/templates/claude/commands/trellis/check-frontend.md +13 -0
  158. package/dist/templates/claude/commands/trellis/create-command.md +154 -0
  159. package/dist/templates/claude/commands/trellis/finish-work.md +129 -0
  160. package/dist/templates/claude/commands/trellis/integrate-skill.md +219 -0
  161. package/dist/templates/claude/commands/trellis/onboard.md +358 -0
  162. package/dist/templates/claude/commands/trellis/parallel.md +193 -0
  163. package/dist/templates/claude/commands/trellis/record-session.md +62 -0
  164. package/dist/templates/claude/commands/trellis/start.md +280 -0
  165. package/dist/templates/claude/commands/trellis/update-spec.md +285 -0
  166. package/dist/templates/claude/hooks/inject-subagent-context.py +772 -0
  167. package/dist/templates/claude/hooks/ralph-loop.py +388 -0
  168. package/dist/templates/claude/hooks/session-start.py +142 -0
  169. package/dist/templates/claude/index.d.ts +54 -0
  170. package/dist/templates/claude/index.d.ts.map +1 -0
  171. package/dist/templates/claude/index.js +85 -0
  172. package/dist/templates/claude/index.js.map +1 -0
  173. package/dist/templates/claude/settings.json +41 -0
  174. package/dist/templates/extract.d.ts +68 -0
  175. package/dist/templates/extract.d.ts.map +1 -0
  176. package/dist/templates/extract.js +128 -0
  177. package/dist/templates/extract.js.map +1 -0
  178. package/dist/templates/markdown/agents.md +25 -0
  179. package/dist/templates/markdown/gitignore.txt +12 -0
  180. package/dist/templates/markdown/index.d.ts +32 -0
  181. package/dist/templates/markdown/index.d.ts.map +1 -0
  182. package/dist/templates/markdown/index.js +58 -0
  183. package/dist/templates/markdown/index.js.map +1 -0
  184. package/dist/templates/markdown/spec/backend/database-guidelines.md.txt +51 -0
  185. package/dist/templates/markdown/spec/backend/directory-structure.md.txt +54 -0
  186. package/dist/templates/markdown/spec/backend/error-handling.md.txt +51 -0
  187. package/dist/templates/markdown/spec/backend/index.md +40 -0
  188. package/dist/templates/markdown/spec/backend/index.md.txt +38 -0
  189. package/dist/templates/markdown/spec/backend/logging-guidelines.md.txt +51 -0
  190. package/dist/templates/markdown/spec/backend/quality-guidelines.md.txt +51 -0
  191. package/dist/templates/markdown/spec/backend/script-conventions.md +467 -0
  192. package/dist/templates/markdown/spec/frontend/component-guidelines.md.txt +59 -0
  193. package/dist/templates/markdown/spec/frontend/directory-structure.md.txt +54 -0
  194. package/dist/templates/markdown/spec/frontend/hook-guidelines.md.txt +51 -0
  195. package/dist/templates/markdown/spec/frontend/index.md.txt +39 -0
  196. package/dist/templates/markdown/spec/frontend/quality-guidelines.md.txt +51 -0
  197. package/dist/templates/markdown/spec/frontend/state-management.md.txt +51 -0
  198. package/dist/templates/markdown/spec/frontend/type-safety.md.txt +51 -0
  199. package/dist/templates/markdown/spec/guides/code-reuse-thinking-guide.md +118 -0
  200. package/dist/templates/markdown/spec/guides/code-reuse-thinking-guide.md.txt +92 -0
  201. package/dist/templates/markdown/spec/guides/cross-layer-thinking-guide.md.txt +94 -0
  202. package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md +394 -0
  203. package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +319 -0
  204. package/dist/templates/markdown/spec/guides/index.md.txt +89 -0
  205. package/dist/templates/markdown/spec/story/character.md.txt +95 -0
  206. package/dist/templates/markdown/spec/story/index.md.txt +31 -0
  207. package/dist/templates/markdown/spec/story/script.md.txt +313 -0
  208. package/dist/templates/markdown/spec/story/world.md.txt +92 -0
  209. package/dist/templates/markdown/workspace-index.md +123 -0
  210. package/dist/templates/markdown/worktree.yaml.txt +58 -0
  211. package/dist/templates/trellis/gitignore.txt +29 -0
  212. package/dist/templates/trellis/index.d.ts +49 -0
  213. package/dist/templates/trellis/index.d.ts.map +1 -0
  214. package/dist/templates/trellis/index.js +92 -0
  215. package/dist/templates/trellis/index.js.map +1 -0
  216. package/dist/templates/trellis/scripts/__init__.py +5 -0
  217. package/dist/templates/trellis/scripts/add_session.py +392 -0
  218. package/dist/templates/trellis/scripts/common/__init__.py +80 -0
  219. package/dist/templates/trellis/scripts/common/cli_adapter.py +435 -0
  220. package/dist/templates/trellis/scripts/common/developer.py +190 -0
  221. package/dist/templates/trellis/scripts/common/git_context.py +383 -0
  222. package/dist/templates/trellis/scripts/common/paths.py +347 -0
  223. package/dist/templates/trellis/scripts/common/phase.py +253 -0
  224. package/dist/templates/trellis/scripts/common/registry.py +366 -0
  225. package/dist/templates/trellis/scripts/common/task_queue.py +255 -0
  226. package/dist/templates/trellis/scripts/common/task_utils.py +178 -0
  227. package/dist/templates/trellis/scripts/common/worktree.py +219 -0
  228. package/dist/templates/trellis/scripts/create_bootstrap.py +290 -0
  229. package/dist/templates/trellis/scripts/get_context.py +16 -0
  230. package/dist/templates/trellis/scripts/get_developer.py +26 -0
  231. package/dist/templates/trellis/scripts/init_developer.py +51 -0
  232. package/dist/templates/trellis/scripts/multi_agent/__init__.py +5 -0
  233. package/dist/templates/trellis/scripts/multi_agent/cleanup.py +403 -0
  234. package/dist/templates/trellis/scripts/multi_agent/create_pr.py +329 -0
  235. package/dist/templates/trellis/scripts/multi_agent/plan.py +233 -0
  236. package/dist/templates/trellis/scripts/multi_agent/start.py +461 -0
  237. package/dist/templates/trellis/scripts/multi_agent/status.py +817 -0
  238. package/dist/templates/trellis/scripts/task.py +1056 -0
  239. package/dist/templates/trellis/scripts-shell-archive/add-session.sh +384 -0
  240. package/dist/templates/trellis/scripts-shell-archive/common/developer.sh +129 -0
  241. package/dist/templates/trellis/scripts-shell-archive/common/git-context.sh +263 -0
  242. package/dist/templates/trellis/scripts-shell-archive/common/paths.sh +208 -0
  243. package/dist/templates/trellis/scripts-shell-archive/common/phase.sh +150 -0
  244. package/dist/templates/trellis/scripts-shell-archive/common/registry.sh +247 -0
  245. package/dist/templates/trellis/scripts-shell-archive/common/task-queue.sh +142 -0
  246. package/dist/templates/trellis/scripts-shell-archive/common/task-utils.sh +151 -0
  247. package/dist/templates/trellis/scripts-shell-archive/common/worktree.sh +128 -0
  248. package/dist/templates/trellis/scripts-shell-archive/create-bootstrap.sh +299 -0
  249. package/dist/templates/trellis/scripts-shell-archive/get-context.sh +7 -0
  250. package/dist/templates/trellis/scripts-shell-archive/get-developer.sh +15 -0
  251. package/dist/templates/trellis/scripts-shell-archive/init-developer.sh +34 -0
  252. package/dist/templates/trellis/scripts-shell-archive/multi-agent/cleanup.sh +396 -0
  253. package/dist/templates/trellis/scripts-shell-archive/multi-agent/create-pr.sh +241 -0
  254. package/dist/templates/trellis/scripts-shell-archive/multi-agent/plan.sh +207 -0
  255. package/dist/templates/trellis/scripts-shell-archive/multi-agent/start.sh +317 -0
  256. package/dist/templates/trellis/scripts-shell-archive/multi-agent/status.sh +828 -0
  257. package/dist/templates/trellis/scripts-shell-archive/task.sh +1204 -0
  258. package/dist/templates/trellis/tasks/.gitkeep +0 -0
  259. package/dist/templates/trellis/workflow.md +416 -0
  260. package/dist/templates/trellis/worktree.yaml +47 -0
  261. package/dist/types/ai-tools.d.ts +48 -0
  262. package/dist/types/ai-tools.d.ts.map +1 -0
  263. package/dist/types/ai-tools.js +32 -0
  264. package/dist/types/ai-tools.js.map +1 -0
  265. package/dist/types/migration.d.ts +86 -0
  266. package/dist/types/migration.d.ts.map +1 -0
  267. package/dist/types/migration.js +8 -0
  268. package/dist/types/migration.js.map +1 -0
  269. package/dist/utils/compare-versions.d.ts +12 -0
  270. package/dist/utils/compare-versions.d.ts.map +1 -0
  271. package/dist/utils/compare-versions.js +76 -0
  272. package/dist/utils/compare-versions.js.map +1 -0
  273. package/dist/utils/file-writer.d.ts +23 -0
  274. package/dist/utils/file-writer.d.ts.map +1 -0
  275. package/dist/utils/file-writer.js +140 -0
  276. package/dist/utils/file-writer.js.map +1 -0
  277. package/dist/utils/project-detector.d.ts +16 -0
  278. package/dist/utils/project-detector.d.ts.map +1 -0
  279. package/dist/utils/project-detector.js +188 -0
  280. package/dist/utils/project-detector.js.map +1 -0
  281. package/dist/utils/template-fetcher.d.ts +51 -0
  282. package/dist/utils/template-fetcher.d.ts.map +1 -0
  283. package/dist/utils/template-fetcher.js +174 -0
  284. package/dist/utils/template-fetcher.js.map +1 -0
  285. package/dist/utils/template-hash.d.ts +78 -0
  286. package/dist/utils/template-hash.d.ts.map +1 -0
  287. package/dist/utils/template-hash.js +239 -0
  288. package/dist/utils/template-hash.js.map +1 -0
  289. package/package.json +87 -0
@@ -0,0 +1,396 @@
1
+ #!/bin/bash
2
+ # =============================================================================
3
+ # Multi-Agent Pipeline: Cleanup Worktree
4
+ # =============================================================================
5
+ # Usage:
6
+ # ./cleanup.sh <branch-name> Remove specific worktree
7
+ # ./cleanup.sh --list List all worktrees
8
+ # ./cleanup.sh --merged Remove merged worktrees
9
+ # ./cleanup.sh --all Remove all worktrees (with confirmation)
10
+ #
11
+ # Options:
12
+ # -y, --yes Skip confirmation prompts
13
+ # --keep-branch Don't delete the git branch
14
+ #
15
+ # This script:
16
+ # 1. Archives task directory to archive/{YYYY-MM}/
17
+ # 2. Removes agent from registry
18
+ # 3. Removes git worktree
19
+ # 4. Optionally deletes git branch
20
+ # =============================================================================
21
+
22
+ set -e
23
+
24
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
25
+ source "$SCRIPT_DIR/../common/paths.sh"
26
+ source "$SCRIPT_DIR/../common/worktree.sh"
27
+ source "$SCRIPT_DIR/../common/developer.sh"
28
+ source "$SCRIPT_DIR/../common/task-queue.sh"
29
+ source "$SCRIPT_DIR/../common/task-utils.sh"
30
+ source "$SCRIPT_DIR/../common/registry.sh"
31
+
32
+ # Colors
33
+ RED='\033[0;31m'
34
+ GREEN='\033[0;32m'
35
+ YELLOW='\033[1;33m'
36
+ BLUE='\033[0;34m'
37
+ NC='\033[0m'
38
+
39
+ log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
40
+ log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
41
+ log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
42
+ log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
43
+
44
+ PROJECT_ROOT=$(get_repo_root)
45
+ SKIP_CONFIRM=false
46
+ KEEP_BRANCH=false
47
+
48
+ # =============================================================================
49
+ # Parse Arguments
50
+ # =============================================================================
51
+ POSITIONAL_ARGS=()
52
+ while [[ $# -gt 0 ]]; do
53
+ case $1 in
54
+ -y|--yes)
55
+ SKIP_CONFIRM=true
56
+ shift
57
+ ;;
58
+ --keep-branch)
59
+ KEEP_BRANCH=true
60
+ shift
61
+ ;;
62
+ --list|--merged|--all)
63
+ ACTION="${1#--}"
64
+ shift
65
+ ;;
66
+ -*)
67
+ log_error "Unknown option: $1"
68
+ exit 1
69
+ ;;
70
+ *)
71
+ POSITIONAL_ARGS+=("$1")
72
+ shift
73
+ ;;
74
+ esac
75
+ done
76
+
77
+ # =============================================================================
78
+ # List Worktrees
79
+ # =============================================================================
80
+ cmd_list() {
81
+ echo -e "${BLUE}=== Git Worktrees ===${NC}"
82
+ echo ""
83
+
84
+ cd "$PROJECT_ROOT"
85
+ git worktree list
86
+
87
+ echo ""
88
+
89
+ # Show registry info
90
+ local registry_file=$(registry_get_file "$PROJECT_ROOT")
91
+
92
+ if [ -f "$registry_file" ]; then
93
+ echo -e "${BLUE}=== Registered Agents ===${NC}"
94
+ echo ""
95
+ jq -r '.agents[] | " \(.id): PID=\(.pid) [\(.worktree_path)]"' "$registry_file" 2>/dev/null || echo " (none)"
96
+ echo ""
97
+ fi
98
+ }
99
+
100
+ # =============================================================================
101
+ # Archive Task (using common function)
102
+ # =============================================================================
103
+ archive_task() {
104
+ local worktree_path="$1"
105
+
106
+ # Find task directory from registry
107
+ local task_dir=$(registry_get_task_dir "$worktree_path" "$PROJECT_ROOT")
108
+
109
+ # Validate task path is safe
110
+ if ! is_safe_task_path "$task_dir" "$PROJECT_ROOT" 2>/dev/null; then
111
+ return 0
112
+ fi
113
+
114
+ local task_dir_abs="${PROJECT_ROOT}/${task_dir}"
115
+ if [ ! -d "$task_dir_abs" ]; then
116
+ return 0
117
+ fi
118
+
119
+ # Use common archive function
120
+ local result=$(archive_task_complete "$task_dir_abs" "$PROJECT_ROOT")
121
+
122
+ # Parse result and log
123
+ echo "$result" | while IFS= read -r line; do
124
+ case "$line" in
125
+ task_completed:*)
126
+ log_info "Completed task: ${line#task_completed:}"
127
+ ;;
128
+ archived_to:*)
129
+ local dest="${line#archived_to:}"
130
+ local task_name=$(basename "$dest")
131
+ local month_dir=$(dirname "$dest")
132
+ log_success "Archived task: $task_name -> $(basename "$month_dir")/"
133
+ ;;
134
+ esac
135
+ done
136
+ }
137
+
138
+ # =============================================================================
139
+ # Cleanup from Registry Only (no worktree)
140
+ # =============================================================================
141
+ cleanup_registry_only() {
142
+ local search="$1"
143
+
144
+ # Find agent using registry function
145
+ local agent_info=$(registry_search_agent "$search" "$PROJECT_ROOT")
146
+
147
+ if [ -z "$agent_info" ]; then
148
+ log_error "No agent found in registry matching: $search"
149
+ exit 1
150
+ fi
151
+
152
+ local agent_id=$(echo "$agent_info" | jq -r '.id')
153
+ local task_dir=$(echo "$agent_info" | jq -r '.task_dir')
154
+
155
+ echo ""
156
+ echo -e "${BLUE}=== Cleanup Agent (no worktree) ===${NC}"
157
+ echo " Agent ID: $agent_id"
158
+ echo " Task Dir: $task_dir"
159
+ echo ""
160
+
161
+ # Confirmation
162
+ if [ "$SKIP_CONFIRM" != "true" ]; then
163
+ if [ -t 0 ]; then
164
+ read -p "Archive task and remove from registry? [y/N] " -n 1 -r
165
+ echo
166
+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
167
+ log_info "Aborted"
168
+ exit 0
169
+ fi
170
+ else
171
+ log_error "Non-interactive mode detected. Use -y to skip confirmation."
172
+ exit 1
173
+ fi
174
+ fi
175
+
176
+ # 1. Archive task directory if exists
177
+ # Validate task path is safe
178
+ if ! is_safe_task_path "$task_dir" "$PROJECT_ROOT" 2>/dev/null; then
179
+ log_warn "Invalid task_dir in registry, skipping archive"
180
+ else
181
+ local task_dir_abs="${PROJECT_ROOT}/${task_dir}"
182
+ if [ -d "$task_dir_abs" ]; then
183
+ local result=$(archive_task_complete "$task_dir_abs" "$PROJECT_ROOT")
184
+
185
+ echo "$result" | while IFS= read -r line; do
186
+ case "$line" in
187
+ task_completed:*)
188
+ log_info "Completed task: ${line#task_completed:}"
189
+ ;;
190
+ archived_to:*)
191
+ local dest="${line#archived_to:}"
192
+ local task_name=$(basename "$dest")
193
+ log_success "Archived task: $task_name -> archive/$(basename "$(dirname "$dest")")/"
194
+ ;;
195
+ esac
196
+ done
197
+ fi
198
+ fi
199
+
200
+ # 2. Remove from registry
201
+ registry_remove_by_id "$agent_id" "$PROJECT_ROOT"
202
+ log_success "Removed from registry: $agent_id"
203
+
204
+ log_success "Cleanup complete"
205
+ }
206
+
207
+ # =============================================================================
208
+ # Cleanup Single Worktree
209
+ # =============================================================================
210
+ cleanup_worktree() {
211
+ local branch="$1"
212
+
213
+ cd "$PROJECT_ROOT"
214
+
215
+ # Find worktree path for branch
216
+ # porcelain format: worktree line comes BEFORE branch line, so use -B2
217
+ local worktree_info=$(git worktree list --porcelain | grep -B2 "branch refs/heads/$branch" | head -3)
218
+ local worktree_path=$(echo "$worktree_info" | grep "^worktree " | cut -d' ' -f2-)
219
+
220
+ if [ -z "$worktree_path" ]; then
221
+ # No worktree found, try to cleanup from registry only
222
+ log_warn "No worktree found for: $branch"
223
+ log_info "Trying to cleanup from registry..."
224
+ cleanup_registry_only "$branch"
225
+ return
226
+ fi
227
+
228
+ echo ""
229
+ echo -e "${BLUE}=== Cleanup Worktree ===${NC}"
230
+ echo " Branch: $branch"
231
+ echo " Worktree: $worktree_path"
232
+ echo ""
233
+
234
+ # Confirmation
235
+ if [ "$SKIP_CONFIRM" != "true" ]; then
236
+ # Check if running interactively
237
+ if [ -t 0 ]; then
238
+ read -p "Remove this worktree? [y/N] " -n 1 -r
239
+ echo
240
+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
241
+ log_info "Aborted"
242
+ exit 0
243
+ fi
244
+ else
245
+ log_error "Non-interactive mode detected. Use -y to skip confirmation."
246
+ exit 1
247
+ fi
248
+ fi
249
+
250
+ # 1. Archive task
251
+ archive_task "$worktree_path"
252
+
253
+ # 2. Remove from registry
254
+ registry_remove_by_worktree "$worktree_path" "$PROJECT_ROOT"
255
+ log_info "Removed from registry"
256
+
257
+ # 3. Remove worktree
258
+ log_info "Removing worktree..."
259
+ git worktree remove "$worktree_path" --force 2>/dev/null || rm -rf "$worktree_path"
260
+ log_success "Worktree removed"
261
+
262
+ # 4. Delete branch (optional)
263
+ if [ "$KEEP_BRANCH" != "true" ]; then
264
+ log_info "Deleting branch..."
265
+ git branch -D "$branch" 2>/dev/null || log_warn "Could not delete branch (may be checked out elsewhere)"
266
+ fi
267
+
268
+ log_success "Cleanup complete for: $branch"
269
+ }
270
+
271
+ # =============================================================================
272
+ # Cleanup Merged Worktrees
273
+ # =============================================================================
274
+ cmd_merged() {
275
+ cd "$PROJECT_ROOT"
276
+
277
+ local main_branch=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@' || echo "main")
278
+
279
+ echo -e "${BLUE}=== Finding Merged Worktrees ===${NC}"
280
+ echo ""
281
+
282
+ local merged_branches=$(git branch --merged "$main_branch" | grep -v "^\*" | grep -v "$main_branch" | tr -d ' ')
283
+
284
+ if [ -z "$merged_branches" ]; then
285
+ log_info "No merged branches found"
286
+ exit 0
287
+ fi
288
+
289
+ local worktree_branches=""
290
+ while IFS= read -r branch; do
291
+ if git worktree list | grep -q "\[$branch\]"; then
292
+ worktree_branches="$worktree_branches $branch"
293
+ echo " - $branch"
294
+ fi
295
+ done <<< "$merged_branches"
296
+
297
+ if [ -z "$worktree_branches" ]; then
298
+ log_info "No merged worktrees found"
299
+ exit 0
300
+ fi
301
+
302
+ echo ""
303
+
304
+ if [ "$SKIP_CONFIRM" != "true" ]; then
305
+ if [ -t 0 ]; then
306
+ read -p "Remove these merged worktrees? [y/N] " -n 1 -r
307
+ echo
308
+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
309
+ log_info "Aborted"
310
+ exit 0
311
+ fi
312
+ else
313
+ log_error "Non-interactive mode detected. Use -y to skip confirmation."
314
+ exit 1
315
+ fi
316
+ fi
317
+
318
+ for branch in $worktree_branches; do
319
+ cleanup_worktree "$branch"
320
+ done
321
+ }
322
+
323
+ # =============================================================================
324
+ # Cleanup All Worktrees
325
+ # =============================================================================
326
+ cmd_all() {
327
+ cd "$PROJECT_ROOT"
328
+
329
+ echo -e "${BLUE}=== All Worktrees ===${NC}"
330
+ echo ""
331
+
332
+ local worktrees=$(git worktree list --porcelain | grep "^worktree " | grep -v "$PROJECT_ROOT$" | cut -d' ' -f2-)
333
+
334
+ if [ -z "$worktrees" ]; then
335
+ log_info "No worktrees to remove"
336
+ exit 0
337
+ fi
338
+
339
+ while IFS= read -r wt; do
340
+ echo " - $wt"
341
+ done <<< "$worktrees"
342
+
343
+ echo ""
344
+
345
+ if [ "$SKIP_CONFIRM" != "true" ]; then
346
+ if [ -t 0 ]; then
347
+ echo -e "${RED}WARNING: This will remove ALL worktrees!${NC}"
348
+ read -p "Are you sure? [y/N] " -n 1 -r
349
+ echo
350
+ if [[ ! $REPLY =~ ^[Yy]$ ]]; then
351
+ log_info "Aborted"
352
+ exit 0
353
+ fi
354
+ else
355
+ log_error "Non-interactive mode detected. Use -y to skip confirmation."
356
+ exit 1
357
+ fi
358
+ fi
359
+
360
+ while IFS= read -r wt; do
361
+ local branch=$(git worktree list | grep "$wt" | awk '{print $NF}' | tr -d '[]')
362
+ if [ -n "$branch" ]; then
363
+ cleanup_worktree "$branch"
364
+ fi
365
+ done <<< "$worktrees"
366
+ }
367
+
368
+ # =============================================================================
369
+ # Main
370
+ # =============================================================================
371
+ case "${ACTION:-}" in
372
+ list)
373
+ cmd_list
374
+ ;;
375
+ merged)
376
+ cmd_merged
377
+ ;;
378
+ all)
379
+ cmd_all
380
+ ;;
381
+ *)
382
+ if [ ${#POSITIONAL_ARGS[@]} -eq 0 ]; then
383
+ echo "Usage:"
384
+ echo " $0 <branch-name> Remove specific worktree"
385
+ echo " $0 --list List all worktrees"
386
+ echo " $0 --merged Remove merged worktrees"
387
+ echo " $0 --all Remove all worktrees"
388
+ echo ""
389
+ echo "Options:"
390
+ echo " -y, --yes Skip confirmation"
391
+ echo " --keep-branch Don't delete git branch"
392
+ exit 1
393
+ fi
394
+ cleanup_worktree "${POSITIONAL_ARGS[0]}"
395
+ ;;
396
+ esac
@@ -0,0 +1,241 @@
1
+ #!/bin/bash
2
+ # =============================================================================
3
+ # Multi-Agent Pipeline: Create PR
4
+ # =============================================================================
5
+ # Usage:
6
+ # ./create-pr.sh [task-dir] [--dry-run]
7
+ #
8
+ # This script:
9
+ # 1. Stages and commits all changes (excluding workspace/)
10
+ # 2. Pushes to origin
11
+ # 3. Creates a Draft PR using `gh pr create`
12
+ # 4. Updates task.json with status="completed", pr_url, and current_phase
13
+ #
14
+ # Note: This is the only action that performs git commit, as it's the final
15
+ # step after all implementation and checks are complete.
16
+ # =============================================================================
17
+
18
+ set -e
19
+
20
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
21
+ source "$SCRIPT_DIR/../common/paths.sh"
22
+ source "$SCRIPT_DIR/../common/phase.sh"
23
+
24
+ # Colors
25
+ RED='\033[0;31m'
26
+ GREEN='\033[0;32m'
27
+ YELLOW='\033[1;33m'
28
+ BLUE='\033[0;34m'
29
+ NC='\033[0m'
30
+
31
+ REPO_ROOT=$(get_repo_root)
32
+
33
+ # =============================================================================
34
+ # Parse Arguments
35
+ # =============================================================================
36
+ TARGET_DIR=""
37
+ DRY_RUN=false
38
+
39
+ while [[ $# -gt 0 ]]; do
40
+ case "$1" in
41
+ --dry-run)
42
+ DRY_RUN=true
43
+ shift
44
+ ;;
45
+ -h|--help)
46
+ echo "Usage: $0 [task-dir] [--dry-run]"
47
+ echo ""
48
+ echo "Options:"
49
+ echo " --dry-run Show what would be done without making changes"
50
+ echo " -h, --help Show this help message"
51
+ exit 0
52
+ ;;
53
+ *)
54
+ if [[ -z "$TARGET_DIR" ]]; then
55
+ TARGET_DIR="$1"
56
+ fi
57
+ shift
58
+ ;;
59
+ esac
60
+ done
61
+
62
+ # =============================================================================
63
+ # Get Task Directory
64
+ # =============================================================================
65
+ if [[ -z "$TARGET_DIR" ]]; then
66
+ # Try to get from .current-task
67
+ CURRENT_TASK_FILE="$REPO_ROOT/.trellis/.current-task"
68
+ if [[ -f "$CURRENT_TASK_FILE" ]]; then
69
+ TARGET_DIR=$(cat "$CURRENT_TASK_FILE")
70
+ fi
71
+
72
+ if [[ -z "$TARGET_DIR" ]]; then
73
+ echo -e "${RED}Error: No task directory specified and no current task set${NC}"
74
+ echo "Usage: $0 [task-dir] [--dry-run]"
75
+ exit 1
76
+ fi
77
+ fi
78
+
79
+ # Support relative paths
80
+ if [[ ! "$TARGET_DIR" = /* ]]; then
81
+ TARGET_DIR="$REPO_ROOT/$TARGET_DIR"
82
+ fi
83
+
84
+ TASK_JSON="$TARGET_DIR/task.json"
85
+ if [[ ! -f "$TASK_JSON" ]]; then
86
+ echo -e "${RED}Error: task.json not found at $TARGET_DIR${NC}"
87
+ exit 1
88
+ fi
89
+
90
+ # =============================================================================
91
+ # Main
92
+ # =============================================================================
93
+ echo -e "${BLUE}=== Create PR ===${NC}"
94
+ if [[ "$DRY_RUN" == "true" ]]; then
95
+ echo -e "${YELLOW}[DRY-RUN MODE] No actual changes will be made${NC}"
96
+ fi
97
+ echo ""
98
+
99
+ # Read task config
100
+ TASK_NAME=$(jq -r '.name' "$TASK_JSON")
101
+ BASE_BRANCH=$(jq -r '.base_branch // "main"' "$TASK_JSON")
102
+ SCOPE=$(jq -r '.scope // "core"' "$TASK_JSON")
103
+ DEV_TYPE=$(jq -r '.dev_type // "feature"' "$TASK_JSON")
104
+
105
+ # Map dev_type to commit prefix
106
+ case "$DEV_TYPE" in
107
+ feature|frontend|backend|fullstack) COMMIT_PREFIX="feat" ;;
108
+ bugfix|fix) COMMIT_PREFIX="fix" ;;
109
+ refactor) COMMIT_PREFIX="refactor" ;;
110
+ docs) COMMIT_PREFIX="docs" ;;
111
+ test) COMMIT_PREFIX="test" ;;
112
+ *) COMMIT_PREFIX="feat" ;;
113
+ esac
114
+
115
+ echo -e "Task: ${TASK_NAME}"
116
+ echo -e "Base branch: ${BASE_BRANCH}"
117
+ echo -e "Scope: ${SCOPE}"
118
+ echo -e "Commit prefix: ${COMMIT_PREFIX}"
119
+ echo ""
120
+
121
+ # Get current branch
122
+ CURRENT_BRANCH=$(git branch --show-current)
123
+ echo -e "Current branch: ${CURRENT_BRANCH}"
124
+
125
+ # Check for changes
126
+ echo -e "${YELLOW}Checking for changes...${NC}"
127
+
128
+ # Stage changes (even in dry-run to detect what would be committed)
129
+ git add -A
130
+
131
+ # Exclude workspace and temp files
132
+ git reset ".trellis/workspace/" 2>/dev/null || true
133
+ git reset .agent-log .agent-runner.sh 2>/dev/null || true
134
+
135
+ # Check if there are staged changes
136
+ if git diff --cached --quiet 2>/dev/null; then
137
+ echo -e "${YELLOW}No staged changes to commit${NC}"
138
+
139
+ # Check for unpushed commits
140
+ UNPUSHED=$(git log "origin/${CURRENT_BRANCH}..HEAD" --oneline 2>/dev/null | wc -l | tr -d ' ' || echo "0")
141
+ if [[ "$UNPUSHED" -eq 0 ]] 2>/dev/null; then
142
+ # In dry-run, also reset the staging
143
+ if [[ "$DRY_RUN" == "true" ]]; then
144
+ git reset HEAD >/dev/null 2>&1 || true
145
+ fi
146
+ echo -e "${RED}No changes to create PR${NC}"
147
+ exit 1
148
+ fi
149
+ echo -e "Found ${UNPUSHED} unpushed commit(s)"
150
+ else
151
+ # Commit changes
152
+ echo -e "${YELLOW}Committing changes...${NC}"
153
+ COMMIT_MSG="${COMMIT_PREFIX}(${SCOPE}): ${TASK_NAME}"
154
+
155
+ if [[ "$DRY_RUN" == "true" ]]; then
156
+ echo -e "[DRY-RUN] Would commit with message: ${COMMIT_MSG}"
157
+ echo -e "[DRY-RUN] Staged files:"
158
+ git diff --cached --name-only | sed 's/^/ - /'
159
+ else
160
+ git commit -m "$COMMIT_MSG"
161
+ echo -e "${GREEN}Committed: ${COMMIT_MSG}${NC}"
162
+ fi
163
+ fi
164
+
165
+ # Push to remote
166
+ echo -e "${YELLOW}Pushing to remote...${NC}"
167
+ if [[ "$DRY_RUN" == "true" ]]; then
168
+ echo -e "[DRY-RUN] Would push to: origin/${CURRENT_BRANCH}"
169
+ else
170
+ git push -u origin "$CURRENT_BRANCH"
171
+ echo -e "${GREEN}Pushed to origin/${CURRENT_BRANCH}${NC}"
172
+ fi
173
+
174
+ # Create PR
175
+ echo -e "${YELLOW}Creating PR...${NC}"
176
+ PR_TITLE="${COMMIT_PREFIX}(${SCOPE}): ${TASK_NAME}"
177
+ PR_URL=""
178
+
179
+ if [[ "$DRY_RUN" == "true" ]]; then
180
+ echo -e "[DRY-RUN] Would create PR:"
181
+ echo -e " Title: ${PR_TITLE}"
182
+ echo -e " Base: ${BASE_BRANCH}"
183
+ echo -e " Head: ${CURRENT_BRANCH}"
184
+ if [[ -f "$TARGET_DIR/prd.md" ]]; then
185
+ echo -e " Body: (from prd.md)"
186
+ fi
187
+ PR_URL="https://github.com/example/repo/pull/DRY-RUN"
188
+ else
189
+ # Check if PR already exists
190
+ EXISTING_PR=$(gh pr list --head "$CURRENT_BRANCH" --base "$BASE_BRANCH" --json url --jq '.[0].url' 2>/dev/null || echo "")
191
+
192
+ if [[ -n "$EXISTING_PR" ]]; then
193
+ echo -e "${YELLOW}PR already exists: ${EXISTING_PR}${NC}"
194
+ PR_URL="$EXISTING_PR"
195
+ else
196
+ # Read PRD as PR body
197
+ PR_BODY=""
198
+ if [[ -f "$TARGET_DIR/prd.md" ]]; then
199
+ PR_BODY=$(cat "$TARGET_DIR/prd.md")
200
+ fi
201
+
202
+ # Create PR
203
+ PR_URL=$(gh pr create \
204
+ --draft \
205
+ --base "$BASE_BRANCH" \
206
+ --title "$PR_TITLE" \
207
+ --body "$PR_BODY" \
208
+ 2>&1)
209
+
210
+ echo -e "${GREEN}PR created: ${PR_URL}${NC}"
211
+ fi
212
+ fi
213
+
214
+ # Update task.json
215
+ echo -e "${YELLOW}Updating task status...${NC}"
216
+ if [[ "$DRY_RUN" == "true" ]]; then
217
+ echo -e "[DRY-RUN] Would update task.json:"
218
+ echo -e " status: completed"
219
+ echo -e " pr_url: ${PR_URL}"
220
+ echo -e " current_phase: (set to create-pr phase)"
221
+ else
222
+ # Get the phase number for create-pr action using common/phase.sh
223
+ CREATE_PR_PHASE=$(get_phase_for_action "$TASK_JSON" "create-pr")
224
+ if [[ -z "$CREATE_PR_PHASE" ]] || [[ "$CREATE_PR_PHASE" == "0" ]]; then
225
+ CREATE_PR_PHASE=4 # Default fallback
226
+ fi
227
+
228
+ jq --arg url "$PR_URL" --argjson phase "$CREATE_PR_PHASE" \
229
+ '.status = "completed" | .pr_url = $url | .current_phase = $phase' "$TASK_JSON" > "${TASK_JSON}.tmp"
230
+ mv "${TASK_JSON}.tmp" "$TASK_JSON"
231
+ echo -e "${GREEN}Task status updated to 'completed', phase ${CREATE_PR_PHASE}${NC}"
232
+ fi
233
+
234
+ # In dry-run, reset the staging area
235
+ if [[ "$DRY_RUN" == "true" ]]; then
236
+ git reset HEAD >/dev/null 2>&1 || true
237
+ fi
238
+
239
+ echo ""
240
+ echo -e "${GREEN}=== PR Created Successfully ===${NC}"
241
+ echo -e "PR URL: ${PR_URL}"