@mindfoldhq/trellis 0.5.0-beta.8 → 0.5.0-rc.0

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 (210) hide show
  1. package/README.md +60 -95
  2. package/dist/cli/index.js +7 -0
  3. package/dist/cli/index.js.map +1 -1
  4. package/dist/commands/init.d.ts +13 -0
  5. package/dist/commands/init.d.ts.map +1 -1
  6. package/dist/commands/init.js +474 -210
  7. package/dist/commands/init.js.map +1 -1
  8. package/dist/commands/update.d.ts.map +1 -1
  9. package/dist/commands/update.js +295 -54
  10. package/dist/commands/update.js.map +1 -1
  11. package/dist/configurators/antigravity.d.ts.map +1 -1
  12. package/dist/configurators/antigravity.js +2 -8
  13. package/dist/configurators/antigravity.js.map +1 -1
  14. package/dist/configurators/claude.d.ts.map +1 -1
  15. package/dist/configurators/claude.js +4 -10
  16. package/dist/configurators/claude.js.map +1 -1
  17. package/dist/configurators/codebuddy.d.ts.map +1 -1
  18. package/dist/configurators/codebuddy.js +3 -3
  19. package/dist/configurators/codebuddy.js.map +1 -1
  20. package/dist/configurators/codex.d.ts.map +1 -1
  21. package/dist/configurators/codex.js +5 -13
  22. package/dist/configurators/codex.js.map +1 -1
  23. package/dist/configurators/copilot.d.ts.map +1 -1
  24. package/dist/configurators/copilot.js +5 -19
  25. package/dist/configurators/copilot.js.map +1 -1
  26. package/dist/configurators/cursor.d.ts.map +1 -1
  27. package/dist/configurators/cursor.js +3 -3
  28. package/dist/configurators/cursor.js.map +1 -1
  29. package/dist/configurators/droid.d.ts.map +1 -1
  30. package/dist/configurators/droid.js +3 -3
  31. package/dist/configurators/droid.js.map +1 -1
  32. package/dist/configurators/gemini.d.ts.map +1 -1
  33. package/dist/configurators/gemini.js +3 -5
  34. package/dist/configurators/gemini.js.map +1 -1
  35. package/dist/configurators/index.d.ts.map +1 -1
  36. package/dist/configurators/index.js +44 -55
  37. package/dist/configurators/index.js.map +1 -1
  38. package/dist/configurators/kilo.d.ts.map +1 -1
  39. package/dist/configurators/kilo.js +2 -8
  40. package/dist/configurators/kilo.js.map +1 -1
  41. package/dist/configurators/kiro.d.ts.map +1 -1
  42. package/dist/configurators/kiro.js +3 -3
  43. package/dist/configurators/kiro.js.map +1 -1
  44. package/dist/configurators/opencode.d.ts.map +1 -1
  45. package/dist/configurators/opencode.js +7 -4
  46. package/dist/configurators/opencode.js.map +1 -1
  47. package/dist/configurators/pi.d.ts +3 -0
  48. package/dist/configurators/pi.d.ts.map +1 -0
  49. package/dist/configurators/pi.js +44 -0
  50. package/dist/configurators/pi.js.map +1 -0
  51. package/dist/configurators/qoder.d.ts +7 -6
  52. package/dist/configurators/qoder.d.ts.map +1 -1
  53. package/dist/configurators/qoder.js +18 -12
  54. package/dist/configurators/qoder.js.map +1 -1
  55. package/dist/configurators/shared.d.ts +30 -6
  56. package/dist/configurators/shared.d.ts.map +1 -1
  57. package/dist/configurators/shared.js +65 -15
  58. package/dist/configurators/shared.js.map +1 -1
  59. package/dist/configurators/windsurf.d.ts.map +1 -1
  60. package/dist/configurators/windsurf.js +2 -8
  61. package/dist/configurators/windsurf.js.map +1 -1
  62. package/dist/constants/paths.d.ts +2 -0
  63. package/dist/constants/paths.d.ts.map +1 -1
  64. package/dist/constants/paths.js +2 -0
  65. package/dist/constants/paths.js.map +1 -1
  66. package/dist/migrations/manifests/0.5.0-beta.0.json +2 -0
  67. package/dist/migrations/manifests/0.5.0-beta.10.json +9 -0
  68. package/dist/migrations/manifests/0.5.0-beta.11.json +9 -0
  69. package/dist/migrations/manifests/0.5.0-beta.12.json +9 -0
  70. package/dist/migrations/manifests/0.5.0-beta.13.json +9 -0
  71. package/dist/migrations/manifests/0.5.0-beta.14.json +9 -0
  72. package/dist/migrations/manifests/0.5.0-beta.15.json +116 -0
  73. package/dist/migrations/manifests/0.5.0-beta.16.json +9 -0
  74. package/dist/migrations/manifests/0.5.0-beta.17.json +9 -0
  75. package/dist/migrations/manifests/0.5.0-beta.18.json +9 -0
  76. package/dist/migrations/manifests/0.5.0-beta.19.json +9 -0
  77. package/dist/migrations/manifests/0.5.0-beta.5.json +2 -0
  78. package/dist/migrations/manifests/0.5.0-beta.9.json +48 -0
  79. package/dist/migrations/manifests/0.5.0-rc.0.json +9 -0
  80. package/dist/templates/claude/agents/trellis-research.md +1 -1
  81. package/dist/templates/claude/settings.json +0 -4
  82. package/dist/templates/codebuddy/agents/trellis-research.md +1 -1
  83. package/dist/templates/codex/agents/trellis-research.toml +3 -2
  84. package/dist/templates/codex/hooks/session-start.py +126 -26
  85. package/dist/templates/codex/skills/finish-work/SKILL.md +41 -109
  86. package/dist/templates/codex/skills/start/SKILL.md +12 -9
  87. package/dist/templates/common/bundled-skills/trellis-meta/SKILL.md +73 -0
  88. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/add-project-local-conventions.md +83 -0
  89. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-agents.md +54 -0
  90. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-context-loading.md +81 -0
  91. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-hooks.md +57 -0
  92. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-skills-or-commands.md +78 -0
  93. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-spec-structure.md +83 -0
  94. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-task-lifecycle.md +90 -0
  95. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-workflow.md +64 -0
  96. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/overview.md +55 -0
  97. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/context-injection.md +68 -0
  98. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/generated-files.md +80 -0
  99. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/overview.md +51 -0
  100. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/spec-system.md +102 -0
  101. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/task-system.md +101 -0
  102. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/workflow.md +75 -0
  103. package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/workspace-memory.md +71 -0
  104. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/agents.md +79 -0
  105. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/hooks-and-settings.md +69 -0
  106. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/overview.md +59 -0
  107. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/platform-map.md +74 -0
  108. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/skills-and-commands.md +83 -0
  109. package/dist/templates/common/commands/continue.md +9 -5
  110. package/dist/templates/common/commands/finish-work.md +34 -10
  111. package/dist/templates/common/index.d.ts +22 -2
  112. package/dist/templates/common/index.d.ts.map +1 -1
  113. package/dist/templates/common/index.js +53 -4
  114. package/dist/templates/common/index.js.map +1 -1
  115. package/dist/templates/common/skills/brainstorm.md +50 -4
  116. package/dist/templates/copilot/hooks/session-start.py +127 -30
  117. package/dist/templates/copilot/prompts/finish-work.prompt.md +44 -112
  118. package/dist/templates/copilot/prompts/start.prompt.md +12 -9
  119. package/dist/templates/cursor/agents/trellis-check.md +1 -1
  120. package/dist/templates/cursor/agents/trellis-implement.md +1 -1
  121. package/dist/templates/cursor/agents/trellis-research.md +2 -2
  122. package/dist/templates/cursor/hooks.json +7 -1
  123. package/dist/templates/droid/droids/trellis-research.md +1 -1
  124. package/dist/templates/extract.d.ts +6 -0
  125. package/dist/templates/extract.d.ts.map +1 -1
  126. package/dist/templates/extract.js +14 -0
  127. package/dist/templates/extract.js.map +1 -1
  128. package/dist/templates/gemini/agents/trellis-research.md +1 -1
  129. package/dist/templates/kiro/agents/trellis-research.json +1 -1
  130. package/dist/templates/markdown/agents.md +19 -12
  131. package/dist/templates/markdown/gitignore.txt +3 -0
  132. package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +24 -0
  133. package/dist/templates/opencode/agents/trellis-check.md +1 -1
  134. package/dist/templates/opencode/agents/trellis-implement.md +7 -4
  135. package/dist/templates/opencode/agents/trellis-research.md +2 -2
  136. package/dist/templates/opencode/lib/trellis-context.js +100 -13
  137. package/dist/templates/opencode/plugins/inject-subagent-context.js +70 -5
  138. package/dist/templates/opencode/plugins/inject-workflow-state.js +38 -44
  139. package/dist/templates/opencode/plugins/session-start.js +76 -31
  140. package/dist/templates/pi/agents/trellis-check.md +28 -0
  141. package/dist/templates/pi/agents/trellis-implement.md +33 -0
  142. package/dist/templates/pi/agents/trellis-research.md +25 -0
  143. package/dist/templates/pi/extensions/trellis/index.ts.txt +997 -0
  144. package/dist/templates/pi/index.d.ts +5 -0
  145. package/dist/templates/pi/index.d.ts.map +1 -0
  146. package/dist/templates/pi/index.js +12 -0
  147. package/dist/templates/pi/index.js.map +1 -0
  148. package/dist/templates/pi/settings.json +12 -0
  149. package/dist/templates/qoder/agents/trellis-research.md +1 -1
  150. package/dist/templates/shared-hooks/index.d.ts +31 -0
  151. package/dist/templates/shared-hooks/index.d.ts.map +1 -1
  152. package/dist/templates/shared-hooks/index.js +59 -0
  153. package/dist/templates/shared-hooks/index.js.map +1 -1
  154. package/dist/templates/shared-hooks/inject-shell-session-context.py +180 -0
  155. package/dist/templates/shared-hooks/inject-subagent-context.py +156 -27
  156. package/dist/templates/shared-hooks/inject-workflow-state.py +85 -92
  157. package/dist/templates/shared-hooks/session-start.py +232 -36
  158. package/dist/templates/trellis/config.yaml +6 -0
  159. package/dist/templates/trellis/gitignore.txt +3 -0
  160. package/dist/templates/trellis/index.d.ts +1 -1
  161. package/dist/templates/trellis/index.d.ts.map +1 -1
  162. package/dist/templates/trellis/index.js +2 -2
  163. package/dist/templates/trellis/index.js.map +1 -1
  164. package/dist/templates/trellis/scripts/common/__init__.py +8 -0
  165. package/dist/templates/trellis/scripts/common/active_task.py +593 -0
  166. package/dist/templates/trellis/scripts/common/cli_adapter.py +72 -14
  167. package/dist/templates/trellis/scripts/common/paths.py +61 -58
  168. package/dist/templates/trellis/scripts/common/session_context.py +12 -0
  169. package/dist/templates/trellis/scripts/common/task_context.py +27 -194
  170. package/dist/templates/trellis/scripts/common/task_store.py +102 -26
  171. package/dist/templates/trellis/scripts/common/tasks.py +4 -1
  172. package/dist/templates/trellis/scripts/common/types.py +0 -2
  173. package/dist/templates/trellis/scripts/common/workflow_phase.py +15 -3
  174. package/dist/templates/trellis/scripts/task.py +99 -34
  175. package/dist/templates/trellis/workflow.md +332 -64
  176. package/dist/types/ai-tools.d.ts +12 -3
  177. package/dist/types/ai-tools.d.ts.map +1 -1
  178. package/dist/types/ai-tools.js +29 -0
  179. package/dist/types/ai-tools.js.map +1 -1
  180. package/dist/utils/file-writer.d.ts.map +1 -1
  181. package/dist/utils/file-writer.js +7 -2
  182. package/dist/utils/file-writer.js.map +1 -1
  183. package/dist/utils/posix.d.ts +13 -0
  184. package/dist/utils/posix.d.ts.map +1 -0
  185. package/dist/utils/posix.js +15 -0
  186. package/dist/utils/posix.js.map +1 -0
  187. package/dist/utils/project-detector.d.ts +2 -0
  188. package/dist/utils/project-detector.d.ts.map +1 -1
  189. package/dist/utils/project-detector.js +120 -11
  190. package/dist/utils/project-detector.js.map +1 -1
  191. package/dist/utils/task-json.d.ts +46 -0
  192. package/dist/utils/task-json.d.ts.map +1 -0
  193. package/dist/utils/task-json.js +49 -0
  194. package/dist/utils/task-json.js.map +1 -0
  195. package/dist/utils/template-fetcher.d.ts +22 -6
  196. package/dist/utils/template-fetcher.d.ts.map +1 -1
  197. package/dist/utils/template-fetcher.js +405 -27
  198. package/dist/utils/template-fetcher.js.map +1 -1
  199. package/dist/utils/template-hash.d.ts +22 -3
  200. package/dist/utils/template-hash.d.ts.map +1 -1
  201. package/dist/utils/template-hash.js +99 -19
  202. package/dist/utils/template-hash.js.map +1 -1
  203. package/package.json +7 -7
  204. package/dist/templates/markdown/spec/backend/directory-structure.md +0 -292
  205. package/dist/templates/markdown/spec/backend/index.md +0 -40
  206. package/dist/templates/markdown/spec/backend/script-conventions.md +0 -742
  207. package/dist/templates/markdown/spec/guides/code-reuse-thinking-guide.md +0 -118
  208. package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md +0 -394
  209. package/dist/templates/shared-hooks/statusline.py +0 -218
  210. package/dist/templates/trellis/scripts/create_bootstrap.py +0 -298
