@mindfoldhq/trellis 0.4.0-beta.1 → 0.4.0-beta.10
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 +19 -5
- package/dist/cli/index.js +3 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/init.d.ts +3 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +48 -23
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +52 -41
- package/dist/commands/update.js.map +1 -1
- package/dist/configurators/codebuddy.d.ts +11 -0
- package/dist/configurators/codebuddy.d.ts.map +1 -0
- package/dist/configurators/codebuddy.js +58 -0
- package/dist/configurators/codebuddy.js.map +1 -0
- package/dist/configurators/codex.d.ts +7 -4
- package/dist/configurators/codex.d.ts.map +1 -1
- package/dist/configurators/codex.js +40 -10
- package/dist/configurators/codex.js.map +1 -1
- package/dist/configurators/copilot.d.ts +9 -0
- package/dist/configurators/copilot.d.ts.map +1 -0
- package/dist/configurators/copilot.js +34 -0
- package/dist/configurators/copilot.js.map +1 -0
- package/dist/configurators/index.d.ts +11 -1
- package/dist/configurators/index.d.ts.map +1 -1
- package/dist/configurators/index.js +72 -4
- package/dist/configurators/index.js.map +1 -1
- package/dist/configurators/opencode.d.ts +1 -1
- package/dist/configurators/opencode.js +1 -1
- package/dist/configurators/windsurf.d.ts +8 -0
- package/dist/configurators/windsurf.d.ts.map +1 -0
- package/dist/configurators/windsurf.js +18 -0
- package/dist/configurators/windsurf.js.map +1 -0
- package/dist/configurators/workflow.d.ts +1 -1
- package/dist/configurators/workflow.d.ts.map +1 -1
- package/dist/configurators/workflow.js +4 -2
- package/dist/configurators/workflow.js.map +1 -1
- package/dist/migrations/manifests/0.3.10.json +9 -0
- package/dist/migrations/manifests/0.4.0-beta.10.json +9 -0
- package/dist/migrations/manifests/0.4.0-beta.2.json +9 -0
- package/dist/migrations/manifests/0.4.0-beta.3.json +9 -0
- package/dist/migrations/manifests/0.4.0-beta.4.json +9 -0
- package/dist/migrations/manifests/0.4.0-beta.5.json +9 -0
- package/dist/migrations/manifests/0.4.0-beta.6.json +9 -0
- package/dist/migrations/manifests/0.4.0-beta.7.json +9 -0
- package/dist/migrations/manifests/0.4.0-beta.8.json +34 -0
- package/dist/migrations/manifests/0.4.0-beta.9.json +9 -0
- package/dist/templates/claude/commands/trellis/record-session.md +3 -2
- package/dist/templates/claude/hooks/inject-subagent-context.py +8 -1
- package/dist/templates/claude/hooks/ralph-loop.py +18 -10
- package/dist/templates/claude/hooks/session-start.py +33 -9
- package/dist/templates/claude/hooks/statusline.py +211 -0
- package/dist/templates/claude/settings.json +4 -0
- package/dist/templates/codebuddy/commands/trellis/before-dev.md +29 -0
- package/dist/templates/codebuddy/commands/trellis/brainstorm.md +487 -0
- package/dist/templates/codebuddy/commands/trellis/break-loop.md +107 -0
- package/dist/templates/codebuddy/commands/trellis/check-cross-layer.md +153 -0
- package/dist/templates/codebuddy/commands/trellis/check.md +25 -0
- package/dist/templates/codebuddy/commands/trellis/create-command.md +154 -0
- package/dist/templates/codebuddy/commands/trellis/finish-work.md +143 -0
- package/dist/templates/codebuddy/commands/trellis/integrate-skill.md +219 -0
- package/dist/templates/codebuddy/commands/trellis/onboard.md +358 -0
- package/dist/templates/codebuddy/commands/trellis/record-session.md +61 -0
- package/dist/templates/codebuddy/commands/trellis/start.md +373 -0
- package/dist/templates/codebuddy/commands/trellis/update-spec.md +354 -0
- package/dist/templates/codebuddy/index.d.ts +25 -0
- package/dist/templates/codebuddy/index.d.ts.map +1 -0
- package/dist/templates/codebuddy/index.js +45 -0
- package/dist/templates/codebuddy/index.js.map +1 -0
- package/dist/templates/codex/agents/check.toml +23 -0
- package/dist/templates/codex/agents/implement.toml +19 -0
- package/dist/templates/codex/agents/research.toml +26 -0
- package/dist/templates/codex/codex-skills/parallel/SKILL.md +194 -0
- package/dist/templates/codex/config.toml +5 -0
- package/dist/templates/codex/hooks/session-start.py +228 -0
- package/dist/templates/codex/hooks.json +16 -0
- package/dist/templates/codex/index.d.ts +27 -5
- package/dist/templates/codex/index.d.ts.map +1 -1
- package/dist/templates/codex/index.js +60 -8
- package/dist/templates/codex/index.js.map +1 -1
- package/dist/templates/codex/skills/before-dev/SKILL.md +1 -1
- package/dist/templates/codex/skills/brainstorm/SKILL.md +1 -1
- package/dist/templates/codex/skills/break-loop/SKILL.md +1 -1
- package/dist/templates/codex/skills/check/SKILL.md +1 -1
- package/dist/templates/codex/skills/check-cross-layer/SKILL.md +1 -1
- package/dist/templates/codex/skills/create-command/SKILL.md +1 -1
- package/dist/templates/codex/skills/finish-work/SKILL.md +1 -1
- package/dist/templates/codex/skills/improve-ut/SKILL.md +69 -0
- package/dist/templates/codex/skills/integrate-skill/SKILL.md +1 -1
- package/dist/templates/codex/skills/onboard/SKILL.md +1 -1
- package/dist/templates/codex/skills/record-session/SKILL.md +4 -3
- package/dist/templates/codex/skills/start/SKILL.md +1 -1
- package/dist/templates/codex/skills/update-spec/SKILL.md +1 -1
- package/dist/templates/copilot/hooks/session-start.py +218 -0
- package/dist/templates/copilot/hooks.json +11 -0
- package/dist/templates/copilot/index.d.ts +23 -0
- package/dist/templates/copilot/index.d.ts.map +1 -0
- package/dist/templates/copilot/index.js +54 -0
- package/dist/templates/copilot/index.js.map +1 -0
- package/dist/templates/copilot/prompts/before-dev.prompt.md +33 -0
- package/dist/templates/copilot/prompts/brainstorm.prompt.md +491 -0
- package/dist/templates/copilot/prompts/break-loop.prompt.md +129 -0
- package/dist/templates/copilot/prompts/check-cross-layer.prompt.md +157 -0
- package/dist/templates/copilot/prompts/check.prompt.md +29 -0
- package/dist/templates/copilot/prompts/create-command.prompt.md +116 -0
- package/dist/templates/copilot/prompts/finish-work.prompt.md +157 -0
- package/dist/templates/copilot/prompts/integrate-skill.prompt.md +223 -0
- package/dist/templates/copilot/prompts/onboard.prompt.md +362 -0
- package/dist/templates/copilot/prompts/parallel.prompt.md +196 -0
- package/dist/templates/copilot/prompts/record-session.prompt.md +66 -0
- package/dist/templates/copilot/prompts/start.prompt.md +397 -0
- package/dist/templates/copilot/prompts/update-spec.prompt.md +358 -0
- package/dist/templates/cursor/commands/trellis-record-session.md +3 -2
- package/dist/templates/extract.d.ts +36 -0
- package/dist/templates/extract.d.ts.map +1 -1
- package/dist/templates/extract.js +64 -0
- package/dist/templates/extract.js.map +1 -1
- package/dist/templates/gemini/commands/trellis/record-session.toml +3 -2
- package/dist/templates/iflow/commands/trellis/record-session.md +3 -2
- package/dist/templates/iflow/hooks/inject-subagent-context.py +8 -1
- package/dist/templates/iflow/hooks/ralph-loop.py +8 -1
- package/dist/templates/iflow/hooks/session-start.py +33 -9
- package/dist/templates/kilo/workflows/record-session.md +3 -2
- package/dist/templates/kiro/skills/before-dev/SKILL.md +1 -1
- package/dist/templates/kiro/skills/brainstorm/SKILL.md +1 -1
- package/dist/templates/kiro/skills/break-loop/SKILL.md +1 -1
- package/dist/templates/kiro/skills/check/SKILL.md +1 -1
- package/dist/templates/kiro/skills/check-cross-layer/SKILL.md +1 -1
- package/dist/templates/kiro/skills/create-command/SKILL.md +1 -1
- package/dist/templates/kiro/skills/finish-work/SKILL.md +1 -1
- package/dist/templates/kiro/skills/integrate-skill/SKILL.md +1 -1
- package/dist/templates/kiro/skills/onboard/SKILL.md +1 -1
- package/dist/templates/kiro/skills/record-session/SKILL.md +4 -3
- package/dist/templates/kiro/skills/start/SKILL.md +1 -1
- package/dist/templates/kiro/skills/update-spec/SKILL.md +1 -1
- package/dist/templates/markdown/agents.md +4 -0
- package/dist/templates/markdown/spec/backend/directory-structure.md +1 -1
- package/dist/templates/markdown/workspace-index.md +2 -0
- package/dist/templates/opencode/agents/dispatch.md +20 -19
- package/dist/templates/opencode/commands/trellis/record-session.md +3 -2
- package/dist/templates/opencode/lib/trellis-context.js +42 -2
- package/dist/templates/opencode/{plugin → plugins}/session-start.js +7 -27
- package/dist/templates/qoder/skills/before-dev/SKILL.md +1 -1
- package/dist/templates/qoder/skills/brainstorm/SKILL.md +1 -1
- package/dist/templates/qoder/skills/break-loop/SKILL.md +1 -1
- package/dist/templates/qoder/skills/check/SKILL.md +1 -1
- package/dist/templates/qoder/skills/check-cross-layer/SKILL.md +1 -1
- package/dist/templates/qoder/skills/create-command/SKILL.md +1 -1
- package/dist/templates/qoder/skills/finish-work/SKILL.md +1 -1
- package/dist/templates/qoder/skills/integrate-skill/SKILL.md +1 -1
- package/dist/templates/qoder/skills/onboard/SKILL.md +1 -1
- package/dist/templates/qoder/skills/record-session/SKILL.md +4 -3
- package/dist/templates/qoder/skills/start/SKILL.md +1 -1
- package/dist/templates/qoder/skills/update-spec/SKILL.md +1 -1
- package/dist/templates/trellis/scripts/add_session.py +69 -16
- package/dist/templates/trellis/scripts/common/__init__.py +2 -0
- package/dist/templates/trellis/scripts/common/cli_adapter.py +133 -21
- package/dist/templates/trellis/scripts/common/config.py +40 -0
- package/dist/templates/trellis/scripts/common/developer.py +2 -2
- package/dist/templates/trellis/scripts/common/packages_context.py +9 -4
- package/dist/templates/trellis/scripts/common/paths.py +57 -6
- package/dist/templates/trellis/scripts/common/session_context.py +98 -2
- package/dist/templates/trellis/scripts/common/task_context.py +27 -1
- package/dist/templates/trellis/scripts/common/task_store.py +6 -4
- package/dist/templates/trellis/scripts/common/task_utils.py +14 -8
- package/dist/templates/trellis/scripts/create_bootstrap.py +1 -1
- package/dist/templates/trellis/scripts/multi_agent/plan.py +7 -6
- package/dist/templates/trellis/scripts/multi_agent/start.py +16 -11
- package/dist/templates/trellis/scripts/task.py +1 -1
- package/dist/templates/trellis/scripts-shell-archive/create-bootstrap.sh +1 -1
- package/dist/templates/trellis/workflow.md +17 -4
- package/dist/templates/windsurf/index.d.ts +21 -0
- package/dist/templates/windsurf/index.d.ts.map +1 -0
- package/dist/templates/windsurf/index.js +44 -0
- package/dist/templates/windsurf/index.js.map +1 -0
- package/dist/templates/windsurf/workflows/trellis-before-dev.md +31 -0
- package/dist/templates/windsurf/workflows/trellis-brainstorm.md +491 -0
- package/dist/templates/windsurf/workflows/trellis-break-loop.md +111 -0
- package/dist/templates/windsurf/workflows/trellis-check-cross-layer.md +157 -0
- package/dist/templates/windsurf/workflows/trellis-check.md +27 -0
- package/dist/templates/windsurf/workflows/trellis-create-command.md +154 -0
- package/dist/templates/windsurf/workflows/trellis-finish-work.md +147 -0
- package/dist/templates/windsurf/workflows/trellis-integrate-skill.md +220 -0
- package/dist/templates/windsurf/workflows/trellis-onboard.md +362 -0
- package/dist/templates/windsurf/workflows/trellis-record-session.md +66 -0
- package/dist/templates/windsurf/workflows/trellis-start.md +373 -0
- package/dist/templates/windsurf/workflows/trellis-update-spec.md +358 -0
- package/dist/types/ai-tools.d.ts +15 -3
- package/dist/types/ai-tools.d.ts.map +1 -1
- package/dist/types/ai-tools.js +42 -2
- package/dist/types/ai-tools.js.map +1 -1
- package/dist/utils/project-detector.d.ts +5 -0
- package/dist/utils/project-detector.d.ts.map +1 -1
- package/dist/utils/project-detector.js +7 -0
- package/dist/utils/project-detector.js.map +1 -1
- package/dist/utils/template-fetcher.d.ts +24 -3
- package/dist/utils/template-fetcher.d.ts.map +1 -1
- package/dist/utils/template-fetcher.js +129 -16
- package/dist/utils/template-fetcher.js.map +1 -1
- package/package.json +1 -1
- /package/dist/templates/opencode/{plugin → plugins}/inject-subagent-context.js +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: start
|
|
3
|
-
description: "
|
|
3
|
+
description: "Initializes an AI development session by reading workflow guides, developer identity, git status, active tasks, and project guidelines from .trellis/. Classifies incoming tasks and routes to brainstorm, direct edit, or task workflow. Use when beginning a new coding session, resuming work, starting a new task, or re-establishing project context."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Start Session
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: update-spec
|
|
3
|
-
description: "
|
|
3
|
+
description: "Captures executable contracts and coding knowledge into .trellis/spec/ documents after implementation, debugging, or design decisions. Enforces code-spec depth for infra and cross-layer changes with mandatory sections for signatures, contracts, validation matrices, and test points. Use when a feature is implemented, a bug is fixed, a design decision is made, a new pattern is discovered, or cross-layer contracts change."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Update Spec - Capture Knowledge into Specifications
|
|
@@ -5,17 +5,23 @@ Add a new session to journal file and update index.md.
|
|
|
5
5
|
|
|
6
6
|
Usage:
|
|
7
7
|
python3 add_session.py --title "Title" --commit "hash" --summary "Summary" [--package cli]
|
|
8
|
+
python3 add_session.py --title "Title" --branch "feat/my-branch"
|
|
8
9
|
|
|
9
10
|
# Pipe detailed content via stdin (use --stdin to opt in):
|
|
10
11
|
cat << 'EOF' | python3 add_session.py --stdin --title "Title" --summary "Summary"
|
|
11
12
|
<session content here>
|
|
12
13
|
EOF
|
|
14
|
+
|
|
15
|
+
Branch resolution order:
|
|
16
|
+
1. --branch CLI arg (explicit)
|
|
17
|
+
2. task.json branch field (from active task)
|
|
18
|
+
3. git branch --show-current (auto-detect)
|
|
19
|
+
4. None (omitted gracefully)
|
|
13
20
|
"""
|
|
14
21
|
|
|
15
22
|
from __future__ import annotations
|
|
16
23
|
|
|
17
24
|
import argparse
|
|
18
|
-
import json
|
|
19
25
|
import re
|
|
20
26
|
import subprocess
|
|
21
27
|
import sys
|
|
@@ -30,6 +36,7 @@ from common.paths import (
|
|
|
30
36
|
get_workspace_dir,
|
|
31
37
|
)
|
|
32
38
|
from common.developer import ensure_developer
|
|
39
|
+
from common.git import run_git
|
|
33
40
|
from common.tasks import load_task
|
|
34
41
|
from common.config import (
|
|
35
42
|
get_packages,
|
|
@@ -139,6 +146,7 @@ def generate_session_content(
|
|
|
139
146
|
extra_content: str,
|
|
140
147
|
today: str,
|
|
141
148
|
package: str | None = None,
|
|
149
|
+
branch: str | None = None,
|
|
142
150
|
) -> str:
|
|
143
151
|
"""Generate session content."""
|
|
144
152
|
if commit and commit != "-":
|
|
@@ -151,13 +159,14 @@ def generate_session_content(
|
|
|
151
159
|
commit_table = "(No commits - planning session)"
|
|
152
160
|
|
|
153
161
|
package_line = f"\n**Package**: {package}" if package else ""
|
|
162
|
+
branch_line = f"\n**Branch**: `{branch}`" if branch else ""
|
|
154
163
|
|
|
155
164
|
return f"""
|
|
156
165
|
|
|
157
166
|
## Session {session_num}: {title}
|
|
158
167
|
|
|
159
168
|
**Date**: {today}
|
|
160
|
-
**Task**: {title}{package_line}
|
|
169
|
+
**Task**: {title}{package_line}{branch_line}
|
|
161
170
|
|
|
162
171
|
### Summary
|
|
163
172
|
|
|
@@ -192,7 +201,8 @@ def update_index(
|
|
|
192
201
|
commit: str,
|
|
193
202
|
new_session: int,
|
|
194
203
|
active_file: str,
|
|
195
|
-
today: str
|
|
204
|
+
today: str,
|
|
205
|
+
branch: str | None = None,
|
|
196
206
|
) -> bool:
|
|
197
207
|
"""Update index.md with new session info."""
|
|
198
208
|
# Format commit for display
|
|
@@ -271,10 +281,25 @@ def update_index(
|
|
|
271
281
|
continue
|
|
272
282
|
|
|
273
283
|
if in_session_history:
|
|
274
|
-
|
|
275
|
-
if re.match(
|
|
276
|
-
|
|
284
|
+
# Migrate old 4/6-column headers to 5-column Branch-only history.
|
|
285
|
+
if re.match(
|
|
286
|
+
r"^\|\s*#\s*\|\s*Date\s*\|\s*Title\s*\|\s*Commits\s*\|\s*Branch\s*\|\s*Base Branch\s*\|\s*$",
|
|
287
|
+
line,
|
|
288
|
+
):
|
|
289
|
+
new_lines.append("| # | Date | Title | Commits | Branch |")
|
|
290
|
+
continue
|
|
291
|
+
if re.match(r"^\|\s*#\s*\|\s*Date\s*\|\s*Title\s*\|\s*Commits\s*\|\s*Branch\s*\|\s*$", line):
|
|
292
|
+
new_lines.append("| # | Date | Title | Commits | Branch |")
|
|
293
|
+
continue
|
|
294
|
+
if re.match(r"^\|\s*#\s*\|\s*Date\s*\|\s*Title\s*\|\s*Commits\s*\|\s*$", line):
|
|
295
|
+
new_lines.append("| # | Date | Title | Commits | Branch |")
|
|
296
|
+
continue
|
|
297
|
+
if re.match(r"^\|[-| ]+\|\s*$", line) and not header_written:
|
|
298
|
+
new_lines.append("|---|------|-------|---------|--------|")
|
|
299
|
+
new_lines.append(f"| {new_session} | {today} | {title} | {commit_display} | `{branch or '-'}` |")
|
|
277
300
|
header_written = True
|
|
301
|
+
continue
|
|
302
|
+
new_lines.append(line)
|
|
278
303
|
continue
|
|
279
304
|
|
|
280
305
|
new_lines.append(line)
|
|
@@ -291,11 +316,16 @@ def update_index(
|
|
|
291
316
|
def _auto_commit_workspace(repo_root: Path) -> None:
|
|
292
317
|
"""Stage .trellis/workspace and .trellis/tasks, then commit with a configured message."""
|
|
293
318
|
commit_msg = get_session_commit_message(repo_root)
|
|
294
|
-
subprocess.run(
|
|
319
|
+
add_result = subprocess.run(
|
|
295
320
|
["git", "add", "-A", ".trellis/workspace", ".trellis/tasks"],
|
|
296
321
|
cwd=repo_root,
|
|
297
322
|
capture_output=True,
|
|
323
|
+
text=True,
|
|
298
324
|
)
|
|
325
|
+
if add_result.returncode != 0:
|
|
326
|
+
print(f"[WARN] git add failed (exit {add_result.returncode}): {add_result.stderr.strip()}", file=sys.stderr)
|
|
327
|
+
print("[WARN] Please commit .trellis/ changes manually: git add .trellis && git commit", file=sys.stderr)
|
|
328
|
+
return
|
|
299
329
|
# Check if there are staged changes
|
|
300
330
|
result = subprocess.run(
|
|
301
331
|
["git", "diff", "--cached", "--quiet", "--", ".trellis/workspace", ".trellis/tasks"],
|
|
@@ -323,6 +353,7 @@ def add_session(
|
|
|
323
353
|
extra_content: str = "(Add details)",
|
|
324
354
|
auto_commit: bool = True,
|
|
325
355
|
package: str | None = None,
|
|
356
|
+
branch: str | None = None,
|
|
326
357
|
) -> int:
|
|
327
358
|
"""Add a new session."""
|
|
328
359
|
repo_root = get_repo_root()
|
|
@@ -348,7 +379,8 @@ def add_session(
|
|
|
348
379
|
new_session = current_session + 1
|
|
349
380
|
|
|
350
381
|
session_content = generate_session_content(
|
|
351
|
-
new_session, title, commit, summary, extra_content, today, package
|
|
382
|
+
new_session, title, commit, summary, extra_content, today, package,
|
|
383
|
+
branch,
|
|
352
384
|
)
|
|
353
385
|
content_lines = len(session_content.splitlines())
|
|
354
386
|
|
|
@@ -385,7 +417,16 @@ def add_session(
|
|
|
385
417
|
|
|
386
418
|
# Update index.md
|
|
387
419
|
active_file = f"{FILE_JOURNAL_PREFIX}{target_num}.md"
|
|
388
|
-
if not update_index(
|
|
420
|
+
if not update_index(
|
|
421
|
+
index_file,
|
|
422
|
+
dev_dir,
|
|
423
|
+
title,
|
|
424
|
+
commit,
|
|
425
|
+
new_session,
|
|
426
|
+
active_file,
|
|
427
|
+
today,
|
|
428
|
+
branch,
|
|
429
|
+
):
|
|
389
430
|
return 1
|
|
390
431
|
|
|
391
432
|
print("", file=sys.stderr)
|
|
@@ -419,6 +460,7 @@ def main() -> int:
|
|
|
419
460
|
parser.add_argument("--summary", default="(Add summary)", help="Brief summary")
|
|
420
461
|
parser.add_argument("--content-file", help="Path to file with detailed content")
|
|
421
462
|
parser.add_argument("--package", help="Package name tag (e.g., cli, docs-site)")
|
|
463
|
+
parser.add_argument("--branch", help="Branch name (auto-detected if omitted)")
|
|
422
464
|
parser.add_argument("--no-commit", action="store_true",
|
|
423
465
|
help="Skip auto-commit of workspace changes")
|
|
424
466
|
parser.add_argument("--stdin", action="store_true",
|
|
@@ -434,8 +476,11 @@ def main() -> int:
|
|
|
434
476
|
elif args.stdin:
|
|
435
477
|
extra_content = sys.stdin.read()
|
|
436
478
|
|
|
437
|
-
#
|
|
479
|
+
# Load active task once — shared by package and branch resolution
|
|
438
480
|
repo_root = get_repo_root()
|
|
481
|
+
current = get_current_task(repo_root)
|
|
482
|
+
task_data = load_task(repo_root / current) if current else None
|
|
483
|
+
|
|
439
484
|
package = args.package
|
|
440
485
|
if package:
|
|
441
486
|
# CLI source: fail-fast in monorepo, ignore in single-repo
|
|
@@ -449,18 +494,26 @@ def main() -> int:
|
|
|
449
494
|
return 1
|
|
450
495
|
else:
|
|
451
496
|
# Inferred: active task's task.json.package → default_package → None
|
|
452
|
-
task_package = None
|
|
453
|
-
current = get_current_task(repo_root)
|
|
454
|
-
if current:
|
|
455
|
-
ct = load_task(repo_root / current)
|
|
456
|
-
if ct and ct.package:
|
|
457
|
-
task_package = ct.package
|
|
497
|
+
task_package = task_data.package if task_data else None
|
|
458
498
|
package = resolve_package(task_package, repo_root)
|
|
459
499
|
|
|
500
|
+
# Resolve branch: CLI → task.json → git auto-detect → None
|
|
501
|
+
branch = args.branch
|
|
502
|
+
|
|
503
|
+
if not branch:
|
|
504
|
+
if task_data and task_data.raw.get("branch"):
|
|
505
|
+
branch = task_data.raw["branch"]
|
|
506
|
+
else:
|
|
507
|
+
_, branch_out, _ = run_git(["branch", "--show-current"], cwd=repo_root)
|
|
508
|
+
detected = branch_out.strip()
|
|
509
|
+
if detected:
|
|
510
|
+
branch = detected
|
|
511
|
+
|
|
460
512
|
return add_session(
|
|
461
513
|
args.title, args.commit, args.summary, extra_content,
|
|
462
514
|
auto_commit=not args.no_commit,
|
|
463
515
|
package=package,
|
|
516
|
+
branch=branch,
|
|
464
517
|
)
|
|
465
518
|
|
|
466
519
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""
|
|
2
2
|
CLI Adapter for Multi-Platform Support.
|
|
3
3
|
|
|
4
|
-
Abstracts differences between Claude Code, OpenCode, Cursor, iFlow, Codex, Kilo, Kiro Code, Gemini CLI, Antigravity,
|
|
4
|
+
Abstracts differences between Claude Code, OpenCode, Cursor, iFlow, Codex, Kilo, Kiro Code, Gemini CLI, Antigravity, Windsurf, Qoder, CodeBuddy, and GitHub Copilot interfaces.
|
|
5
5
|
|
|
6
6
|
Supported platforms:
|
|
7
7
|
- claude: Claude Code (default)
|
|
@@ -13,7 +13,10 @@ Supported platforms:
|
|
|
13
13
|
- kiro: Kiro Code (skills-based)
|
|
14
14
|
- gemini: Gemini CLI
|
|
15
15
|
- antigravity: Antigravity (workflow-based)
|
|
16
|
+
- windsurf: Windsurf (workflow-based)
|
|
16
17
|
- qoder: Qoder
|
|
18
|
+
- codebuddy: CodeBuddy
|
|
19
|
+
- copilot: GitHub Copilot (VS Code)
|
|
17
20
|
|
|
18
21
|
Usage:
|
|
19
22
|
from common.cli_adapter import CLIAdapter
|
|
@@ -42,7 +45,10 @@ Platform = Literal[
|
|
|
42
45
|
"kiro",
|
|
43
46
|
"gemini",
|
|
44
47
|
"antigravity",
|
|
48
|
+
"windsurf",
|
|
45
49
|
"qoder",
|
|
50
|
+
"codebuddy",
|
|
51
|
+
"copilot",
|
|
46
52
|
]
|
|
47
53
|
|
|
48
54
|
|
|
@@ -87,7 +93,7 @@ class CLIAdapter:
|
|
|
87
93
|
"""Get platform-specific config directory name.
|
|
88
94
|
|
|
89
95
|
Returns:
|
|
90
|
-
Directory name ('.claude', '.opencode', '.cursor', '.iflow', '.
|
|
96
|
+
Directory name ('.claude', '.opencode', '.cursor', '.iflow', '.codex', '.kilocode', '.kiro', '.gemini', '.agent', '.windsurf', '.qoder', or '.codebuddy')
|
|
91
97
|
"""
|
|
92
98
|
if self.platform == "opencode":
|
|
93
99
|
return ".opencode"
|
|
@@ -96,7 +102,7 @@ class CLIAdapter:
|
|
|
96
102
|
elif self.platform == "iflow":
|
|
97
103
|
return ".iflow"
|
|
98
104
|
elif self.platform == "codex":
|
|
99
|
-
return ".
|
|
105
|
+
return ".codex"
|
|
100
106
|
elif self.platform == "kilo":
|
|
101
107
|
return ".kilocode"
|
|
102
108
|
elif self.platform == "kiro":
|
|
@@ -105,8 +111,14 @@ class CLIAdapter:
|
|
|
105
111
|
return ".gemini"
|
|
106
112
|
elif self.platform == "antigravity":
|
|
107
113
|
return ".agent"
|
|
114
|
+
elif self.platform == "windsurf":
|
|
115
|
+
return ".windsurf"
|
|
108
116
|
elif self.platform == "qoder":
|
|
109
117
|
return ".qoder"
|
|
118
|
+
elif self.platform == "codebuddy":
|
|
119
|
+
return ".codebuddy"
|
|
120
|
+
elif self.platform == "copilot":
|
|
121
|
+
return ".github/copilot"
|
|
110
122
|
else:
|
|
111
123
|
return ".claude"
|
|
112
124
|
|
|
@@ -117,7 +129,7 @@ class CLIAdapter:
|
|
|
117
129
|
project_root: Project root directory
|
|
118
130
|
|
|
119
131
|
Returns:
|
|
120
|
-
Path to config directory (.claude, .opencode, .cursor, .iflow, .
|
|
132
|
+
Path to config directory (.claude, .opencode, .cursor, .iflow, .codex, .kilocode, .kiro, .gemini, .agent, .windsurf, .qoder, or .codebuddy)
|
|
121
133
|
"""
|
|
122
134
|
return project_root / self.config_dir_name
|
|
123
135
|
|
|
@@ -129,9 +141,11 @@ class CLIAdapter:
|
|
|
129
141
|
project_root: Project root directory
|
|
130
142
|
|
|
131
143
|
Returns:
|
|
132
|
-
Path to agent .md
|
|
144
|
+
Path to agent definition file (.md for most platforms, .toml for Codex)
|
|
133
145
|
"""
|
|
134
146
|
mapped_name = self.get_agent_name(agent)
|
|
147
|
+
if self.platform == "codex":
|
|
148
|
+
return self.get_config_dir(project_root) / "agents" / f"{mapped_name}.toml"
|
|
135
149
|
return self.get_config_dir(project_root) / "agents" / f"{mapped_name}.md"
|
|
136
150
|
|
|
137
151
|
def get_commands_path(self, project_root: Path, *parts: str) -> Path:
|
|
@@ -147,8 +161,19 @@ class CLIAdapter:
|
|
|
147
161
|
Note:
|
|
148
162
|
Cursor uses prefix naming: .cursor/commands/trellis-<name>.md
|
|
149
163
|
Antigravity uses workflow directory: .agent/workflows/<name>.md
|
|
164
|
+
Windsurf uses workflow directory: .windsurf/workflows/trellis-<name>.md
|
|
165
|
+
Copilot uses prompt files: .github/prompts/<name>.prompt.md
|
|
150
166
|
Claude/OpenCode use subdirectory: .claude/commands/trellis/<name>.md
|
|
151
167
|
"""
|
|
168
|
+
if self.platform == "windsurf":
|
|
169
|
+
workflow_dir = self.get_config_dir(project_root) / "workflows"
|
|
170
|
+
if not parts:
|
|
171
|
+
return workflow_dir
|
|
172
|
+
if len(parts) >= 2 and parts[0] == "trellis":
|
|
173
|
+
filename = parts[-1]
|
|
174
|
+
return workflow_dir / f"trellis-{filename}"
|
|
175
|
+
return workflow_dir / Path(*parts)
|
|
176
|
+
|
|
152
177
|
if self.platform in ("antigravity", "kilo"):
|
|
153
178
|
workflow_dir = self.get_config_dir(project_root) / "workflows"
|
|
154
179
|
if not parts:
|
|
@@ -158,6 +183,17 @@ class CLIAdapter:
|
|
|
158
183
|
return workflow_dir / filename
|
|
159
184
|
return workflow_dir / Path(*parts)
|
|
160
185
|
|
|
186
|
+
if self.platform == "copilot":
|
|
187
|
+
prompts_dir = project_root / ".github" / "prompts"
|
|
188
|
+
if not parts:
|
|
189
|
+
return prompts_dir
|
|
190
|
+
if len(parts) >= 2 and parts[0] == "trellis":
|
|
191
|
+
filename = parts[-1]
|
|
192
|
+
if filename.endswith(".md"):
|
|
193
|
+
filename = filename[:-3]
|
|
194
|
+
return prompts_dir / f"{filename}.prompt.md"
|
|
195
|
+
return prompts_dir / Path(*parts)
|
|
196
|
+
|
|
161
197
|
if not parts:
|
|
162
198
|
return self.get_config_dir(project_root) / "commands"
|
|
163
199
|
|
|
@@ -186,6 +222,7 @@ class CLIAdapter:
|
|
|
186
222
|
Kiro: .kiro/skills/<name>/SKILL.md
|
|
187
223
|
Gemini: .gemini/commands/trellis/<name>.toml
|
|
188
224
|
Antigravity: .agent/workflows/<name>.md
|
|
225
|
+
Windsurf: .windsurf/workflows/trellis-<name>.md
|
|
189
226
|
Others: .{platform}/commands/trellis/<name>.md
|
|
190
227
|
"""
|
|
191
228
|
if self.platform == "cursor":
|
|
@@ -198,8 +235,12 @@ class CLIAdapter:
|
|
|
198
235
|
return f".gemini/commands/trellis/{name}.toml"
|
|
199
236
|
elif self.platform == "antigravity":
|
|
200
237
|
return f".agent/workflows/{name}.md"
|
|
238
|
+
elif self.platform == "windsurf":
|
|
239
|
+
return f".windsurf/workflows/trellis-{name}.md"
|
|
201
240
|
elif self.platform == "kilo":
|
|
202
241
|
return f".kilocode/workflows/{name}.md"
|
|
242
|
+
elif self.platform == "copilot":
|
|
243
|
+
return f".github/prompts/{name}.prompt.md"
|
|
203
244
|
else:
|
|
204
245
|
return f"{self.config_dir_name}/commands/trellis/{name}.md"
|
|
205
246
|
|
|
@@ -225,8 +266,14 @@ class CLIAdapter:
|
|
|
225
266
|
return {} # Gemini CLI doesn't have a non-interactive env var
|
|
226
267
|
elif self.platform == "antigravity":
|
|
227
268
|
return {}
|
|
269
|
+
elif self.platform == "windsurf":
|
|
270
|
+
return {}
|
|
228
271
|
elif self.platform == "qoder":
|
|
229
272
|
return {}
|
|
273
|
+
elif self.platform == "codebuddy":
|
|
274
|
+
return {}
|
|
275
|
+
elif self.platform == "copilot":
|
|
276
|
+
return {}
|
|
230
277
|
else:
|
|
231
278
|
return {"CLAUDE_NON_INTERACTIVE": "1"}
|
|
232
279
|
|
|
@@ -278,12 +325,8 @@ class CLIAdapter:
|
|
|
278
325
|
cmd.append(prompt)
|
|
279
326
|
|
|
280
327
|
elif self.platform == "iflow":
|
|
281
|
-
cmd = ["iflow", "-p"]
|
|
282
|
-
cmd.
|
|
283
|
-
# iFlow doesn't support --session-id on creation
|
|
284
|
-
if verbose:
|
|
285
|
-
cmd.append("--verbose")
|
|
286
|
-
cmd.append(prompt)
|
|
328
|
+
cmd = ["iflow", "-y", "-p"]
|
|
329
|
+
cmd.append(f"${mapped_agent} {prompt}")
|
|
287
330
|
elif self.platform == "codex":
|
|
288
331
|
cmd = ["codex", "exec"]
|
|
289
332
|
cmd.append(prompt)
|
|
@@ -296,8 +339,20 @@ class CLIAdapter:
|
|
|
296
339
|
raise ValueError(
|
|
297
340
|
"Antigravity workflows are UI slash commands; CLI agent run is not supported."
|
|
298
341
|
)
|
|
342
|
+
elif self.platform == "windsurf":
|
|
343
|
+
raise ValueError(
|
|
344
|
+
"Windsurf workflows are UI slash commands; CLI agent run is not supported."
|
|
345
|
+
)
|
|
299
346
|
elif self.platform == "qoder":
|
|
300
347
|
cmd = ["qodercli", "-p", prompt]
|
|
348
|
+
elif self.platform == "codebuddy":
|
|
349
|
+
raise ValueError(
|
|
350
|
+
"CodeBuddy does not support non-interactive mode (no CLI agent)"
|
|
351
|
+
)
|
|
352
|
+
elif self.platform == "copilot":
|
|
353
|
+
raise ValueError(
|
|
354
|
+
"GitHub Copilot is IDE-only; CLI agent run is not supported."
|
|
355
|
+
)
|
|
301
356
|
|
|
302
357
|
else: # claude
|
|
303
358
|
cmd = ["claude", "-p"]
|
|
@@ -344,8 +399,20 @@ class CLIAdapter:
|
|
|
344
399
|
raise ValueError(
|
|
345
400
|
"Antigravity workflows are UI slash commands; CLI resume is not supported."
|
|
346
401
|
)
|
|
402
|
+
elif self.platform == "windsurf":
|
|
403
|
+
raise ValueError(
|
|
404
|
+
"Windsurf workflows are UI slash commands; CLI resume is not supported."
|
|
405
|
+
)
|
|
347
406
|
elif self.platform == "qoder":
|
|
348
407
|
return ["qodercli", "--resume", session_id]
|
|
408
|
+
elif self.platform == "codebuddy":
|
|
409
|
+
raise ValueError(
|
|
410
|
+
"CodeBuddy does not support non-interactive mode (no CLI agent)"
|
|
411
|
+
)
|
|
412
|
+
elif self.platform == "copilot":
|
|
413
|
+
raise ValueError(
|
|
414
|
+
"GitHub Copilot is IDE-only; CLI resume is not supported."
|
|
415
|
+
)
|
|
349
416
|
else:
|
|
350
417
|
return ["claude", "--resume", session_id]
|
|
351
418
|
|
|
@@ -408,8 +475,14 @@ class CLIAdapter:
|
|
|
408
475
|
return "gemini"
|
|
409
476
|
elif self.platform == "antigravity":
|
|
410
477
|
return "agy"
|
|
478
|
+
elif self.platform == "windsurf":
|
|
479
|
+
return "windsurf"
|
|
411
480
|
elif self.platform == "qoder":
|
|
412
481
|
return "qodercli"
|
|
482
|
+
elif self.platform == "codebuddy":
|
|
483
|
+
return "codebuddy"
|
|
484
|
+
elif self.platform == "copilot":
|
|
485
|
+
return "copilot"
|
|
413
486
|
else:
|
|
414
487
|
return "claude"
|
|
415
488
|
|
|
@@ -417,9 +490,18 @@ class CLIAdapter:
|
|
|
417
490
|
def supports_cli_agents(self) -> bool:
|
|
418
491
|
"""Check if platform supports running agents via CLI.
|
|
419
492
|
|
|
420
|
-
Claude Code, OpenCode, and
|
|
493
|
+
Claude Code, OpenCode, iFlow, and Codex support CLI agent execution.
|
|
421
494
|
Cursor is IDE-only and doesn't support CLI agents.
|
|
422
495
|
"""
|
|
496
|
+
return self.platform in ("claude", "opencode", "iflow", "codex")
|
|
497
|
+
|
|
498
|
+
@property
|
|
499
|
+
def requires_agent_definition_file(self) -> bool:
|
|
500
|
+
"""Check if platform requires an agent definition file (.md/.toml) to run.
|
|
501
|
+
|
|
502
|
+
Claude Code, OpenCode, iFlow: require agent .md files (--agent flag).
|
|
503
|
+
Codex: auto-discovers agents from .codex/agents/*.toml, no --agent flag.
|
|
504
|
+
"""
|
|
423
505
|
return self.platform in ("claude", "opencode", "iflow")
|
|
424
506
|
|
|
425
507
|
# =========================================================================
|
|
@@ -465,7 +547,7 @@ def get_cli_adapter(platform: str = "claude") -> CLIAdapter:
|
|
|
465
547
|
"""Get CLI adapter for the specified platform.
|
|
466
548
|
|
|
467
549
|
Args:
|
|
468
|
-
platform: Platform name ('claude', 'opencode', 'cursor', 'iflow', 'codex', 'kilo', 'kiro', 'gemini', 'antigravity',
|
|
550
|
+
platform: Platform name ('claude', 'opencode', 'cursor', 'iflow', 'codex', 'kilo', 'kiro', 'gemini', 'antigravity', 'windsurf', 'qoder', or 'codebuddy')
|
|
469
551
|
|
|
470
552
|
Returns:
|
|
471
553
|
CLIAdapter instance
|
|
@@ -483,10 +565,13 @@ def get_cli_adapter(platform: str = "claude") -> CLIAdapter:
|
|
|
483
565
|
"kiro",
|
|
484
566
|
"gemini",
|
|
485
567
|
"antigravity",
|
|
568
|
+
"windsurf",
|
|
486
569
|
"qoder",
|
|
570
|
+
"codebuddy",
|
|
571
|
+
"copilot",
|
|
487
572
|
):
|
|
488
573
|
raise ValueError(
|
|
489
|
-
f"Unsupported platform: {platform} (must be 'claude', 'opencode', 'cursor', 'iflow', 'codex', 'kilo', 'kiro', 'gemini', 'antigravity',
|
|
574
|
+
f"Unsupported platform: {platform} (must be 'claude', 'opencode', 'cursor', 'iflow', 'codex', 'kilo', 'kiro', 'gemini', 'antigravity', 'windsurf', 'qoder', 'codebuddy', or 'copilot')"
|
|
490
575
|
)
|
|
491
576
|
|
|
492
577
|
return CLIAdapter(platform=platform) # type: ignore
|
|
@@ -498,10 +583,15 @@ _ALL_PLATFORM_CONFIG_DIRS = (
|
|
|
498
583
|
".iflow",
|
|
499
584
|
".opencode",
|
|
500
585
|
".agents",
|
|
586
|
+
".codex",
|
|
501
587
|
".kilocode",
|
|
502
588
|
".kiro",
|
|
503
589
|
".gemini",
|
|
504
590
|
".agent",
|
|
591
|
+
".windsurf",
|
|
592
|
+
".qoder",
|
|
593
|
+
".codebuddy",
|
|
594
|
+
".github/copilot",
|
|
505
595
|
)
|
|
506
596
|
"""All platform config directory names (used by detect_platform exclusion checks)."""
|
|
507
597
|
|
|
@@ -523,19 +613,21 @@ def detect_platform(project_root: Path) -> Platform:
|
|
|
523
613
|
2. .opencode directory exists → opencode
|
|
524
614
|
3. .iflow directory exists → iflow
|
|
525
615
|
4. .cursor directory exists (without .claude) → cursor
|
|
526
|
-
5. .
|
|
616
|
+
5. .codex exists and no other platform dirs → codex
|
|
527
617
|
6. .kilocode directory exists → kilo
|
|
528
618
|
7. .kiro/skills exists and no other platform dirs → kiro
|
|
529
619
|
8. .gemini directory exists → gemini
|
|
530
620
|
9. .agent/workflows exists and no other platform dirs → antigravity
|
|
531
|
-
10. .
|
|
532
|
-
11.
|
|
621
|
+
10. .windsurf/workflows exists and no other platform dirs → windsurf
|
|
622
|
+
11. .codebuddy directory exists → codebuddy
|
|
623
|
+
12. .qoder directory exists → qoder
|
|
624
|
+
13. Default → claude
|
|
533
625
|
|
|
534
626
|
Args:
|
|
535
627
|
project_root: Project root directory
|
|
536
628
|
|
|
537
629
|
Returns:
|
|
538
|
-
Detected platform ('claude', 'opencode', 'cursor', 'iflow', 'codex', 'kilo', 'kiro', 'gemini', 'antigravity',
|
|
630
|
+
Detected platform ('claude', 'opencode', 'cursor', 'iflow', 'codex', 'kilo', 'kiro', 'gemini', 'antigravity', 'windsurf', 'qoder', 'codebuddy', or default 'claude')
|
|
539
631
|
"""
|
|
540
632
|
import os
|
|
541
633
|
|
|
@@ -551,7 +643,10 @@ def detect_platform(project_root: Path) -> Platform:
|
|
|
551
643
|
"kiro",
|
|
552
644
|
"gemini",
|
|
553
645
|
"antigravity",
|
|
646
|
+
"windsurf",
|
|
554
647
|
"qoder",
|
|
648
|
+
"codebuddy",
|
|
649
|
+
"copilot",
|
|
555
650
|
):
|
|
556
651
|
return env_platform # type: ignore
|
|
557
652
|
|
|
@@ -572,9 +667,10 @@ def detect_platform(project_root: Path) -> Platform:
|
|
|
572
667
|
if (project_root / ".gemini").is_dir():
|
|
573
668
|
return "gemini"
|
|
574
669
|
|
|
575
|
-
# Check for
|
|
576
|
-
|
|
577
|
-
|
|
670
|
+
# Check for .codex directory (Codex-specific)
|
|
671
|
+
# .agents/skills/ alone does NOT trigger codex detection (it's a shared standard)
|
|
672
|
+
if (project_root / ".codex").is_dir() and not _has_other_platform_dir(
|
|
673
|
+
project_root, {".codex", ".agents"}
|
|
578
674
|
):
|
|
579
675
|
return "codex"
|
|
580
676
|
|
|
@@ -596,10 +692,26 @@ def detect_platform(project_root: Path) -> Platform:
|
|
|
596
692
|
):
|
|
597
693
|
return "antigravity"
|
|
598
694
|
|
|
695
|
+
# Check for Windsurf workflow directory only when no other platform config exists
|
|
696
|
+
if (
|
|
697
|
+
project_root / ".windsurf" / "workflows"
|
|
698
|
+
).is_dir() and not _has_other_platform_dir(
|
|
699
|
+
project_root, {".windsurf"}
|
|
700
|
+
):
|
|
701
|
+
return "windsurf"
|
|
702
|
+
|
|
703
|
+
# Check for .codebuddy directory (CodeBuddy-specific)
|
|
704
|
+
if (project_root / ".codebuddy").is_dir():
|
|
705
|
+
return "codebuddy"
|
|
706
|
+
|
|
599
707
|
# Check for .qoder directory (Qoder-specific)
|
|
600
708
|
if (project_root / ".qoder").is_dir():
|
|
601
709
|
return "qoder"
|
|
602
710
|
|
|
711
|
+
# Check for .github/copilot directory (GitHub Copilot-specific)
|
|
712
|
+
if (project_root / ".github" / "copilot").is_dir():
|
|
713
|
+
return "copilot"
|
|
714
|
+
|
|
603
715
|
return "claude"
|
|
604
716
|
|
|
605
717
|
|
|
@@ -21,6 +21,15 @@ DEFAULT_MAX_JOURNAL_LINES = 2000
|
|
|
21
21
|
CONFIG_FILE = "config.yaml"
|
|
22
22
|
|
|
23
23
|
|
|
24
|
+
def _is_true_config_value(value: object) -> bool:
|
|
25
|
+
"""Return True when a config value represents an enabled flag."""
|
|
26
|
+
if isinstance(value, bool):
|
|
27
|
+
return value
|
|
28
|
+
if isinstance(value, str):
|
|
29
|
+
return value.strip().lower() == "true"
|
|
30
|
+
return False
|
|
31
|
+
|
|
32
|
+
|
|
24
33
|
def _get_config_path(repo_root: Path | None = None) -> Path:
|
|
25
34
|
"""Get path to config.yaml."""
|
|
26
35
|
root = repo_root or get_repo_root()
|
|
@@ -130,6 +139,37 @@ def get_submodule_packages(repo_root: Path | None = None) -> dict[str, str]:
|
|
|
130
139
|
}
|
|
131
140
|
|
|
132
141
|
|
|
142
|
+
def get_git_packages(repo_root: Path | None = None) -> dict[str, str]:
|
|
143
|
+
"""Get packages that have their own independent git repository.
|
|
144
|
+
|
|
145
|
+
These are sub-directories with their own .git (not submodules),
|
|
146
|
+
marked with ``git: true`` in config.yaml.
|
|
147
|
+
|
|
148
|
+
Returns:
|
|
149
|
+
Dict mapping package name to its path for git-repo packages.
|
|
150
|
+
Empty dict if none configured.
|
|
151
|
+
|
|
152
|
+
Example config::
|
|
153
|
+
|
|
154
|
+
packages:
|
|
155
|
+
backend:
|
|
156
|
+
path: iqs
|
|
157
|
+
git: true
|
|
158
|
+
|
|
159
|
+
Example return::
|
|
160
|
+
|
|
161
|
+
{"backend": "iqs"}
|
|
162
|
+
"""
|
|
163
|
+
packages = get_packages(repo_root)
|
|
164
|
+
if packages is None:
|
|
165
|
+
return {}
|
|
166
|
+
return {
|
|
167
|
+
name: cfg.get("path", name)
|
|
168
|
+
for name, cfg in packages.items()
|
|
169
|
+
if _is_true_config_value(cfg.get("git"))
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
|
|
133
173
|
def is_monorepo(repo_root: Path | None = None) -> bool:
|
|
134
174
|
"""Check if the project is configured as a monorepo (has packages in config)."""
|
|
135
175
|
return get_packages(repo_root) is not None
|
|
@@ -123,8 +123,8 @@ def init_developer(name: str, repo_root: Path | None = None) -> bool:
|
|
|
123
123
|
## Session History
|
|
124
124
|
|
|
125
125
|
<!-- @@@auto:session-history -->
|
|
126
|
-
| # | Date | Title | Commits |
|
|
127
|
-
|
|
126
|
+
| # | Date | Title | Commits | Branch |
|
|
127
|
+
|---|------|-------|---------|--------|
|
|
128
128
|
<!-- @@@/auto:session-history -->
|
|
129
129
|
|
|
130
130
|
---
|