@mindfoldhq/trellis 0.6.7 → 0.6.9

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 (174) hide show
  1. package/README.md +1 -1
  2. package/dist/cli/index.d.ts.map +1 -1
  3. package/dist/cli/index.js +38 -0
  4. package/dist/cli/index.js.map +1 -1
  5. package/dist/commands/channel/adapters/codex.d.ts +7 -1
  6. package/dist/commands/channel/adapters/codex.d.ts.map +1 -1
  7. package/dist/commands/channel/adapters/codex.js +19 -2
  8. package/dist/commands/channel/adapters/codex.js.map +1 -1
  9. package/dist/commands/channel/adapters/index.d.ts +3 -1
  10. package/dist/commands/channel/adapters/index.d.ts.map +1 -1
  11. package/dist/commands/channel/adapters/index.js +1 -1
  12. package/dist/commands/channel/adapters/index.js.map +1 -1
  13. package/dist/commands/channel/agent-loader.d.ts +2 -2
  14. package/dist/commands/channel/agent-loader.d.ts.map +1 -1
  15. package/dist/commands/channel/agent-loader.js +9 -5
  16. package/dist/commands/channel/agent-loader.js.map +1 -1
  17. package/dist/commands/channel/context-loader.d.ts +1 -1
  18. package/dist/commands/channel/context-loader.d.ts.map +1 -1
  19. package/dist/commands/channel/context-loader.js +36 -15
  20. package/dist/commands/channel/context-loader.js.map +1 -1
  21. package/dist/commands/channel/context-trust.d.ts +31 -0
  22. package/dist/commands/channel/context-trust.d.ts.map +1 -0
  23. package/dist/commands/channel/context-trust.js +139 -0
  24. package/dist/commands/channel/context-trust.js.map +1 -0
  25. package/dist/commands/channel/index.d.ts.map +1 -1
  26. package/dist/commands/channel/index.js +4 -0
  27. package/dist/commands/channel/index.js.map +1 -1
  28. package/dist/commands/channel/spawn.d.ts +3 -0
  29. package/dist/commands/channel/spawn.d.ts.map +1 -1
  30. package/dist/commands/channel/spawn.js +5 -2
  31. package/dist/commands/channel/spawn.js.map +1 -1
  32. package/dist/commands/channel/supervisor.d.ts +3 -0
  33. package/dist/commands/channel/supervisor.d.ts.map +1 -1
  34. package/dist/commands/channel/supervisor.js +1 -0
  35. package/dist/commands/channel/supervisor.js.map +1 -1
  36. package/dist/commands/init.d.ts +3 -0
  37. package/dist/commands/init.d.ts.map +1 -1
  38. package/dist/commands/init.js.map +1 -1
  39. package/dist/commands/mem.d.ts.map +1 -1
  40. package/dist/commands/mem.js +30 -9
  41. package/dist/commands/mem.js.map +1 -1
  42. package/dist/commands/update.d.ts +12 -1
  43. package/dist/commands/update.d.ts.map +1 -1
  44. package/dist/commands/update.js +75 -7
  45. package/dist/commands/update.js.map +1 -1
  46. package/dist/configurators/codex.d.ts +36 -0
  47. package/dist/configurators/codex.d.ts.map +1 -1
  48. package/dist/configurators/codex.js +111 -13
  49. package/dist/configurators/codex.js.map +1 -1
  50. package/dist/configurators/grok.d.ts +22 -0
  51. package/dist/configurators/grok.d.ts.map +1 -0
  52. package/dist/configurators/grok.js +58 -0
  53. package/dist/configurators/grok.js.map +1 -0
  54. package/dist/configurators/index.d.ts.map +1 -1
  55. package/dist/configurators/index.js +17 -2
  56. package/dist/configurators/index.js.map +1 -1
  57. package/dist/configurators/kimi.d.ts +29 -0
  58. package/dist/configurators/kimi.d.ts.map +1 -0
  59. package/dist/configurators/kimi.js +81 -0
  60. package/dist/configurators/kimi.js.map +1 -0
  61. package/dist/configurators/pi.js +9 -9
  62. package/dist/configurators/pi.js.map +1 -1
  63. package/dist/configurators/shared.d.ts.map +1 -1
  64. package/dist/configurators/shared.js +12 -4
  65. package/dist/configurators/shared.js.map +1 -1
  66. package/dist/configurators/snow.d.ts +31 -0
  67. package/dist/configurators/snow.d.ts.map +1 -0
  68. package/dist/configurators/snow.js +95 -0
  69. package/dist/configurators/snow.js.map +1 -0
  70. package/dist/configurators/workflow.d.ts +14 -0
  71. package/dist/configurators/workflow.d.ts.map +1 -1
  72. package/dist/configurators/workflow.js +37 -1
  73. package/dist/configurators/workflow.js.map +1 -1
  74. package/dist/configurators/zcode.d.ts +9 -4
  75. package/dist/configurators/zcode.d.ts.map +1 -1
  76. package/dist/configurators/zcode.js +41 -12
  77. package/dist/configurators/zcode.js.map +1 -1
  78. package/dist/migrations/manifests/0.5.0-beta.0.json +1 -1
  79. package/dist/migrations/manifests/0.6.8.json +17 -0
  80. package/dist/migrations/manifests/0.6.9.json +9 -0
  81. package/dist/templates/codex/agents/trellis-check.toml +7 -12
  82. package/dist/templates/codex/agents/trellis-implement.toml +7 -12
  83. package/dist/templates/codex/agents/trellis-research.toml +15 -15
  84. package/dist/templates/codex/config.toml +11 -0
  85. package/dist/templates/codex/hooks/session-start.py +9 -3
  86. package/dist/templates/codex/hooks.json +12 -0
  87. package/dist/templates/codex/skills/brainstorm/SKILL.md +40 -13
  88. package/dist/templates/common/bundled-skills/trellis-meta/SKILL.md +2 -2
  89. package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-skills-or-commands.md +1 -1
  90. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/agents.md +1 -0
  91. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/hooks-and-settings.md +1 -1
  92. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/overview.md +1 -1
  93. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/platform-map.md +10 -4
  94. package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/skills-and-commands.md +2 -1
  95. package/dist/templates/common/bundled-skills/trellis-session-insight/SKILL.md +1 -1
  96. package/dist/templates/common/skills/brainstorm.md +40 -13
  97. package/dist/templates/copilot/prompts/brainstorm.prompt.md +40 -13
  98. package/dist/templates/grok/agents/trellis-check.md +105 -0
  99. package/dist/templates/grok/agents/trellis-implement.md +116 -0
  100. package/dist/templates/grok/agents/trellis-research.md +146 -0
  101. package/dist/templates/grok/index.d.ts +16 -0
  102. package/dist/templates/grok/index.d.ts.map +1 -0
  103. package/dist/templates/grok/index.js +19 -0
  104. package/dist/templates/grok/index.js.map +1 -0
  105. package/dist/templates/kimi/agents/trellis-check.md +103 -0
  106. package/dist/templates/kimi/agents/trellis-implement.md +114 -0
  107. package/dist/templates/kimi/agents/trellis-research.md +144 -0
  108. package/dist/templates/kimi/index.d.ts +19 -0
  109. package/dist/templates/kimi/index.d.ts.map +1 -0
  110. package/dist/templates/kimi/index.js +22 -0
  111. package/dist/templates/kimi/index.js.map +1 -0
  112. package/dist/templates/omp/extensions/trellis/index.ts.txt +133 -9
  113. package/dist/templates/opencode/lib/session-utils.js +8 -2
  114. package/dist/templates/opencode/lib/trellis-context.js +263 -43
  115. package/dist/templates/opencode/plugins/inject-subagent-context.js +89 -35
  116. package/dist/templates/opencode/plugins/inject-workflow-state.js +90 -5
  117. package/dist/templates/pi/extensions/trellis/index.ts.txt +278 -24
  118. package/dist/templates/pi/settings.json +0 -3
  119. package/dist/templates/shared-hooks/index.d.ts +11 -5
  120. package/dist/templates/shared-hooks/index.d.ts.map +1 -1
  121. package/dist/templates/shared-hooks/index.js +16 -5
  122. package/dist/templates/shared-hooks/index.js.map +1 -1
  123. package/dist/templates/shared-hooks/inject-subagent-context.py +466 -104
  124. package/dist/templates/shared-hooks/inject-workflow-state.py +86 -29
  125. package/dist/templates/shared-hooks/session-start.py +26 -6
  126. package/dist/templates/snow/SNOW.md +86 -0
  127. package/dist/templates/snow/agents/trellis-check.md +135 -0
  128. package/dist/templates/snow/agents/trellis-implement.md +153 -0
  129. package/dist/templates/snow/agents/trellis-research.md +114 -0
  130. package/dist/templates/snow/hooks/beforeSubAgentStart.json +15 -0
  131. package/dist/templates/snow/hooks/onSessionStart.json +15 -0
  132. package/dist/templates/snow/hooks/onUserMessage.json +15 -0
  133. package/dist/templates/snow/hooks/write-trellis-context.py +644 -0
  134. package/dist/templates/snow/index.d.ts +26 -0
  135. package/dist/templates/snow/index.d.ts.map +1 -0
  136. package/dist/templates/snow/index.js +36 -0
  137. package/dist/templates/snow/index.js.map +1 -0
  138. package/dist/templates/template-utils.d.ts.map +1 -1
  139. package/dist/templates/template-utils.js +5 -1
  140. package/dist/templates/template-utils.js.map +1 -1
  141. package/dist/templates/trellis/config.yaml +55 -7
  142. package/dist/templates/trellis/gitattributes.txt +9 -0
  143. package/dist/templates/trellis/index.d.ts +3 -1
  144. package/dist/templates/trellis/index.d.ts.map +1 -1
  145. package/dist/templates/trellis/index.js +3 -1
  146. package/dist/templates/trellis/index.js.map +1 -1
  147. package/dist/templates/trellis/scripts/add_session.py +94 -28
  148. package/dist/templates/trellis/scripts/common/active_task.py +44 -13
  149. package/dist/templates/trellis/scripts/common/cli_adapter.py +69 -5
  150. package/dist/templates/trellis/scripts/common/config.py +105 -10
  151. package/dist/templates/trellis/scripts/common/git.py +36 -0
  152. package/dist/templates/trellis/scripts/common/io.py +16 -9
  153. package/dist/templates/trellis/scripts/common/task_context.py +101 -7
  154. package/dist/templates/trellis/scripts/common/task_store.py +149 -22
  155. package/dist/templates/trellis/scripts/common/task_utils.py +3 -1
  156. package/dist/templates/trellis/scripts/common/trellis_config.py +2 -1
  157. package/dist/templates/trellis/scripts/common/workflow_phase.py +19 -12
  158. package/dist/templates/trellis/scripts/task.py +106 -10
  159. package/dist/templates/trellis/workflow.md +20 -19
  160. package/dist/templates/zcode/agents/trellis-check.md +7 -0
  161. package/dist/templates/zcode/agents/trellis-implement.md +13 -4
  162. package/dist/templates/zcode/config.json +42 -0
  163. package/dist/templates/zcode/index.d.ts +10 -1
  164. package/dist/templates/zcode/index.d.ts.map +1 -1
  165. package/dist/templates/zcode/index.js +12 -2
  166. package/dist/templates/zcode/index.js.map +1 -1
  167. package/dist/types/ai-tools.d.ts +4 -4
  168. package/dist/types/ai-tools.d.ts.map +1 -1
  169. package/dist/types/ai-tools.js +114 -2
  170. package/dist/types/ai-tools.js.map +1 -1
  171. package/dist/utils/template-fetcher.d.ts.map +1 -1
  172. package/dist/utils/template-fetcher.js +0 -3
  173. package/dist/utils/template-fetcher.js.map +1 -1
  174. package/package.json +2 -2
