@fifine/aim-studio 0.0.2 → 0.0.3
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/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +123 -101
- package/dist/commands/init.js.map +1 -1
- package/dist/configurators/workflow.d.ts.map +1 -1
- package/dist/configurators/workflow.js +91 -65
- package/dist/configurators/workflow.js.map +1 -1
- package/dist/templates/aim/scripts/common/paths.py +3 -2
- package/dist/templates/aim/scripts/export.py +427 -0
- package/dist/templates/claude/commands/aim/export.md +89 -115
- package/dist/templates/claude/commands/aim/onboard.md +10 -8
- package/dist/templates/claude/commands/aim/start.md +104 -37
- package/dist/templates/claude/hooks/inject-subagent-context.py +6 -10
- package/dist/templates/claude/hooks/session-start.py +134 -24
- package/dist/templates/markdown/index.d.ts +5 -0
- package/dist/templates/markdown/index.d.ts.map +1 -1
- package/dist/templates/markdown/index.js +6 -0
- package/dist/templates/markdown/index.js.map +1 -1
- package/dist/templates/markdown/spec/cli/directory-structure.md.txt +71 -0
- package/dist/templates/markdown/spec/cli/error-handling.md.txt +91 -0
- package/dist/templates/markdown/spec/cli/index.md.txt +37 -0
- package/dist/templates/markdown/spec/cli/options-flags.md.txt +71 -0
- package/dist/templates/markdown/spec/cli/output-formatting.md.txt +93 -0
- package/dist/utils/project-detector.d.ts +1 -1
- package/dist/utils/project-detector.d.ts.map +1 -1
- package/dist/utils/project-detector.js +20 -0
- package/dist/utils/project-detector.js.map +1 -1
- package/package.json +1 -1
- package/dist/templates/claude/commands/trellis/before-backend-dev.md +0 -13
- package/dist/templates/claude/commands/trellis/before-frontend-dev.md +0 -13
- package/dist/templates/claude/commands/trellis/break-loop.md +0 -125
- package/dist/templates/claude/commands/trellis/check-backend.md +0 -13
- package/dist/templates/claude/commands/trellis/check-cross-layer.md +0 -153
- package/dist/templates/claude/commands/trellis/check-frontend.md +0 -13
- package/dist/templates/claude/commands/trellis/create-command.md +0 -154
- package/dist/templates/claude/commands/trellis/finish-work.md +0 -129
- package/dist/templates/claude/commands/trellis/integrate-skill.md +0 -219
- package/dist/templates/claude/commands/trellis/onboard.md +0 -358
- package/dist/templates/claude/commands/trellis/parallel.md +0 -193
- package/dist/templates/claude/commands/trellis/record-session.md +0 -62
- package/dist/templates/claude/commands/trellis/start.md +0 -280
- package/dist/templates/claude/commands/trellis/update-spec.md +0 -285
- package/dist/templates/trellis/gitignore.txt +0 -29
- package/dist/templates/trellis/index.d.ts +0 -49
- package/dist/templates/trellis/index.d.ts.map +0 -1
- package/dist/templates/trellis/index.js +0 -92
- package/dist/templates/trellis/index.js.map +0 -1
- package/dist/templates/trellis/scripts/__init__.py +0 -5
- package/dist/templates/trellis/scripts/add_session.py +0 -392
- package/dist/templates/trellis/scripts/common/__init__.py +0 -80
- package/dist/templates/trellis/scripts/common/cli_adapter.py +0 -435
- package/dist/templates/trellis/scripts/common/developer.py +0 -190
- package/dist/templates/trellis/scripts/common/git_context.py +0 -383
- package/dist/templates/trellis/scripts/common/paths.py +0 -347
- package/dist/templates/trellis/scripts/common/phase.py +0 -253
- package/dist/templates/trellis/scripts/common/registry.py +0 -366
- package/dist/templates/trellis/scripts/common/task_queue.py +0 -255
- package/dist/templates/trellis/scripts/common/task_utils.py +0 -178
- package/dist/templates/trellis/scripts/common/worktree.py +0 -219
- package/dist/templates/trellis/scripts/create_bootstrap.py +0 -290
- package/dist/templates/trellis/scripts/get_context.py +0 -16
- package/dist/templates/trellis/scripts/get_developer.py +0 -26
- package/dist/templates/trellis/scripts/init_developer.py +0 -51
- package/dist/templates/trellis/scripts/multi_agent/__init__.py +0 -5
- package/dist/templates/trellis/scripts/multi_agent/cleanup.py +0 -403
- package/dist/templates/trellis/scripts/multi_agent/create_pr.py +0 -329
- package/dist/templates/trellis/scripts/multi_agent/plan.py +0 -233
- package/dist/templates/trellis/scripts/multi_agent/start.py +0 -461
- package/dist/templates/trellis/scripts/multi_agent/status.py +0 -817
- package/dist/templates/trellis/scripts/task.py +0 -1056
- package/dist/templates/trellis/scripts-shell-archive/add-session.sh +0 -384
- package/dist/templates/trellis/scripts-shell-archive/common/developer.sh +0 -129
- package/dist/templates/trellis/scripts-shell-archive/common/git-context.sh +0 -263
- package/dist/templates/trellis/scripts-shell-archive/common/paths.sh +0 -208
- package/dist/templates/trellis/scripts-shell-archive/common/phase.sh +0 -150
- package/dist/templates/trellis/scripts-shell-archive/common/registry.sh +0 -247
- package/dist/templates/trellis/scripts-shell-archive/common/task-queue.sh +0 -142
- package/dist/templates/trellis/scripts-shell-archive/common/task-utils.sh +0 -151
- package/dist/templates/trellis/scripts-shell-archive/common/worktree.sh +0 -128
- package/dist/templates/trellis/scripts-shell-archive/create-bootstrap.sh +0 -299
- package/dist/templates/trellis/scripts-shell-archive/get-context.sh +0 -7
- package/dist/templates/trellis/scripts-shell-archive/get-developer.sh +0 -15
- package/dist/templates/trellis/scripts-shell-archive/init-developer.sh +0 -34
- package/dist/templates/trellis/scripts-shell-archive/multi-agent/cleanup.sh +0 -396
- package/dist/templates/trellis/scripts-shell-archive/multi-agent/create-pr.sh +0 -241
- package/dist/templates/trellis/scripts-shell-archive/multi-agent/plan.sh +0 -207
- package/dist/templates/trellis/scripts-shell-archive/multi-agent/start.sh +0 -317
- package/dist/templates/trellis/scripts-shell-archive/multi-agent/status.sh +0 -828
- package/dist/templates/trellis/scripts-shell-archive/task.sh +0 -1204
- package/dist/templates/trellis/tasks/.gitkeep +0 -0
- package/dist/templates/trellis/workflow.md +0 -416
- package/dist/templates/trellis/worktree.yaml +0 -47
|
@@ -1,383 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
|
-
"""
|
|
4
|
-
Git and Session Context utilities.
|
|
5
|
-
|
|
6
|
-
Provides:
|
|
7
|
-
output_json - Output context in JSON format
|
|
8
|
-
output_text - Output context in text format
|
|
9
|
-
"""
|
|
10
|
-
|
|
11
|
-
from __future__ import annotations
|
|
12
|
-
|
|
13
|
-
import sys
|
|
14
|
-
|
|
15
|
-
# IMPORTANT: Force stdout to use UTF-8 on Windows
|
|
16
|
-
# This fixes UnicodeEncodeError when outputting non-ASCII characters
|
|
17
|
-
if sys.platform == "win32":
|
|
18
|
-
import io as _io
|
|
19
|
-
if hasattr(sys.stdout, "reconfigure"):
|
|
20
|
-
sys.stdout.reconfigure(encoding="utf-8", errors="replace") # type: ignore[union-attr]
|
|
21
|
-
elif hasattr(sys.stdout, "detach"):
|
|
22
|
-
sys.stdout = _io.TextIOWrapper(sys.stdout.detach(), encoding="utf-8", errors="replace") # type: ignore[union-attr]
|
|
23
|
-
|
|
24
|
-
import json
|
|
25
|
-
import subprocess
|
|
26
|
-
from pathlib import Path
|
|
27
|
-
|
|
28
|
-
from .paths import (
|
|
29
|
-
DIR_SCRIPTS,
|
|
30
|
-
DIR_SPEC,
|
|
31
|
-
DIR_TASKS,
|
|
32
|
-
DIR_WORKFLOW,
|
|
33
|
-
DIR_WORKSPACE,
|
|
34
|
-
FILE_TASK_JSON,
|
|
35
|
-
count_lines,
|
|
36
|
-
get_active_journal_file,
|
|
37
|
-
get_current_task,
|
|
38
|
-
get_developer,
|
|
39
|
-
get_repo_root,
|
|
40
|
-
get_tasks_dir,
|
|
41
|
-
)
|
|
42
|
-
|
|
43
|
-
# =============================================================================
|
|
44
|
-
# Helper Functions
|
|
45
|
-
# =============================================================================
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
def _run_git_command(args: list[str], cwd: Path | None = None) -> tuple[int, str, str]:
|
|
49
|
-
"""Run a git command and return (returncode, stdout, stderr).
|
|
50
|
-
|
|
51
|
-
Uses UTF-8 encoding with -c i18n.logOutputEncoding=UTF-8 to ensure
|
|
52
|
-
consistent output across all platforms (Windows, macOS, Linux).
|
|
53
|
-
"""
|
|
54
|
-
try:
|
|
55
|
-
# Force git to output UTF-8 for consistent cross-platform behavior
|
|
56
|
-
git_args = ["git", "-c", "i18n.logOutputEncoding=UTF-8"] + args
|
|
57
|
-
result = subprocess.run(
|
|
58
|
-
git_args,
|
|
59
|
-
cwd=cwd,
|
|
60
|
-
capture_output=True,
|
|
61
|
-
text=True,
|
|
62
|
-
encoding="utf-8",
|
|
63
|
-
errors="replace",
|
|
64
|
-
)
|
|
65
|
-
return result.returncode, result.stdout, result.stderr
|
|
66
|
-
except Exception as e:
|
|
67
|
-
return 1, "", str(e)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
def _read_json_file(path: Path) -> dict | None:
|
|
71
|
-
"""Read and parse a JSON file."""
|
|
72
|
-
try:
|
|
73
|
-
return json.loads(path.read_text(encoding="utf-8"))
|
|
74
|
-
except (FileNotFoundError, json.JSONDecodeError, OSError):
|
|
75
|
-
return None
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
# =============================================================================
|
|
79
|
-
# JSON Output
|
|
80
|
-
# =============================================================================
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
def get_context_json(repo_root: Path | None = None) -> dict:
|
|
84
|
-
"""Get context as a dictionary.
|
|
85
|
-
|
|
86
|
-
Args:
|
|
87
|
-
repo_root: Repository root path. Defaults to auto-detected.
|
|
88
|
-
|
|
89
|
-
Returns:
|
|
90
|
-
Context dictionary.
|
|
91
|
-
"""
|
|
92
|
-
if repo_root is None:
|
|
93
|
-
repo_root = get_repo_root()
|
|
94
|
-
|
|
95
|
-
developer = get_developer(repo_root)
|
|
96
|
-
tasks_dir = get_tasks_dir(repo_root)
|
|
97
|
-
journal_file = get_active_journal_file(repo_root)
|
|
98
|
-
|
|
99
|
-
journal_lines = 0
|
|
100
|
-
journal_relative = ""
|
|
101
|
-
if journal_file and developer:
|
|
102
|
-
journal_lines = count_lines(journal_file)
|
|
103
|
-
journal_relative = (
|
|
104
|
-
f"{DIR_WORKFLOW}/{DIR_WORKSPACE}/{developer}/{journal_file.name}"
|
|
105
|
-
)
|
|
106
|
-
|
|
107
|
-
# Git info
|
|
108
|
-
_, branch_out, _ = _run_git_command(["branch", "--show-current"], cwd=repo_root)
|
|
109
|
-
branch = branch_out.strip() or "unknown"
|
|
110
|
-
|
|
111
|
-
_, status_out, _ = _run_git_command(["status", "--porcelain"], cwd=repo_root)
|
|
112
|
-
git_status_count = len([line for line in status_out.splitlines() if line.strip()])
|
|
113
|
-
is_clean = git_status_count == 0
|
|
114
|
-
|
|
115
|
-
# Recent commits
|
|
116
|
-
_, log_out, _ = _run_git_command(["log", "--oneline", "-5"], cwd=repo_root)
|
|
117
|
-
commits = []
|
|
118
|
-
for line in log_out.splitlines():
|
|
119
|
-
if line.strip():
|
|
120
|
-
parts = line.split(" ", 1)
|
|
121
|
-
if len(parts) >= 2:
|
|
122
|
-
commits.append({"hash": parts[0], "message": parts[1]})
|
|
123
|
-
elif len(parts) == 1:
|
|
124
|
-
commits.append({"hash": parts[0], "message": ""})
|
|
125
|
-
|
|
126
|
-
# Tasks
|
|
127
|
-
tasks = []
|
|
128
|
-
if tasks_dir.is_dir():
|
|
129
|
-
for d in tasks_dir.iterdir():
|
|
130
|
-
if d.is_dir() and d.name != "archive":
|
|
131
|
-
task_json_path = d / FILE_TASK_JSON
|
|
132
|
-
if task_json_path.is_file():
|
|
133
|
-
data = _read_json_file(task_json_path)
|
|
134
|
-
if data:
|
|
135
|
-
tasks.append(
|
|
136
|
-
{
|
|
137
|
-
"dir": d.name,
|
|
138
|
-
"name": data.get("name") or data.get("id") or "unknown",
|
|
139
|
-
"status": data.get("status", "unknown"),
|
|
140
|
-
}
|
|
141
|
-
)
|
|
142
|
-
|
|
143
|
-
return {
|
|
144
|
-
"developer": developer or "",
|
|
145
|
-
"git": {
|
|
146
|
-
"branch": branch,
|
|
147
|
-
"isClean": is_clean,
|
|
148
|
-
"uncommittedChanges": git_status_count,
|
|
149
|
-
"recentCommits": commits,
|
|
150
|
-
},
|
|
151
|
-
"tasks": {
|
|
152
|
-
"active": tasks,
|
|
153
|
-
"directory": f"{DIR_WORKFLOW}/{DIR_TASKS}",
|
|
154
|
-
},
|
|
155
|
-
"journal": {
|
|
156
|
-
"file": journal_relative,
|
|
157
|
-
"lines": journal_lines,
|
|
158
|
-
"nearLimit": journal_lines > 1800,
|
|
159
|
-
},
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
def output_json(repo_root: Path | None = None) -> None:
|
|
164
|
-
"""Output context in JSON format.
|
|
165
|
-
|
|
166
|
-
Args:
|
|
167
|
-
repo_root: Repository root path. Defaults to auto-detected.
|
|
168
|
-
"""
|
|
169
|
-
context = get_context_json(repo_root)
|
|
170
|
-
print(json.dumps(context, indent=2, ensure_ascii=False))
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
# =============================================================================
|
|
174
|
-
# Text Output
|
|
175
|
-
# =============================================================================
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
def get_context_text(repo_root: Path | None = None) -> str:
|
|
179
|
-
"""Get context as formatted text.
|
|
180
|
-
|
|
181
|
-
Args:
|
|
182
|
-
repo_root: Repository root path. Defaults to auto-detected.
|
|
183
|
-
|
|
184
|
-
Returns:
|
|
185
|
-
Formatted text output.
|
|
186
|
-
"""
|
|
187
|
-
if repo_root is None:
|
|
188
|
-
repo_root = get_repo_root()
|
|
189
|
-
|
|
190
|
-
lines = []
|
|
191
|
-
lines.append("========================================")
|
|
192
|
-
lines.append("SESSION CONTEXT")
|
|
193
|
-
lines.append("========================================")
|
|
194
|
-
lines.append("")
|
|
195
|
-
|
|
196
|
-
developer = get_developer(repo_root)
|
|
197
|
-
|
|
198
|
-
# Developer section
|
|
199
|
-
lines.append("## DEVELOPER")
|
|
200
|
-
if not developer:
|
|
201
|
-
lines.append(
|
|
202
|
-
f"ERROR: Not initialized. Run: python3 ./{DIR_WORKFLOW}/{DIR_SCRIPTS}/init_developer.py <name>"
|
|
203
|
-
)
|
|
204
|
-
return "\n".join(lines)
|
|
205
|
-
|
|
206
|
-
lines.append(f"Name: {developer}")
|
|
207
|
-
lines.append("")
|
|
208
|
-
|
|
209
|
-
# Git status
|
|
210
|
-
lines.append("## GIT STATUS")
|
|
211
|
-
_, branch_out, _ = _run_git_command(["branch", "--show-current"], cwd=repo_root)
|
|
212
|
-
branch = branch_out.strip() or "unknown"
|
|
213
|
-
lines.append(f"Branch: {branch}")
|
|
214
|
-
|
|
215
|
-
_, status_out, _ = _run_git_command(["status", "--porcelain"], cwd=repo_root)
|
|
216
|
-
status_lines = [line for line in status_out.splitlines() if line.strip()]
|
|
217
|
-
status_count = len(status_lines)
|
|
218
|
-
|
|
219
|
-
if status_count == 0:
|
|
220
|
-
lines.append("Working directory: Clean")
|
|
221
|
-
else:
|
|
222
|
-
lines.append(f"Working directory: {status_count} uncommitted change(s)")
|
|
223
|
-
lines.append("")
|
|
224
|
-
lines.append("Changes:")
|
|
225
|
-
_, short_out, _ = _run_git_command(["status", "--short"], cwd=repo_root)
|
|
226
|
-
for line in short_out.splitlines()[:10]:
|
|
227
|
-
lines.append(line)
|
|
228
|
-
lines.append("")
|
|
229
|
-
|
|
230
|
-
# Recent commits
|
|
231
|
-
lines.append("## RECENT COMMITS")
|
|
232
|
-
_, log_out, _ = _run_git_command(["log", "--oneline", "-5"], cwd=repo_root)
|
|
233
|
-
if log_out.strip():
|
|
234
|
-
for line in log_out.splitlines():
|
|
235
|
-
lines.append(line)
|
|
236
|
-
else:
|
|
237
|
-
lines.append("(no commits)")
|
|
238
|
-
lines.append("")
|
|
239
|
-
|
|
240
|
-
# Current task
|
|
241
|
-
lines.append("## CURRENT TASK")
|
|
242
|
-
current_task = get_current_task(repo_root)
|
|
243
|
-
if current_task:
|
|
244
|
-
current_task_dir = repo_root / current_task
|
|
245
|
-
task_json_path = current_task_dir / FILE_TASK_JSON
|
|
246
|
-
lines.append(f"Path: {current_task}")
|
|
247
|
-
|
|
248
|
-
if task_json_path.is_file():
|
|
249
|
-
data = _read_json_file(task_json_path)
|
|
250
|
-
if data:
|
|
251
|
-
t_name = data.get("name") or data.get("id") or "unknown"
|
|
252
|
-
t_status = data.get("status", "unknown")
|
|
253
|
-
t_created = data.get("createdAt", "unknown")
|
|
254
|
-
t_desc = data.get("description", "")
|
|
255
|
-
|
|
256
|
-
lines.append(f"Name: {t_name}")
|
|
257
|
-
lines.append(f"Status: {t_status}")
|
|
258
|
-
lines.append(f"Created: {t_created}")
|
|
259
|
-
if t_desc:
|
|
260
|
-
lines.append(f"Description: {t_desc}")
|
|
261
|
-
|
|
262
|
-
# Check for prd.md
|
|
263
|
-
prd_file = current_task_dir / "prd.md"
|
|
264
|
-
if prd_file.is_file():
|
|
265
|
-
lines.append("")
|
|
266
|
-
lines.append("[!] This task has prd.md - read it for task details")
|
|
267
|
-
else:
|
|
268
|
-
lines.append("(none)")
|
|
269
|
-
lines.append("")
|
|
270
|
-
|
|
271
|
-
# Active tasks
|
|
272
|
-
lines.append("## ACTIVE TASKS")
|
|
273
|
-
tasks_dir = get_tasks_dir(repo_root)
|
|
274
|
-
task_count = 0
|
|
275
|
-
|
|
276
|
-
if tasks_dir.is_dir():
|
|
277
|
-
for d in sorted(tasks_dir.iterdir()):
|
|
278
|
-
if d.is_dir() and d.name != "archive":
|
|
279
|
-
dir_name = d.name
|
|
280
|
-
t_json = d / FILE_TASK_JSON
|
|
281
|
-
status = "unknown"
|
|
282
|
-
assignee = "-"
|
|
283
|
-
|
|
284
|
-
if t_json.is_file():
|
|
285
|
-
data = _read_json_file(t_json)
|
|
286
|
-
if data:
|
|
287
|
-
status = data.get("status", "unknown")
|
|
288
|
-
assignee = data.get("assignee", "-")
|
|
289
|
-
|
|
290
|
-
lines.append(f"- {dir_name}/ ({status}) @{assignee}")
|
|
291
|
-
task_count += 1
|
|
292
|
-
|
|
293
|
-
if task_count == 0:
|
|
294
|
-
lines.append("(no active tasks)")
|
|
295
|
-
lines.append(f"Total: {task_count} active task(s)")
|
|
296
|
-
lines.append("")
|
|
297
|
-
|
|
298
|
-
# My tasks
|
|
299
|
-
lines.append("## MY TASKS (Assigned to me)")
|
|
300
|
-
my_task_count = 0
|
|
301
|
-
|
|
302
|
-
if tasks_dir.is_dir():
|
|
303
|
-
for d in sorted(tasks_dir.iterdir()):
|
|
304
|
-
if d.is_dir() and d.name != "archive":
|
|
305
|
-
t_json = d / FILE_TASK_JSON
|
|
306
|
-
if t_json.is_file():
|
|
307
|
-
data = _read_json_file(t_json)
|
|
308
|
-
if data:
|
|
309
|
-
assignee = data.get("assignee", "")
|
|
310
|
-
status = data.get("status", "planning")
|
|
311
|
-
|
|
312
|
-
if assignee == developer and status != "done":
|
|
313
|
-
title = data.get("title") or data.get("name") or "unknown"
|
|
314
|
-
priority = data.get("priority", "P2")
|
|
315
|
-
lines.append(f"- [{priority}] {title} ({status})")
|
|
316
|
-
my_task_count += 1
|
|
317
|
-
|
|
318
|
-
if my_task_count == 0:
|
|
319
|
-
lines.append("(no tasks assigned to you)")
|
|
320
|
-
lines.append("")
|
|
321
|
-
|
|
322
|
-
# Journal file
|
|
323
|
-
lines.append("## JOURNAL FILE")
|
|
324
|
-
journal_file = get_active_journal_file(repo_root)
|
|
325
|
-
if journal_file:
|
|
326
|
-
journal_lines = count_lines(journal_file)
|
|
327
|
-
relative = f"{DIR_WORKFLOW}/{DIR_WORKSPACE}/{developer}/{journal_file.name}"
|
|
328
|
-
lines.append(f"Active file: {relative}")
|
|
329
|
-
lines.append(f"Line count: {journal_lines} / 2000")
|
|
330
|
-
if journal_lines > 1800:
|
|
331
|
-
lines.append("[!] WARNING: Approaching 2000 line limit!")
|
|
332
|
-
else:
|
|
333
|
-
lines.append("No journal file found")
|
|
334
|
-
lines.append("")
|
|
335
|
-
|
|
336
|
-
# Paths
|
|
337
|
-
lines.append("## PATHS")
|
|
338
|
-
lines.append(f"Workspace: {DIR_WORKFLOW}/{DIR_WORKSPACE}/{developer}/")
|
|
339
|
-
lines.append(f"Tasks: {DIR_WORKFLOW}/{DIR_TASKS}/")
|
|
340
|
-
lines.append(f"Spec: {DIR_WORKFLOW}/{DIR_SPEC}/")
|
|
341
|
-
lines.append("")
|
|
342
|
-
|
|
343
|
-
lines.append("========================================")
|
|
344
|
-
|
|
345
|
-
return "\n".join(lines)
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
def output_text(repo_root: Path | None = None) -> None:
|
|
349
|
-
"""Output context in text format.
|
|
350
|
-
|
|
351
|
-
Args:
|
|
352
|
-
repo_root: Repository root path. Defaults to auto-detected.
|
|
353
|
-
"""
|
|
354
|
-
print(get_context_text(repo_root))
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
# =============================================================================
|
|
358
|
-
# Main Entry
|
|
359
|
-
# =============================================================================
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
def main() -> None:
|
|
363
|
-
"""CLI entry point."""
|
|
364
|
-
import argparse
|
|
365
|
-
|
|
366
|
-
parser = argparse.ArgumentParser(description="Get Session Context for AI Agent")
|
|
367
|
-
parser.add_argument(
|
|
368
|
-
"--json",
|
|
369
|
-
"-j",
|
|
370
|
-
action="store_true",
|
|
371
|
-
help="Output context in JSON format",
|
|
372
|
-
)
|
|
373
|
-
|
|
374
|
-
args = parser.parse_args()
|
|
375
|
-
|
|
376
|
-
if args.json:
|
|
377
|
-
output_json()
|
|
378
|
-
else:
|
|
379
|
-
output_text()
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
if __name__ == "__main__":
|
|
383
|
-
main()
|