@mindfoldhq/trellis 0.6.0-beta.7 → 0.6.0-beta.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/dist/configurators/codex.d.ts.map +1 -1
  2. package/dist/configurators/codex.js +5 -3
  3. package/dist/configurators/codex.js.map +1 -1
  4. package/dist/configurators/shared.js +4 -4
  5. package/dist/configurators/shared.js.map +1 -1
  6. package/dist/migrations/manifests/0.6.0-beta.8.json +9 -0
  7. package/dist/templates/claude/agents/trellis-check.md +2 -2
  8. package/dist/templates/claude/agents/trellis-implement.md +8 -7
  9. package/dist/templates/codebuddy/agents/trellis-check.md +2 -2
  10. package/dist/templates/codebuddy/agents/trellis-implement.md +8 -7
  11. package/dist/templates/codex/agents/trellis-check.toml +4 -4
  12. package/dist/templates/codex/agents/trellis-implement.toml +4 -4
  13. package/dist/templates/codex/hooks/session-start.py +183 -119
  14. package/dist/templates/codex/skills/before-dev/SKILL.md +12 -6
  15. package/dist/templates/codex/skills/brainstorm/SKILL.md +113 -51
  16. package/dist/templates/codex/skills/check/SKILL.md +86 -18
  17. package/dist/templates/codex/skills/start/SKILL.md +33 -323
  18. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-context-loading.md +7 -4
  19. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-spec-structure.md +1 -1
  20. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-workflow.md +3 -2
  21. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/context-injection.md +5 -5
  22. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/spec-system.md +1 -1
  23. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/task-system.md +8 -6
  24. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/agents.md +5 -4
  25. package/dist/templates/common/commands/continue.md +6 -5
  26. package/dist/templates/common/commands/start.md +7 -6
  27. package/dist/templates/common/skills/before-dev.md +12 -6
  28. package/dist/templates/common/skills/brainstorm.md +56 -42
  29. package/dist/templates/common/skills/check.md +7 -1
  30. package/dist/templates/copilot/hooks/session-start.py +183 -90
  31. package/dist/templates/copilot/prompts/before-dev.prompt.md +12 -6
  32. package/dist/templates/copilot/prompts/brainstorm.prompt.md +146 -84
  33. package/dist/templates/copilot/prompts/check.prompt.md +86 -18
  34. package/dist/templates/copilot/prompts/parallel.prompt.md +16 -8
  35. package/dist/templates/copilot/prompts/start.prompt.md +33 -367
  36. package/dist/templates/cursor/agents/trellis-check.md +2 -2
  37. package/dist/templates/cursor/agents/trellis-implement.md +8 -7
  38. package/dist/templates/droid/droids/trellis-check.md +2 -2
  39. package/dist/templates/droid/droids/trellis-implement.md +8 -7
  40. package/dist/templates/gemini/agents/trellis-implement.md +7 -6
  41. package/dist/templates/kiro/agents/trellis-check.json +1 -1
  42. package/dist/templates/kiro/agents/trellis-implement.json +1 -1
  43. package/dist/templates/opencode/agents/trellis-check.md +2 -2
  44. package/dist/templates/opencode/agents/trellis-implement.md +9 -8
  45. package/dist/templates/opencode/lib/session-utils.js +212 -123
  46. package/dist/templates/opencode/plugins/inject-subagent-context.js +23 -7
  47. package/dist/templates/opencode/plugins/inject-workflow-state.js +1 -4
  48. package/dist/templates/pi/extensions/trellis/index.ts.txt +7 -5
  49. package/dist/templates/qoder/agents/trellis-implement.md +7 -6
  50. package/dist/templates/shared-hooks/inject-subagent-context.py +36 -14
  51. package/dist/templates/shared-hooks/inject-workflow-state.py +18 -42
  52. package/dist/templates/shared-hooks/session-start.py +197 -163
  53. package/dist/templates/trellis/scripts/common/task_context.py +3 -3
  54. package/dist/templates/trellis/scripts/common/task_store.py +39 -7
  55. package/dist/templates/trellis/scripts/common/workflow_phase.py +7 -10
  56. package/dist/templates/trellis/scripts/task.py +3 -3
  57. package/dist/templates/trellis/workflow.md +98 -98
  58. package/package.json +1 -1