@@ -96,6 +96,9 @@ def _detect_platform(input_data: dict) -> str | None:
96
96
  if isinstance(input_data.get("cursor_version"), str):
97
97
  return "cursor"
98
98
  env_map = {
99
+ # ZCode may set both ZCODE_PROJECT_DIR and CLAUDE_PROJECT_DIR; check
100
+ # ZCODE first so ZCode sessions aren't misdetected as claude.
101
+ "ZCODE_PROJECT_DIR": "zcode",
99
102
  "CLAUDE_PROJECT_DIR": "claude",
100
103
  "CURSOR_PROJECT_DIR": "cursor",
101
104
  "CODEBUDDY_PROJECT_DIR": "codebuddy",
@@ -128,6 +131,8 @@ def _detect_platform(input_data: dict) -> str | None:
128
131
  return "kiro"
129
132
  if ".trae" in script_parts:
130
133
  return "trae"
134
+ if ".zcode" in script_parts:
135
+ return "zcode"
131
136
  return None
132
137
 
133
138
 
@@ -223,28 +228,82 @@ def _read_trellis_config(root: Path) -> dict:
223
228
  return {}
224
229
 
225
230
 
226
- def _codex_mode_banner(config: dict) -> str:
227
- """Emit a `<codex-mode>` banner for the additionalContext payload.
231
+ DEFAULT_PROMPT_INJECTION_SKIP_KEYWORD = "no-trellis"
228
232
 
229
- Reads `codex.dispatch_mode` from .trellis/config.yaml; defaults to
230
- `inline` when missing or invalid because Codex sub-agents run with
231
- `fork_turns="none"` isolation and can't inherit the parent session's
232
- task context. The banner makes the active mode explicit to Codex AI
233
- per turn, complementing the workflow-state body which is per-status.
234
- Mode tells AI which dispatch protocol to follow; workflow-state tells
235
- AI what step it's at.
233
+
234
+ def _resolve_skip_keyword(config: dict) -> str:
235
+ """Read `prompt_injection.skip_keyword` from parsed .trellis/config.yaml.
236
+
237
+ Mirrors `common.config.get_prompt_injection_config()`. Defaults to
238
+ "no-trellis"; "" disables the escape hatch entirely. A non-string value
239
+ falls back to the default.
240
+ """
241
+ if isinstance(config, dict):
242
+ section = config.get("prompt_injection")
243
+ if isinstance(section, dict):
244
+ raw = section.get("skip_keyword", DEFAULT_PROMPT_INJECTION_SKIP_KEYWORD)
245
+ if isinstance(raw, str):
246
+ return raw
247
+ return DEFAULT_PROMPT_INJECTION_SKIP_KEYWORD
248
+
249
+
250
+ def prompt_has_skip_keyword(prompt: str, keyword: str) -> bool:
251
+ """Case-insensitive, word-boundary match of `keyword` in `prompt`.
252
+
253
+ Hyphen counts as a word char so "no-trellisx" / "xno-trellis" /
254
+ "foo-no-trellis" don't match, but punctuation/whitespace boundaries do.
255
+ Empty keyword never matches (disables the escape hatch).
256
+ """
257
+ if not keyword or not isinstance(prompt, str):
258
+ return False
259
+ pattern = r"(?<![\w-])" + re.escape(keyword) + r"(?![\w-])"
260
+ return re.search(pattern, prompt, re.IGNORECASE) is not None
261
+
262
+
263
+ def _resolve_codex_dispatch_mode(config: dict) -> str:
264
+ """Normalize `codex.dispatch_mode` from .trellis/config.yaml to "auto" or "inline".
265
+
266
+ Defaults to `auto`. The legacy `sub-agent` value is an alias for `auto`.
267
+ Any other explicit value (including invalid ones) falls back to `inline`
268
+ without per-turn warnings. Shared by `_codex_mode_banner` (the per-turn
269
+ banner) and `resolve_breadcrumb_key` (the breadcrumb tag key) so the two
270
+ stay in lockstep.
236
271
  """
237
- mode = "inline"
272
+ mode = "auto"
238
273
  if isinstance(config, dict):
239
274
  codex_cfg = config.get("codex")
240
275
  if isinstance(codex_cfg, dict):
241
- cfg_mode = codex_cfg.get("dispatch_mode")
242
- if cfg_mode in ("inline", "sub-agent"):
243
- mode = cfg_mode
244
- if mode == "sub-agent":
276
+ cfg_mode = str(codex_cfg.get("dispatch_mode", mode)).strip().lower()
277
+ if cfg_mode == "inline":
278
+ mode = "inline"
279
+ elif cfg_mode in ("auto", "sub-agent"):
280
+ mode = "auto"
281
+ else:
282
+ mode = "inline"
283
+ return mode
284
+
285
+
286
+ def _codex_mode_banner(config: dict) -> str:
287
+ """Emit a `<codex-mode>` banner for the additionalContext payload.
288
+
289
+ Reads `codex.dispatch_mode` from .trellis/config.yaml; defaults to
290
+ `auto`, which dispatches Trellis sub-agents using native Codex context
291
+ injection with a child-side fallback. This does not rely on inherited
292
+ parent transcripts: `fork_turns` remains caller-controlled, and
293
+ fresh-history sub-agents still receive their explicit delegated task and
294
+ inherited session configuration. `inline` is an explicit opt-out; the
295
+ legacy `sub-agent` value is an alias for `auto`. Invalid explicit values
296
+ fall back to `inline` without per-turn warnings. The banner makes the
297
+ active mode explicit to Codex AI per turn, complementing the workflow-state
298
+ body which is per-status. Mode tells AI which dispatch protocol to follow;
299
+ workflow-state tells AI what step it's at.
300
+ """
301
+ mode = _resolve_codex_dispatch_mode(config)
302
+ if mode == "auto":
245
303
  meaning = (
246
- "sub-agent: implement/check work defaults to Trellis sub-agents; "
247
- "the main session still coordinates, clarifies, updates specs, commits, and finishes."
304
+ "auto: implement/check work defaults to Trellis sub-agents; native Codex "
305
+ "context injection is preferred and child-side loading is the fallback. "
306
+ "The main session still coordinates, clarifies, updates specs, commits, and finishes."
248
307
  )
249
308
  else:
250
309
  meaning = (
@@ -259,22 +318,17 @@ def resolve_breadcrumb_key(
259
318
  ) -> str:
260
319
  """Pick the breadcrumb tag key based on Codex dispatch_mode.
261
320
 
262
- Codex defaults to ``inline`` because sub-agents run with ``fork_turns="none"``
263
- isolation and can't inherit the parent session's task context. Users can
264
- opt into ``codex.dispatch_mode: sub-agent`` in ``.trellis/config.yaml``
265
- to use the parallel ``<status>-inline`` tag ``<status>`` flip. Invalid
266
- or missing values fall back to inline.
321
+ Codex defaults to ``auto`` and therefore uses the ordinary ``<status>``
322
+ breadcrumb for native SubagentStart dispatch with child-side fallback;
323
+ it does not depend on an inherited parent transcript. ``inline`` selects
324
+ the parallel ``<status>-inline`` tag; ``sub-agent`` remains an alias for
325
+ ``auto``. Invalid explicit values fall back to inline without per-turn
326
+ warnings.
267
327
 
268
328
  Non-codex platforms return the plain status unchanged.
269
329
  """
270
330
  if platform == "codex":
271
- mode = "inline"
272
- if isinstance(config, dict):
273
- codex_cfg = config.get("codex")
274
- if isinstance(codex_cfg, dict):
275
- cfg_mode = codex_cfg.get("dispatch_mode")
276
- if cfg_mode in ("inline", "sub-agent"):
277
- mode = cfg_mode
331
+ mode = _resolve_codex_dispatch_mode(config)
278
332
  return f"{status}-inline" if mode == "inline" else status
279
333
  return status
280
334
 
@@ -353,9 +407,12 @@ def main() -> int:
353
407
  if root is None:
354
408
  return 0 # not a Trellis project
355
409
 
410
+ config = _read_trellis_config(root)
411
+ if prompt_has_skip_keyword(data.get("prompt", ""), _resolve_skip_keyword(config)):
412
+ return 0 # user opted out of the per-turn breadcrumb for this turn
413
+
356
414
  templates = load_breadcrumbs(root)
357
415
  platform = _detect_platform(data)
358
- config = _read_trellis_config(root)
359
416
  task = get_active_task(root, data)
360
417
  if task is None:
361
418
  # No active task — still emit a breadcrumb nudging AI toward
@@ -68,8 +68,14 @@ def _normalize_windows_shell_path(path_str: str) -> str:
68
68
 
69
69
 
70
70
  FIRST_REPLY_NOTICE = """<first-reply-notice>
71
- First visible reply: say once in Chinese that Trellis SessionStart context is loaded, then answer directly.
72
- This notice is one-shot: do not repeat it after the first assistant reply in the same session.
71
+ On the first visible assistant reply in this session, briefly acknowledge that Trellis SessionStart context loaded.
72
+ Choose the acknowledgment language in this order:
73
+ 1. Use the language of the user's current request (the user message that triggered this reply).
74
+ 2. If that request has no clear natural language, use an explicitly established project communication language.
75
+ 3. If neither provides a language, output the language-neutral fallback exactly: `Trellis SessionStart ✓`.
76
+ Continue directly with the user's request after the acknowledgment.
77
+ The acknowledgment must not alter the language used for the remainder of the response.
78
+ This notice is one-shot: do not repeat it after the first visible assistant reply in this session.
73
79
  </first-reply-notice>"""
74
80
 
75
81
  # Force UTF-8 on stdin/stdout/stderr on Windows. Default codepage there is
@@ -138,6 +144,7 @@ def should_skip_injection() -> bool:
138
144
  "KIRO_NON_INTERACTIVE",
139
145
  "COPILOT_NON_INTERACTIVE",
140
146
  "TRAE_NON_INTERACTIVE",
147
+ "ZCODE_NON_INTERACTIVE",
141
148
  ]
142
149
  return any(os.environ.get(var) == "1" for var in non_interactive_vars)
143
150
 
@@ -188,6 +195,9 @@ def _detect_platform(input_data: dict) -> str | None:
188
195
  if isinstance(input_data.get("cursor_version"), str):
189
196
  return "cursor"
190
197
  env_map = {
198
+ # ZCode may set both ZCODE_PROJECT_DIR and CLAUDE_PROJECT_DIR; check
199
+ # ZCODE first so ZCode sessions aren't misdetected as claude.
200
+ "ZCODE_PROJECT_DIR": "zcode",
191
201
  "CLAUDE_PROJECT_DIR": "claude",
192
202
  "CURSOR_PROJECT_DIR": "cursor",
193
203
  "CODEBUDDY_PROJECT_DIR": "codebuddy",
@@ -220,6 +230,8 @@ def _detect_platform(input_data: dict) -> str | None:
220
230
  return "kiro"
221
231
  if ".trae" in script_parts:
222
232
  return "trae"
233
+ if ".zcode" in script_parts:
234
+ return "zcode"
223
235
  return None
224
236
 
225
237
 
@@ -744,6 +756,7 @@ def main():
744
756
  "KIRO_PROJECT_DIR",
745
757
  "COPILOT_PROJECT_DIR",
746
758
  "TRAE_PROJECT_DIR",
759
+ "ZCODE_PROJECT_DIR",
747
760
  ]
748
761
  project_dir = None
749
762
  for var in project_dir_env_vars:
@@ -826,15 +839,22 @@ Context loaded. Follow <task-status>. Load workflow/spec/task details only when
826
839
  print(context_text, flush=True)
827
840
  return
828
841
 
829
- result = {
830
- # Claude Code / Qoder / CodeBuddy / Droid / Gemini / Copilot format
842
+ platform = _detect_platform(hook_input)
843
+ result: dict[str, object] = {
844
+ # Claude Code / Qoder / CodeBuddy / Droid / Gemini / Copilot / Trae /
845
+ # ZCode format.
831
846
  "hookSpecificOutput": {
832
847
  "hookEventName": "SessionStart",
833
848
  "additionalContext": context_text,
834
849
  },
835
- # Cursor sessionStart format (top-level snake_case per Cursor docs)
836
- "additional_context": context_text,
837
850
  }
851
+ # Cursor sessionStart format (top-level snake_case per Cursor docs).
852
+ # ZCode reads BOTH `hookSpecificOutput.additionalContext` and top-level
853
+ # `additional_context` without deduplication, so emitting both keys would
854
+ # duplicate the context in the conversation. Keep the previous shared output
855
+ # shape for every other platform.
856
+ if platform != "zcode":
857
+ result["additional_context"] = context_text
838
858
 
839
859
  # Output JSON - stdout is already configured for UTF-8
840
860
  print(json.dumps(result, ensure_ascii=False), flush=True)
@@ -0,0 +1,86 @@
1
+ # Trellis on Snow CLI
2
+
3
+ Snow is a **class-1** Trellis host: auto context inject + project agent discovery +
4
+ `beforeSubAgentStart` prompt enrichment.
5
+
6
+ | Capability | Status |
7
+ | ------------------------------------------------- | ---------------------------------------------------------------------------- |
8
+ | Skills (`.snow/skills/trellis-*/SKILL.md`) | Works |
9
+ | Prompt commands (`.snow/commands/trellis-*.json`) | Works (`/trellis-continue`, `/trellis-finish-work`, …) |
10
+ | Context hooks (`.snow/hooks/`) | Inject model context via stdout JSON + write `.snow/log/trellis-context.txt` |
11
+ | Project agents (`.snow/agents/*.md`) | Auto-discovered by Snow (`#trellis-implement`, …) |
12
+ | `beforeSubAgentStart` | Injects active-task breadcrumb into sub-agent prompts |
13
+ | `trellis-start` | Optional — session hooks replace the old manual ritual |
14
+
15
+ ## Quick start
16
+
17
+ ```bash
18
+ trellis init --snow -u your-name
19
+ snow
20
+ ```
21
+
22
+ In Snow:
23
+
24
+ 1. Open a session in the project root — `onSessionStart` injects Trellis context automatically.
25
+ 2. Dispatch implement/check/research (project agents under `.snow/agents/`). Prefer prompt first line:
26
+
27
+ ```text
28
+ Active task: .trellis/tasks/<id>
29
+ ```
30
+
31
+ 3. Optional: `/trellis-continue` / `/trellis-finish-work`, or `skill-execute` on `trellis-*` skills.
32
+ 4. Debug injects: set `SNOW_DEBUG_HOOKS=1` and inspect `.snow/log/hooks-inject.txt`.
33
+
34
+ ## Agents
35
+
36
+ Snow loads project agents from `.snow/agents/**/*.md` (priority over `~/.snow/sub-agents.json`).
37
+ Primary path: project agent discovery — no manual merge required. Do not use legacy sub-agent JSON merge files.
38
+
39
+ Context loading is class-1 hook inject (`beforeSubAgentStart` / session / user). Agents are **not** shipped with class-2 pull-based prelude text. Hooks already inject context; agents still re-read task artifacts for correctness.
40
+
41
+ ## Tool names (Snow-native)
42
+
43
+ - `filesystem-read` / `filesystem-create` / `filesystem-replaceedit` / `filesystem-edit`
44
+ - `terminal-execute`
45
+ - `ace-search` / `codebase-search`
46
+ - `todo-manage` / `notebook-manage`
47
+ - `skill-execute`
48
+ - `websearch-search` / `websearch-fetch` (research)
49
+ - `ide-get_diagnostics`
50
+
51
+ ## Hook protocol
52
+
53
+ Session / user / sub-agent hooks emit:
54
+
55
+ ```json
56
+ { "additionalContext": "...", "display": "..." }
57
+ ```
58
+
59
+ - exit 0 + JSON → inject (prepend); UI bubble keeps user original text
60
+ - exit 1 on `onUserMessage` → replace (not used by Trellis)
61
+ - non-JSON stdout → ignored
62
+
63
+ Hook modes (same script, different depth):
64
+
65
+ | Hook | argv mode | Payload |
66
+ | --------------------- | ---------- | ---------------------------------------------------------------- |
67
+ | `onSessionStart` | `session` | full (~7.5KB): task.py, artifacts, prd summary, workflow/session |
68
+ | `onUserMessage` | `user` | compact (~2.8KB): task.py + artifact presence only |
69
+ | `beforeSubAgentStart` | `subagent` | full + agent-kind tailoring (implement/check/research) |
70
+
71
+ ## Session identity (multi-session)
72
+
73
+ Snow injects these env vars into hook commands, `terminal-execute`, bash mode, and sub-agent children:
74
+
75
+ | Variable | Example | Purpose |
76
+ | -------------------- | ------------------- | ----------------------------------------- |
77
+ | `SNOW_SESSION_ID` | `c2343752-...` | Native Snow session uuid |
78
+ | `TRELLIS_CONTEXT_ID` | `snow-c2343752-...` | Preferred Trellis active-task context key |
79
+ | `SNOW_CWD` | project root | Working directory for hooks/tools |
80
+ | `SNOW_PLATFORM` | `snow` | Platform tag |
81
+
82
+ Notes:
83
+
84
+ - `TRELLIS_CONTEXT_ID` wins when already set (explicit override).
85
+ - Otherwise Trellis resolves `SNOW_SESSION_ID` via `active_task.py` as platform `snow`.
86
+ - Hook stdin may also include dual keys: `sessionId` / `session_id`.
@@ -0,0 +1,135 @@
1
+ ---
2
+ name: trellis-check
3
+ id: trellis-check
4
+ description: |
5
+ Code quality check expert for Trellis. Reviews code changes against specs
6
+ and self-fixes issues. On Snow CLI, auto-loaded from `.snow/agents/`; first
7
+ prompt line should be Active task: <path>.
8
+ tools:
9
+ - filesystem-read
10
+ - filesystem-create
11
+ - filesystem-replaceedit
12
+ - filesystem-edit
13
+ - terminal-execute
14
+ - ace-search
15
+ - codebase-search
16
+ - todo-manage
17
+ - notebook-manage
18
+ - skill-execute
19
+ - ide-get_diagnostics
20
+ ---
21
+
22
+ # Check Agent
23
+
24
+ You are the Check Agent in the Trellis workflow on **Snow CLI**.
25
+
26
+ ## Snow tool map
27
+
28
+ | Need | Tool |
29
+ | ----------------------------- | -------------------------------------------- |
30
+ | Read files | `filesystem-read` |
31
+ | Fix code | `filesystem-replaceedit` / `filesystem-edit` |
32
+ | `git diff` / lint / typecheck | `terminal-execute` |
33
+ | Search | `ace-search` / `codebase-search` |
34
+ | Diagnostics | `ide-get_diagnostics` |
35
+
36
+ ## Recursion Guard
37
+
38
+ You are already the `trellis-check` sub-agent that the main session dispatched. Do the review and fixes directly.
39
+
40
+ - Do NOT spawn another `trellis-check` or `trellis-implement` sub-agent.
41
+ - If workflow.md, skills, or the parent prompt say to dispatch `trellis-implement` / `trellis-check`, treat that as a main-session instruction that is already satisfied by your current role.
42
+ - Only the main session may dispatch Trellis implement/check agents. If more implementation work is needed, report that recommendation instead of spawning.
43
+
44
+ ## Dispatch note (main session)
45
+
46
+ On Snow CLI (class-1), the main session launches this agent with a full-context prompt. Always start the prompt with:
47
+
48
+ ```text
49
+ Active task: <path from task.py current>
50
+ ```
51
+
52
+ - Session/user hooks inject Trellis context into the main session.
53
+ - `beforeSubAgentStart` injects Trellis task context into this sub-agent prompt.
54
+ - Still re-read prd/design/implement as required below (hook inject is a breadcrumb, not a full substitute).
55
+ - Optionally Read `.snow/log/trellis-context.txt`.
56
+
57
+ ## Context
58
+
59
+ Before checking, read:
60
+
61
+ - `.trellis/spec/` - Development guidelines
62
+ - Pre-commit checklist for quality standards
63
+ - Task `prd.md` / `design.md` / `implement.md` if present
64
+ - `check.jsonl` when curated (skip `_example` seed rows)
65
+ - `.snow/log/trellis-context.txt` if present
66
+
67
+ ## Core Responsibilities
68
+
69
+ 1. **Get code changes** - Use `terminal-execute` with `git diff` to get uncommitted code
70
+ 2. **Check against specs** - Verify code follows guidelines
71
+ 3. **Self-fix** - Fix issues yourself, not just report them
72
+ 4. **Run verification** - typecheck and lint
73
+
74
+ ## Important
75
+
76
+ **Fix issues yourself**, don't just report them.
77
+
78
+ You have write and edit tools (`filesystem-replaceedit` / `filesystem-edit`), you can modify code directly.
79
+
80
+ ---
81
+
82
+ ## Workflow
83
+
84
+ ### Step 1: Get Changes
85
+
86
+ ```bash
87
+ git diff --name-only
88
+ git diff
89
+ ```
90
+
91
+ ### Step 2: Check Against Specs and Task Artifacts
92
+
93
+ Read the task's prd.md, design.md if present, and implement.md if present, then read relevant specs in `.trellis/spec/` to check code.
94
+
95
+ ### Step 3: Self-Fix
96
+
97
+ After finding issues:
98
+
99
+ 1. Fix the issue directly
100
+ 2. Record what was fixed
101
+ 3. Continue checking other issues
102
+
103
+ ### Step 4: Run Verification
104
+
105
+ Run project's lint and typecheck commands via `terminal-execute` to verify changes.
106
+ If failed, fix issues and re-run.
107
+
108
+ ---
109
+
110
+ ## Report Format
111
+
112
+ ```markdown
113
+ ## Self-Check Complete
114
+
115
+ ### Files Checked
116
+
117
+ - src/components/Feature.tsx
118
+
119
+ ### Issues Found and Fixed
120
+
121
+ 1. `<file>:<line>` - <what was fixed>
122
+
123
+ ### Issues Not Fixed
124
+
125
+ (If any)
126
+
127
+ ### Verification Results
128
+
129
+ - TypeCheck: Passed
130
+ - Lint: Passed
131
+
132
+ ### Summary
133
+
134
+ Checked X files, found Y issues, all fixed.
135
+ ```
@@ -0,0 +1,153 @@
1
+ ---
2
+ name: trellis-implement
3
+ id: trellis-implement
4
+ description: |
5
+ Code implementation expert for Trellis. Understands specs and requirements,
6
+ then implements features. No git commit allowed. On Snow CLI, auto-loaded from
7
+ `.snow/agents/`; first prompt line should be Active task: <path>.
8
+ tools:
9
+ - filesystem-read
10
+ - filesystem-create
11
+ - filesystem-replaceedit
12
+ - filesystem-edit
13
+ - terminal-execute
14
+ - ace-search
15
+ - codebase-search
16
+ - todo-manage
17
+ - notebook-manage
18
+ - skill-execute
19
+ - ide-get_diagnostics
20
+ ---
21
+
22
+ # Implement Agent
23
+
24
+ You are the Implement Agent in the Trellis workflow on **Snow CLI**.
25
+
26
+ ## Snow tool map
27
+
28
+ Use Snow-native tool ids (not Claude `Read`/`Edit`/`Bash` names):
29
+
30
+ | Need | Tool |
31
+ | ------------------------- | --------------------------------------------- |
32
+ | Read files / dirs | `filesystem-read` |
33
+ | Create file | `filesystem-create` |
34
+ | Edit existing file | `filesystem-replaceedit` or `filesystem-edit` |
35
+ | Shell / tests | `terminal-execute` |
36
+ | Symbol / text search | `ace-search` |
37
+ | Semantic codebase search | `codebase-search` |
38
+ | Track multi-step work | `todo-manage` |
39
+ | Persist non-obvious notes | `notebook-manage` |
40
+ | Run a Trellis skill | `skill-execute` |
41
+ | IDE errors | `ide-get_diagnostics` |
42
+
43
+ Prefer batch `filesystem-read` when loading several task artifacts.
44
+
45
+ ## Recursion Guard
46
+
47
+ You are already the `trellis-implement` sub-agent that the main session dispatched. Do the implementation work directly.
48
+
49
+ - Do NOT spawn another `trellis-implement` or `trellis-check` sub-agent.
50
+ - If workflow.md, skills, or the parent prompt say to dispatch `trellis-implement` / `trellis-check`, treat that as a main-session instruction that is already satisfied by your current role.
51
+ - Only the main session may dispatch Trellis implement/check agents. If more parallel work is needed, report that recommendation instead of spawning.
52
+
53
+ ## Dispatch note (main session)
54
+
55
+ On Snow CLI (class-1), project agents under `.snow/agents/` are auto-discovered. Prefer starting the prompt with:
56
+
57
+ ```text
58
+ Active task: <path from task.py current>
59
+ ```
60
+
61
+ - Session/user hooks inject Trellis context into the main session.
62
+ - `beforeSubAgentStart` injects Trellis breadcrumb into this sub-agent prompt.
63
+ - Still re-read task artifacts below (hook inject is a breadcrumb, not a substitute for prd/design/implement).
64
+ - Optionally Read `.snow/log/trellis-context.txt` if present.
65
+ - Main session also receives session/user injects (class-1 hook path; no class-2 pull prelude).
66
+
67
+ ## Context
68
+
69
+ Before implementing, read:
70
+
71
+ - `.trellis/workflow.md` - Project workflow
72
+ - `.trellis/spec/` - Development guidelines
73
+ - Task `prd.md` - Requirements document
74
+ - Task `design.md` / `implement.md` if present
75
+ - `implement.jsonl` when curated (skip `_example` seed rows)
76
+ - `.snow/log/trellis-context.txt` if present (breadcrumb from inject hooks)
77
+
78
+ ## Core Responsibilities
79
+
80
+ 1. **Understand specs** - Read relevant spec files in `.trellis/spec/`
81
+ 2. **Understand requirements** - Read prd.md and design/implement artifacts
82
+ 3. **Implement features** - Write code following specs and design
83
+ 4. **Self-check** - Ensure code quality (`terminal-execute` lint/typecheck)
84
+ 5. **Report results** - Report completion status
85
+
86
+ ## Forbidden Operations
87
+
88
+ **Do NOT execute these git commands:**
89
+
90
+ - `git commit`
91
+ - `git push`
92
+ - `git merge`
93
+
94
+ ---
95
+
96
+ ## Workflow
97
+
98
+ ### 1. Understand Specs
99
+
100
+ Read relevant specs based on task type:
101
+
102
+ - Spec layers: `.trellis/spec/<package>/<layer>/`
103
+ - Shared guides: `.trellis/spec/guides/`
104
+
105
+ ### 2. Understand Requirements
106
+
107
+ Read the task's prd.md and design/implement files:
108
+
109
+ - What are the core requirements
110
+ - Key points of technical design
111
+ - Which files to modify/create
112
+
113
+ ### 3. Implement Features
114
+
115
+ - Write code following specs and technical design
116
+ - Follow existing code patterns
117
+ - Only do what's required, no over-engineering
118
+
119
+ ### 4. Verify
120
+
121
+ Run project's lint and typecheck commands via `terminal-execute` to verify changes.
122
+
123
+ ---
124
+
125
+ ## Report Format
126
+
127
+ ```markdown
128
+ ## Implementation Complete
129
+
130
+ ### Files Modified
131
+
132
+ - `src/components/Feature.tsx` - New component
133
+ - `src/hooks/useFeature.ts` - New hook
134
+
135
+ ### Implementation Summary
136
+
137
+ 1. Created Feature component...
138
+ 2. Added useFeature hook...
139
+
140
+ ### Verification Results
141
+
142
+ - Lint: Passed
143
+ - TypeCheck: Passed
144
+ ```
145
+
146
+ ---
147
+
148
+ ## Code Standards
149
+
150
+ - Follow existing code patterns
151
+ - Don't add unnecessary abstractions
152
+ - Only do what's required, no over-engineering
153
+ - Keep code readable