@fifine/aim-studio 0.0.4 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +59 -41
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +3 -5
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +42 -8
- package/dist/commands/update.js.map +1 -1
- package/dist/configurators/workflow.d.ts.map +1 -1
- package/dist/configurators/workflow.js +4 -104
- package/dist/configurators/workflow.js.map +1 -1
- package/dist/templates/aim/scripts/export.py +2 -2
- package/dist/templates/claude/commands/aim/legitimize.md +268 -0
- package/dist/templates/claude/commands/aim/start.md +92 -179
- package/dist/templates/claude/commands/aim/story.md +60 -10
- package/dist/templates/markdown/index.d.ts +1 -0
- package/dist/templates/markdown/index.d.ts.map +1 -1
- package/dist/templates/markdown/index.js +1 -0
- package/dist/templates/markdown/index.js.map +1 -1
- package/dist/templates/markdown/spec/story/style-guide.md.txt +96 -0
- package/package.json +1 -1
- package/dist/migrations/manifests/0.3.0-rc.2.json +0 -9
- package/dist/templates/aim/scripts/multi_agent/__init__.py +0 -5
- package/dist/templates/aim/scripts/multi_agent/cleanup.py +0 -403
- package/dist/templates/aim/scripts/multi_agent/create_pr.py +0 -329
- package/dist/templates/aim/scripts/multi_agent/plan.py +0 -233
- package/dist/templates/aim/scripts/multi_agent/start.py +0 -461
- package/dist/templates/aim/scripts/multi_agent/status.py +0 -817
- package/dist/templates/aim/scripts-shell-archive/add-session.sh +0 -384
- package/dist/templates/aim/scripts-shell-archive/common/developer.sh +0 -129
- package/dist/templates/aim/scripts-shell-archive/common/git-context.sh +0 -263
- package/dist/templates/aim/scripts-shell-archive/common/paths.sh +0 -208
- package/dist/templates/aim/scripts-shell-archive/common/phase.sh +0 -150
- package/dist/templates/aim/scripts-shell-archive/common/registry.sh +0 -247
- package/dist/templates/aim/scripts-shell-archive/common/task-queue.sh +0 -142
- package/dist/templates/aim/scripts-shell-archive/common/task-utils.sh +0 -151
- package/dist/templates/aim/scripts-shell-archive/common/worktree.sh +0 -128
- package/dist/templates/aim/scripts-shell-archive/create-bootstrap.sh +0 -299
- package/dist/templates/aim/scripts-shell-archive/get-context.sh +0 -7
- package/dist/templates/aim/scripts-shell-archive/get-developer.sh +0 -15
- package/dist/templates/aim/scripts-shell-archive/init-developer.sh +0 -34
- package/dist/templates/aim/scripts-shell-archive/multi-agent/cleanup.sh +0 -396
- package/dist/templates/aim/scripts-shell-archive/multi-agent/create-pr.sh +0 -241
- package/dist/templates/aim/scripts-shell-archive/multi-agent/plan.sh +0 -207
- package/dist/templates/aim/scripts-shell-archive/multi-agent/start.sh +0 -317
- package/dist/templates/aim/scripts-shell-archive/multi-agent/status.sh +0 -828
- package/dist/templates/aim/scripts-shell-archive/task.sh +0 -1204
- package/dist/templates/claude/agents/check.md +0 -122
- package/dist/templates/claude/agents/debug.md +0 -106
- package/dist/templates/claude/agents/dispatch.md +0 -230
- package/dist/templates/claude/agents/implement.md +0 -96
- package/dist/templates/claude/agents/plan.md +0 -396
- package/dist/templates/claude/agents/research.md +0 -120
- package/dist/templates/claude/commands/aim/before-backend-dev.md +0 -13
- package/dist/templates/claude/commands/aim/before-frontend-dev.md +0 -13
- package/dist/templates/claude/commands/aim/break-loop.md +0 -153
- package/dist/templates/claude/commands/aim/check-backend.md +0 -13
- package/dist/templates/claude/commands/aim/check-cross-layer.md +0 -153
- package/dist/templates/claude/commands/aim/check-frontend.md +0 -13
- package/dist/templates/claude/commands/aim/create-command.md +0 -154
- package/dist/templates/claude/commands/aim/integrate-skill.md +0 -219
- package/dist/templates/claude/commands/aim/parallel.md +0 -217
- package/dist/templates/claude/commands/aim/update-spec.md +0 -285
- package/dist/templates/claude/hooks/ralph-loop.py +0 -388
- package/dist/templates/markdown/spec/backend/database-guidelines.md.txt +0 -51
- package/dist/templates/markdown/spec/backend/directory-structure.md.txt +0 -54
- package/dist/templates/markdown/spec/backend/error-handling.md.txt +0 -51
- package/dist/templates/markdown/spec/backend/index.md +0 -40
- package/dist/templates/markdown/spec/backend/index.md.txt +0 -38
- package/dist/templates/markdown/spec/backend/logging-guidelines.md.txt +0 -51
- package/dist/templates/markdown/spec/backend/quality-guidelines.md.txt +0 -51
- package/dist/templates/markdown/spec/backend/script-conventions.md +0 -467
- package/dist/templates/markdown/spec/cli/directory-structure.md.txt +0 -71
- package/dist/templates/markdown/spec/cli/error-handling.md.txt +0 -91
- package/dist/templates/markdown/spec/cli/index.md.txt +0 -37
- package/dist/templates/markdown/spec/cli/options-flags.md.txt +0 -71
- package/dist/templates/markdown/spec/cli/output-formatting.md.txt +0 -93
- package/dist/templates/markdown/spec/frontend/component-guidelines.md.txt +0 -59
- package/dist/templates/markdown/spec/frontend/directory-structure.md.txt +0 -54
- package/dist/templates/markdown/spec/frontend/hook-guidelines.md.txt +0 -51
- package/dist/templates/markdown/spec/frontend/index.md.txt +0 -39
- package/dist/templates/markdown/spec/frontend/quality-guidelines.md.txt +0 -51
- package/dist/templates/markdown/spec/frontend/state-management.md.txt +0 -51
- package/dist/templates/markdown/spec/frontend/type-safety.md.txt +0 -51
- package/dist/templates/markdown/spec/guides/code-reuse-thinking-guide.md +0 -118
- package/dist/templates/markdown/spec/guides/code-reuse-thinking-guide.md.txt +0 -92
- package/dist/templates/markdown/spec/guides/cross-layer-thinking-guide.md.txt +0 -94
- package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md +0 -394
- package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +0 -319
- package/dist/templates/markdown/spec/guides/index.md.txt +0 -89
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
# Quality Guidelines
|
|
2
|
-
|
|
3
|
-
> Code quality standards for backend development.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Overview
|
|
8
|
-
|
|
9
|
-
<!--
|
|
10
|
-
Document your project's quality standards here.
|
|
11
|
-
|
|
12
|
-
Questions to answer:
|
|
13
|
-
- What patterns are forbidden?
|
|
14
|
-
- What linting rules do you enforce?
|
|
15
|
-
- What are your testing requirements?
|
|
16
|
-
- What code review standards apply?
|
|
17
|
-
-->
|
|
18
|
-
|
|
19
|
-
(To be filled by the team)
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
## Forbidden Patterns
|
|
24
|
-
|
|
25
|
-
<!-- Patterns that should never be used and why -->
|
|
26
|
-
|
|
27
|
-
(To be filled by the team)
|
|
28
|
-
|
|
29
|
-
---
|
|
30
|
-
|
|
31
|
-
## Required Patterns
|
|
32
|
-
|
|
33
|
-
<!-- Patterns that must always be used -->
|
|
34
|
-
|
|
35
|
-
(To be filled by the team)
|
|
36
|
-
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
## Testing Requirements
|
|
40
|
-
|
|
41
|
-
<!-- What level of testing is expected -->
|
|
42
|
-
|
|
43
|
-
(To be filled by the team)
|
|
44
|
-
|
|
45
|
-
---
|
|
46
|
-
|
|
47
|
-
## Code Review Checklist
|
|
48
|
-
|
|
49
|
-
<!-- What reviewers should check -->
|
|
50
|
-
|
|
51
|
-
(To be filled by the team)
|
|
@@ -1,467 +0,0 @@
|
|
|
1
|
-
# Script Conventions
|
|
2
|
-
|
|
3
|
-
> Standards for Python scripts in the `.aim-studio/scripts/` directory.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Overview
|
|
8
|
-
|
|
9
|
-
All workflow scripts are written in **Python 3.10+** for cross-platform compatibility. Scripts use only the standard library (no external dependencies).
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## Directory Structure
|
|
14
|
-
|
|
15
|
-
```
|
|
16
|
-
.aim-studio/scripts/
|
|
17
|
-
├── __init__.py # Package init
|
|
18
|
-
├── common/ # Shared modules
|
|
19
|
-
│ ├── __init__.py
|
|
20
|
-
│ ├── paths.py # Path constants and functions
|
|
21
|
-
│ ├── developer.py # Developer identity management
|
|
22
|
-
│ ├── task_queue.py # Task queue CRUD
|
|
23
|
-
│ ├── task_utils.py # Task helper functions
|
|
24
|
-
│ ├── phase.py # Multi-agent phase tracking
|
|
25
|
-
│ ├── registry.py # Agent registry management
|
|
26
|
-
│ ├── worktree.py # Git worktree utilities
|
|
27
|
-
│ └── git_context.py # Git/session context
|
|
28
|
-
├── multi_agent/ # Multi-agent pipeline scripts
|
|
29
|
-
│ ├── __init__.py
|
|
30
|
-
│ ├── start.py # Start worktree agent
|
|
31
|
-
│ ├── status.py # Monitor agent status
|
|
32
|
-
│ ├── plan.py # Start plan agent
|
|
33
|
-
│ ├── cleanup.py # Cleanup worktree
|
|
34
|
-
│ └── create_pr.py # Create PR from task
|
|
35
|
-
├── task.py # Main task management CLI
|
|
36
|
-
├── get_context.py # Session context retrieval
|
|
37
|
-
├── init_developer.py # Developer initialization
|
|
38
|
-
├── get_developer.py # Get current developer
|
|
39
|
-
├── add_session.py # Session recording
|
|
40
|
-
└── create_bootstrap.py # Bootstrap task creation
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
---
|
|
44
|
-
|
|
45
|
-
## Script Types
|
|
46
|
-
|
|
47
|
-
### Library Modules (`common/*.py`)
|
|
48
|
-
|
|
49
|
-
Shared utilities imported by other scripts. **Never run directly.**
|
|
50
|
-
|
|
51
|
-
```python
|
|
52
|
-
# common/paths.py - Example library module
|
|
53
|
-
|
|
54
|
-
from __future__ import annotations
|
|
55
|
-
|
|
56
|
-
from pathlib import Path
|
|
57
|
-
|
|
58
|
-
# Constants
|
|
59
|
-
DIR_WORKFLOW = ".aim-studio"
|
|
60
|
-
DIR_SCRIPTS = "scripts"
|
|
61
|
-
DIR_TASKS = "tasks"
|
|
62
|
-
|
|
63
|
-
def get_repo_root() -> Path | None:
|
|
64
|
-
"""Find repository root by looking for .aim-studio directory."""
|
|
65
|
-
current = Path.cwd().resolve()
|
|
66
|
-
while current != current.parent:
|
|
67
|
-
if (current / DIR_WORKFLOW).is_dir():
|
|
68
|
-
return current
|
|
69
|
-
current = current.parent
|
|
70
|
-
return None
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
### Entry Scripts (`*.py`)
|
|
74
|
-
|
|
75
|
-
CLI tools that users run directly. Include docstring with usage.
|
|
76
|
-
|
|
77
|
-
```python
|
|
78
|
-
#!/usr/bin/env python3
|
|
79
|
-
"""
|
|
80
|
-
Task Management Script.
|
|
81
|
-
|
|
82
|
-
Usage:
|
|
83
|
-
python3 task.py create "<title>" [--slug <name>]
|
|
84
|
-
python3 task.py list [--mine] [--status <status>]
|
|
85
|
-
python3 task.py start <dir>
|
|
86
|
-
python3 task.py finish
|
|
87
|
-
python3 task.py archive <task-name>
|
|
88
|
-
"""
|
|
89
|
-
|
|
90
|
-
from __future__ import annotations
|
|
91
|
-
|
|
92
|
-
import argparse
|
|
93
|
-
import sys
|
|
94
|
-
from pathlib import Path
|
|
95
|
-
|
|
96
|
-
from common.paths import get_repo_root, DIR_WORKFLOW
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
def main() -> int:
|
|
100
|
-
"""Main entry point."""
|
|
101
|
-
parser = argparse.ArgumentParser(description="Task management")
|
|
102
|
-
# ... argument setup
|
|
103
|
-
args = parser.parse_args()
|
|
104
|
-
# ... command dispatch
|
|
105
|
-
return 0
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
if __name__ == "__main__":
|
|
109
|
-
sys.exit(main())
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
---
|
|
113
|
-
|
|
114
|
-
## Coding Standards
|
|
115
|
-
|
|
116
|
-
### Type Hints
|
|
117
|
-
|
|
118
|
-
Use modern type hints (Python 3.10+ syntax):
|
|
119
|
-
|
|
120
|
-
```python
|
|
121
|
-
# Good
|
|
122
|
-
def get_tasks(status: str | None = None) -> list[dict]:
|
|
123
|
-
...
|
|
124
|
-
|
|
125
|
-
def read_json(path: Path) -> dict | None:
|
|
126
|
-
...
|
|
127
|
-
|
|
128
|
-
# Bad - old style
|
|
129
|
-
from typing import Optional, List, Dict
|
|
130
|
-
def get_tasks(status: Optional[str] = None) -> List[Dict]:
|
|
131
|
-
...
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
### Path Handling
|
|
135
|
-
|
|
136
|
-
Always use `pathlib.Path`:
|
|
137
|
-
|
|
138
|
-
```python
|
|
139
|
-
# Good
|
|
140
|
-
from pathlib import Path
|
|
141
|
-
|
|
142
|
-
def read_file(path: Path) -> str:
|
|
143
|
-
return path.read_text(encoding="utf-8")
|
|
144
|
-
|
|
145
|
-
config_path = repo_root / DIR_WORKFLOW / "config.json"
|
|
146
|
-
|
|
147
|
-
# Bad - string concatenation
|
|
148
|
-
config_path = repo_root + "/" + DIR_WORKFLOW + "/config.json"
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
### JSON Operations
|
|
152
|
-
|
|
153
|
-
Use helper functions for consistent error handling:
|
|
154
|
-
|
|
155
|
-
```python
|
|
156
|
-
import json
|
|
157
|
-
from pathlib import Path
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
def read_json(path: Path) -> dict | None:
|
|
161
|
-
"""Read JSON file, return None on error."""
|
|
162
|
-
try:
|
|
163
|
-
return json.loads(path.read_text(encoding="utf-8"))
|
|
164
|
-
except (FileNotFoundError, json.JSONDecodeError):
|
|
165
|
-
return None
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
def write_json(path: Path, data: dict) -> bool:
|
|
169
|
-
"""Write JSON file, return success status."""
|
|
170
|
-
try:
|
|
171
|
-
path.write_text(
|
|
172
|
-
json.dumps(data, indent=2, ensure_ascii=False),
|
|
173
|
-
encoding="utf-8"
|
|
174
|
-
)
|
|
175
|
-
return True
|
|
176
|
-
except Exception:
|
|
177
|
-
return False
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
### Subprocess Execution
|
|
181
|
-
|
|
182
|
-
```python
|
|
183
|
-
import subprocess
|
|
184
|
-
from pathlib import Path
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
def run_command(
|
|
188
|
-
cmd: list[str],
|
|
189
|
-
cwd: Path | None = None
|
|
190
|
-
) -> tuple[int, str, str]:
|
|
191
|
-
"""Run command and return (returncode, stdout, stderr)."""
|
|
192
|
-
result = subprocess.run(
|
|
193
|
-
cmd,
|
|
194
|
-
cwd=cwd,
|
|
195
|
-
capture_output=True,
|
|
196
|
-
text=True
|
|
197
|
-
)
|
|
198
|
-
return result.returncode, result.stdout, result.stderr
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
---
|
|
202
|
-
|
|
203
|
-
## Cross-Platform Compatibility
|
|
204
|
-
|
|
205
|
-
### CRITICAL: Windows stdout Encoding
|
|
206
|
-
|
|
207
|
-
On Windows, Python's stdout defaults to the system code page (e.g., GBK/CP936 in China, CP1252 in Western locales). This causes `UnicodeEncodeError` when printing non-ASCII characters.
|
|
208
|
-
|
|
209
|
-
**The Problem Chain**:
|
|
210
|
-
|
|
211
|
-
```
|
|
212
|
-
Windows code page = GBK (936)
|
|
213
|
-
↓
|
|
214
|
-
Python stdout defaults to GBK encoding
|
|
215
|
-
↓
|
|
216
|
-
Subprocess output contains special chars → replaced with \ufffd (replacement char)
|
|
217
|
-
↓
|
|
218
|
-
json.dumps(ensure_ascii=False) → print()
|
|
219
|
-
↓
|
|
220
|
-
GBK cannot encode \ufffd → UnicodeEncodeError: 'gbk' codec can't encode character
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
**Root Cause**: Even if you set `PYTHONIOENCODING` in subprocess calls, the **parent process's stdout** still uses the system code page. The error occurs when `print()` tries to write to stdout.
|
|
224
|
-
|
|
225
|
-
---
|
|
226
|
-
|
|
227
|
-
#### GOOD: Use `sys.stdout.reconfigure()` (Python 3.7+)
|
|
228
|
-
|
|
229
|
-
```python
|
|
230
|
-
import sys
|
|
231
|
-
|
|
232
|
-
# MUST be at the top of the script, before any print() calls
|
|
233
|
-
if sys.platform == "win32":
|
|
234
|
-
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
|
|
235
|
-
sys.stderr.reconfigure(encoding="utf-8", errors="replace")
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
**Why this works**: `reconfigure()` modifies the existing stream **in-place**, changing its encoding settings directly. This affects all subsequent writes to stdout.
|
|
239
|
-
|
|
240
|
-
**Best Practice**: Add this to `common/__init__.py` so all scripts that `from common import ...` automatically get the fix:
|
|
241
|
-
|
|
242
|
-
```python
|
|
243
|
-
# common/__init__.py
|
|
244
|
-
import sys
|
|
245
|
-
|
|
246
|
-
if sys.platform == "win32":
|
|
247
|
-
sys.stdout.reconfigure(encoding="utf-8", errors="replace")
|
|
248
|
-
sys.stderr.reconfigure(encoding="utf-8", errors="replace")
|
|
249
|
-
|
|
250
|
-
# ... rest of exports
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
---
|
|
254
|
-
|
|
255
|
-
#### BAD: Do NOT use `io.TextIOWrapper`
|
|
256
|
-
|
|
257
|
-
```python
|
|
258
|
-
# BAD - This does NOT reliably fix the encoding issue!
|
|
259
|
-
import sys
|
|
260
|
-
import io
|
|
261
|
-
|
|
262
|
-
if sys.platform == "win32":
|
|
263
|
-
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8", errors="replace")
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
**Why this fails**:
|
|
267
|
-
|
|
268
|
-
1. **Creates a new wrapper, doesn't fix the underlying issue**: `TextIOWrapper` wraps `sys.stdout.buffer`, but the original stdout object and its encoding settings may still interfere in some code paths.
|
|
269
|
-
|
|
270
|
-
2. **Loses original stdout properties**: The new wrapper may not preserve all attributes of the original `sys.stdout` (like `isatty()`, line buffering behavior).
|
|
271
|
-
|
|
272
|
-
3. **Race condition with buffering**: If any output was buffered before the replacement, it may still be encoded with the old encoding.
|
|
273
|
-
|
|
274
|
-
4. **Not idempotent**: Calling this multiple times creates nested wrappers, while `reconfigure()` is safe to call multiple times.
|
|
275
|
-
|
|
276
|
-
**Real-world failure case**: Users reported that `io.TextIOWrapper` did not fix the `UnicodeEncodeError` on Windows, while `sys.stdout.reconfigure()` worked immediately.
|
|
277
|
-
|
|
278
|
-
---
|
|
279
|
-
|
|
280
|
-
#### Summary
|
|
281
|
-
|
|
282
|
-
| Method | Works? | Reason |
|
|
283
|
-
|--------|--------|--------|
|
|
284
|
-
| `sys.stdout.reconfigure(encoding="utf-8")` | ✅ Yes | Modifies stream in-place |
|
|
285
|
-
| `io.TextIOWrapper(sys.stdout.buffer, ...)` | ❌ No | Creates wrapper, doesn't fix underlying encoding |
|
|
286
|
-
| `PYTHONIOENCODING=utf-8` env var | ⚠️ Partial | Only works if set **before** Python starts |
|
|
287
|
-
|
|
288
|
-
### CRITICAL: Always Use `python3` Explicitly
|
|
289
|
-
|
|
290
|
-
Windows does not support shebang (`#!/usr/bin/env python3`). Always document invocation with explicit `python3`:
|
|
291
|
-
|
|
292
|
-
```python
|
|
293
|
-
# In docstrings
|
|
294
|
-
"""
|
|
295
|
-
Usage:
|
|
296
|
-
python3 task.py create "My Task"
|
|
297
|
-
python3 task.py list --mine
|
|
298
|
-
"""
|
|
299
|
-
|
|
300
|
-
# In error messages
|
|
301
|
-
print("Usage: python3 task.py <command>")
|
|
302
|
-
print("Run: python3 ./.aim-studio/scripts/init_developer.py <name>")
|
|
303
|
-
|
|
304
|
-
# In help text
|
|
305
|
-
print("Next steps:")
|
|
306
|
-
print(" python3 task.py start <dir>")
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
### Path Separators
|
|
310
|
-
|
|
311
|
-
Use `pathlib.Path` - it handles separators automatically:
|
|
312
|
-
|
|
313
|
-
```python
|
|
314
|
-
# Good - works on all platforms
|
|
315
|
-
path = Path(".aim-studio") / "scripts" / "task.py"
|
|
316
|
-
|
|
317
|
-
# Bad - Unix-only
|
|
318
|
-
path = ".aim-studio/scripts/task.py"
|
|
319
|
-
```
|
|
320
|
-
|
|
321
|
-
---
|
|
322
|
-
|
|
323
|
-
## Error Handling
|
|
324
|
-
|
|
325
|
-
### Exit Codes
|
|
326
|
-
|
|
327
|
-
| Code | Meaning |
|
|
328
|
-
|------|---------|
|
|
329
|
-
| 0 | Success |
|
|
330
|
-
| 1 | General error |
|
|
331
|
-
| 2 | Usage error (wrong arguments) |
|
|
332
|
-
|
|
333
|
-
### Error Messages
|
|
334
|
-
|
|
335
|
-
Print errors to stderr with context:
|
|
336
|
-
|
|
337
|
-
```python
|
|
338
|
-
import sys
|
|
339
|
-
|
|
340
|
-
def error(msg: str) -> None:
|
|
341
|
-
"""Print error message to stderr."""
|
|
342
|
-
print(f"Error: {msg}", file=sys.stderr)
|
|
343
|
-
|
|
344
|
-
# Usage
|
|
345
|
-
if not repo_root:
|
|
346
|
-
error("Not in a AIM Studio project (no .aim-studio directory found)")
|
|
347
|
-
sys.exit(1)
|
|
348
|
-
```
|
|
349
|
-
|
|
350
|
-
---
|
|
351
|
-
|
|
352
|
-
## Argument Parsing
|
|
353
|
-
|
|
354
|
-
Use `argparse` for consistent CLI interface:
|
|
355
|
-
|
|
356
|
-
```python
|
|
357
|
-
import argparse
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
def main() -> int:
|
|
361
|
-
parser = argparse.ArgumentParser(
|
|
362
|
-
description="Task management",
|
|
363
|
-
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
364
|
-
epilog="""
|
|
365
|
-
Examples:
|
|
366
|
-
python3 task.py create "Add login" --slug add-login
|
|
367
|
-
python3 task.py list --mine --status in_progress
|
|
368
|
-
"""
|
|
369
|
-
)
|
|
370
|
-
|
|
371
|
-
subparsers = parser.add_subparsers(dest="command", required=True)
|
|
372
|
-
|
|
373
|
-
# create command
|
|
374
|
-
create_parser = subparsers.add_parser("create", help="Create new task")
|
|
375
|
-
create_parser.add_argument("title", help="Task title")
|
|
376
|
-
create_parser.add_argument("--slug", help="URL-friendly name")
|
|
377
|
-
|
|
378
|
-
# list command
|
|
379
|
-
list_parser = subparsers.add_parser("list", help="List tasks")
|
|
380
|
-
list_parser.add_argument("--mine", "-m", action="store_true")
|
|
381
|
-
list_parser.add_argument("--status", "-s", choices=["planning", "in_progress", "review", "completed"])
|
|
382
|
-
|
|
383
|
-
args = parser.parse_args()
|
|
384
|
-
|
|
385
|
-
if args.command == "create":
|
|
386
|
-
return cmd_create(args)
|
|
387
|
-
elif args.command == "list":
|
|
388
|
-
return cmd_list(args)
|
|
389
|
-
|
|
390
|
-
return 0
|
|
391
|
-
```
|
|
392
|
-
|
|
393
|
-
---
|
|
394
|
-
|
|
395
|
-
## Import Conventions
|
|
396
|
-
|
|
397
|
-
### Relative Imports Within Package
|
|
398
|
-
|
|
399
|
-
```python
|
|
400
|
-
# In task.py (root level)
|
|
401
|
-
from common.paths import get_repo_root, DIR_WORKFLOW
|
|
402
|
-
from common.developer import get_developer
|
|
403
|
-
|
|
404
|
-
# In common/developer.py
|
|
405
|
-
from .paths import get_repo_root, DIR_WORKFLOW
|
|
406
|
-
```
|
|
407
|
-
|
|
408
|
-
### Standard Library Imports
|
|
409
|
-
|
|
410
|
-
Group and order imports:
|
|
411
|
-
|
|
412
|
-
```python
|
|
413
|
-
# 1. Future imports
|
|
414
|
-
from __future__ import annotations
|
|
415
|
-
|
|
416
|
-
# 2. Standard library
|
|
417
|
-
import argparse
|
|
418
|
-
import json
|
|
419
|
-
import os
|
|
420
|
-
import subprocess
|
|
421
|
-
import sys
|
|
422
|
-
from datetime import datetime
|
|
423
|
-
from pathlib import Path
|
|
424
|
-
|
|
425
|
-
# 3. Local imports
|
|
426
|
-
from common.paths import get_repo_root
|
|
427
|
-
from common.developer import get_developer
|
|
428
|
-
```
|
|
429
|
-
|
|
430
|
-
---
|
|
431
|
-
|
|
432
|
-
## DO / DON'T
|
|
433
|
-
|
|
434
|
-
### DO
|
|
435
|
-
|
|
436
|
-
- Use `pathlib.Path` for all path operations
|
|
437
|
-
- Use type hints (Python 3.10+ syntax)
|
|
438
|
-
- Return exit codes from `main()`
|
|
439
|
-
- Print errors to stderr
|
|
440
|
-
- Always use `python3` in documentation and messages
|
|
441
|
-
- Use `encoding="utf-8"` for all file operations
|
|
442
|
-
|
|
443
|
-
### DON'T
|
|
444
|
-
|
|
445
|
-
- Don't use string path concatenation
|
|
446
|
-
- Don't use `os.path` when `pathlib` works
|
|
447
|
-
- Don't rely on shebang for invocation documentation
|
|
448
|
-
- Don't use `print()` for errors (use stderr)
|
|
449
|
-
- Don't hardcode paths - use constants from `common/paths.py`
|
|
450
|
-
- Don't use external dependencies (stdlib only)
|
|
451
|
-
|
|
452
|
-
---
|
|
453
|
-
|
|
454
|
-
## Example: Complete Script
|
|
455
|
-
|
|
456
|
-
See `.aim-studio/scripts/task.py` for a comprehensive example with:
|
|
457
|
-
- Multiple subcommands
|
|
458
|
-
- Argument parsing
|
|
459
|
-
- JSON file operations
|
|
460
|
-
- Error handling
|
|
461
|
-
- Cross-platform path handling
|
|
462
|
-
|
|
463
|
-
---
|
|
464
|
-
|
|
465
|
-
## Migration Note
|
|
466
|
-
|
|
467
|
-
> **Historical Context**: Scripts were migrated from Bash to Python in v0.3.0 for cross-platform compatibility. The old shell scripts are archived in `.aim-studio/scripts-shell-archive/` (if preserved).
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
# CLI Directory Structure
|
|
2
|
-
|
|
3
|
-
> How the CLI tool is organized.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Overview
|
|
8
|
-
|
|
9
|
-
Describe your CLI project's directory structure and organization.
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## Entry Point
|
|
14
|
-
|
|
15
|
-
| File | Purpose |
|
|
16
|
-
|------|---------|
|
|
17
|
-
| `bin/aim.js` | Main CLI entry point |
|
|
18
|
-
| `src/cli/` | CLI argument parsing |
|
|
19
|
-
| `src/commands/` | Command implementations |
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
## Example Structure
|
|
24
|
-
|
|
25
|
-
```
|
|
26
|
-
.
|
|
27
|
-
├── bin/
|
|
28
|
-
│ └── aim.js # CLI entry point
|
|
29
|
-
├── src/
|
|
30
|
-
│ ├── cli/ # Command-line parsing
|
|
31
|
-
│ │ └── index.ts
|
|
32
|
-
│ ├── commands/ # Command implementations
|
|
33
|
-
│ │ ├── init.ts
|
|
34
|
-
│ │ └── update.ts
|
|
35
|
-
│ ├── utils/ # Utility functions
|
|
36
|
-
│ └── types/ # TypeScript types
|
|
37
|
-
├── package.json
|
|
38
|
-
└── tsconfig.json
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
---
|
|
42
|
-
|
|
43
|
-
## Patterns
|
|
44
|
-
|
|
45
|
-
Describe common patterns used in your project:
|
|
46
|
-
|
|
47
|
-
### Command Organization
|
|
48
|
-
|
|
49
|
-
```typescript
|
|
50
|
-
// Example: how commands are registered
|
|
51
|
-
export const commands = [init, update];
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
### Module Boundaries
|
|
55
|
-
|
|
56
|
-
- `src/cli/` - Pure CLI concerns (parsing, help text)
|
|
57
|
-
- `src/commands/` - Business logic
|
|
58
|
-
- `src/utils/` - Shared utilities
|
|
59
|
-
|
|
60
|
-
---
|
|
61
|
-
|
|
62
|
-
## Anti-Patterns
|
|
63
|
-
|
|
64
|
-
- ❌ Mixing business logic in CLI entry point
|
|
65
|
-
- ❌ No separation between commands
|
|
66
|
-
|
|
67
|
-
---
|
|
68
|
-
|
|
69
|
-
## Add Your Examples
|
|
70
|
-
|
|
71
|
-
Replace these with real examples from your codebase.
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
# CLI Error Handling
|
|
2
|
-
|
|
3
|
-
> How errors are handled and reported.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Overview
|
|
8
|
-
|
|
9
|
-
Document your CLI's error handling patterns, exit codes, and error messages.
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## Exit Codes
|
|
14
|
-
|
|
15
|
-
| Code | Meaning |
|
|
16
|
-
|------|---------|
|
|
17
|
-
| `0` | Success |
|
|
18
|
-
| `1` | General error |
|
|
19
|
-
| `2` | Misuse of command |
|
|
20
|
-
| `3` | Internal error |
|
|
21
|
-
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
## Error Categories
|
|
25
|
-
|
|
26
|
-
| Category | Exit Code | Example |
|
|
27
|
-
|----------|-----------|---------|
|
|
28
|
-
| Validation | `2` | Missing required argument |
|
|
29
|
-
| Not Found | `2` | File/directory not found |
|
|
30
|
-
| Permission | `2` | Cannot write to directory |
|
|
31
|
-
| Internal | `3` | Unexpected exception |
|
|
32
|
-
|
|
33
|
-
---
|
|
34
|
-
|
|
35
|
-
## Error Message Format
|
|
36
|
-
|
|
37
|
-
```
|
|
38
|
-
❌ Error: <short description>
|
|
39
|
-
<detailed explanation (optional)>
|
|
40
|
-
<suggestion/fix (optional)>
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
### Example
|
|
44
|
-
|
|
45
|
-
```
|
|
46
|
-
❌ Error: Template not found
|
|
47
|
-
Template "react" does not exist
|
|
48
|
-
Run "aim template list" to see available templates
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
---
|
|
52
|
-
|
|
53
|
-
## Patterns
|
|
54
|
-
|
|
55
|
-
### Throwing Errors
|
|
56
|
-
|
|
57
|
-
```typescript
|
|
58
|
-
import { error as consoleError, exit } from 'node:process';
|
|
59
|
-
|
|
60
|
-
function validateArgs(args: string[]) {
|
|
61
|
-
if (!args.length) {
|
|
62
|
-
consoleError('Error: Missing required argument');
|
|
63
|
-
exit(2);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
### Try-Catch with Exit
|
|
69
|
-
|
|
70
|
-
```typescript
|
|
71
|
-
try {
|
|
72
|
-
await doSomething();
|
|
73
|
-
} catch (err) {
|
|
74
|
-
consoleError(`Error: ${err.message}`);
|
|
75
|
-
exit(1);
|
|
76
|
-
}
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
---
|
|
80
|
-
|
|
81
|
-
## Anti-Patterns
|
|
82
|
-
|
|
83
|
-
- ❌ Silent failures
|
|
84
|
-
- ❌ Stack traces exposed to users
|
|
85
|
-
- ❌ No error suggestions
|
|
86
|
-
|
|
87
|
-
---
|
|
88
|
-
|
|
89
|
-
## Add Your Examples
|
|
90
|
-
|
|
91
|
-
Replace with your actual error handling patterns.
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
# CLI Tool Development Guidelines
|
|
2
|
-
|
|
3
|
-
> Best practices for CLI tool development in this project.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Overview
|
|
8
|
-
|
|
9
|
-
This directory contains guidelines for CLI tool development. Fill in each file with your project's specific conventions.
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## Guidelines Index
|
|
14
|
-
|
|
15
|
-
| Guide | Description | Status |
|
|
16
|
-
|-------|-------------|--------|
|
|
17
|
-
| [Directory Structure](./directory-structure.md) | Command organization, module layout | TODO |
|
|
18
|
-
| [Options & Flags](./options-flags.md) | Global options, flags, environment variables | TODO |
|
|
19
|
-
| [Output Formatting](./output-formatting.md) | Output formats, colors, user feedback | TODO |
|
|
20
|
-
| [Error Handling](./error-handling.md) | Error codes, messages, exit statuses | TODO |
|
|
21
|
-
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
## How to Fill These Guidelines
|
|
25
|
-
|
|
26
|
-
For each guideline file:
|
|
27
|
-
|
|
28
|
-
1. Document your project's **actual conventions** (not ideals)
|
|
29
|
-
2. Include **code examples** from your codebase
|
|
30
|
-
3. List **forbidden patterns** and why
|
|
31
|
-
4. Add **common mistakes** your team has made
|
|
32
|
-
|
|
33
|
-
The goal is to help AI assistants and new team members understand how YOUR project works.
|
|
34
|
-
|
|
35
|
-
---
|
|
36
|
-
|
|
37
|
-
**Language**: All documentation should be written in **English**.
|