@@ -2,28 +2,34 @@ Read the relevant development guidelines before starting your task.
2
2
 
3
3
  Execute these steps:
4
4
 
5
- 1. **Discover packages and their spec layers**:
5
+ 1. **Read current task artifacts**:
6
+ - `prd.md` for requirements and acceptance criteria
7
+ - `design.md` if present for technical design
8
+ - `implement.md` if present for execution order and validation plan
9
+
10
+ 2. **Discover packages and their spec layers**:
6
11
  ```bash
7
12
  python3 ./.trellis/scripts/get_context.py --mode packages
8
13
  ```
9
14
 
10
- 2. **Identify which specs apply** to your task based on:
15
+ 3. **Identify which specs apply** to your task based on:
11
16
  - Which package you're modifying (e.g., `cli/`, `docs-site/`)
12
17
  - What type of work (backend, frontend, unit-test, docs, etc.)
18
+ - Any spec/research paths referenced by the task artifacts
13
19
 
14
- 3. **Read the spec index** for each relevant module:
20
+ 4. **Read the spec index** for each relevant module:
15
21
  ```bash
16
22
  cat .trellis/spec/<package>/<layer>/index.md
17
23
  ```
18
24
  Follow the **"Pre-Development Checklist"** section in the index.
19
25
 
20
- 4. **Read the specific guideline files** listed in the Pre-Development Checklist that are relevant to your task. The index is NOT the goal — it points you to the actual guideline files (e.g., `error-handling.md`, `conventions.md`, `mock-strategies.md`). Read those files to understand the coding standards and patterns.
26
+ 5. **Read the specific guideline files** listed in the Pre-Development Checklist that are relevant to your task. The index is NOT the goal — it points you to the actual guideline files (e.g., `error-handling.md`, `conventions.md`, `mock-strategies.md`). Read those files to understand the coding standards and patterns.
21
27
 
22
- 5. **Always read shared guides**:
28
+ 6. **Always read shared guides**:
23
29
  ```bash
24
30
  cat .trellis/spec/guides/index.md
25
31
  ```
26
32
 
27
- 6. Understand the coding standards and patterns you need to follow, then proceed with your development plan.
33
+ 7. Understand the coding standards and patterns you need to follow, then proceed with your development plan.
28
34
 
29
35
  This step is **mandatory** before writing any code.