@@ -1,16 +1,20 @@
1
1
  #!/usr/bin/env python3
2
2
  # -*- coding: utf-8 -*-
3
3
  """
4
- Copilot Session Start Hook - Inject Trellis context into VS Code Copilot sessions.
4
+ Copilot Session Start Hook - Emit Trellis session-start diagnostics.
5
5
 
6
- Output format follows Copilot hook protocol:
7
- stdout JSON { hookSpecificOutput: { hookEventName: "SessionStart", additionalContext: "..." } }
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
11
14
 
12
15
  import json
13
16
  import os
17
+ import re
14
18
  import subprocess
15
19
  import sys
16
20
  import warnings
@@ -24,6 +28,43 @@ def should_skip_injection() -> bool:
24
28
  return os.environ.get("COPILOT_NON_INTERACTIVE") == "1"
25
29
 
26
30
 
31
+ def configure_project_encoding(project_dir: Path) -> None:
32
+ """Reuse Trellis' shared Windows stdio encoding helper before JSON output."""
33
+ scripts_dir = project_dir / ".trellis" / "scripts"
34
+ if str(scripts_dir) not in sys.path:
35
+ sys.path.insert(0, str(scripts_dir))
36
+
37
+ try:
38
+ from common import configure_encoding # type: ignore[import-not-found]
39
+
40
+ configure_encoding()
41
+ except Exception:
42
+ pass
43
+
44
+
45
+ def _has_curated_jsonl_entry(jsonl_path: Path) -> bool:
46
+ """Return True iff jsonl has at least one row with a ``file`` field.
47
+
48
+ A freshly seeded jsonl only contains a ``{"_example": ...}`` row (no
49
+ ``file`` key) — that is NOT "ready". Readiness requires at least one
50
+ curated entry. Matches the contract used by ``inject-subagent-context.py``.
51
+ """
52
+ try:
53
+ for line in jsonl_path.read_text(encoding="utf-8").splitlines():
54
+ line = line.strip()
55
+ if not line:
56
+ continue
57
+ try:
58
+ row = json.loads(line)
59
+ except json.JSONDecodeError:
60
+ continue
61
+ if isinstance(row, dict) and row.get("file"):
62
+ return True
63
+ except (OSError, UnicodeDecodeError):
64
+ return False
65
+ return False
66
+
67
+
27
68
  def read_file(path: Path, fallback: str = "") -> str:
28
69
  try:
29
70
  return path.read_text(encoding="utf-8")
@@ -31,10 +72,32 @@ def read_file(path: Path, fallback: str = "") -> str:
31
72
  return fallback
32
73
 
33
74
 
34
- def run_script(script_path: Path) -> str:
75
+ def _resolve_context_key(project_dir: Path, hook_input: dict) -> str | None:
76
+ scripts_dir = project_dir / ".trellis" / "scripts"
77
+ if str(scripts_dir) not in sys.path:
78
+ sys.path.insert(0, str(scripts_dir))
79
+ try:
80
+ from common.active_task import resolve_context_key # type: ignore[import-not-found]
81
+ except Exception:
82
+ return None
83
+ return resolve_context_key(hook_input, platform="copilot")
84
+
85
+
86
+ def _resolve_active_task(trellis_dir: Path, hook_input: dict):
87
+ scripts_dir = trellis_dir / "scripts"
88
+ if str(scripts_dir) not in sys.path:
89
+ sys.path.insert(0, str(scripts_dir))
90
+ from common.active_task import resolve_active_task # type: ignore[import-not-found]
91
+
92
+ return resolve_active_task(trellis_dir.parent, hook_input, platform="copilot")
93
+
94
+
95
+ def run_script(script_path: Path, context_key: str | None = None) -> str:
35
96
  try:
36
97
  env = os.environ.copy()
37
98
  env["PYTHONIOENCODING"] = "utf-8"
99
+ if context_key:
100
+ env["TRELLIS_CONTEXT_ID"] = context_key
38
101
  cmd = [sys.executable, "-W", "ignore", str(script_path)]
39
102
  result = subprocess.run(
40
103
  cmd,
@@ -80,18 +143,15 @@ def _resolve_task_dir(trellis_dir: Path, task_ref: str) -> Path:
80
143
  return trellis_dir / "tasks" / path_obj
81
144
 
82
145
 
83
- def _get_task_status(trellis_dir: Path) -> str:
84
- current_task_file = trellis_dir / ".current-task"
85
- if not current_task_file.is_file():
86
- return "Status: NO ACTIVE TASK\nNext: Describe what you want to work on"
87
-
88
- task_ref = _normalize_task_ref(current_task_file.read_text(encoding="utf-8").strip())
89
- if not task_ref:
90
- return "Status: NO ACTIVE TASK\nNext: Describe what you want to work on"
146
+ def _get_task_status(trellis_dir: Path, hook_input: dict) -> str:
147
+ active = _resolve_active_task(trellis_dir, hook_input)
148
+ if not active.task_path:
149
+ return f"Status: NO ACTIVE TASK\nSource: {active.source}\nNext: Describe what you want to work on"
91
150
 
151
+ task_ref = active.task_path
92
152
  task_dir = _resolve_task_dir(trellis_dir, task_ref)
93
- if not task_dir.is_dir():
94
- return f"Status: STALE POINTER\nTask: {task_ref}\nNext: Task directory not found. Run: python3 ./.trellis/scripts/task.py finish"
153
+ if active.stale or not task_dir.is_dir():
154
+ return f"Status: STALE POINTER\nTask: {task_ref}\nSource: {active.source}\nNext: Task directory not found. Run: python3 ./.trellis/scripts/task.py finish"
95
155
 
96
156
  task_json_path = task_dir / "task.json"
97
157
  task_data: dict = {}
@@ -105,24 +165,34 @@ def _get_task_status(trellis_dir: Path) -> str:
105
165
  task_status = task_data.get("status", "unknown")
106
166
 
107
167
  if task_status == "completed":
108
- return f"Status: COMPLETED\nTask: {task_title}\nNext: Archive with `python3 ./.trellis/scripts/task.py archive {task_dir.name}` or start a new task"
168
+ 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"
109
169
 
110
170
  has_context = False
111
171
  for jsonl_name in ("implement.jsonl", "check.jsonl", "spec.jsonl"):
112
172
  jsonl_path = task_dir / jsonl_name
113
- if jsonl_path.is_file() and jsonl_path.stat().st_size > 0:
173
+ if jsonl_path.is_file() and _has_curated_jsonl_entry(jsonl_path):
114
174
  has_context = True
115
175
  break
116
176
 
117
177
  has_prd = (task_dir / "prd.md").is_file()
118
178
 
119
179
  if not has_prd:
120
- return f"Status: NOT READY\nTask: {task_title}\nMissing: prd.md not created\nNext: Write PRD, then research init-context start"
180
+ 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"
121
181
 
122
182
  if not has_context:
123
- return f"Status: NOT READY\nTask: {task_title}\nMissing: Context not configured (no jsonl files)\nNext: Complete Phase 2 (research init-context start) before implementing"
124
-
125
- return f"Status: READY\nTask: {task_title}\nNext: Continue with implement or check"
183
+ 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`"
184
+
185
+ return (
186
+ f"Status: READY\nTask: {task_title}\n"
187
+ f"Source: {active.source}\n"
188
+ "Next required action: dispatch `trellis-implement` per Phase 2.1. "
189
+ "For agent-capable platforms, the default is to NOT edit code in the main session. "
190
+ "After implementation, dispatch `trellis-check` per Phase 2.2 before reporting completion.\n"
191
+ "User override (per-turn escape hatch): if the user's CURRENT message explicitly tells the "
192
+ "main session to handle it directly (\"你直接改\" / \"别派 sub-agent\" / \"main session 写就行\" / "
193
+ "\"do it inline\" / \"不用 sub-agent\"), honor it for this turn and edit code directly. "
194
+ "Per-turn only; do NOT invent an override the user did not say."
195
+ )
126
196
 
127
197
 
128
198
  def _extract_range(content: str, start_header: str, end_header: str) -> str:
@@ -145,8 +215,23 @@ def _extract_range(content: str, start_header: str, end_header: str) -> str:
145
215
  return "\n".join(lines[start:end]).rstrip()
146
216
 
147
217
 
218
+ _BREADCRUMB_TAG_RE = re.compile(
219
+ r"\[workflow-state:([A-Za-z0-9_-]+)\]\s*\n.*?\n\s*\[/workflow-state:\1\]",
220
+ re.DOTALL,
221
+ )
222
+
223
+
224
+ def _strip_breadcrumb_tag_blocks(content: str) -> str:
225
+ return _BREADCRUMB_TAG_RE.sub("", content)
226
+
227
+
148
228
  def _build_workflow_toc(workflow_path: Path) -> str:
149
- """Inject workflow guide: TOC + Phase Index + Phase 1/2/3 step details."""
229
+ """Inject workflow guide: TOC + Phase Index + Phase 1/2/3 step details.
230
+
231
+ Since v0.5.0-rc.0 the [workflow-state:STATUS] breadcrumb tag blocks
232
+ live inside ## Phase Index. They're consumed by inject-workflow-state.py
233
+ on each UserPromptSubmit, so strip them from the session-start payload.
234
+ """
150
235
  content = read_file(workflow_path)
151
236
  if not content:
152
237
  return "No workflow.md found"
@@ -162,9 +247,9 @@ def _build_workflow_toc(workflow_path: Path) -> str:
162
247
  out_lines.append(line)
163
248
  out_lines += ["", "---", ""]
164
249
 
165
- phases = _extract_range(content, "Phase Index", "Workflow State Breadcrumbs")
250
+ phases = _extract_range(content, "Phase Index", "Customizing Trellis (for forks)")
166
251
  if phases:
167
- out_lines.append(phases)
252
+ out_lines.append(_strip_breadcrumb_tag_blocks(phases).rstrip())
168
253
 
169
254
  return "\n".join(out_lines).rstrip()
170
255
 
@@ -176,11 +261,17 @@ def main() -> None:
176
261
  # Read hook input from stdin
177
262
  try:
178
263
  hook_input = json.loads(sys.stdin.read())
264
+ if not isinstance(hook_input, dict):
265
+ hook_input = {}
179
266
  project_dir = Path(hook_input.get("cwd", ".")).resolve()
180
267
  except (json.JSONDecodeError, KeyError):
268
+ hook_input = {}
181
269
  project_dir = Path(".").resolve()
182
270
 
271
+ configure_project_encoding(project_dir)
272
+
183
273
  trellis_dir = project_dir / ".trellis"
274
+ context_key = _resolve_context_key(project_dir, hook_input)
184
275
 
185
276
  output = StringIO()
186
277
 
@@ -193,7 +284,7 @@ Read and follow all instructions below carefully.
193
284
 
194
285
  output.write("<current-state>\n")
195
286
  context_script = trellis_dir / "scripts" / "get_context.py"
196
- output.write(run_script(context_script))
287
+ output.write(run_script(context_script, context_key))
197
288
  output.write("\n</current-state>\n\n")
198
289
 
199
290
  output.write("<workflow>\n")
@@ -208,8 +299,11 @@ Read and follow all instructions below carefully.
208
299
  "- If you're spawning an implement/check sub-agent, context is injected "
209
300
  "automatically via `{task}/implement.jsonl` / `check.jsonl`. You do NOT "
210
301
  "need to read these indexes yourself.\n"
211
- "- If you're editing code directly in the main session, Read the relevant "
212
- "index(es) on-demand and follow their Pre-Dev Checklist.\n\n"
302
+ "- For agent-capable platforms, the default is to dispatch "
303
+ "`trellis-implement` and `trellis-check` (so JSONL context is loaded by "
304
+ "the sub-agents) rather than editing code in the main session. "
305
+ "Honor a per-turn user override only if the user's current message "
306
+ "explicitly opts out (see <task-status> below for override phrases).\n\n"
213
307
  )
214
308
 
215
309
  # guides/ inlined (cross-package thinking, broadly useful)
@@ -253,19 +347,22 @@ Read and follow all instructions below carefully.
253
347
  )
254
348
  output.write("</guidelines>\n\n")
255
349
 
256
- task_status = _get_task_status(trellis_dir)
350
+ task_status = _get_task_status(trellis_dir, hook_input)
257
351
  output.write(f"<task-status>\n{task_status}\n</task-status>\n\n")
258
352
 
259
353
  output.write("""<ready>
260
354
  Context loaded. Workflow index, project state, and guidelines are already injected above — do NOT re-read them.
261
- Wait for the user's first message, then handle it following the workflow guide.
262
- If there is an active task, ask whether to continue it.
355
+ When the user sends the first message, follow <task-status> and the workflow guide.
356
+ If a task is READY, execute its Next required action without asking whether to continue.
263
357
  </ready>""")
264
358
 
265
359
  context = output.getvalue()
266
360
  result = {
267
361
  "suppressOutput": True,
268
- "systemMessage": f"Trellis context injected ({len(context)} chars)",
362
+ "systemMessage": (
363
+ f"Trellis SessionStart diagnostics emitted ({len(context)} chars); "
364
+ "Copilot currently ignores sessionStart hook output."
365
+ ),
269
366
  "hookSpecificOutput": {
270
367
  "hookEventName": "SessionStart",
271
368
  "additionalContext": context,
@@ -1,157 +1,89 @@
1
1
  ---
2
- description: "Trellis Copilot prompt: Finish Work - Pre-Commit Checklist"
2
+ description: "Trellis Copilot prompt: Finish Work survey + archive task + record session journal"
3
3
  ---
4
4
 
5
- # Finish Work - Pre-Commit Checklist
5
+ # Finish Work
6
6
 
7
- Before submitting or committing, use this checklist to ensure work completeness.
7
+ Wrap up the current session: archive the active task (and any other completed-but-unarchived tasks the user wants to clean up) and record the session journal. Code commits are NOT done here — those happen in workflow Phase 3.4 before you invoke this prompt.
8
8
 
9
- **Timing**: After code is written and tested, before commit
9
+ **Timing**: After Phase 3.4 (Commit changes) when the working tree is already clean.
10
10
 
11
11
  ---
12
12
 
13
- ## Checklist
14
-
15
- ### 1. Code Quality
13
+ ## Step 1: Survey current state
16
14
 
17
15
  ```bash
18
- # Must pass
19
- pnpm lint
20
- pnpm type-check
21
- pnpm test
16
+ python3 ./.trellis/scripts/get_context.py --mode record
22
17
  ```
23
18
 
24
- - [ ] `pnpm lint` passes with 0 errors?
25
- - [ ] `pnpm type-check` passes with no type errors?
26
- - [ ] Tests pass?
27
- - [ ] No `console.log` statements (use logger)?
28
- - [ ] No non-null assertions (the `x!` operator)?
29
- - [ ] No `any` types?
30
-
31
- ### 1.5. Test Coverage
32
-
33
- Check if your change needs new or updated tests (see `.trellis/spec/unit-test/conventions.md`):
34
-
35
- - [ ] New pure function �?unit test added?
36
- - [ ] Bug fix �?regression test added in `test/regression.test.ts`?
37
- - [ ] Changed init/update behavior �?integration test added/updated?
38
- - [ ] No logic change (text/data only) �?no test needed
39
-
40
- ### 2. Code-Spec Sync
41
-
42
- **Code-Spec Docs**:
43
- - [ ] Does `.trellis/spec/backend/` need updates?
44
- - New patterns, new modules, new conventions
45
- - [ ] Does `.trellis/spec/frontend/` need updates?
46
- - New components, new hooks, new patterns
47
- - [ ] Does `.trellis/spec/guides/` need updates?
48
- - New cross-layer flows, lessons from bugs
49
-
50
- **Key Question**:
51
- > "If I fixed a bug or discovered something non-obvious, should I document it so future me (or others) won't hit the same issue?"
52
-
53
- If YES -> Update the relevant code-spec doc.
54
-
55
- ### 2.5. Code-Spec Hard Block (Infra/Cross-Layer)
56
-
57
- If this change touches infra or cross-layer contracts, this is a blocking checklist:
58
-
59
- - [ ] Spec content is executable (real signatures/contracts), not principle-only text
60
- - [ ] Includes file path + command/API name + payload field names
61
- - [ ] Includes validation and error matrix
62
- - [ ] Includes Good/Base/Bad cases
63
- - [ ] Includes required tests and assertion points
19
+ This prints:
64
20
 
65
- **Block Rule**:
66
- In pipeline mode, the finish agent will automatically detect and execute spec updates when gaps are found.
67
- If running this checklist manually, ensure spec sync is complete before committing �?run `/` if needed.
21
+ - **My active tasks** — review whether any besides the current one are actually done (code merged, AC met) and should be archived this round.
22
+ - **Git status** quick visual on what's dirty.
23
+ - **Recent commits** you'll need their hashes in Step 4 for `--commit`.
68
24
 
69
- ### 3. API Changes
25
+ If `--mode record` surfaces other completed tasks not tied to the current session, surface them to the user with a one-shot confirmation: "These N tasks look done — archive them too in this round? [y/N]". Default is no; the current active task is always archived in Step 3 regardless.
70
26
 
71
- If you modified API endpoints:
27
+ ## Step 2: Sanity check — working tree must be clean
72
28
 
73
- - [ ] Input schema updated?
74
- - [ ] Output schema updated?
75
- - [ ] API documentation updated?
76
- - [ ] Client code updated to match?
29
+ Run:
77
30
 
78
- ### 4. Database Changes
31
+ ```bash
32
+ git status --porcelain
33
+ ```
79
34
 
80
- If you modified database schema:
35
+ Filter out paths under `.trellis/workspace/` and `.trellis/tasks/` — those are managed by `add_session.py` and `task.py archive` auto-commits and will appear dirty as part of this prompt's own work.
81
36
 
82
- - [ ] Migration file created?
83
- - [ ] Schema file updated?
84
- - [ ] Related queries updated?
85
- - [ ] Seed data updated (if applicable)?
37
+ If anything else is dirty (any path outside those two prefixes), **stop and bail out** with:
86
38
 
87
- ### 5. Cross-Layer Verification
39
+ > "Working tree has uncommitted code changes. Return to workflow Phase 3.4 to commit them before running `/finish-work`."
88
40
 
89
- If the change spans multiple layers:
41
+ Do NOT run `git commit` here. Do NOT prompt the user to commit. The user goes back to Phase 3.4 and the AI drives the batched commit there.
90
42
 
91
- - [ ] Data flows correctly through all layers?
92
- - [ ] Error handling works at each boundary?
93
- - [ ] Types are consistent across layers?
94
- - [ ] Loading states handled?
43
+ ## Step 3: Archive task(s)
95
44
 
96
- ### 6. Manual Testing
45
+ ```bash
46
+ python3 ./.trellis/scripts/task.py archive <task-name>
47
+ ```
97
48
 
98
- - [ ] Feature works in browser/app?
99
- - [ ] Edge cases tested?
100
- - [ ] Error states tested?
101
- - [ ] Works after page refresh?
49
+ At minimum: the current active task (if any). Plus any extra tasks the user confirmed in Step 1. Each archive produces a `chore(task): archive ...` commit via the script's auto-commit.
102
50
 
103
- ---
51
+ If there is no active task and the user did not confirm any cleanup archives, skip this step.
104
52
 
105
- ## Quick Check Flow
53
+ ## Step 4: Record session journal
106
54
 
107
55
  ```bash
108
- # 1. Code checks
109
- pnpm lint && pnpm type-check
110
-
111
- # 2. View changes
112
- git status
113
- git diff --name-only
114
-
115
- # 3. Based on changed files, check relevant items above
56
+ python3 ./.trellis/scripts/add_session.py \
57
+ --title "Session Title" \
58
+ --commit "hash1,hash2" \
59
+ --summary "Brief summary"
116
60
  ```
117
61
 
118
- ---
119
-
120
- ## Common Oversights
62
+ Use the work-commit hashes produced in Phase 3.4 (visible in Step 1's `Recent commits` list, or via `git log --oneline`) for `--commit`. Do not include the archive commit hashes from Step 3. This produces a `chore: record journal` commit.
121
63
 
122
- | Oversight | Consequence | Check |
123
- |-----------|-------------|-------|
124
- | Code-spec docs not updated | Others don't know the change | Check .trellis/spec/ |
125
- | Spec text is abstract only | Easy regressions in infra/cross-layer changes | Require signature/contract/matrix/cases/tests |
126
- | Migration not created | Schema out of sync | Check db/migrations/ |
127
- | Types not synced | Runtime errors | Check shared types |
128
- | Tests not updated | False confidence | Run full test suite |
129
- | Console.log left in | Noisy production logs | Search for console.log |
64
+ Final git log order: `<work commits from 3.4>` → `chore(task): archive ...` (one or more) → `chore: record journal`.
130
65
 
131
66
  ---
132
67
 
133
68
  ## Relationship to Other Commands
134
69
 
135
70
  ```
136
- Development Flow:
137
- Write code -> Test -> / -> git commit -> /
138
- | |
139
- Ensure completeness Record progress
140
-
71
+ Development Flow (workflow.md Phase 3):
72
+ 3.1 Quality verification
73
+ 3.2 Debug retrospective (on demand)
74
+ 3.3 Spec update
75
+ 3.4 Commit changes -> AI drafts batched commits, user confirms
76
+ 3.5 Wrap-up -> /finish-work (this prompt: survey + archive + journal)
77
+
141
78
  Debug Flow:
142
- Hit bug -> Fix -> / -> Knowledge capture
143
- |
144
- Deep analysis
79
+ Hit bug -> Fix -> /break-loop -> Knowledge capture
145
80
  ```
146
81
 
147
- - `/` - Check work completeness (this command)
148
- - `/` - Record session and commits
149
- - `/` - Deep analysis after debugging
82
+ - `/finish-work` survey + archive + record session (this prompt)
83
+ - `/break-loop` deep analysis after debugging
150
84
 
151
85
  ---
152
86
 
153
87
  ## Core Principle
154
88
 
155
- > **Delivery includes not just code, but also documentation, verification, and knowledge capture.**
156
-
157
- Complete work = Code + Docs + Tests + Verification
89
+ > **Finish-work is pure bookkeeping.** Code is already committed before this runs. If the working tree is dirty, this prompt refuses to proceed.
@@ -273,17 +273,21 @@ Task(
273
273
 
274
274
  **Step 6: Configure Context** `[AI]`
275
275
 
276
- Initialize default context:
276
+ `implement.jsonl` and `check.jsonl` were seeded on `task.py create` with a single self-describing `_example` line. Curate real entries now (see workflow.md Phase 1.3 for the full rule):
277
+
278
+ - Put **spec files** (`.trellis/spec/<package>/<layer>/*.md`) and **research files** (`{TASK_DIR}/research/*.md`) only.
279
+ - Do NOT put code files — those are read during implementation, not pre-registered here.
280
+ - Split: `implement.jsonl` = specs the implement sub-agent needs; `check.jsonl` = specs the check sub-agent needs.
281
+
282
+ Discover available specs:
277
283
 
278
284
  ```bash
279
- python3 ./.trellis/scripts/task.py init-context "$TASK_DIR" <type>
280
- # type: backend | frontend | fullstack
285
+ python3 ./.trellis/scripts/get_context.py --mode packages
281
286
  ```
282
287
 
283
- Add code-spec files found by Research Agent:
288
+ Append entries (either edit the jsonl file directly, or):
284
289
 
285
290
  ```bash
286
- # For each relevant code-spec and code pattern:
287
291
  python3 ./.trellis/scripts/task.py add-context "$TASK_DIR" implement "<path>" "<reason>"
288
292
  python3 ./.trellis/scripts/task.py add-context "$TASK_DIR" check "<path>" "<reason>"
289
293
  ```
@@ -294,7 +298,7 @@ python3 ./.trellis/scripts/task.py add-context "$TASK_DIR" check "<path>" "<reas
294
298
  python3 ./.trellis/scripts/task.py start "$TASK_DIR"
295
299
  ```
296
300
 
297
- This sets `.current-task` so hooks can inject context.
301
+ This sets the active task through Trellis' session resolver so hooks can inject context for this AI session. If the command fails because no session identity is available, rerun it from an IDE/session that exposes session identity or set `TRELLIS_CONTEXT_ID`.
298
302
 
299
303
  ---
300
304
 
@@ -368,9 +372,8 @@ If yes, resume from the appropriate step (usually Step 7 or 8).
368
372
  | Script | Purpose |
369
373
  |--------|---------|
370
374
  | `python3 ./.trellis/scripts/get_context.py` | Get session context |
371
- | `python3 ./.trellis/scripts/task.py create` | Create task directory |
372
- | `python3 ./.trellis/scripts/task.py init-context` | Initialize jsonl files |
373
- | `python3 ./.trellis/scripts/task.py add-context` | Add code-spec/context file to jsonl |
375
+ | `python3 ./.trellis/scripts/task.py create` | Create task directory (seeds jsonl on sub-agent platforms) |
376
+ | `python3 ./.trellis/scripts/task.py add-context` | Append code-spec/research entry to jsonl |
374
377
  | `python3 ./.trellis/scripts/task.py start` | Set current task |
375
378
  | `python3 ./.trellis/scripts/task.py finish` | Clear current task |
376
379
  | `python3 ./.trellis/scripts/task.py archive` | Archive completed task |
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: trellis-check
3
3
  description: |
4
- Code quality check expert. Reviews code changes against specs and self-fixes issues.
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.
5
5
  tools: Read, Write, Edit, Bash, Glob, Grep, mcp__exa__web_search_exa, mcp__exa__get_code_context_exa
6
6
  ---
7
7
  # Check Agent
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: trellis-implement
3
3
  description: |
4
- Code implementation expert. Understands specs and requirements, then implements features. No git commit allowed.
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.
5
5
  tools: Read, Write, Edit, Bash, Glob, Grep, mcp__exa__web_search_exa, mcp__exa__get_code_context_exa
6
6
  ---
7
7
  # Implement Agent
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: trellis-research
3
3
  description: |
4
- Code and tech search expert. Finds files, patterns, and tech solutions, and PERSISTS every finding to the current task's research/ directory. No code modifications outside that directory.
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.
5
5
  tools: Read, Write, Glob, Grep, Bash, mcp__exa__web_search_exa, mcp__exa__get_code_context_exa, Skill, mcp__chrome-devtools__*
6
6
  ---
7
7
  # Research Agent
@@ -29,7 +29,7 @@ Conversations get compacted; files don't. Every research output MUST end up as a
29
29
 
30
30
  ### Step 1: Resolve Current Task
31
31
 
32
- Read `.trellis/.current-task` → task directory (e.g. `.trellis/tasks/04-17-foo/`). If empty or missing, ask the user where to write output; do NOT guess.
32
+ Run `python3 ./.trellis/scripts/task.py current --source` → active task path. If no active task is set, ask the user where to write output; do NOT guess.
33
33
 
34
34
  Ensure `{TASK_DIR}/research/` exists:
35
35
 
@@ -4,7 +4,7 @@
4
4
  "preToolUse": [
5
5
  {
6
6
  "command": "{{PYTHON_CMD}} .cursor/hooks/inject-subagent-context.py",
7
- "matcher": "Task",
7
+ "matcher": "Task|Subagent",
8
8
  "timeout": 30
9
9
  }
10
10
  ],
@@ -19,6 +19,12 @@
19
19
  "command": "{{PYTHON_CMD}} .cursor/hooks/inject-workflow-state.py",
20
20
  "timeout": 5
21
21
  }
22
+ ],
23
+ "beforeShellExecution": [
24
+ {
25
+ "command": "{{PYTHON_CMD}} .cursor/hooks/inject-shell-session-context.py",
26
+ "timeout": 5
27
+ }
22
28
  ]
23
29
  }
24
30
  }
@@ -29,7 +29,7 @@ Conversations get compacted; files don't. Every research output MUST end up as a
29
29
 
30
30
  ### Step 1: Resolve Current Task
31
31
 
32
- Read `.trellis/.current-task` → task directory (e.g. `.trellis/tasks/04-17-foo/`). If empty or missing, ask the user where to write output; do NOT guess.
32
+ Run `python3 ./.trellis/scripts/task.py current --source` → active task path. If no active task is set, ask the user where to write output; do NOT guess.
33
33
 
34
34
  Ensure `{TASK_DIR}/research/` exists:
35
35
 
@@ -13,6 +13,12 @@ export declare function getClaudeTemplatePath(): string;
13
13
  * Get the path to the opencode templates directory (agents, plugins, lib).
14
14
  */
15
15
  export declare function getOpenCodeTemplatePath(): string;
16
+ /**
17
+ * Get the path to the Pi Agent templates directory (agents, extension, settings).
18
+ */
19
+ export declare function getPiTemplatePath(): string;
20
+ /** @deprecated Use getPiTemplatePath() instead. */
21
+ export declare function getPiSourcePath(): string;
16
22
  /**
17
23
  * Read a file from the trellis template directory.
18
24
  */
@@ -1 +1 @@
1
- {"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../../src/templates/extract.ts"],"names":[],"mappings":"AAQA,KAAK,gBAAgB,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;AAE5D;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAQ/C;AAED,wDAAwD;AACxD,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAQ9C;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAQhD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAI5D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,gBAAgB,EAC1B,QAAQ,EAAE,MAAM,GACf,MAAM,CAGR;AAED,wBAAgB,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GACjC,OAAO,CAAC,IAAI,CAAC,CAIf"}
1
+ {"version":3,"file":"extract.d.ts","sourceRoot":"","sources":["../../src/templates/extract.ts"],"names":[],"mappings":"AAQA,KAAK,gBAAgB,GAAG,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;AAE5D;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,MAAM,CAQ/C;AAED,wDAAwD;AACxD,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAQ9C;AAED;;GAEG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAQhD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAQ1C;AAED,mDAAmD;AACnD,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAI5D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,gBAAgB,EAC1B,QAAQ,EAAE,MAAM,GACf,MAAM,CAGR;AAED,wBAAgB,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED;;GAEG;AACH,wBAAsB,cAAc,CAClC,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GACjC,OAAO,CAAC,IAAI,CAAC,CAIf"}
@@ -38,6 +38,20 @@ export function getOpenCodeTemplatePath() {
38
38
  }
39
39
  throw new Error("Could not find opencode templates directory. Expected at templates/opencode/");
40
40
  }
41
+ /**
42
+ * Get the path to the Pi Agent templates directory (agents, extension, settings).
43
+ */
44
+ export function getPiTemplatePath() {
45
+ const templatePath = path.join(__dirname, "pi");
46
+ if (fs.existsSync(templatePath)) {
47
+ return templatePath;
48
+ }
49
+ throw new Error("Could not find pi templates directory. Expected at templates/pi/");
50
+ }
51
+ /** @deprecated Use getPiTemplatePath() instead. */
52
+ export function getPiSourcePath() {
53
+ return getPiTemplatePath();
54
+ }
41
55
  /**
42
56
  * Read a file from the trellis template directory.
43
57
  */