@fifine/aim-studio 0.0.3 → 0.0.5

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 (98) hide show
  1. package/README.md +65 -99
  2. package/dist/commands/init.d.ts.map +1 -1
  3. package/dist/commands/init.js +3 -5
  4. package/dist/commands/init.js.map +1 -1
  5. package/dist/configurators/workflow.d.ts.map +1 -1
  6. package/dist/configurators/workflow.js +4 -104
  7. package/dist/configurators/workflow.js.map +1 -1
  8. package/dist/constants/paths.d.ts +5 -5
  9. package/dist/constants/paths.d.ts.map +1 -1
  10. package/dist/constants/paths.js +5 -5
  11. package/dist/constants/paths.js.map +1 -1
  12. package/dist/templates/aim/index.d.ts +1 -0
  13. package/dist/templates/aim/index.d.ts.map +1 -1
  14. package/dist/templates/aim/index.js +2 -0
  15. package/dist/templates/aim/index.js.map +1 -1
  16. package/dist/templates/aim/scripts/common/developer.py +2 -1
  17. package/dist/templates/aim/scripts/export.py +306 -15
  18. package/dist/templates/aim/workflow.md +12 -13
  19. package/dist/templates/claude/commands/aim/export.md +208 -32
  20. package/dist/templates/claude/commands/aim/finish-work.md +23 -0
  21. package/dist/templates/claude/commands/aim/legitimize.md +250 -0
  22. package/dist/templates/claude/commands/aim/start.md +92 -179
  23. package/dist/templates/claude/commands/aim/story.md +303 -67
  24. package/dist/templates/markdown/index.d.ts +1 -0
  25. package/dist/templates/markdown/index.d.ts.map +1 -1
  26. package/dist/templates/markdown/index.js +1 -0
  27. package/dist/templates/markdown/index.js.map +1 -1
  28. package/dist/templates/markdown/spec/story/style-guide.md.txt +96 -0
  29. package/package.json +1 -1
  30. package/dist/migrations/manifests/0.3.0-rc.2.json +0 -9
  31. package/dist/templates/aim/scripts/multi_agent/__init__.py +0 -5
  32. package/dist/templates/aim/scripts/multi_agent/cleanup.py +0 -403
  33. package/dist/templates/aim/scripts/multi_agent/create_pr.py +0 -329
  34. package/dist/templates/aim/scripts/multi_agent/plan.py +0 -233
  35. package/dist/templates/aim/scripts/multi_agent/start.py +0 -461
  36. package/dist/templates/aim/scripts/multi_agent/status.py +0 -817
  37. package/dist/templates/aim/scripts-shell-archive/add-session.sh +0 -384
  38. package/dist/templates/aim/scripts-shell-archive/common/developer.sh +0 -129
  39. package/dist/templates/aim/scripts-shell-archive/common/git-context.sh +0 -263
  40. package/dist/templates/aim/scripts-shell-archive/common/paths.sh +0 -208
  41. package/dist/templates/aim/scripts-shell-archive/common/phase.sh +0 -150
  42. package/dist/templates/aim/scripts-shell-archive/common/registry.sh +0 -247
  43. package/dist/templates/aim/scripts-shell-archive/common/task-queue.sh +0 -142
  44. package/dist/templates/aim/scripts-shell-archive/common/task-utils.sh +0 -151
  45. package/dist/templates/aim/scripts-shell-archive/common/worktree.sh +0 -128
  46. package/dist/templates/aim/scripts-shell-archive/create-bootstrap.sh +0 -299
  47. package/dist/templates/aim/scripts-shell-archive/get-context.sh +0 -7
  48. package/dist/templates/aim/scripts-shell-archive/get-developer.sh +0 -15
  49. package/dist/templates/aim/scripts-shell-archive/init-developer.sh +0 -34
  50. package/dist/templates/aim/scripts-shell-archive/multi-agent/cleanup.sh +0 -396
  51. package/dist/templates/aim/scripts-shell-archive/multi-agent/create-pr.sh +0 -241
  52. package/dist/templates/aim/scripts-shell-archive/multi-agent/plan.sh +0 -207
  53. package/dist/templates/aim/scripts-shell-archive/multi-agent/start.sh +0 -317
  54. package/dist/templates/aim/scripts-shell-archive/multi-agent/status.sh +0 -828
  55. package/dist/templates/aim/scripts-shell-archive/task.sh +0 -1204
  56. package/dist/templates/claude/agents/check.md +0 -122
  57. package/dist/templates/claude/agents/debug.md +0 -106
  58. package/dist/templates/claude/agents/dispatch.md +0 -230
  59. package/dist/templates/claude/agents/implement.md +0 -96
  60. package/dist/templates/claude/agents/plan.md +0 -396
  61. package/dist/templates/claude/agents/research.md +0 -120
  62. package/dist/templates/claude/commands/aim/before-backend-dev.md +0 -13
  63. package/dist/templates/claude/commands/aim/before-frontend-dev.md +0 -13
  64. package/dist/templates/claude/commands/aim/break-loop.md +0 -153
  65. package/dist/templates/claude/commands/aim/check-backend.md +0 -13
  66. package/dist/templates/claude/commands/aim/check-cross-layer.md +0 -153
  67. package/dist/templates/claude/commands/aim/check-frontend.md +0 -13
  68. package/dist/templates/claude/commands/aim/create-command.md +0 -154
  69. package/dist/templates/claude/commands/aim/integrate-skill.md +0 -219
  70. package/dist/templates/claude/commands/aim/parallel.md +0 -217
  71. package/dist/templates/claude/commands/aim/update-spec.md +0 -285
  72. package/dist/templates/claude/hooks/ralph-loop.py +0 -388
  73. package/dist/templates/markdown/spec/backend/database-guidelines.md.txt +0 -51
  74. package/dist/templates/markdown/spec/backend/directory-structure.md.txt +0 -54
  75. package/dist/templates/markdown/spec/backend/error-handling.md.txt +0 -51
  76. package/dist/templates/markdown/spec/backend/index.md +0 -40
  77. package/dist/templates/markdown/spec/backend/index.md.txt +0 -38
  78. package/dist/templates/markdown/spec/backend/logging-guidelines.md.txt +0 -51
  79. package/dist/templates/markdown/spec/backend/quality-guidelines.md.txt +0 -51
  80. package/dist/templates/markdown/spec/backend/script-conventions.md +0 -467
  81. package/dist/templates/markdown/spec/cli/directory-structure.md.txt +0 -71
  82. package/dist/templates/markdown/spec/cli/error-handling.md.txt +0 -91
  83. package/dist/templates/markdown/spec/cli/index.md.txt +0 -37
  84. package/dist/templates/markdown/spec/cli/options-flags.md.txt +0 -71
  85. package/dist/templates/markdown/spec/cli/output-formatting.md.txt +0 -93
  86. package/dist/templates/markdown/spec/frontend/component-guidelines.md.txt +0 -59
  87. package/dist/templates/markdown/spec/frontend/directory-structure.md.txt +0 -54
  88. package/dist/templates/markdown/spec/frontend/hook-guidelines.md.txt +0 -51
  89. package/dist/templates/markdown/spec/frontend/index.md.txt +0 -39
  90. package/dist/templates/markdown/spec/frontend/quality-guidelines.md.txt +0 -51
  91. package/dist/templates/markdown/spec/frontend/state-management.md.txt +0 -51
  92. package/dist/templates/markdown/spec/frontend/type-safety.md.txt +0 -51
  93. package/dist/templates/markdown/spec/guides/code-reuse-thinking-guide.md +0 -118
  94. package/dist/templates/markdown/spec/guides/code-reuse-thinking-guide.md.txt +0 -92
  95. package/dist/templates/markdown/spec/guides/cross-layer-thinking-guide.md.txt +0 -94
  96. package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md +0 -394
  97. package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +0 -319
  98. package/dist/templates/markdown/spec/guides/index.md.txt +0 -89