@@ -68,7 +68,7 @@ TASK_DIR=$(python3 ./.trellis/scripts/task.py create "brainstorm: <short goal>"
68
68
  Use a slug without a date prefix. `task.py create` adds the `MM-DD-`
69
69
  directory prefix automatically.
70
70
 
71
- Create/seed `prd.md` immediately with what you know:
71
+ `task.py create` already created a default `prd.md`. Immediately update it with what you know:
72
72
 
73
73
  ```markdown
74
74
  # brainstorm: <short goal>
@@ -77,7 +77,7 @@ Create/seed `prd.md` immediately with what you know:
77
77
 
78
78
  <one paragraph: what + why>
79
79
 
80
- ## What I already know
80
+ ## Background / Known Context
81
81
 
82
82
  * <facts from user message>
83
83
  * <facts discovered from repo/docs>
@@ -90,11 +90,11 @@ Create/seed `prd.md` immediately with what you know:
90
90
 
91
91
  * <ONLY Blocking / Preference questions; keep list short>
92
92
 
93
- ## Requirements (evolving)
93
+ ## Requirements
94
94
 
95
95
  * <start with what is known>
96
96
 
97
- ## Acceptance Criteria (evolving)
97
+ ## Acceptance Criteria
98
98
 
99
99
  * [ ] <testable criterion>
100
100
 
@@ -109,10 +109,39 @@ Create/seed `prd.md` immediately with what you know:
109
109
 
110
110
  * <what we will not do in this task>
111
111
 
112
- ## Technical Notes
112
+ ## Research References
113
+
114
+ * <links to research/*.md or external references>
115
+ ```
116
+
117
+ For complex tasks, also create/update:
118
+
119
+ ```markdown
120
+ # design.md
121
+
122
+ ## Technical Design
123
+
124
+ <boundaries, contracts, data flow, compatibility, tradeoffs>
125
+
126
+ ## Rollout / Rollback
127
+
128
+ <operational notes if relevant>
129
+ ```
130
+
131
+ ```markdown
132
+ # implement.md
133
+
134
+ ## Implementation Checklist
135
+
136
+ - [ ] <ordered implementation step>
137
+
138
+ ## Validation
139
+
140
+ - <lint/typecheck/test command>
113
141
 
114
- * <files inspected, constraints, links, references>
115
- * <research notes summary if applicable>
142
+ ## Review Gates
143
+
144
+ - <human or technical checkpoint before start/finish>
116
145
  ```
117
146
 
118
147
  ---
@@ -135,8 +164,8 @@ Before asking questions like "what does the code look like?", gather context you
135
164
 
136
165
  Write findings into PRD:
137
166
 
138
- * Add to `What I already know`
139
- * Add constraints/links to `Technical Notes`
167
+ * Add user-visible facts to `Background / Known Context`
168
+ * Write technical findings to `research/*.md`, `design.md`, or `implement.md` as appropriate
140
169
 
141
170
  ---
142
171
 
@@ -402,7 +431,7 @@ Record the outcome in PRD as an ADR-lite section:
402
431
 
403
432
  ---
404
433
 
405
- ## Step 8: Final Confirmation + Implementation Plan
434
+ ## Step 8: Final Confirmation + Planning Artifacts
406
435
 
407
436
  When open questions are resolved, confirm complete requirements with a structured summary:
408
437
 
@@ -431,16 +460,13 @@ Here's my understanding of the complete requirements:
431
460
 
432
461
  * ...
433
462
 
434
- **Technical Approach**:
435
- <brief summary + key decisions>
436
-
437
- **Implementation Plan (small PRs)**:
463
+ **Artifact status**:
438
464
 
439
- * PR1: <scaffolding + tests + minimal plumbing>
440
- * PR2: <core behavior>
441
- * PR3: <edge cases + docs + cleanup>
465
+ * prd.md: <ready / needs update>
466
+ * design.md: <not needed for lightweight / ready / missing>
467
+ * implement.md: <not needed for lightweight / ready / missing>
442
468
 
443
- Does this look correct? If yes, I'll proceed with implementation.
469
+ Does this look correct? If yes, the next step is planning review before `task.py start`.
444
470
  ```
445
471
 
446
472
  ### Subtask Decomposition (Complex Tasks)
@@ -477,25 +503,13 @@ python3 ./.trellis/scripts/task.py add-subtask "$TASK_DIR" "$CHILD_DIR"
477
503
 
478
504
  * [ ] ...
479
505
 
480
- ## Definition of Done
481
-
482
- * ...
483
-
484
- ## Technical Approach
485
-
486
- <key design + decisions>
487
-
488
- ## Decision (ADR-lite)
489
-
490
- Context / Decision / Consequences
491
-
492
506
  ## Out of Scope
493
507
 
494
508
  * ...
495
509
 
496
- ## Technical Notes
510
+ ## Research References
497
511
 
498
- <constraints, references, files, research notes>
512
+ * <links to research/*.md or external references>
499
513
  ```
500
514
 
501
515
  ---
@@ -512,25 +526,25 @@ Context / Decision / Consequences
512
526
 
513
527
  ## Integration with Start Workflow
514
528
 
515
- After brainstorm completes (Step 8 confirmation approved), the flow continues to the Task Workflow's **Phase 2: Prepare for Implementation**:
529
+ After brainstorm completes (Step 8 confirmation approved), the flow continues to the Task Workflow planning review gate:
516
530
 
517
531
  ```text
518
532
  Brainstorm
519
- Step 0: Create task directory + seed PRD
533
+ Step 0: Create task directory + update PRD
520
534
  Step 1–7: Discover requirements, research, converge
521
- Step 8: Final confirmation → user approves
535
+ Step 8: Final confirmation → user approves planning artifacts
522
536
 
523
- Task Workflow Phase 2 (Prepare for Implementation)
524
- Code-Spec Depth Check (if applicable)
525
- Research codebase (based on confirmed PRD)
526
- Configure code-spec context (jsonl files)
527
- Activate task
537
+ Task Workflow Phase 1 (Plan)
538
+ Lightweight task → PRD-only may be enough
539
+ Complex task design.md + implement.md required
540
+ Sub-agent platforms curate implement.jsonl / check.jsonl manifests
541
+ Review gate → task.py start
528
542
 
529
- Task Workflow Phase 3 (Execute)
543
+ Task Workflow Phase 2 (Execute)
530
544
  Implement → Check → Complete
531
545
  ```
532
546
 
533
- The task directory and PRD already exist from brainstorm, so Phase 1 of the Task Workflow is skipped entirely.
547
+ The task directory and PRD already exist from brainstorm, but Phase 1 is not skipped; it owns artifact review and the `task.py start` gate.
534
548
 
535
549
  ---
536
550
 
@@ -11,7 +11,13 @@ git diff --name-only HEAD
11
11
  git status
12
12
  ```
13
13
 
14
- ## Step 2: Read Applicable Specs
14
+ ## Step 2: Read Task Artifacts and Applicable Specs
15
+
16
+ Read the current task artifacts in order:
17
+
18
+ - `prd.md`
19
+ - `design.md` if present
20
+ - `implement.md` if present
15
21
 
16
22
  ```bash
17
23
  python3 ./.trellis/scripts/get_context.py --mode packages
@@ -199,12 +199,19 @@ def _resolve_task_dir(trellis_dir: Path, task_ref: str) -> Path:
199
199
  def _get_task_status(trellis_dir: Path, hook_input: dict) -> str:
200
200
  active = _resolve_active_task(trellis_dir, hook_input)
201
201
  if not active.task_path:
202
- return f"Status: NO ACTIVE TASK\nSource: {active.source}\nNext: Describe what you want to work on"
202
+ return (
203
+ "Status: NO ACTIVE TASK\n"
204
+ "Next: Classify the current turn and ask for task-creation consent "
205
+ "before creating any Trellis task."
206
+ )
203
207
 
204
208
  task_ref = active.task_path
205
209
  task_dir = _resolve_task_dir(trellis_dir, task_ref)
206
210
  if active.stale or not task_dir.is_dir():
207
- return f"Status: STALE POINTER\nTask: {task_ref}\nSource: {active.source}\nNext: Task directory not found. Run: python3 ./.trellis/scripts/task.py finish"
211
+ return (
212
+ f"Status: STALE POINTER\nTask: {task_ref}\n"
213
+ "Next: Task directory not found. Run: python3 ./.trellis/scripts/task.py finish"
214
+ )
208
215
 
209
216
  task_json_path = task_dir / "task.json"
210
217
  task_data: dict = {}
@@ -218,36 +225,170 @@ def _get_task_status(trellis_dir: Path, hook_input: dict) -> str:
218
225
  task_status = task_data.get("status", "unknown")
219
226
 
220
227
  if task_status == "completed":
221
- return f"Status: COMPLETED\nTask: {task_title}\nSource: {active.source}\nNext: Archive with `python3 ./.trellis/scripts/task.py archive {task_dir.name}` or start a new task"
222
-
223
- has_context = False
224
- for jsonl_name in ("implement.jsonl", "check.jsonl", "spec.jsonl"):
225
- jsonl_path = task_dir / jsonl_name
226
- if jsonl_path.is_file() and _has_curated_jsonl_entry(jsonl_path):
227
- has_context = True
228
- break
228
+ return (
229
+ f"Status: COMPLETED\nTask: {task_title}\n"
230
+ f"Next: Archive with `python3 ./.trellis/scripts/task.py archive {task_dir.name}` "
231
+ "or start a new task."
232
+ )
229
233
 
230
234
  has_prd = (task_dir / "prd.md").is_file()
235
+ has_design = (task_dir / "design.md").is_file()
236
+ has_implement = (task_dir / "implement.md").is_file()
237
+ present = [
238
+ name
239
+ for name in ("prd.md", "design.md", "implement.md", "implement.jsonl", "check.jsonl")
240
+ if (task_dir / name).is_file()
241
+ ]
242
+ present_line = ", ".join(present) if present else "none"
231
243
 
232
244
  if not has_prd:
233
- return f"Status: NOT READY\nTask: {task_title}\nSource: {active.source}\nMissing: prd.md not created\nNext: Write PRD (see workflow.md Phase 1.1) then curate implement.jsonl per Phase 1.3"
245
+ return (
246
+ f"Status: PLANNING\nTask: {task_title}\nPresent: {present_line}\n"
247
+ "Next: Load trellis-brainstorm and write prd.md. Stay in planning."
248
+ )
234
249
 
235
- if not has_context:
236
- return f"Status: NOT READY\nTask: {task_title}\nSource: {active.source}\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`"
250
+ if task_status == "planning":
251
+ if has_design and has_implement:
252
+ next_action = "Review planning artifacts with the user before `task.py start`."
253
+ else:
254
+ next_action = (
255
+ "Lightweight task can ask for start review with PRD-only; "
256
+ "complex task must add design.md and implement.md before `task.py start`."
257
+ )
258
+ return (
259
+ f"Status: PLANNING\nTask: {task_title}\nPresent: {present_line}\n"
260
+ f"Next: {next_action}"
261
+ )
237
262
 
238
263
  return (
239
- f"Status: READY\nTask: {task_title}\n"
240
- f"Source: {active.source}\n"
241
- "Next required action: dispatch `trellis-implement` per Phase 2.1. "
242
- "For agent-capable platforms, the default is to NOT edit code in the main session. "
243
- "After implementation, dispatch `trellis-check` per Phase 2.2 before reporting completion.\n"
244
- "User override (per-turn escape hatch): if the user's CURRENT message explicitly tells the "
245
- "main session to handle it directly (\"你直接改\" / \"别派 sub-agent\" / \"main session 写就行\" / "
246
- "\"do it inline\" / \"不用 sub-agent\"), honor it for this turn and edit code directly. "
247
- "Per-turn only; do NOT invent an override the user did not say."
264
+ f"Status: {task_status.upper()}\nTask: {task_title}\nPresent: {present_line}\n"
265
+ "Next: Follow the matching per-turn workflow-state. Context order is jsonl entries, "
266
+ "prd.md, design.md if present, implement.md if present."
248
267
  )
249
268
 
250
269
 
270
+ def _run_git(repo_root: Path, args: list[str]) -> str:
271
+ try:
272
+ result = subprocess.run(
273
+ ["git", *args],
274
+ capture_output=True,
275
+ text=True,
276
+ encoding="utf-8",
277
+ errors="replace",
278
+ timeout=3,
279
+ cwd=str(repo_root),
280
+ )
281
+ except (subprocess.TimeoutExpired, FileNotFoundError, PermissionError):
282
+ return ""
283
+ if result.returncode != 0:
284
+ return ""
285
+ return result.stdout.strip()
286
+
287
+
288
+ def _format_git_state(repo_root: Path) -> str:
289
+ branch = _run_git(repo_root, ["branch", "--show-current"]) or "(detached)"
290
+ dirty_lines = [
291
+ line for line in _run_git(repo_root, ["status", "--porcelain"]).splitlines()
292
+ if line.strip()
293
+ ]
294
+ dirty_text = "clean" if not dirty_lines else f"dirty {len(dirty_lines)} paths"
295
+ return f"Git: branch {branch}; {dirty_text}."
296
+
297
+
298
+ def _repo_relative(repo_root: Path, path: Path) -> str:
299
+ try:
300
+ return path.relative_to(repo_root).as_posix()
301
+ except ValueError:
302
+ return str(path)
303
+
304
+
305
+ def _collect_spec_index_paths(trellis_dir: Path) -> list[str]:
306
+ paths: list[str] = []
307
+ guides_index = trellis_dir / "spec" / "guides" / "index.md"
308
+ if guides_index.is_file():
309
+ paths.append(".trellis/spec/guides/index.md")
310
+
311
+ spec_dir = trellis_dir / "spec"
312
+ if not spec_dir.is_dir():
313
+ return paths
314
+
315
+ for sub in sorted(spec_dir.iterdir()):
316
+ if not sub.is_dir() or sub.name.startswith(".") or sub.name == "guides":
317
+ continue
318
+ index_file = sub / "index.md"
319
+ if index_file.is_file():
320
+ paths.append(f".trellis/spec/{sub.name}/index.md")
321
+ continue
322
+ for nested in sorted(sub.iterdir()):
323
+ if not nested.is_dir():
324
+ continue
325
+ nested_index = nested / "index.md"
326
+ if nested_index.is_file():
327
+ paths.append(f".trellis/spec/{sub.name}/{nested.name}/index.md")
328
+
329
+ return paths
330
+
331
+
332
+ def _build_compact_current_state(
333
+ trellis_dir: Path,
334
+ hook_input: dict,
335
+ spec_index_paths: list[str],
336
+ ) -> str:
337
+ repo_root = trellis_dir.parent
338
+ lines: list[str] = []
339
+
340
+ try:
341
+ from common.paths import get_active_journal_file, get_developer, get_tasks_dir, count_lines # type: ignore[import-not-found]
342
+ from common.tasks import iter_active_tasks # type: ignore[import-not-found]
343
+ except Exception:
344
+ get_active_journal_file = None # type: ignore[assignment]
345
+ get_developer = None # type: ignore[assignment]
346
+ get_tasks_dir = None # type: ignore[assignment]
347
+ count_lines = None # type: ignore[assignment]
348
+ iter_active_tasks = None # type: ignore[assignment]
349
+
350
+ developer = get_developer(repo_root) if get_developer else None
351
+ lines.append(f"Developer: {developer or '(not initialized)'}")
352
+ lines.append(_format_git_state(repo_root))
353
+
354
+ active = _resolve_active_task(trellis_dir, hook_input)
355
+ if active.task_path:
356
+ task_dir = _resolve_task_dir(trellis_dir, active.task_path)
357
+ status = "unknown"
358
+ task_json = task_dir / "task.json"
359
+ if task_json.is_file():
360
+ try:
361
+ data = json.loads(task_json.read_text(encoding="utf-8"))
362
+ if isinstance(data, dict):
363
+ status = str(data.get("status") or "unknown")
364
+ except (json.JSONDecodeError, OSError):
365
+ pass
366
+ lines.append(f"Current task: {_repo_relative(repo_root, task_dir)}; status={status}.")
367
+ else:
368
+ lines.append("Current task: none.")
369
+
370
+ if get_tasks_dir and iter_active_tasks:
371
+ try:
372
+ task_count = sum(1 for _ in iter_active_tasks(get_tasks_dir(repo_root)))
373
+ lines.append(
374
+ f"Active tasks: {task_count} total. Use `python3 ./.trellis/scripts/task.py list --mine` only if needed."
375
+ )
376
+ except Exception:
377
+ pass
378
+
379
+ if get_active_journal_file and count_lines:
380
+ journal = get_active_journal_file(repo_root)
381
+ if journal:
382
+ lines.append(
383
+ f"Journal: {_repo_relative(repo_root, journal)}, {count_lines(journal)} / 2000 lines."
384
+ )
385
+
386
+ if spec_index_paths:
387
+ lines.append(f"Spec indexes: {len(spec_index_paths)} available.")
388
+
389
+ return "\n".join(lines)
390
+
391
+
251
392
  def _extract_range(content: str, start_header: str, end_header: str) -> str:
252
393
  """Extract lines starting at `## start_header` up to (but excluding) `## end_header`."""
253
394
  lines = content.splitlines()
@@ -275,32 +416,25 @@ _BREADCRUMB_TAG_RE = re.compile(
275
416
 
276
417
 
277
418
  def _strip_breadcrumb_tag_blocks(content: str) -> str:
278
- return _BREADCRUMB_TAG_RE.sub("", content)
419
+ stripped = _BREADCRUMB_TAG_RE.sub("", content)
420
+ stripped = re.sub(r"<!--.*?-->", "", stripped, flags=re.DOTALL)
421
+ stripped = re.sub(r"^\[(?!/?workflow-state:)/?[^\]\n]+\]\s*\n?", "", stripped, flags=re.MULTILINE)
422
+ return re.sub(r"\n{3,}", "\n\n", stripped).strip()
279
423
 
280
424
 
281
425
  def _build_workflow_toc(workflow_path: Path) -> str:
282
- """Inject workflow guide: TOC + Phase Index + Phase 1/2/3 step details.
283
-
284
- Since v0.5.0-rc.0 the [workflow-state:STATUS] breadcrumb tag blocks
285
- live inside ## Phase Index. They're consumed by inject-workflow-state.py
286
- on each UserPromptSubmit, so strip them from the session-start payload.
287
- """
426
+ """Inject only the compact Phase Index summary for SessionStart."""
288
427
  content = read_file(workflow_path)
289
428
  if not content:
290
429
  return "No workflow.md found"
291
430
 
292
431
  out_lines = [
293
- "# Development Workflow Section Index",
294
- "Full guide: .trellis/workflow.md (read on demand)",
432
+ "# Development Workflow - Session Summary",
433
+ "Full guide: .trellis/workflow.md. Step detail: `python3 ./.trellis/scripts/get_context.py --mode phase --step <X.Y>`.",
295
434
  "",
296
- "## Table of Contents",
297
435
  ]
298
- for line in content.splitlines():
299
- if line.startswith("## "):
300
- out_lines.append(line)
301
- out_lines += ["", "---", ""]
302
436
 
303
- phases = _extract_range(content, "Phase Index", "Customizing Trellis (for forks)")
437
+ phases = _extract_range(content, "Phase Index", "Phase 1: Plan")
304
438
  if phases:
305
439
  out_lines.append(_strip_breadcrumb_tag_blocks(phases).rstrip())
306
440
 
@@ -324,73 +458,34 @@ def main() -> None:
324
458
  configure_project_encoding(project_dir)
325
459
 
326
460
  trellis_dir = project_dir / ".trellis"
327
- context_key = _resolve_context_key(project_dir, hook_input)
461
+ spec_index_paths = _collect_spec_index_paths(trellis_dir)
328
462
 
329
463
  output = StringIO()
330
464
 
331
465
  output.write("""<session-context>
332
- You are starting a new session in a Trellis-managed project.
333
- Read and follow all instructions below carefully.
466
+ Trellis compact SessionStart context. Use it to orient the session; load details on demand.
334
467
  </session-context>
335
468
 
336
469
  """)
337
470
 
338
471
  output.write("<current-state>\n")
339
- context_script = trellis_dir / "scripts" / "get_context.py"
340
- output.write(run_script(context_script, context_key))
472
+ output.write(_build_compact_current_state(trellis_dir, hook_input, spec_index_paths))
341
473
  output.write("\n</current-state>\n\n")
342
474
 
343
- output.write("<workflow>\n")
475
+ output.write("<trellis-workflow>\n")
344
476
  output.write(_build_workflow_toc(trellis_dir / "workflow.md"))
345
- output.write("\n</workflow>\n\n")
477
+ output.write("\n</trellis-workflow>\n\n")
346
478
 
347
479
  output.write("<guidelines>\n")
348
480
  output.write(
349
- "Project spec indexes are listed by path below. Each index contains a "
350
- "**Pre-Development Checklist** listing the specific guideline files to "
351
- "read before coding.\n\n"
352
- "- If you're spawning an implement/check sub-agent, context is injected "
353
- "automatically via `{task}/implement.jsonl` / `check.jsonl`. You do NOT "
354
- "need to read these indexes yourself.\n"
355
- "- For agent-capable platforms, the default is to dispatch "
356
- "`trellis-implement` and `trellis-check` (so JSONL context is loaded by "
357
- "the sub-agents) rather than editing code in the main session. "
358
- "Honor a per-turn user override only if the user's current message "
359
- "explicitly opts out (see <task-status> below for override phrases).\n\n"
481
+ "Task context order for implementation/check: jsonl entries -> `prd.md` -> "
482
+ "`design.md if present` -> `implement.md if present`. Missing optional artifacts "
483
+ "are skipped for lightweight tasks.\n\n"
360
484
  )
361
485
 
362
- # guides/ inlined (cross-package thinking, broadly useful)
363
- guides_index = trellis_dir / "spec" / "guides" / "index.md"
364
- if guides_index.is_file():
365
- output.write("## guides (inlined — cross-package thinking guides)\n")
366
- output.write(read_file(guides_index))
367
- output.write("\n\n")
368
-
369
- # Other indexes — paths only
370
- paths: list[str] = []
371
- spec_dir = trellis_dir / "spec"
372
- if spec_dir.is_dir():
373
- for sub in sorted(spec_dir.iterdir()):
374
- if not sub.is_dir() or sub.name.startswith("."):
375
- continue
376
- if sub.name == "guides":
377
- continue
378
- index_file = sub / "index.md"
379
- if index_file.is_file():
380
- paths.append(f".trellis/spec/{sub.name}/index.md")
381
- else:
382
- for nested in sorted(sub.iterdir()):
383
- if not nested.is_dir():
384
- continue
385
- nested_index = nested / "index.md"
386
- if nested_index.is_file():
387
- paths.append(
388
- f".trellis/spec/{sub.name}/{nested.name}/index.md"
389
- )
390
-
391
- if paths:
392
- output.write("## Available spec indexes (read on demand)\n")
393
- for p in paths:
486
+ if spec_index_paths:
487
+ output.write("## Available indexes (read on demand)\n")
488
+ for p in spec_index_paths:
394
489
  output.write(f"- {p}\n")
395
490
  output.write("\n")
396
491
 
@@ -404,9 +499,7 @@ Read and follow all instructions below carefully.
404
499
  output.write(f"<task-status>\n{task_status}\n</task-status>\n\n")
405
500
 
406
501
  output.write("""<ready>
407
- Context loaded. Workflow index, project state, and guidelines are already injected above — do NOT re-read them.
408
- When the user sends the first message, follow <task-status> and the workflow guide.
409
- If a task is READY, execute its Next required action without asking whether to continue.
502
+ Context loaded. Follow <task-status>. Load workflow/spec/task details only when needed.
410
503
  </ready>""")
411
504
 
412
505
  context = output.getvalue()
@@ -6,28 +6,34 @@ Read the relevant development guidelines before starting your task.
6
6
 
7
7
  Execute these steps:
8
8
 
9
- 1. **Discover packages and their spec layers**:
9
+ 1. **Read current task artifacts**:
10
+ - `prd.md` for requirements and acceptance criteria
11
+ - `design.md` if present for technical design
12
+ - `implement.md` if present for execution order and validation plan
13
+
14
+ 2. **Discover packages and their spec layers**:
10
15
  ```bash
11
16
  python3 ./.trellis/scripts/get_context.py --mode packages
12
17
  ```
13
18
 
14
- 2. **Identify which specs apply** to your task based on:
19
+ 3. **Identify which specs apply** to your task based on:
15
20
  - Which package you're modifying (e.g., `cli/`, `docs-site/`)
16
21
  - What type of work (backend, frontend, unit-test, docs, etc.)
22
+ - Any spec/research paths referenced by the task artifacts
17
23
 
18
- 3. **Read the spec index** for each relevant module:
24
+ 4. **Read the spec index** for each relevant module:
19
25
  ```bash
20
26
  cat .trellis/spec/<package>/<layer>/index.md
21
27
  ```
22
28
  Follow the **"Pre-Development Checklist"** section in the index.
23
29
 
24
- 4. **Read the specific guideline files** listed in the Pre-Development Checklist that are relevant to your task. The index is NOT the goal �?it points you to the actual guideline files (e.g., `error-handling.md`, `conventions.md`, `mock-strategies.md`). Read those files to understand the coding standards and patterns.
30
+ 5. **Read the specific guideline files** listed in the Pre-Development Checklist that are relevant to your task. The index is NOT the goal it points you to the actual guideline files (e.g., `error-handling.md`, `conventions.md`, `mock-strategies.md`). Read those files to understand the coding standards and patterns.
25
31
 
26
- 5. **Always read shared guides**:
32
+ 6. **Always read shared guides**:
27
33
  ```bash
28
34
  cat .trellis/spec/guides/index.md
29
35
  ```
30
36
 
31
- 6. Understand the coding standards and patterns you need to follow, then proceed with your development plan.
37
+ 7. Understand the coding standards and patterns you need to follow, then proceed with your development plan.
32
38
 
33
39
  This step is **mandatory** before writing any code.