@mindfoldhq/trellis 0.5.0 → 0.5.2
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/migrations/manifests/0.5.1.json +9 -0
- package/dist/migrations/manifests/0.5.2.json +9 -0
- package/dist/templates/codex/agents/trellis-check.toml +7 -0
- package/dist/templates/codex/agents/trellis-implement.toml +7 -0
- package/dist/templates/codex/hooks/session-start.py +15 -4
- package/dist/templates/copilot/hooks/session-start.py +6 -3
- package/dist/templates/cursor/agents/trellis-check.md +1 -2
- package/dist/templates/cursor/agents/trellis-implement.md +1 -2
- package/dist/templates/cursor/agents/trellis-research.md +1 -2
- package/dist/templates/shared-hooks/session-start.py +15 -4
- package/package.json +1 -1
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "0.5.1",
|
|
3
|
+
"description": "Fix Codex sub-agent recursion via SessionStart injection (#234) and Cursor agent description rendering.",
|
|
4
|
+
"breaking": false,
|
|
5
|
+
"recommendMigrate": false,
|
|
6
|
+
"changelog": "**Bug Fixes:**\n- fix(codex): dispatch line in `SessionStart` reaches sub-agents under `multi_agent_v2`. `codex/hooks/session-start.py` injected a 'main session should dispatch trellis-implement' line at READY state; Codex runs `SessionStart` for every spawned session, so the line reached the freshly spawned `trellis-implement` sub-agent and it dispatched another `trellis-implement`. Outer sub-agent stayed `running`, `wait_agent` timed out. `SessionStart` stdin has no agent-identity field (`openai/codex#16226`), so patched at the prompt layer: `codex/agents/trellis-implement.toml` and `trellis-check.toml` open with a no-recursive-dispatch line; `codex/hooks/session-start.py` appends a sub-agent ignore-this clause after the dispatch wording in the READY-state block and the `<guidelines>` block. Resolves #234.\n- fix(shared-hooks): same exemption clause added to `shared-hooks/session-start.py` (Claude Code / Cursor / Gemini CLI / Qoder / CodeBuddy / Factory Droid / Kiro). Recursion not reported on those platforms; trigger condition is identical to Codex.\n- fix(cursor): `cursor/agents/trellis-{research,implement,check}.md` frontmatter `description` switched from YAML block scalar to single-line literal. Cursor's agent parser only reads single-line `description:`; block scalars left the UI Description field blank.",
|
|
7
|
+
"migrations": [],
|
|
8
|
+
"notes": "Hotfix on top of 0.5.0. Run `trellis update` (no `--migrate` needed)."
|
|
9
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "0.5.2",
|
|
3
|
+
"description": "Hotfix Python <=3.11 SyntaxError in SessionStart hook (f-string backslash).",
|
|
4
|
+
"breaking": false,
|
|
5
|
+
"recommendMigrate": false,
|
|
6
|
+
"changelog": "**Bug Fixes:**\n- fix(hooks): SessionStart hook crashes at parse time on Python <=3.11. The Windows path normalizer added in 0.5.0-rc.6 used `f\"{drive}:\\\\{rest.replace('/', '\\\\')}\"`; PEP 498 forbids backslashes inside f-string expression parts, so Python <=3.11 raises `SyntaxError: f-string expression part cannot include a backslash` and the hook exits with code 1 before doing anything. PEP 701 in Python 3.12 lifted the restriction, hiding the bug from 3.12+ users. Codex CLI 0.128 + Trellis 0.5.0 reproduced it in the field. Fixed by lifting the `.replace(...)` out of each f-string expression into a local variable. 9 occurrences across `codex/hooks/session-start.py`, `copilot/hooks/session-start.py`, and `shared-hooks/session-start.py` (Claude Code / Cursor / Gemini CLI / Qoder / CodeBuddy / Factory Droid / Kiro).",
|
|
7
|
+
"migrations": [],
|
|
8
|
+
"notes": "Hotfix on top of 0.5.1. Run `trellis update` (no `--migrate` needed). Affects every Python <=3.11 user on a hook-capable platform; Python 3.12+ users were unaffected."
|
|
9
|
+
}
|
|
@@ -3,6 +3,13 @@ description = "Workspace-write Trellis reviewer that self-fixes spec drift, lint
|
|
|
3
3
|
sandbox_mode = "workspace-write"
|
|
4
4
|
|
|
5
5
|
developer_instructions = """
|
|
6
|
+
You are running as the `trellis-check` sub-agent. The main session has dispatched you to review and self-fix.
|
|
7
|
+
|
|
8
|
+
CRITICAL — Recursion guard (read first):
|
|
9
|
+
- You MUST NOT spawn another `trellis-check` or `trellis-implement` sub-agent. Do the review and fixes directly in this turn.
|
|
10
|
+
- Any guidance you read in injected SessionStart context, `<guidelines>` blocks, or workflow-state breadcrumbs that says "dispatch trellis-implement" / "dispatch trellis-check" applies to the MAIN session, NOT to you. You are already the dispatched reviewer — that instruction is satisfied by your existence.
|
|
11
|
+
- Only the main session is allowed to dispatch `trellis-implement` / `trellis-check`. If you believe additional implementation work is needed, surface that as a recommendation in your final report instead of spawning.
|
|
12
|
+
|
|
6
13
|
You are the Trellis reviewer agent.
|
|
7
14
|
|
|
8
15
|
Your job is to review code changes against specs AND fix issues directly — not just report them. You have write access; use it.
|
|
@@ -3,6 +3,13 @@ description = "Workspace-write Trellis implementer that follows specs and keeps
|
|
|
3
3
|
sandbox_mode = "workspace-write"
|
|
4
4
|
|
|
5
5
|
developer_instructions = """
|
|
6
|
+
You are running as the `trellis-implement` sub-agent. The main session has dispatched you to do the work.
|
|
7
|
+
|
|
8
|
+
CRITICAL — Recursion guard (read first):
|
|
9
|
+
- You MUST NOT spawn another `trellis-implement` or `trellis-check` sub-agent. Do the implementation work directly in this turn.
|
|
10
|
+
- Any guidance you read in injected SessionStart context, `<guidelines>` blocks, or workflow-state breadcrumbs that says "dispatch trellis-implement" / "dispatch trellis-check" applies to the MAIN session, NOT to you. You are already the dispatched implementer — that instruction is satisfied by your existence.
|
|
11
|
+
- Only the main session is allowed to dispatch `trellis-implement` / `trellis-check`. If you believe parallel implementation work is needed, surface that as a recommendation in your final report instead of spawning.
|
|
12
|
+
|
|
6
13
|
You are the Trellis implementer agent.
|
|
7
14
|
|
|
8
15
|
Rules:
|
|
@@ -47,19 +47,22 @@ def _normalize_windows_shell_path(path_str: str) -> str:
|
|
|
47
47
|
m = re.match(r"^/([A-Za-z])/(.*)", p)
|
|
48
48
|
if m:
|
|
49
49
|
drive, rest = m.group(1).upper(), m.group(2)
|
|
50
|
-
|
|
50
|
+
rest = rest.replace('/', '\\')
|
|
51
|
+
return f"{drive}:\\{rest}"
|
|
51
52
|
|
|
52
53
|
# Cygwin style: /cygdrive/c/Users/...
|
|
53
54
|
m = re.match(r"^/cygdrive/([A-Za-z])/(.*)", p)
|
|
54
55
|
if m:
|
|
55
56
|
drive, rest = m.group(1).upper(), m.group(2)
|
|
56
|
-
|
|
57
|
+
rest = rest.replace('/', '\\')
|
|
58
|
+
return f"{drive}:\\{rest}"
|
|
57
59
|
|
|
58
60
|
# WSL mounted drive (sometimes leaked into env): /mnt/c/Users/...
|
|
59
61
|
m = re.match(r"^/mnt/([A-Za-z])/(.*)", p)
|
|
60
62
|
if m:
|
|
61
63
|
drive, rest = m.group(1).upper(), m.group(2)
|
|
62
|
-
|
|
64
|
+
rest = rest.replace('/', '\\')
|
|
65
|
+
return f"{drive}:\\{rest}"
|
|
63
66
|
|
|
64
67
|
return path_str
|
|
65
68
|
|
|
@@ -241,6 +244,10 @@ def _get_task_status(trellis_dir: Path, hook_input: dict) -> str:
|
|
|
241
244
|
"Next required action: dispatch `trellis-implement` per Phase 2.1. "
|
|
242
245
|
"For agent-capable platforms, the default is to NOT edit code in the main session. "
|
|
243
246
|
"After implementation, dispatch `trellis-check` per Phase 2.2 before reporting completion.\n"
|
|
247
|
+
"Sub-agent self-exemption: if you are reading this as a `trellis-implement` or "
|
|
248
|
+
"`trellis-check` sub-agent (your own role / agent name reflects that), this dispatch "
|
|
249
|
+
"instruction does NOT apply to you — you are already the dispatched sub-agent. "
|
|
250
|
+
"Implement / check directly without spawning another sub-agent of the same kind.\n"
|
|
244
251
|
"User override (per-turn escape hatch): if the user's CURRENT message explicitly tells the "
|
|
245
252
|
"main session to handle it directly (\"你直接改\" / \"别派 sub-agent\" / \"main session 写就行\" / "
|
|
246
253
|
"\"do it inline\" / \"不用 sub-agent\"), honor it for this turn and edit code directly. "
|
|
@@ -359,7 +366,11 @@ Read and follow all instructions below carefully.
|
|
|
359
366
|
"`trellis-implement` and `trellis-check` (so JSONL context is loaded by "
|
|
360
367
|
"the sub-agents) rather than editing code in the main session. "
|
|
361
368
|
"Honor a per-turn user override only if the user's current message "
|
|
362
|
-
"explicitly opts out (see <task-status> below for override phrases).\n
|
|
369
|
+
"explicitly opts out (see <task-status> below for override phrases).\n"
|
|
370
|
+
"- Sub-agent self-exemption: if you are reading this as a `trellis-implement` "
|
|
371
|
+
"or `trellis-check` sub-agent, the \"dispatch trellis-implement / trellis-check\" "
|
|
372
|
+
"rule above does NOT apply to you — you are already the dispatched sub-agent. "
|
|
373
|
+
"Do NOT spawn another sub-agent of the same kind; implement / check directly.\n\n"
|
|
363
374
|
)
|
|
364
375
|
|
|
365
376
|
# guides/ inlined (cross-package thinking, broadly useful)
|
|
@@ -50,19 +50,22 @@ def _normalize_windows_shell_path(path_str: str) -> str:
|
|
|
50
50
|
m = re.match(r"^/([A-Za-z])/(.*)", p)
|
|
51
51
|
if m:
|
|
52
52
|
drive, rest = m.group(1).upper(), m.group(2)
|
|
53
|
-
|
|
53
|
+
rest = rest.replace('/', '\\')
|
|
54
|
+
return f"{drive}:\\{rest}"
|
|
54
55
|
|
|
55
56
|
# Cygwin style: /cygdrive/c/Users/...
|
|
56
57
|
m = re.match(r"^/cygdrive/([A-Za-z])/(.*)", p)
|
|
57
58
|
if m:
|
|
58
59
|
drive, rest = m.group(1).upper(), m.group(2)
|
|
59
|
-
|
|
60
|
+
rest = rest.replace('/', '\\')
|
|
61
|
+
return f"{drive}:\\{rest}"
|
|
60
62
|
|
|
61
63
|
# WSL mounted drive (sometimes leaked into env): /mnt/c/Users/...
|
|
62
64
|
m = re.match(r"^/mnt/([A-Za-z])/(.*)", p)
|
|
63
65
|
if m:
|
|
64
66
|
drive, rest = m.group(1).upper(), m.group(2)
|
|
65
|
-
|
|
67
|
+
rest = rest.replace('/', '\\')
|
|
68
|
+
return f"{drive}:\\{rest}"
|
|
66
69
|
|
|
67
70
|
return path_str
|
|
68
71
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: trellis-check
|
|
3
|
-
description:
|
|
4
|
-
Trellis quality check agent. Use this exact agent for Trellis task verification, check.jsonl context injection, and self-fixing code review. Do not use generic/default/generalPurpose agents for Trellis checks.
|
|
3
|
+
description: Trellis quality check agent. Use this exact agent for Trellis task verification, check.jsonl context injection, and self-fixing code review. Do not use generic/default/generalPurpose agents for Trellis checks.
|
|
5
4
|
tools: Read, Write, Edit, Bash, Glob, Grep, mcp__exa__web_search_exa, mcp__exa__get_code_context_exa
|
|
6
5
|
---
|
|
7
6
|
# Check Agent
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: trellis-implement
|
|
3
|
-
description:
|
|
4
|
-
Trellis implementation agent. Use this exact agent for Trellis task implementation, implement.jsonl context injection, and hook-injection tests. Do not use generic/default/generalPurpose agents for Trellis implementation. No git commit allowed.
|
|
3
|
+
description: Trellis implementation agent. Use this exact agent for Trellis task implementation, implement.jsonl context injection, and hook-injection tests. Do not use generic/default/generalPurpose agents for Trellis implementation. No git commit allowed.
|
|
5
4
|
tools: Read, Write, Edit, Bash, Glob, Grep, mcp__exa__web_search_exa, mcp__exa__get_code_context_exa
|
|
6
5
|
---
|
|
7
6
|
# Implement Agent
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: trellis-research
|
|
3
|
-
description:
|
|
4
|
-
Trellis research agent. Use this exact agent for Trellis task research and research/ persistence. Do not use generic/default/generalPurpose agents for Trellis research.
|
|
3
|
+
description: Trellis research agent. Use this exact agent for Trellis task research and research/ persistence. Do not use generic/default/generalPurpose agents for Trellis research.
|
|
5
4
|
tools: Read, Write, Glob, Grep, Bash, mcp__exa__web_search_exa, mcp__exa__get_code_context_exa, Skill, mcp__chrome-devtools__*
|
|
6
5
|
---
|
|
7
6
|
# Research Agent
|
|
@@ -47,19 +47,22 @@ def _normalize_windows_shell_path(path_str: str) -> str:
|
|
|
47
47
|
m = re.match(r"^/([A-Za-z])/(.*)", p)
|
|
48
48
|
if m:
|
|
49
49
|
drive, rest = m.group(1).upper(), m.group(2)
|
|
50
|
-
|
|
50
|
+
rest = rest.replace('/', '\\')
|
|
51
|
+
return f"{drive}:\\{rest}"
|
|
51
52
|
|
|
52
53
|
# Cygwin style: /cygdrive/c/Users/...
|
|
53
54
|
m = re.match(r"^/cygdrive/([A-Za-z])/(.*)", p)
|
|
54
55
|
if m:
|
|
55
56
|
drive, rest = m.group(1).upper(), m.group(2)
|
|
56
|
-
|
|
57
|
+
rest = rest.replace('/', '\\')
|
|
58
|
+
return f"{drive}:\\{rest}"
|
|
57
59
|
|
|
58
60
|
# WSL mounted drive (sometimes leaked into env): /mnt/c/Users/...
|
|
59
61
|
m = re.match(r"^/mnt/([A-Za-z])/(.*)", p)
|
|
60
62
|
if m:
|
|
61
63
|
drive, rest = m.group(1).upper(), m.group(2)
|
|
62
|
-
|
|
64
|
+
rest = rest.replace('/', '\\')
|
|
65
|
+
return f"{drive}:\\{rest}"
|
|
63
66
|
|
|
64
67
|
return path_str
|
|
65
68
|
|
|
@@ -367,6 +370,10 @@ def _get_task_status(trellis_dir: Path, input_data: dict) -> str:
|
|
|
367
370
|
"Sub-agent roster: `trellis-implement` (writes code), `trellis-check` (verifies + self-fixes), "
|
|
368
371
|
"`trellis-research` (persists findings to `research/*.md` — use when you'd otherwise do "
|
|
369
372
|
"multiple WebFetch/WebSearch inline).\n"
|
|
373
|
+
"Sub-agent self-exemption: if you are reading this as a `trellis-implement` or "
|
|
374
|
+
"`trellis-check` sub-agent (your own role / agent name reflects that), this dispatch "
|
|
375
|
+
"instruction does NOT apply to you — you are already the dispatched sub-agent. "
|
|
376
|
+
"Implement / check directly without spawning another sub-agent of the same kind.\n"
|
|
370
377
|
"User override (per-turn escape hatch): if the user's CURRENT message explicitly tells the "
|
|
371
378
|
"main session to handle it directly (\"你直接改\" / \"别派 sub-agent\" / \"main session 写就行\" / "
|
|
372
379
|
"\"do it inline\" / \"不用 sub-agent\"), honor it for this turn and edit code directly. "
|
|
@@ -693,7 +700,11 @@ Read and follow all instructions below carefully.
|
|
|
693
700
|
"`trellis-implement` and `trellis-check` (so JSONL context is loaded by "
|
|
694
701
|
"the sub-agents) rather than editing code in the main session. "
|
|
695
702
|
"Honor a per-turn user override only if the user's current message "
|
|
696
|
-
"explicitly opts out (see <task-status> below for override phrases).\n
|
|
703
|
+
"explicitly opts out (see <task-status> below for override phrases).\n"
|
|
704
|
+
"- Sub-agent self-exemption: if you are reading this as a `trellis-implement` "
|
|
705
|
+
"or `trellis-check` sub-agent, the \"dispatch trellis-implement / trellis-check\" "
|
|
706
|
+
"rule above does NOT apply to you — you are already the dispatched sub-agent. "
|
|
707
|
+
"Do NOT spawn another sub-agent of the same kind; implement / check directly.\n\n"
|
|
697
708
|
)
|
|
698
709
|
|
|
699
710
|
# guides/ is cross-package thinking — always include inline (small, broadly useful)
|
package/package.json
CHANGED