@mindfoldhq/trellis 0.5.0-beta.12 → 0.5.0-beta.14
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.0-beta.13.json +9 -0
- package/dist/migrations/manifests/0.5.0-beta.14.json +9 -0
- package/dist/templates/codex/agents/trellis-check.toml +16 -0
- package/dist/templates/codex/agents/trellis-implement.toml +16 -0
- package/dist/templates/codex/hooks/session-start.py +35 -5
- package/dist/templates/copilot/hooks/session-start.py +37 -9
- package/dist/templates/opencode/plugins/inject-workflow-state.js +5 -1
- package/dist/templates/opencode/plugins/session-start.js +20 -8
- package/dist/templates/shared-hooks/inject-workflow-state.py +5 -2
- package/dist/templates/shared-hooks/session-start.py +16 -8
- package/dist/templates/shared-hooks/statusline.py +4 -3
- package/dist/templates/trellis/scripts/task.py +10 -1
- package/dist/templates/trellis/workflow.md +2 -1
- package/package.json +1 -1
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "0.5.0-beta.13",
|
|
3
|
+
"description": "Patch follow-up to beta.12: `task.py start` now transitions `task.json` status planning → in_progress (previously stuck at planning even after the user explicitly started work). Codex sub-agent instructions for seed-row handling — written into the dogfood root during beta.11's init-context-removal but never backported into `packages/cli/src/templates/codex/agents/` — are now in the packaged templates, so fresh `trellis init` / `trellis update` finally ship Phase 1.3 fallback guidance to Codex users. `.codex/config.toml` documents the `features.codex_hooks` user-level opt-in. No src/ changes; `trellis update` is a straight content refresh.",
|
|
4
|
+
"breaking": false,
|
|
5
|
+
"recommendMigrate": false,
|
|
6
|
+
"changelog": "**Bug Fixes:**\n- fix(task.py): `task.py start <task>` transitions `task.json` status `planning` → `in_progress`. Previously `cmd_start` only wrote `.current-task` and ran `after_start` hooks — user explicitly started work but status stayed at `planning`. Non-`planning` statuses (`in_progress`, `review`, `completed`) are preserved on resume so replays don't clobber progress. See `packages/cli/src/templates/trellis/scripts/task.py:cmd_start`.\n- fix(templates/codex): backport the \"Required: Load Trellis Context First\" preamble into packaged `codex/agents/trellis-check.toml` and `codex/agents/trellis-implement.toml`. The block teaches Codex sub-agents to (1) skip `{\"_example\": ...}` seed rows and (2) fall back to prd-only context plus self-discovered specs via `get_context.py --mode packages` when the jsonl has no curated entries. It was edited into the dogfood root during beta.11 init-context-removal but never propagated into `packages/cli/src/templates/codex/agents/`, so up through beta.12 Codex users on fresh `trellis init` / `trellis update` got agent prompts missing the Phase 1.3 fallback path and the agents blocked on seed-only jsonl instead of proceeding with prd.md + spec judgment.\n\n**Docs:**\n- docs(codex): `.codex/config.toml` documents the `[features] codex_hooks = true` user-level opt-in. Project-scoped config cannot enable `features.*`; without the flag, `hooks.json` is silently ignored and Trellis context injection never runs — previously this looked like a bug. The old `shell_environment_policy` stub (dead config unrelated to Trellis) is removed in favor of the opt-in hint.",
|
|
7
|
+
"migrations": [],
|
|
8
|
+
"notes": "Pure content refresh. Existing tasks and jsonl files keep working untouched. After `trellis update`, `task.py start <existing-task-in-planning>` will now write `in_progress` on the first invocation — no action needed from you. Codex users who manually edited their `.codex/agents/trellis-*.toml` will see the Required-Context preamble added on update; `trellis update` prompts per-file when hashes drift."
|
|
9
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "0.5.0-beta.14",
|
|
3
|
+
"description": "Patch follow-up to beta.13: SessionStart hooks now emit a one-shot `<first-reply-notice>` block so the first visible assistant reply announces that Trellis context has been injected (proof-of-load for noisy or summarized hosts). READY-state breadcrumbs across shared/opencode/codex/copilot hooks + `trellis/workflow.md` replace the soft \"Continue with implement or check\" wording with an explicit \"Next required action: dispatch `trellis-implement` … do NOT edit code in the main session\" directive, closing a loophole where agent-capable sessions would still hand-edit code in the main thread. Windows statusline no longer crashes on typed stdout/stderr streams: `sys.stdout.detach() + TextIOWrapper(...)` is replaced with `reconfigure(encoding='utf-8', errors='replace')`. No src/ runtime-code changes outside templates; `trellis update` is a straight content refresh.",
|
|
4
|
+
"breaking": false,
|
|
5
|
+
"recommendMigrate": false,
|
|
6
|
+
"changelog": "**Enhancements:**\n- feat(hooks): SessionStart emits a one-shot `<first-reply-notice>` block instructing the model to open its first visible reply with one short Chinese sentence confirming Trellis context has been injected (workflow, task status, developer identity, git status, active tasks, spec index). Applied to `shared-hooks/session-start.py`, `codex/hooks/session-start.py`, `opencode/plugins/session-start.js`. Notice is explicitly one-shot — not repeated on later turns in the same session. Closes the visibility gap on hosts that collapse or summarize hook output.\n- feat(hooks): READY-state breadcrumbs now say \"Next required action: dispatch `trellis-implement` per Phase 2.1. For agent-capable platforms, do NOT edit code in the main session. After implementation, dispatch `trellis-check` per Phase 2.2 before reporting completion.\" Replaces the old \"Next: Continue with implement or check\" wording that let the main thread silently hand-edit code. Applied uniformly across `shared-hooks/session-start.py` + `inject-workflow-state.py`, `opencode/plugins/session-start.js` + `inject-workflow-state.js`, `codex/hooks/session-start.py`, `copilot/hooks/session-start.py`, and the `[workflow-state:in_progress]` block in `trellis/workflow.md`. `<ready>` directive also drops the \"ask whether to continue\" prompt in favor of \"execute its Next required action\".\n\n**Bug Fixes:**\n- fix(statusline): Windows UTF-8 setup replaces `sys.stdout = io.TextIOWrapper(sys.stdout.detach(), encoding='utf-8')` with `stream.reconfigure(encoding='utf-8', errors='replace')`. The old pattern crashed on hosts that wrap stdout/stderr with typed streams (Copilot / certain Codex environments) because `detach()` is not available on typed wrappers. `reconfigure` is the supported API on Python 3.7+ text streams and is a no-op when unavailable. Fix applied to `shared-hooks/statusline.py`.\n- fix(hooks): Codex and Copilot SessionStart hooks now invoke a shared `configure_project_encoding(project_dir)` helper before emitting JSON, loading `.trellis/scripts/common.configure_encoding()` when present. Prevents stray mojibake in hook stdout on Windows Codex/Copilot runs that haven't already wrapped stdout.\n- docs(copilot): `copilot/hooks/session-start.py` docstring + `systemMessage` text now state plainly that GitHub Copilot currently ignores `sessionStart` hook output. The JSON shape is kept for protocol parity and future host support, but users should rely on `UserPromptSubmit` breadcrumbs and hook logs for Copilot today.",
|
|
7
|
+
"migrations": [],
|
|
8
|
+
"notes": "Pure content refresh. Existing tasks, jsonl files, and `.current-task` are preserved. After `trellis update`, fresh sessions across Claude Code / Codex / Copilot / OpenCode will prepend a one-line Chinese confirmation of SessionStart context on the first assistant reply, and the main thread will no longer be nudged to hand-edit code when a task is READY. Windows statusline stops crashing on Copilot/Codex typed stdout. No action needed beyond `trellis update`."
|
|
9
|
+
}
|
|
@@ -3,6 +3,22 @@ description = "Workspace-write Trellis reviewer that self-fixes spec drift, lint
|
|
|
3
3
|
sandbox_mode = "workspace-write"
|
|
4
4
|
|
|
5
5
|
developer_instructions = """
|
|
6
|
+
## Required: Load Trellis Context First
|
|
7
|
+
|
|
8
|
+
This platform does NOT auto-inject task context via hook. Before doing anything else, you MUST load context yourself:
|
|
9
|
+
|
|
10
|
+
1. Read `.trellis/.current-task` to find the current task path (e.g. `.trellis/tasks/04-17-foo/`).
|
|
11
|
+
2. Read the task's `prd.md` (requirements) and `info.md` if it exists (technical design).
|
|
12
|
+
3. Read `<task-path>/check.jsonl` — JSONL list of dev spec files relevant to this agent.
|
|
13
|
+
4. For each entry in the JSONL, Read its `file` path — these are the dev specs you must follow.
|
|
14
|
+
**Skip rows without a `"file"` field** (e.g. `{"_example": "..."}` seed rows left over from `task.py create` before the curator ran).
|
|
15
|
+
|
|
16
|
+
If `check.jsonl` has no curated entries (only a seed row, or the file is missing), fall back to: read `prd.md`, list available specs with `python3 ./.trellis/scripts/get_context.py --mode packages`, and pick the specs that match the task domain yourself. Do NOT block on the missing jsonl — proceed with prd-only context plus your spec judgment.
|
|
17
|
+
|
|
18
|
+
If `.current-task` is missing or the task has no `prd.md`, ask the user what to work on; do NOT proceed without context.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
6
22
|
You are the Trellis reviewer agent.
|
|
7
23
|
|
|
8
24
|
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,22 @@ description = "Workspace-write Trellis implementer that follows specs and keeps
|
|
|
3
3
|
sandbox_mode = "workspace-write"
|
|
4
4
|
|
|
5
5
|
developer_instructions = """
|
|
6
|
+
## Required: Load Trellis Context First
|
|
7
|
+
|
|
8
|
+
This platform does NOT auto-inject task context via hook. Before doing anything else, you MUST load context yourself:
|
|
9
|
+
|
|
10
|
+
1. Read `.trellis/.current-task` to find the current task path (e.g. `.trellis/tasks/04-17-foo/`).
|
|
11
|
+
2. Read the task's `prd.md` (requirements) and `info.md` if it exists (technical design).
|
|
12
|
+
3. Read `<task-path>/implement.jsonl` — JSONL list of dev spec files relevant to this agent.
|
|
13
|
+
4. For each entry in the JSONL, Read its `file` path — these are the dev specs you must follow.
|
|
14
|
+
**Skip rows without a `"file"` field** (e.g. `{"_example": "..."}` seed rows left over from `task.py create` before the curator ran).
|
|
15
|
+
|
|
16
|
+
If `implement.jsonl` has no curated entries (only a seed row, or the file is missing), fall back to: read `prd.md`, list available specs with `python3 ./.trellis/scripts/get_context.py --mode packages`, and pick the specs that match the task domain yourself. Do NOT block on the missing jsonl — proceed with prd-only context plus your spec judgment.
|
|
17
|
+
|
|
18
|
+
If `.current-task` is missing or the task has no `prd.md`, ask the user what to work on; do NOT proceed without context.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
6
22
|
You are the Trellis implementer agent.
|
|
7
23
|
|
|
8
24
|
Rules:
|
|
@@ -19,11 +19,31 @@ from pathlib import Path
|
|
|
19
19
|
|
|
20
20
|
warnings.filterwarnings("ignore")
|
|
21
21
|
|
|
22
|
+
FIRST_REPLY_NOTICE = """<first-reply-notice>
|
|
23
|
+
On the first visible assistant reply in this session, begin with exactly one short Chinese sentence:
|
|
24
|
+
Trellis SessionStart 已注入:workflow、当前任务状态、开发者身份、git 状态、active tasks、spec 索引已加载。
|
|
25
|
+
Then continue directly with the user's request. This notice is one-shot: do not repeat it after the first assistant reply in the same session.
|
|
26
|
+
</first-reply-notice>"""
|
|
27
|
+
|
|
22
28
|
|
|
23
29
|
def should_skip_injection() -> bool:
|
|
24
30
|
return os.environ.get("CODEX_NON_INTERACTIVE") == "1"
|
|
25
31
|
|
|
26
32
|
|
|
33
|
+
def configure_project_encoding(project_dir: Path) -> None:
|
|
34
|
+
"""Reuse Trellis' shared Windows stdio encoding helper before JSON output."""
|
|
35
|
+
scripts_dir = project_dir / ".trellis" / "scripts"
|
|
36
|
+
if str(scripts_dir) not in sys.path:
|
|
37
|
+
sys.path.insert(0, str(scripts_dir))
|
|
38
|
+
|
|
39
|
+
try:
|
|
40
|
+
from common import configure_encoding # type: ignore[import-not-found]
|
|
41
|
+
|
|
42
|
+
configure_encoding()
|
|
43
|
+
except Exception:
|
|
44
|
+
pass
|
|
45
|
+
|
|
46
|
+
|
|
27
47
|
def _has_curated_jsonl_entry(jsonl_path: Path) -> bool:
|
|
28
48
|
"""Return True iff jsonl has at least one row with a ``file`` field.
|
|
29
49
|
|
|
@@ -145,7 +165,12 @@ def _get_task_status(trellis_dir: Path) -> str:
|
|
|
145
165
|
if not has_context:
|
|
146
166
|
return f"Status: NOT READY\nTask: {task_title}\nMissing: implement.jsonl / check.jsonl missing or empty\nNext: Curate entries per workflow.md Phase 1.3 (spec + research files only), then `task.py start`"
|
|
147
167
|
|
|
148
|
-
return
|
|
168
|
+
return (
|
|
169
|
+
f"Status: READY\nTask: {task_title}\n"
|
|
170
|
+
"Next required action: dispatch `trellis-implement` per Phase 2.1. "
|
|
171
|
+
"For agent-capable platforms, do NOT edit code in the main session. "
|
|
172
|
+
"After implementation, dispatch `trellis-check` per Phase 2.2 before reporting completion."
|
|
173
|
+
)
|
|
149
174
|
|
|
150
175
|
|
|
151
176
|
def _extract_range(content: str, start_header: str, end_header: str) -> str:
|
|
@@ -203,6 +228,8 @@ def main() -> None:
|
|
|
203
228
|
except (json.JSONDecodeError, KeyError):
|
|
204
229
|
project_dir = Path(".").resolve()
|
|
205
230
|
|
|
231
|
+
configure_project_encoding(project_dir)
|
|
232
|
+
|
|
206
233
|
trellis_dir = project_dir / ".trellis"
|
|
207
234
|
|
|
208
235
|
output = StringIO()
|
|
@@ -213,6 +240,8 @@ Read and follow all instructions below carefully.
|
|
|
213
240
|
</session-context>
|
|
214
241
|
|
|
215
242
|
""")
|
|
243
|
+
output.write(FIRST_REPLY_NOTICE)
|
|
244
|
+
output.write("\n\n")
|
|
216
245
|
|
|
217
246
|
output.write("<current-state>\n")
|
|
218
247
|
context_script = trellis_dir / "scripts" / "get_context.py"
|
|
@@ -231,8 +260,9 @@ Read and follow all instructions below carefully.
|
|
|
231
260
|
"- If you're spawning an implement/check sub-agent, context is injected "
|
|
232
261
|
"automatically via `{task}/implement.jsonl` / `check.jsonl`. You do NOT "
|
|
233
262
|
"need to read these indexes yourself.\n"
|
|
234
|
-
"-
|
|
235
|
-
"
|
|
263
|
+
"- For agent-capable platforms, do NOT edit code directly in the main "
|
|
264
|
+
"session; dispatch `trellis-implement` and `trellis-check` so JSONL "
|
|
265
|
+
"context is loaded by the sub-agents.\n\n"
|
|
236
266
|
)
|
|
237
267
|
|
|
238
268
|
# guides/ inlined (cross-package thinking, broadly useful)
|
|
@@ -281,8 +311,8 @@ Read and follow all instructions below carefully.
|
|
|
281
311
|
|
|
282
312
|
output.write("""<ready>
|
|
283
313
|
Context loaded. Workflow index, project state, and guidelines are already injected above — do NOT re-read them.
|
|
284
|
-
|
|
285
|
-
If
|
|
314
|
+
When the user sends the first message, follow <task-status> and the workflow guide.
|
|
315
|
+
If a task is READY, execute its Next required action without asking whether to continue.
|
|
286
316
|
</ready>""")
|
|
287
317
|
|
|
288
318
|
context = output.getvalue()
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
"""
|
|
4
|
-
Copilot Session Start Hook -
|
|
4
|
+
Copilot Session Start Hook - Emit Trellis session-start diagnostics.
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
GitHub Copilot's documented SessionStart behavior ignores hook output, so this
|
|
7
|
+
script must not be treated as proof that model-visible context was injected.
|
|
8
|
+
The JSON shape is kept for parity with other Trellis hooks and future host
|
|
9
|
+
support, but current Copilot users should rely on UserPromptSubmit breadcrumbs
|
|
10
|
+
and hook logs instead.
|
|
8
11
|
"""
|
|
9
12
|
|
|
10
13
|
from __future__ import annotations
|
|
@@ -24,6 +27,20 @@ def should_skip_injection() -> bool:
|
|
|
24
27
|
return os.environ.get("COPILOT_NON_INTERACTIVE") == "1"
|
|
25
28
|
|
|
26
29
|
|
|
30
|
+
def configure_project_encoding(project_dir: Path) -> None:
|
|
31
|
+
"""Reuse Trellis' shared Windows stdio encoding helper before JSON output."""
|
|
32
|
+
scripts_dir = project_dir / ".trellis" / "scripts"
|
|
33
|
+
if str(scripts_dir) not in sys.path:
|
|
34
|
+
sys.path.insert(0, str(scripts_dir))
|
|
35
|
+
|
|
36
|
+
try:
|
|
37
|
+
from common import configure_encoding # type: ignore[import-not-found]
|
|
38
|
+
|
|
39
|
+
configure_encoding()
|
|
40
|
+
except Exception:
|
|
41
|
+
pass
|
|
42
|
+
|
|
43
|
+
|
|
27
44
|
def _has_curated_jsonl_entry(jsonl_path: Path) -> bool:
|
|
28
45
|
"""Return True iff jsonl has at least one row with a ``file`` field.
|
|
29
46
|
|
|
@@ -145,7 +162,12 @@ def _get_task_status(trellis_dir: Path) -> str:
|
|
|
145
162
|
if not has_context:
|
|
146
163
|
return f"Status: NOT READY\nTask: {task_title}\nMissing: implement.jsonl / check.jsonl missing or empty\nNext: Curate entries per workflow.md Phase 1.3 (spec + research files only), then `task.py start`"
|
|
147
164
|
|
|
148
|
-
return
|
|
165
|
+
return (
|
|
166
|
+
f"Status: READY\nTask: {task_title}\n"
|
|
167
|
+
"Next required action: dispatch `trellis-implement` per Phase 2.1. "
|
|
168
|
+
"For agent-capable platforms, do NOT edit code in the main session. "
|
|
169
|
+
"After implementation, dispatch `trellis-check` per Phase 2.2 before reporting completion."
|
|
170
|
+
)
|
|
149
171
|
|
|
150
172
|
|
|
151
173
|
def _extract_range(content: str, start_header: str, end_header: str) -> str:
|
|
@@ -203,6 +225,8 @@ def main() -> None:
|
|
|
203
225
|
except (json.JSONDecodeError, KeyError):
|
|
204
226
|
project_dir = Path(".").resolve()
|
|
205
227
|
|
|
228
|
+
configure_project_encoding(project_dir)
|
|
229
|
+
|
|
206
230
|
trellis_dir = project_dir / ".trellis"
|
|
207
231
|
|
|
208
232
|
output = StringIO()
|
|
@@ -231,8 +255,9 @@ Read and follow all instructions below carefully.
|
|
|
231
255
|
"- If you're spawning an implement/check sub-agent, context is injected "
|
|
232
256
|
"automatically via `{task}/implement.jsonl` / `check.jsonl`. You do NOT "
|
|
233
257
|
"need to read these indexes yourself.\n"
|
|
234
|
-
"-
|
|
235
|
-
"
|
|
258
|
+
"- For agent-capable platforms, do NOT edit code directly in the main "
|
|
259
|
+
"session; dispatch `trellis-implement` and `trellis-check` so JSONL "
|
|
260
|
+
"context is loaded by the sub-agents.\n\n"
|
|
236
261
|
)
|
|
237
262
|
|
|
238
263
|
# guides/ inlined (cross-package thinking, broadly useful)
|
|
@@ -281,14 +306,17 @@ Read and follow all instructions below carefully.
|
|
|
281
306
|
|
|
282
307
|
output.write("""<ready>
|
|
283
308
|
Context loaded. Workflow index, project state, and guidelines are already injected above — do NOT re-read them.
|
|
284
|
-
|
|
285
|
-
If
|
|
309
|
+
When the user sends the first message, follow <task-status> and the workflow guide.
|
|
310
|
+
If a task is READY, execute its Next required action without asking whether to continue.
|
|
286
311
|
</ready>""")
|
|
287
312
|
|
|
288
313
|
context = output.getvalue()
|
|
289
314
|
result = {
|
|
290
315
|
"suppressOutput": True,
|
|
291
|
-
"systemMessage":
|
|
316
|
+
"systemMessage": (
|
|
317
|
+
f"Trellis SessionStart diagnostics emitted ({len(context)} chars); "
|
|
318
|
+
"Copilot currently ignores sessionStart hook output."
|
|
319
|
+
),
|
|
292
320
|
"hookSpecificOutput": {
|
|
293
321
|
"hookEventName": "SessionStart",
|
|
294
322
|
"additionalContext": context,
|
|
@@ -58,7 +58,11 @@ const FALLBACK_BREADCRUMBS = {
|
|
|
58
58
|
"main session — PRD only links to research files.",
|
|
59
59
|
in_progress:
|
|
60
60
|
"Flow: trellis-implement → trellis-check → trellis-update-spec → finish\n" +
|
|
61
|
-
"
|
|
61
|
+
"Next required action: inspect conversation history + git status, then " +
|
|
62
|
+
"execute the next uncompleted step in that sequence.\n" +
|
|
63
|
+
"For agent-capable platforms, do NOT edit code in the main session; " +
|
|
64
|
+
"dispatch `trellis-implement` for implementation and dispatch " +
|
|
65
|
+
"`trellis-check` before reporting completion.",
|
|
62
66
|
completed:
|
|
63
67
|
"User commits changes; then run task.py archive.",
|
|
64
68
|
}
|
|
@@ -14,6 +14,12 @@ import { TrellisContext, contextCollector, debugLog } from "../lib/trellis-conte
|
|
|
14
14
|
|
|
15
15
|
const PYTHON_CMD = platform() === "win32" ? "python" : "python3"
|
|
16
16
|
|
|
17
|
+
const FIRST_REPLY_NOTICE = `<first-reply-notice>
|
|
18
|
+
On the first visible assistant reply in this session, begin with exactly one short Chinese sentence:
|
|
19
|
+
Trellis SessionStart 已注入:workflow、当前任务状态、开发者身份、git 状态、active tasks、spec 索引已加载。
|
|
20
|
+
Then continue directly with the user's request. This notice is one-shot: do not repeat it after the first assistant reply in the same session.
|
|
21
|
+
</first-reply-notice>`
|
|
22
|
+
|
|
17
23
|
|
|
18
24
|
/**
|
|
19
25
|
* Return true iff jsonl has at least one row with a `file` field.
|
|
@@ -95,7 +101,12 @@ function getTaskStatus(ctx) {
|
|
|
95
101
|
return `Status: NOT READY\nTask: ${taskTitle}\nMissing: implement.jsonl / check.jsonl missing or empty\nNext: Curate entries per workflow.md Phase 1.3 (spec + research files only), then \`task.py start\``
|
|
96
102
|
}
|
|
97
103
|
|
|
98
|
-
return
|
|
104
|
+
return (
|
|
105
|
+
`Status: READY\nTask: ${taskTitle}\n` +
|
|
106
|
+
"Next required action: dispatch `trellis-implement` per Phase 2.1. " +
|
|
107
|
+
"For agent-capable platforms, do NOT edit code in the main session. " +
|
|
108
|
+
"After implementation, dispatch `trellis-check` per Phase 2.2 before reporting completion."
|
|
109
|
+
)
|
|
99
110
|
}
|
|
100
111
|
|
|
101
112
|
/**
|
|
@@ -215,7 +226,7 @@ function resolveSpecScope(config) {
|
|
|
215
226
|
/**
|
|
216
227
|
* Build session context for injection
|
|
217
228
|
*/
|
|
218
|
-
function buildSessionContext(ctx) {
|
|
229
|
+
export function buildSessionContext(ctx) {
|
|
219
230
|
const directory = ctx.directory
|
|
220
231
|
const trellisDir = join(directory, ".trellis")
|
|
221
232
|
|
|
@@ -229,6 +240,7 @@ function buildSessionContext(ctx) {
|
|
|
229
240
|
You are starting a new session in a Trellis-managed project.
|
|
230
241
|
Read and follow all instructions below carefully.
|
|
231
242
|
</trellis-context>`)
|
|
243
|
+
parts.push(FIRST_REPLY_NOTICE)
|
|
232
244
|
|
|
233
245
|
// Legacy migration warning
|
|
234
246
|
const legacyWarning = checkLegacySpec(directory, config)
|
|
@@ -288,8 +300,7 @@ Read and follow all instructions below carefully.
|
|
|
288
300
|
}
|
|
289
301
|
|
|
290
302
|
// 4. Guidelines — paths-only for most indexes; guides/ inlined (cross-package,
|
|
291
|
-
// broadly useful). Sub-agents get their specific specs via jsonl injection
|
|
292
|
-
// main agent reads paths on demand when editing code directly.
|
|
303
|
+
// broadly useful). Sub-agents get their specific specs via jsonl injection.
|
|
293
304
|
parts.push("<guidelines>")
|
|
294
305
|
parts.push(
|
|
295
306
|
"Project spec indexes are listed by path below. Each index contains a " +
|
|
@@ -298,8 +309,9 @@ Read and follow all instructions below carefully.
|
|
|
298
309
|
"- If you're spawning an implement/check sub-agent, context is injected " +
|
|
299
310
|
"automatically via `{task}/implement.jsonl` / `check.jsonl`. You do NOT " +
|
|
300
311
|
"need to read these indexes yourself.\n" +
|
|
301
|
-
"-
|
|
302
|
-
"
|
|
312
|
+
"- For agent-capable platforms, do NOT edit code directly in the main " +
|
|
313
|
+
"session; dispatch `trellis-implement` and `trellis-check` so JSONL " +
|
|
314
|
+
"context is loaded by the sub-agents.\n"
|
|
303
315
|
)
|
|
304
316
|
|
|
305
317
|
const specDir = join(directory, ".trellis", "spec")
|
|
@@ -379,8 +391,8 @@ Read and follow all instructions below carefully.
|
|
|
379
391
|
// 7. Final directive
|
|
380
392
|
parts.push(`<ready>
|
|
381
393
|
Context loaded. Workflow index, project state, and guidelines are already injected above — do NOT re-read them.
|
|
382
|
-
|
|
383
|
-
If
|
|
394
|
+
When the user sends the first message, follow <task-status> and the workflow guide.
|
|
395
|
+
If a task is READY, execute its Next required action without asking whether to continue.
|
|
384
396
|
</ready>`)
|
|
385
397
|
|
|
386
398
|
return parts.join("\n\n")
|
|
@@ -153,8 +153,11 @@ _FALLBACK_BREADCRUMBS = {
|
|
|
153
153
|
),
|
|
154
154
|
"in_progress": (
|
|
155
155
|
"Flow: trellis-implement → trellis-check → trellis-update-spec → finish\n"
|
|
156
|
-
"
|
|
157
|
-
"
|
|
156
|
+
"Next required action: inspect conversation history + git status, then "
|
|
157
|
+
"execute the next uncompleted step in that sequence.\n"
|
|
158
|
+
"For agent-capable platforms, do NOT edit code in the main session; "
|
|
159
|
+
"dispatch `trellis-implement` for implementation and dispatch "
|
|
160
|
+
"`trellis-check` before reporting completion."
|
|
158
161
|
),
|
|
159
162
|
"completed": (
|
|
160
163
|
"User commits changes; then run task.py archive."
|
|
@@ -16,6 +16,12 @@ import sys
|
|
|
16
16
|
from io import StringIO
|
|
17
17
|
from pathlib import Path
|
|
18
18
|
|
|
19
|
+
FIRST_REPLY_NOTICE = """<first-reply-notice>
|
|
20
|
+
On the first visible assistant reply in this session, begin with exactly one short Chinese sentence:
|
|
21
|
+
Trellis SessionStart 已注入:workflow、当前任务状态、开发者身份、git 状态、active tasks、spec 索引已加载。
|
|
22
|
+
Then continue directly with the user's request. This notice is one-shot: do not repeat it after the first assistant reply in the same session.
|
|
23
|
+
</first-reply-notice>"""
|
|
24
|
+
|
|
19
25
|
# IMPORTANT: Force stdout to use UTF-8 on Windows
|
|
20
26
|
# This fixes UnicodeEncodeError when outputting non-ASCII characters
|
|
21
27
|
if sys.platform.startswith("win"):
|
|
@@ -209,10 +215,9 @@ def _get_task_status(trellis_dir: Path) -> str:
|
|
|
209
215
|
# Case 5: PRD + curated jsonl (or agent-less platform with no jsonl) — enter Execute phase
|
|
210
216
|
return (
|
|
211
217
|
f"Status: READY\nTask: {task_title}\n"
|
|
212
|
-
"Next
|
|
213
|
-
"
|
|
214
|
-
"
|
|
215
|
-
"After implementation, spawn `trellis-check` sub-agent for quality verification.\n"
|
|
218
|
+
"Next required action: dispatch `trellis-implement` per Phase 2.1. "
|
|
219
|
+
"For agent-capable platforms, do NOT edit code in the main session. "
|
|
220
|
+
"After implementation, dispatch `trellis-check` per Phase 2.2 before reporting completion.\n"
|
|
216
221
|
"Sub-agent roster: `trellis-implement` (writes code), `trellis-check` (verifies + self-fixes), "
|
|
217
222
|
"`trellis-research` (persists findings to `research/*.md` — use when you'd otherwise do "
|
|
218
223
|
"multiple WebFetch/WebSearch inline)."
|
|
@@ -469,6 +474,8 @@ Read and follow all instructions below carefully.
|
|
|
469
474
|
</session-context>
|
|
470
475
|
|
|
471
476
|
""")
|
|
477
|
+
output.write(FIRST_REPLY_NOTICE)
|
|
478
|
+
output.write("\n\n")
|
|
472
479
|
|
|
473
480
|
# Legacy migration warning
|
|
474
481
|
legacy_warning = _check_legacy_spec(trellis_dir, is_mono, packages)
|
|
@@ -492,8 +499,9 @@ Read and follow all instructions below carefully.
|
|
|
492
499
|
"- If you're spawning an implement/check sub-agent, context is injected "
|
|
493
500
|
"automatically via `{task}/implement.jsonl` / `check.jsonl`. You do NOT "
|
|
494
501
|
"need to read these indexes yourself.\n"
|
|
495
|
-
"-
|
|
496
|
-
"
|
|
502
|
+
"- For agent-capable platforms, do NOT edit code directly in the main "
|
|
503
|
+
"session; dispatch `trellis-implement` and `trellis-check` so JSONL "
|
|
504
|
+
"context is loaded by the sub-agents.\n\n"
|
|
497
505
|
)
|
|
498
506
|
|
|
499
507
|
# guides/ is cross-package thinking — always include inline (small, broadly useful)
|
|
@@ -550,8 +558,8 @@ Read and follow all instructions below carefully.
|
|
|
550
558
|
|
|
551
559
|
output.write("""<ready>
|
|
552
560
|
Context loaded. Workflow index, project state, and guidelines are already injected above — do NOT re-read them.
|
|
553
|
-
|
|
554
|
-
If
|
|
561
|
+
When the user sends the first message, follow <task-status> and the workflow guide.
|
|
562
|
+
If a task is READY, execute its Next required action without asking whether to continue.
|
|
555
563
|
</ready>""")
|
|
556
564
|
|
|
557
565
|
result = {
|
|
@@ -11,7 +11,6 @@ Info line: model · ctx% · branch · duration · developer · tasks · rate lim
|
|
|
11
11
|
"""
|
|
12
12
|
from __future__ import annotations
|
|
13
13
|
|
|
14
|
-
import io
|
|
15
14
|
import json
|
|
16
15
|
import re
|
|
17
16
|
import subprocess
|
|
@@ -21,8 +20,10 @@ from pathlib import Path
|
|
|
21
20
|
# Fix: Windows Python defaults to GBK encoding, which corrupts UTF-8
|
|
22
21
|
# characters like the middle dot (·). Wrap stdout/stderr with UTF-8.
|
|
23
22
|
if sys.platform == "win32":
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
for stream in (sys.stdout, sys.stderr):
|
|
24
|
+
reconfigure = getattr(stream, "reconfigure", None)
|
|
25
|
+
if callable(reconfigure):
|
|
26
|
+
reconfigure(encoding="utf-8", errors="replace")
|
|
26
27
|
|
|
27
28
|
|
|
28
29
|
def _read_text(path: Path) -> str:
|
|
@@ -37,6 +37,7 @@ from common.paths import (
|
|
|
37
37
|
set_current_task,
|
|
38
38
|
clear_current_task,
|
|
39
39
|
)
|
|
40
|
+
from common.io import read_json, write_json
|
|
40
41
|
from common.task_utils import resolve_task_dir, run_task_hooks
|
|
41
42
|
from common.tasks import iter_active_tasks, children_progress
|
|
42
43
|
|
|
@@ -86,10 +87,18 @@ def cmd_start(args: argparse.Namespace) -> int:
|
|
|
86
87
|
|
|
87
88
|
if set_current_task(task_dir, repo_root):
|
|
88
89
|
print(colored(f"✓ Current task set to: {task_dir}", Colors.GREEN))
|
|
90
|
+
|
|
91
|
+
task_json_path = full_path / FILE_TASK_JSON
|
|
92
|
+
if task_json_path.is_file():
|
|
93
|
+
data = read_json(task_json_path)
|
|
94
|
+
if data and data.get("status") == "planning":
|
|
95
|
+
data["status"] = "in_progress"
|
|
96
|
+
if write_json(task_json_path, data):
|
|
97
|
+
print(colored("✓ Status: planning → in_progress", Colors.GREEN))
|
|
98
|
+
|
|
89
99
|
print()
|
|
90
100
|
print(colored("The hook will now inject context from this task's jsonl files.", Colors.BLUE))
|
|
91
101
|
|
|
92
|
-
task_json_path = full_path / FILE_TASK_JSON
|
|
93
102
|
run_task_hooks("after_start", task_json_path, repo_root)
|
|
94
103
|
return 0
|
|
95
104
|
else:
|
|
@@ -471,7 +471,8 @@ Research belongs in `{task_dir}/research/*.md`, written by `trellis-research` su
|
|
|
471
471
|
|
|
472
472
|
[workflow-state:in_progress]
|
|
473
473
|
Flow: trellis-implement → trellis-check → trellis-update-spec → finish
|
|
474
|
-
|
|
474
|
+
Next required action: inspect conversation history + git status, then execute the next uncompleted step in that sequence.
|
|
475
|
+
For agent-capable platforms, do NOT edit code in the main session; dispatch `trellis-implement` for implementation and dispatch `trellis-check` before reporting completion.
|
|
475
476
|
[/workflow-state:in_progress]
|
|
476
477
|
|
|
477
478
|
[workflow-state:completed]
|
package/package.json
CHANGED