@@ -1,403 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Multi-Agent Pipeline: Cleanup Worktree.
4
-
5
- Usage:
6
- python3 cleanup.py <branch-name> Remove specific worktree
7
- python3 cleanup.py --list List all worktrees
8
- python3 cleanup.py --merged Remove merged worktrees
9
- python3 cleanup.py --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
- from __future__ import annotations
23
-
24
- import argparse
25
- import shutil
26
- import subprocess
27
- import sys
28
- from pathlib import Path
29
-
30
- # Add parent directory to path for imports
31
- sys.path.insert(0, str(Path(__file__).parent.parent))
32
-
33
- from common.git_context import _run_git_command
34
- from common.paths import get_repo_root
35
- from common.registry import (
36
- registry_get_file,
37
- registry_get_task_dir,
38
- registry_remove_by_id,
39
- registry_remove_by_worktree,
40
- registry_search_agent,
41
- )
42
- from common.task_utils import (
43
- archive_task_complete,
44
- is_safe_task_path,
45
- )
46
-
47
- # =============================================================================
48
- # Colors
49
- # =============================================================================
50
-
51
-
52
- class Colors:
53
- RED = "\033[0;31m"
54
- GREEN = "\033[0;32m"
55
- YELLOW = "\033[1;33m"
56
- BLUE = "\033[0;34m"
57
- NC = "\033[0m"
58
-
59
-
60
- def log_info(msg: str) -> None:
61
- print(f"{Colors.BLUE}[INFO]{Colors.NC} {msg}")
62
-
63
-
64
- def log_success(msg: str) -> None:
65
- print(f"{Colors.GREEN}[SUCCESS]{Colors.NC} {msg}")
66
-
67
-
68
- def log_warn(msg: str) -> None:
69
- print(f"{Colors.YELLOW}[WARN]{Colors.NC} {msg}")
70
-
71
-
72
- def log_error(msg: str) -> None:
73
- print(f"{Colors.RED}[ERROR]{Colors.NC} {msg}")
74
-
75
-
76
- # =============================================================================
77
- # Helper Functions
78
- # =============================================================================
79
-
80
-
81
- def confirm(prompt: str, skip_confirm: bool) -> bool:
82
- """Ask for confirmation."""
83
- if skip_confirm:
84
- return True
85
-
86
- if not sys.stdin.isatty():
87
- log_error("Non-interactive mode detected. Use -y to skip confirmation.")
88
- return False
89
-
90
- response = input(f"{prompt} [y/N] ")
91
- return response.lower() in ("y", "yes")
92
-
93
-
94
- # =============================================================================
95
- # Commands
96
- # =============================================================================
97
-
98
-
99
- def cmd_list(repo_root: Path) -> int:
100
- """List worktrees."""
101
- print(f"{Colors.BLUE}=== Git Worktrees ==={Colors.NC}")
102
- print()
103
-
104
- subprocess.run(["git", "worktree", "list"], cwd=repo_root)
105
- print()
106
-
107
- # Show registry info
108
- registry_file = registry_get_file(repo_root)
109
- if registry_file and registry_file.is_file():
110
- print(f"{Colors.BLUE}=== Registered Agents ==={Colors.NC}")
111
- print()
112
-
113
- import json
114
-
115
- data = json.loads(registry_file.read_text(encoding="utf-8"))
116
- agents = data.get("agents", [])
117
-
118
- if agents:
119
- for agent in agents:
120
- print(
121
- f" {agent.get('id', '?')}: PID={agent.get('pid', '?')} [{agent.get('worktree_path', '?')}]"
122
- )
123
- else:
124
- print(" (none)")
125
- print()
126
-
127
- return 0
128
-
129
-
130
- def archive_task(worktree_path: str, repo_root: Path) -> None:
131
- """Archive task directory."""
132
- task_dir = registry_get_task_dir(worktree_path, repo_root)
133
-
134
- if not task_dir or not is_safe_task_path(task_dir, repo_root):
135
- return
136
-
137
- task_dir_abs = repo_root / task_dir
138
- if not task_dir_abs.is_dir():
139
- return
140
-
141
- result = archive_task_complete(task_dir_abs, repo_root)
142
- if "archived_to" in result:
143
- dest = Path(result["archived_to"])
144
- log_success(f"Archived task: {dest.name} -> archive/{dest.parent.name}/")
145
-
146
-
147
- def cleanup_registry_only(search: str, repo_root: Path, skip_confirm: bool) -> int:
148
- """Cleanup from registry only (no worktree)."""
149
- agent_info = registry_search_agent(search, repo_root)
150
-
151
- if not agent_info:
152
- log_error(f"No agent found in registry matching: {search}")
153
- return 1
154
-
155
- agent_id = agent_info.get("id", "?")
156
- task_dir = agent_info.get("task_dir", "?")
157
-
158
- print()
159
- print(f"{Colors.BLUE}=== Cleanup Agent (no worktree) ==={Colors.NC}")
160
- print(f" Agent ID: {agent_id}")
161
- print(f" Task Dir: {task_dir}")
162
- print()
163
-
164
- if not confirm("Archive task and remove from registry?", skip_confirm):
165
- log_info("Aborted")
166
- return 0
167
-
168
- # Archive task directory if exists
169
- if task_dir and is_safe_task_path(task_dir, repo_root):
170
- task_dir_abs = repo_root / task_dir
171
- if task_dir_abs.is_dir():
172
- result = archive_task_complete(task_dir_abs, repo_root)
173
- if "archived_to" in result:
174
- dest = Path(result["archived_to"])
175
- log_success(
176
- f"Archived task: {dest.name} -> archive/{dest.parent.name}/"
177
- )
178
- else:
179
- log_warn("Invalid task_dir in registry, skipping archive")
180
-
181
- # Remove from registry
182
- registry_remove_by_id(agent_id, repo_root)
183
- log_success(f"Removed from registry: {agent_id}")
184
-
185
- log_success("Cleanup complete")
186
- return 0
187
-
188
-
189
- def cleanup_worktree(
190
- branch: str, repo_root: Path, skip_confirm: bool, keep_branch: bool
191
- ) -> int:
192
- """Cleanup single worktree."""
193
- # Find worktree path for branch
194
- _, worktree_list, _ = _run_git_command(
195
- ["worktree", "list", "--porcelain"], cwd=repo_root
196
- )
197
-
198
- worktree_path = None
199
- current_worktree = None
200
-
201
- for line in worktree_list.splitlines():
202
- if line.startswith("worktree "):
203
- current_worktree = line[9:] # Remove "worktree " prefix
204
- elif line.startswith("branch refs/heads/"):
205
- current_branch = line[18:] # Remove "branch refs/heads/" prefix
206
- if current_branch == branch:
207
- worktree_path = current_worktree
208
- break
209
-
210
- if not worktree_path:
211
- # No worktree found, try to cleanup from registry only
212
- log_warn(f"No worktree found for: {branch}")
213
- log_info("Trying to cleanup from registry...")
214
- return cleanup_registry_only(branch, repo_root, skip_confirm)
215
-
216
- print()
217
- print(f"{Colors.BLUE}=== Cleanup Worktree ==={Colors.NC}")
218
- print(f" Branch: {branch}")
219
- print(f" Worktree: {worktree_path}")
220
- print()
221
-
222
- if not confirm("Remove this worktree?", skip_confirm):
223
- log_info("Aborted")
224
- return 0
225
-
226
- # 1. Archive task
227
- archive_task(worktree_path, repo_root)
228
-
229
- # 2. Remove from registry
230
- registry_remove_by_worktree(worktree_path, repo_root)
231
- log_info("Removed from registry")
232
-
233
- # 3. Remove worktree
234
- log_info("Removing worktree...")
235
- ret, _, _ = _run_git_command(
236
- ["worktree", "remove", worktree_path, "--force"], cwd=repo_root
237
- )
238
- if ret != 0:
239
- # Try removing directory manually
240
- try:
241
- shutil.rmtree(worktree_path)
242
- except Exception as e:
243
- log_error(f"Failed to remove worktree: {e}")
244
-
245
- log_success("Worktree removed")
246
-
247
- # 4. Delete branch (optional)
248
- if not keep_branch:
249
- log_info("Deleting branch...")
250
- ret, _, _ = _run_git_command(["branch", "-D", branch], cwd=repo_root)
251
- if ret != 0:
252
- log_warn("Could not delete branch (may be checked out elsewhere)")
253
-
254
- log_success(f"Cleanup complete for: {branch}")
255
- return 0
256
-
257
-
258
- def cmd_merged(repo_root: Path, skip_confirm: bool, keep_branch: bool) -> int:
259
- """Cleanup merged worktrees."""
260
- # Get main branch
261
- _, head_out, _ = _run_git_command(
262
- ["symbolic-ref", "refs/remotes/origin/HEAD"], cwd=repo_root
263
- )
264
- main_branch = head_out.strip().replace("refs/remotes/origin/", "") or "main"
265
-
266
- print(f"{Colors.BLUE}=== Finding Merged Worktrees ==={Colors.NC}")
267
- print()
268
-
269
- # Get merged branches
270
- _, merged_out, _ = _run_git_command(
271
- ["branch", "--merged", main_branch], cwd=repo_root
272
- )
273
- merged_branches = []
274
- for line in merged_out.splitlines():
275
- branch = line.strip().lstrip("* ")
276
- if branch and branch != main_branch:
277
- merged_branches.append(branch)
278
-
279
- if not merged_branches:
280
- log_info("No merged branches found")
281
- return 0
282
-
283
- # Get worktree list
284
- _, worktree_list, _ = _run_git_command(["worktree", "list"], cwd=repo_root)
285
-
286
- worktree_branches = []
287
- for branch in merged_branches:
288
- if f"[{branch}]" in worktree_list:
289
- worktree_branches.append(branch)
290
- print(f" - {branch}")
291
-
292
- if not worktree_branches:
293
- log_info("No merged worktrees found")
294
- return 0
295
-
296
- print()
297
- if not confirm("Remove these merged worktrees?", skip_confirm):
298
- log_info("Aborted")
299
- return 0
300
-
301
- for branch in worktree_branches:
302
- cleanup_worktree(branch, repo_root, True, keep_branch)
303
-
304
- return 0
305
-
306
-
307
- def cmd_all(repo_root: Path, skip_confirm: bool, keep_branch: bool) -> int:
308
- """Cleanup all worktrees."""
309
- print(f"{Colors.BLUE}=== All Worktrees ==={Colors.NC}")
310
- print()
311
-
312
- # Get worktree list
313
- _, worktree_list, _ = _run_git_command(
314
- ["worktree", "list", "--porcelain"], cwd=repo_root
315
- )
316
-
317
- worktrees = []
318
- main_worktree = str(repo_root.resolve())
319
-
320
- for line in worktree_list.splitlines():
321
- if line.startswith("worktree "):
322
- wt = line[9:]
323
- if wt != main_worktree:
324
- worktrees.append(wt)
325
-
326
- if not worktrees:
327
- log_info("No worktrees to remove")
328
- return 0
329
-
330
- for wt in worktrees:
331
- print(f" - {wt}")
332
-
333
- print()
334
- print(f"{Colors.RED}WARNING: This will remove ALL worktrees!{Colors.NC}")
335
-
336
- if not confirm("Are you sure?", skip_confirm):
337
- log_info("Aborted")
338
- return 0
339
-
340
- # Get branch for each worktree
341
- for wt in worktrees:
342
- # Find branch name from worktree list
343
- _, wt_list, _ = _run_git_command(["worktree", "list"], cwd=repo_root)
344
- for line in wt_list.splitlines():
345
- if wt in line:
346
- # Extract branch from [branch] format
347
- import re
348
-
349
- match = re.search(r"\[([^\]]+)\]", line)
350
- if match:
351
- branch = match.group(1)
352
- cleanup_worktree(branch, repo_root, True, keep_branch)
353
- break
354
-
355
- return 0
356
-
357
-
358
- # =============================================================================
359
- # Main
360
- # =============================================================================
361
-
362
-
363
- def main() -> int:
364
- """Main entry point."""
365
- parser = argparse.ArgumentParser(
366
- description="Multi-Agent Pipeline: Cleanup Worktree"
367
- )
368
- parser.add_argument("branch", nargs="?", help="Branch name to cleanup")
369
- parser.add_argument("-y", "--yes", action="store_true", help="Skip confirmation")
370
- parser.add_argument(
371
- "--keep-branch", action="store_true", help="Don't delete git branch"
372
- )
373
- parser.add_argument("--list", action="store_true", help="List all worktrees")
374
- parser.add_argument("--merged", action="store_true", help="Remove merged worktrees")
375
- parser.add_argument("--all", action="store_true", help="Remove all worktrees")
376
-
377
- args = parser.parse_args()
378
- repo_root = get_repo_root()
379
-
380
- if args.list:
381
- return cmd_list(repo_root)
382
- elif args.merged:
383
- return cmd_merged(repo_root, args.yes, args.keep_branch)
384
- elif args.all:
385
- return cmd_all(repo_root, args.yes, args.keep_branch)
386
- elif args.branch:
387
- return cleanup_worktree(args.branch, repo_root, args.yes, args.keep_branch)
388
- else:
389
- print("""Usage:
390
- python3 cleanup.py <branch-name> Remove specific worktree
391
- python3 cleanup.py --list List all worktrees
392
- python3 cleanup.py --merged Remove merged worktrees
393
- python3 cleanup.py --all Remove all worktrees
394
-
395
- Options:
396
- -y, --yes Skip confirmation
397
- --keep-branch Don't delete git branch
398
- """)
399
- return 1
400
-
401
-
402
- if __name__ == "__main__":
403
- sys.exit(main())