@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
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Snow CLI template module.
3
+ *
4
+ * Snow CLI is a class-1 platform:
5
+ * - Skills under `.snow/skills/<name>/SKILL.md`
6
+ * - Slash commands under `.snow/commands/trellis-*.json` (prompt type)
7
+ * - Project agents under `.snow/agents/<name>.md` (auto-discovered)
8
+ * - Inject hooks under `.snow/hooks/` (additionalContext + log breadcrumb)
9
+ * - Operator guide `.snow/SNOW.md`
10
+ *
11
+ * hasHooks=true: SessionStart/UserMessage/beforeSubAgentStart inject workflow
12
+ * context, so trellis-start is filtered out of skills/commands (optional
13
+ * recovery still documented in SNOW.md).
14
+ *
15
+ * Class-1: do NOT inject the class-2 "does NOT auto-inject" pull-based prelude.
16
+ * Hook inject (session/user/beforeSubAgentStart) is the primary context path.
17
+ * trellis-research remains standalone (no implement/check-specific prelude).
18
+ */
19
+ import { createTemplateReader, } from "../template-utils.js";
20
+ const { listMdAgents, readTemplate, listFiles } = createTemplateReader(import.meta.url);
21
+ /** Sub-agent definitions (trellis-implement, trellis-check, trellis-research). */
22
+ export function getAllAgents() {
23
+ return listMdAgents();
24
+ }
25
+ /** Inject + breadcrumb hooks (onSessionStart / onUserMessage / beforeSubAgentStart). */
26
+ export function getAllHooks() {
27
+ return listFiles("hooks").map((name) => ({
28
+ targetPath: name,
29
+ content: readTemplate(`hooks/${name}`),
30
+ }));
31
+ }
32
+ /** Operator guide copied to `.snow/SNOW.md`. */
33
+ export function getSnowGuide() {
34
+ return readTemplate("SNOW.md");
35
+ }
36
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/templates/snow/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EACL,oBAAoB,GAGrB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,GAAG,oBAAoB,CACpE,MAAM,CAAC,IAAI,CAAC,GAAG,CAChB,CAAC;AAEF,kFAAkF;AAClF,MAAM,UAAU,YAAY;IAC1B,OAAO,YAAY,EAAE,CAAC;AACxB,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,WAAW;IACzB,OAAO,SAAS,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACvC,UAAU,EAAE,IAAI;QAChB,OAAO,EAAE,YAAY,CAAC,SAAS,IAAI,EAAE,CAAC;KACvC,CAAC,CAAC,CAAC;AACN,CAAC;AAED,gDAAgD;AAChD,MAAM,UAAU,YAAY;IAC1B,OAAO,YAAY,CAAC,SAAS,CAAC,CAAC;AACjC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"template-utils.d.ts","sourceRoot":"","sources":["../../src/templates/template-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,MAAM,CAAC;IAC/C,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;IACrC,YAAY,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,KAAK,aAAa,EAAE,CAAC;IAChD,cAAc,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,KAAK,aAAa,EAAE,CAAC;IAClD,WAAW,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,KAAK,YAAY,CAAC;IACjD,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;CACzC;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,MAAM,GAAG,cAAc,CAqD1E"}
1
+ {"version":3,"file":"template-utils.d.ts","sourceRoot":"","sources":["../../src/templates/template-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,MAAM,CAAC;IAC/C,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;IACrC,YAAY,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,KAAK,aAAa,EAAE,CAAC;IAChD,cAAc,EAAE,CAAC,GAAG,CAAC,EAAE,MAAM,KAAK,aAAa,EAAE,CAAC;IAClD,WAAW,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,KAAK,YAAY,CAAC;IACjD,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;CACzC;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,MAAM,GAAG,cAAc,CAyD1E"}
@@ -16,7 +16,11 @@ export function createTemplateReader(importMetaUrl) {
16
16
  }
17
17
  function listFiles(dir) {
18
18
  try {
19
- return readdirSync(join(__dirname, dir)).sort();
19
+ // Only regular files — skip dirs like __pycache__ that break readTemplate.
20
+ return readdirSync(join(__dirname, dir), { withFileTypes: true })
21
+ .filter((e) => e.isFile())
22
+ .map((e) => e.name)
23
+ .sort();
20
24
  }
21
25
  catch {
22
26
  return [];
@@ -1 +1 @@
1
- {"version":3,"file":"template-utils.js","sourceRoot":"","sources":["../../src/templates/template-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAqBzC;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,aAAqB;IACxD,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC;IAExD,SAAS,YAAY,CAAC,YAAoB;QACxC,OAAO,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,EAAE,OAAO,CAAC,CAAC;IAC9D,CAAC;IAED,SAAS,SAAS,CAAC,GAAW;QAC5B,IAAI,CAAC;YACH,OAAO,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAClD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED,mDAAmD;IACnD,SAAS,YAAY,CAAC,GAAG,GAAG,QAAQ;QAClC,OAAO,SAAS,CAAC,GAAG,CAAC;aAClB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;aAChC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACX,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;YAC1B,OAAO,EAAE,YAAY,CAAC,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC;SACrC,CAAC,CAAC,CAAC;IACR,CAAC;IAED,4DAA4D;IAC5D,SAAS,cAAc,CAAC,GAAG,GAAG,QAAQ;QACpC,OAAO,SAAS,CAAC,GAAG,CAAC;aAClB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;aAClC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACX,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YAC5B,OAAO,EAAE,YAAY,CAAC,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC;SACrC,CAAC,CAAC,CAAC;IACR,CAAC;IAED,oDAAoD;IACpD,SAAS,WAAW,CAAC,QAAQ,GAAG,eAAe;QAC7C,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;IACnE,CAAC;IAED,+CAA+C;IAC/C,SAAS,SAAS,CAAC,QAAgB;QACjC,OAAO,YAAY,CAAC,QAAQ,CAAC,CAAC;IAChC,CAAC;IAED,OAAO;QACL,YAAY;QACZ,SAAS;QACT,YAAY;QACZ,cAAc;QACd,WAAW;QACX,SAAS;KACV,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"template-utils.js","sourceRoot":"","sources":["../../src/templates/template-utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAqBzC;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,aAAqB;IACxD,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,CAAC;IAExD,SAAS,YAAY,CAAC,YAAoB;QACxC,OAAO,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,EAAE,OAAO,CAAC,CAAC;IAC9D,CAAC;IAED,SAAS,SAAS,CAAC,GAAW;QAC5B,IAAI,CAAC;YACH,2EAA2E;YAC3E,OAAO,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;iBAC9D,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;iBACzB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;iBAClB,IAAI,EAAE,CAAC;QACZ,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAED,mDAAmD;IACnD,SAAS,YAAY,CAAC,GAAG,GAAG,QAAQ;QAClC,OAAO,SAAS,CAAC,GAAG,CAAC;aAClB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;aAChC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACX,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;YAC1B,OAAO,EAAE,YAAY,CAAC,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC;SACrC,CAAC,CAAC,CAAC;IACR,CAAC;IAED,4DAA4D;IAC5D,SAAS,cAAc,CAAC,GAAG,GAAG,QAAQ;QACpC,OAAO,SAAS,CAAC,GAAG,CAAC;aAClB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;aAClC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACX,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YAC5B,OAAO,EAAE,YAAY,CAAC,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC;SACrC,CAAC,CAAC,CAAC;IACR,CAAC;IAED,oDAAoD;IACpD,SAAS,WAAW,CAAC,QAAQ,GAAG,eAAe;QAC7C,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;IACnE,CAAC;IAED,+CAA+C;IAC/C,SAAS,SAAS,CAAC,QAAgB;QACjC,OAAO,YAAY,CAAC,QAAQ,CAAC,CAAC;IAChC,CAAC;IAED,OAAO;QACL,YAAY;QACZ,SAAS;QACT,YAAY;QACZ,cAAc;QACd,WAAW;QACX,SAAS;KACV,CAAC;AACJ,CAAC"}
@@ -91,20 +91,68 @@ max_journal_lines: 2000
91
91
  # unless explicitly killed or given `--timeout`).
92
92
  # `max_live_workers: 0` disables the spawn-time budget check.
93
93
  #
94
+ # `trusted_context_dirs` extends the `--file`/`--jsonl`/`--agent` containment
95
+ # check beyond the worker cwd — useful when `.trellis/tasks` or
96
+ # `.trellis/workspace` is a symlink to an external directory. Realpaths under
97
+ # any listed dir are accepted in addition to cwd.
98
+ # `auto_trust_trellis_symlinks: false` disables the narrow auto-trust of
99
+ # `.trellis/tasks` / `.trellis/workspace` when either is itself a top-level
100
+ # symlink (auto-trust is on by default).
101
+ #
94
102
  channel:
95
103
  worker_guard:
96
104
  idle_timeout: 5m
97
105
  max_live_workers: 6
106
+ # trusted_context_dirs:
107
+ # - /work/user/trellis_workspace
108
+ # auto_trust_trellis_symlinks: false
98
109
 
99
110
  #-------------------------------------------------------------------------------
100
111
  # Codex (dispatch behavior)
101
112
  #-------------------------------------------------------------------------------
102
- # Codex-only knob; other platforms ignore it. Default ("inline") makes the
103
- # main Codex agent edit code directly because Codex sub-agents run with
104
- # `fork_turns="none"` isolation and can't inherit the parent session's
105
- # task context. Set to "sub-agent" to opt into the legacy dispatch model
106
- # (main agent spawns trellis-implement / trellis-check / trellis-research
107
- # sub-agents).
113
+ # Codex-only knob; other platforms ignore it. Default ("auto") dispatches
114
+ # trellis-implement / trellis-check / trellis-research sub-agents. This does
115
+ # not rely on inherited parent transcripts: `fork_turns` remains
116
+ # caller-controlled, while Codex's native SubagentStart hook injects task
117
+ # context when trusted and child-side loading remains the fallback when it is
118
+ # unavailable. Set to "inline" only to keep implementation and checks in the
119
+ # main session. "sub-agent" remains a backwards-compatible alias for "auto".
120
+ # Invalid explicit values safely use inline mode.
121
+ #
122
+ # In "auto" mode, dispatched sub-agents inherit the main session's model
123
+ # unless you pin one. To use a cheaper/faster model for implement/check/
124
+ # research sub-agent work, edit `model` / `model_reasoning_effort` directly
125
+ # on the generated `.codex/agents/trellis-*.toml` files (see the commented
126
+ # hint lines in those files) — there is no config.yaml knob for this,
127
+ # `trellis update` preserves your edits across regeneration.
108
128
  #
109
129
  # codex:
110
- # dispatch_mode: inline # or "sub-agent" to dispatch trellis-* sub-agents
130
+ # dispatch_mode: auto # or "inline"; legacy alias: "sub-agent"
131
+
132
+ #-------------------------------------------------------------------------------
133
+ # Sub-agent context injection limits
134
+ #-------------------------------------------------------------------------------
135
+ # Caps how much task context (implement.jsonl / check.jsonl referenced files,
136
+ # plus prd.md / design.md / implement.md) gets inlined into a sub-agent's
137
+ # first prompt. Oversized files are truncated with a notice; once the total
138
+ # payload cap is reached, remaining files degrade to index lines (path +
139
+ # reason + size) instead of being inlined.
140
+ #
141
+ # All values are byte counts. `0` disables the corresponding limit.
142
+ #
143
+ # context_injection:
144
+ # max_file_bytes: 32768 # per implement.jsonl / check.jsonl referenced file
145
+ # max_artifact_bytes: 65536 # per task artifact (prd.md / design.md / implement.md)
146
+ # max_total_bytes: 131072 # whole injected payload; overflow degrades to index lines
147
+
148
+ #-------------------------------------------------------------------------------
149
+ # Per-turn prompt injection
150
+ #-------------------------------------------------------------------------------
151
+ # Escape hatch for the per-turn <workflow-state> breadcrumb. When a user
152
+ # prompt contains the skip keyword as a standalone word (case-insensitive,
153
+ # word-boundary match — "no-trellisfoo" does NOT count), the breadcrumb is
154
+ # skipped for that turn only. Does not affect SessionStart or sub-agent
155
+ # context injection.
156
+ #
157
+ # prompt_injection:
158
+ # skip_keyword: "no-trellis" # "" disables the escape hatch entirely
@@ -0,0 +1,9 @@
1
+ # Trellis: append-only developer journals should merge cleanly across
2
+ # parallel sessions/worktrees — each session only appends a new block, so
3
+ # there is nothing to actually conflict on.
4
+ #
5
+ # Do NOT add a rule for workspace/*/index.md here — it is fully regenerated
6
+ # every session, so a real conflict there is expected and safe to resolve by
7
+ # picking either side (task state lives in task.json, not index.md). See
8
+ # .trellis/spec/cli/backend/directory-structure.md for details.
9
+ .trellis/workspace/*/journal-*.md merge=union
@@ -15,7 +15,8 @@
15
15
  * ├── scripts-shell-archive/ # Archived shell scripts (for reference)
16
16
  * ├── workflow.md # Workflow guide
17
17
  * ├── config.yaml # Trellis configuration
18
- * └── gitignore.txt # .gitignore content
18
+ * ├── gitignore.txt # .gitignore content
19
+ * └── gitattributes.txt # project-root .gitattributes content
19
20
  */
20
21
  export declare const scriptsInit: string;
21
22
  export declare const commonInit: string;
@@ -47,6 +48,7 @@ export declare const addSessionScript: string;
47
48
  export declare const workflowMdTemplate: string;
48
49
  export declare const configYamlTemplate: string;
49
50
  export declare const gitignoreTemplate: string;
51
+ export declare const gitattributesTemplate: string;
50
52
  export declare const implementAgentTemplate: string;
51
53
  export declare const checkAgentTemplate: string;
52
54
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/trellis/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAcH,eAAO,MAAM,WAAW,QAAsC,CAAC;AAG/D,eAAO,MAAM,UAAU,QAA6C,CAAC;AACrE,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,eAAe,QAA8C,CAAC;AAC3E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,YAAY,QAA2C,CAAC;AACrE,eAAO,MAAM,QAAQ,QAAuC,CAAC;AAC7D,eAAO,MAAM,SAAS,QAAwC,CAAC;AAC/D,eAAO,MAAM,SAAS,QAAwC,CAAC;AAC/D,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,iBAAiB,QAAiD,CAAC;AAChF,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,oBAAoB,QAEhC,CAAC;AACF,eAAO,MAAM,qBAAqB,QAEjC,CAAC;AACF,eAAO,MAAM,mBAAmB,QAE/B,CAAC;AACF,eAAO,MAAM,mBAAmB,QAE/B,CAAC;AACF,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAG9E,eAAO,MAAM,kBAAkB,QAA2C,CAAC;AAC3E,eAAO,MAAM,mBAAmB,QAA4C,CAAC;AAC7E,eAAO,MAAM,UAAU,QAAkC,CAAC;AAC1D,eAAO,MAAM,gBAAgB,QAAyC,CAAC;AACvE,eAAO,MAAM,gBAAgB,QAAyC,CAAC;AAGvE,eAAO,MAAM,kBAAkB,QAA8B,CAAC;AAC9D,eAAO,MAAM,kBAAkB,QAA8B,CAAC;AAC9D,eAAO,MAAM,iBAAiB,QAAgC,CAAC;AAM/D,eAAO,MAAM,sBAAsB,QAAsC,CAAC;AAC1E,eAAO,MAAM,kBAAkB,QAAkC,CAAC;AAElE;;GAEG;AACH,wBAAgB,aAAa,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAqCnD;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAKlD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/templates/trellis/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAcH,eAAO,MAAM,WAAW,QAAsC,CAAC;AAG/D,eAAO,MAAM,UAAU,QAA6C,CAAC;AACrE,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,eAAe,QAA8C,CAAC;AAC3E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAC9E,eAAO,MAAM,YAAY,QAA2C,CAAC;AACrE,eAAO,MAAM,QAAQ,QAAuC,CAAC;AAC7D,eAAO,MAAM,SAAS,QAAwC,CAAC;AAC/D,eAAO,MAAM,SAAS,QAAwC,CAAC;AAC/D,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,WAAW,QAA0C,CAAC;AACnE,eAAO,MAAM,iBAAiB,QAAiD,CAAC;AAChF,eAAO,MAAM,eAAe,QAA+C,CAAC;AAC5E,eAAO,MAAM,oBAAoB,QAEhC,CAAC;AACF,eAAO,MAAM,qBAAqB,QAEjC,CAAC;AACF,eAAO,MAAM,mBAAmB,QAE/B,CAAC;AACF,eAAO,MAAM,mBAAmB,QAE/B,CAAC;AACF,eAAO,MAAM,gBAAgB,QAAgD,CAAC;AAG9E,eAAO,MAAM,kBAAkB,QAA2C,CAAC;AAC3E,eAAO,MAAM,mBAAmB,QAA4C,CAAC;AAC7E,eAAO,MAAM,UAAU,QAAkC,CAAC;AAC1D,eAAO,MAAM,gBAAgB,QAAyC,CAAC;AACvE,eAAO,MAAM,gBAAgB,QAAyC,CAAC;AAGvE,eAAO,MAAM,kBAAkB,QAA8B,CAAC;AAC9D,eAAO,MAAM,kBAAkB,QAA8B,CAAC;AAC9D,eAAO,MAAM,iBAAiB,QAAgC,CAAC;AAC/D,eAAO,MAAM,qBAAqB,QAAoC,CAAC;AAMvE,eAAO,MAAM,sBAAsB,QAAsC,CAAC;AAC1E,eAAO,MAAM,kBAAkB,QAAkC,CAAC;AAElE;;GAEG;AACH,wBAAgB,aAAa,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAqCnD;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAKlD"}
@@ -15,7 +15,8 @@
15
15
  * ├── scripts-shell-archive/ # Archived shell scripts (for reference)
16
16
  * ├── workflow.md # Workflow guide
17
17
  * ├── config.yaml # Trellis configuration
18
- * └── gitignore.txt # .gitignore content
18
+ * ├── gitignore.txt # .gitignore content
19
+ * └── gitattributes.txt # project-root .gitattributes content
19
20
  */
20
21
  import { readFileSync } from "node:fs";
21
22
  import { dirname, join } from "node:path";
@@ -59,6 +60,7 @@ export const addSessionScript = readTemplate("scripts/add_session.py");
59
60
  export const workflowMdTemplate = readTemplate("workflow.md");
60
61
  export const configYamlTemplate = readTemplate("config.yaml");
61
62
  export const gitignoreTemplate = readTemplate("gitignore.txt");
63
+ export const gitattributesTemplate = readTemplate("gitattributes.txt");
62
64
  // Channel runtime agent definitions (loaded by
63
65
  // `packages/cli/src/commands/channel/agent-loader.ts` from `.trellis/agents/`).
64
66
  // These are platform-agnostic Trellis runtime files dispatched at `trellis init`
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/templates/trellis/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC,SAAS,YAAY,CAAC,YAAoB;IACxC,OAAO,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,EAAE,OAAO,CAAC,CAAC;AAC9D,CAAC;AAED,gCAAgC;AAChC,MAAM,CAAC,MAAM,WAAW,GAAG,YAAY,CAAC,qBAAqB,CAAC,CAAC;AAE/D,0BAA0B;AAC1B,MAAM,CAAC,MAAM,UAAU,GAAG,YAAY,CAAC,4BAA4B,CAAC,CAAC;AACrE,MAAM,CAAC,MAAM,WAAW,GAAG,YAAY,CAAC,yBAAyB,CAAC,CAAC;AACnE,MAAM,CAAC,MAAM,eAAe,GAAG,YAAY,CAAC,6BAA6B,CAAC,CAAC;AAC3E,MAAM,CAAC,MAAM,gBAAgB,GAAG,YAAY,CAAC,+BAA+B,CAAC,CAAC;AAC9E,MAAM,CAAC,MAAM,eAAe,GAAG,YAAY,CAAC,8BAA8B,CAAC,CAAC;AAC5E,MAAM,CAAC,MAAM,eAAe,GAAG,YAAY,CAAC,8BAA8B,CAAC,CAAC;AAC5E,MAAM,CAAC,MAAM,gBAAgB,GAAG,YAAY,CAAC,+BAA+B,CAAC,CAAC;AAC9E,MAAM,CAAC,MAAM,gBAAgB,GAAG,YAAY,CAAC,+BAA+B,CAAC,CAAC;AAC9E,MAAM,CAAC,MAAM,YAAY,GAAG,YAAY,CAAC,0BAA0B,CAAC,CAAC;AACrE,MAAM,CAAC,MAAM,QAAQ,GAAG,YAAY,CAAC,sBAAsB,CAAC,CAAC;AAC7D,MAAM,CAAC,MAAM,SAAS,GAAG,YAAY,CAAC,uBAAuB,CAAC,CAAC;AAC/D,MAAM,CAAC,MAAM,SAAS,GAAG,YAAY,CAAC,uBAAuB,CAAC,CAAC;AAC/D,MAAM,CAAC,MAAM,WAAW,GAAG,YAAY,CAAC,yBAAyB,CAAC,CAAC;AACnE,MAAM,CAAC,MAAM,WAAW,GAAG,YAAY,CAAC,yBAAyB,CAAC,CAAC;AACnE,MAAM,CAAC,MAAM,iBAAiB,GAAG,YAAY,CAAC,gCAAgC,CAAC,CAAC;AAChF,MAAM,CAAC,MAAM,eAAe,GAAG,YAAY,CAAC,8BAA8B,CAAC,CAAC;AAC5E,MAAM,CAAC,MAAM,oBAAoB,GAAG,YAAY,CAC9C,mCAAmC,CACpC,CAAC;AACF,MAAM,CAAC,MAAM,qBAAqB,GAAG,YAAY,CAC/C,oCAAoC,CACrC,CAAC;AACF,MAAM,CAAC,MAAM,mBAAmB,GAAG,YAAY,CAC7C,kCAAkC,CACnC,CAAC;AACF,MAAM,CAAC,MAAM,mBAAmB,GAAG,YAAY,CAC7C,kCAAkC,CACnC,CAAC;AACF,MAAM,CAAC,MAAM,gBAAgB,GAAG,YAAY,CAAC,+BAA+B,CAAC,CAAC;AAE9E,wBAAwB;AACxB,MAAM,CAAC,MAAM,kBAAkB,GAAG,YAAY,CAAC,0BAA0B,CAAC,CAAC;AAC3E,MAAM,CAAC,MAAM,mBAAmB,GAAG,YAAY,CAAC,2BAA2B,CAAC,CAAC;AAC7E,MAAM,CAAC,MAAM,UAAU,GAAG,YAAY,CAAC,iBAAiB,CAAC,CAAC;AAC1D,MAAM,CAAC,MAAM,gBAAgB,GAAG,YAAY,CAAC,wBAAwB,CAAC,CAAC;AACvE,MAAM,CAAC,MAAM,gBAAgB,GAAG,YAAY,CAAC,wBAAwB,CAAC,CAAC;AAEvE,sBAAsB;AACtB,MAAM,CAAC,MAAM,kBAAkB,GAAG,YAAY,CAAC,aAAa,CAAC,CAAC;AAC9D,MAAM,CAAC,MAAM,kBAAkB,GAAG,YAAY,CAAC,aAAa,CAAC,CAAC;AAC9D,MAAM,CAAC,MAAM,iBAAiB,GAAG,YAAY,CAAC,eAAe,CAAC,CAAC;AAE/D,+CAA+C;AAC/C,gFAAgF;AAChF,iFAAiF;AACjF,qCAAqC;AACrC,MAAM,CAAC,MAAM,sBAAsB,GAAG,YAAY,CAAC,qBAAqB,CAAC,CAAC;AAC1E,MAAM,CAAC,MAAM,kBAAkB,GAAG,YAAY,CAAC,iBAAiB,CAAC,CAAC;AAElE;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IAE1C,eAAe;IACf,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;IAExC,SAAS;IACT,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,UAAU,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,eAAe,CAAC,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,gBAAgB,CAAC,CAAC;IACvD,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,eAAe,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,eAAe,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,gBAAgB,CAAC,CAAC;IACvD,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,gBAAgB,CAAC,CAAC;IACvD,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,YAAY,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC;IACtC,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC;IACxC,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC;IACxC,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAC;IAC5C,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,iBAAiB,CAAC,CAAC;IACzD,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,eAAe,CAAC,CAAC;IACrD,OAAO,CAAC,GAAG,CAAC,2BAA2B,EAAE,oBAAoB,CAAC,CAAC;IAC/D,OAAO,CAAC,GAAG,CAAC,4BAA4B,EAAE,qBAAqB,CAAC,CAAC;IACjE,OAAO,CAAC,GAAG,CAAC,0BAA0B,EAAE,mBAAmB,CAAC,CAAC;IAC7D,OAAO,CAAC,GAAG,CAAC,0BAA0B,EAAE,mBAAmB,CAAC,CAAC;IAC7D,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,gBAAgB,CAAC,CAAC;IAEvD,OAAO;IACP,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,kBAAkB,CAAC,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,mBAAmB,CAAC,CAAC;IACtD,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IACnC,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,CAAC;IAEhD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,MAAM,CAAC,GAAG,CAAC,cAAc,EAAE,sBAAsB,CAAC,CAAC;IACnD,MAAM,CAAC,GAAG,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC;IAC3C,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/templates/trellis/index.ts"],"names":[],"mappings":"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"}
@@ -12,6 +12,9 @@ Usage:
12
12
  <session content here>
13
13
  EOF
14
14
 
15
+ # Structured content (repeatable; a section with no bullets is omitted):
16
+ python3 add_session.py --title "Title" --change "Did X" --test "Ran Y" --next-step "Do Z"
17
+
15
18
  Branch resolution order:
16
19
  1. --branch CLI arg (explicit)
17
20
  2. task.json branch field (from active task, if still exists)
@@ -38,6 +41,7 @@ from common.paths import (
38
41
  )
39
42
  from common.developer import ensure_developer
40
43
  from common.git import run_git
44
+ from common.log import Colors, colored
41
45
  from common.safe_commit import (
42
46
  print_gitignore_warning,
43
47
  safe_git_add,
@@ -56,12 +60,6 @@ from common.config import (
56
60
  )
57
61
 
58
62
 
59
- DEFAULT_MAIN_CHANGES = (
60
- "- Detailed change bullets were not supplied; see the summary above."
61
- )
62
- DEFAULT_TESTING = "- Validation was not recorded for this session."
63
-
64
-
65
63
  # =============================================================================
66
64
  # Helper Functions
67
65
  # =============================================================================
@@ -183,6 +181,49 @@ def resolve_session_branch(
183
181
  return None
184
182
 
185
183
 
184
+ def is_git_worktree(repo_root: Path) -> bool:
185
+ """Return True when repo_root is a linked worktree (not the main working tree).
186
+
187
+ Standard test: `git rev-parse --git-dir` (per-worktree) differs from
188
+ `git rev-parse --git-common-dir` (shared across all worktrees) once both
189
+ are resolved to absolute paths. In the main working tree these are the
190
+ same directory.
191
+ """
192
+ rc_dir, git_dir, _ = run_git(["rev-parse", "--git-dir"], cwd=repo_root)
193
+ rc_common, git_common_dir, _ = run_git(
194
+ ["rev-parse", "--git-common-dir"], cwd=repo_root
195
+ )
196
+ if rc_dir != 0 or rc_common != 0:
197
+ return False
198
+
199
+ git_dir_path = (repo_root / git_dir.strip()).resolve()
200
+ git_common_dir_path = (repo_root / git_common_dir.strip()).resolve()
201
+ return git_dir_path != git_common_dir_path
202
+
203
+
204
+ def warn_if_parallel_worktree(repo_root: Path) -> None:
205
+ """Non-blocking note: index.md conflicts across parallel worktrees/branches
206
+ are expected and safe. Only fires when running in a linked git worktree
207
+ (not the main tree) with `session_auto_commit` enabled (#415 quick-fix tier).
208
+ """
209
+ if not get_session_auto_commit(repo_root):
210
+ return
211
+ if not is_git_worktree(repo_root):
212
+ return
213
+ print(
214
+ colored(
215
+ "[NOTE] Running in a git worktree with session_auto_commit enabled: "
216
+ "journal-*.md files auto-merge via .gitattributes, but index.md "
217
+ "conflicts across parallel worktrees/branches are expected and safe "
218
+ "to resolve by picking either side (task state lives in task.json, "
219
+ "not index.md). See .trellis/spec/cli/backend/directory-structure.md "
220
+ '("Workspace Journal Merge Behavior").',
221
+ Colors.YELLOW,
222
+ ),
223
+ file=sys.stderr,
224
+ )
225
+
226
+
186
227
  def create_new_journal_file(
187
228
  dev_dir: Path, num: int, developer: str, today: str, max_lines: int = 2000,
188
229
  ) -> Path:
@@ -202,16 +243,39 @@ def create_new_journal_file(
202
243
  return new_file
203
244
 
204
245
 
246
+ def _render_bullet_section(header: str, items: list[str], bullet_prefix: str = "- ") -> str:
247
+ """Render a Markdown section as bullets, or "" when there is no content.
248
+
249
+ A section with zero provided values is omitted entirely from the
250
+ rendered entry rather than falling back to a placeholder string.
251
+ """
252
+ if not items:
253
+ return ""
254
+ bullets = "\n".join(f"{bullet_prefix}{item}" for item in items)
255
+ return f"\n\n### {header}\n\n{bullets}"
256
+
257
+
258
+ def _render_main_changes(changes: list[str], extra_content: str | None) -> str:
259
+ """Render the Main Changes section from --change bullets or freeform content."""
260
+ if changes:
261
+ return _render_bullet_section("Main Changes", changes)
262
+ if extra_content:
263
+ return f"\n\n### Main Changes\n\n{extra_content}"
264
+ return ""
265
+
266
+
205
267
  def generate_session_content(
206
268
  session_num: int,
207
269
  title: str,
208
270
  commit: str,
209
271
  summary: str,
210
- extra_content: str,
211
272
  today: str,
212
273
  package: str | None = None,
213
274
  branch: str | None = None,
214
- testing_content: str = DEFAULT_TESTING,
275
+ changes: list[str] | None = None,
276
+ extra_content: str | None = None,
277
+ tests: list[str] | None = None,
278
+ next_steps: list[str] | None = None,
215
279
  ) -> str:
216
280
  """Generate session content."""
217
281
  if commit and commit != "-":
@@ -226,6 +290,10 @@ def generate_session_content(
226
290
  package_line = f"\n**Package**: {package}" if package else ""
227
291
  branch_line = f"\n**Branch**: `{branch}`" if branch else ""
228
292
 
293
+ main_changes_section = _render_main_changes(changes or [], extra_content)
294
+ testing_section = _render_bullet_section("Testing", tests or [], bullet_prefix="- [OK] ")
295
+ next_steps_section = _render_bullet_section("Next Steps", next_steps or [])
296
+
229
297
  return f"""
230
298
 
231
299
  ## Session {session_num}: {title}
@@ -235,27 +303,15 @@ def generate_session_content(
235
303
 
236
304
  ### Summary
237
305
 
238
- {summary}
239
-
240
- ### Main Changes
241
-
242
- {extra_content}
306
+ {summary}{main_changes_section}
243
307
 
244
308
  ### Git Commits
245
309
 
246
- {commit_table}
247
-
248
- ### Testing
249
-
250
- {testing_content}
310
+ {commit_table}{testing_section}
251
311
 
252
312
  ### Status
253
313
 
254
- [OK] **Completed**
255
-
256
- ### Next Steps
257
-
258
- - None - task complete
314
+ [OK] **Completed**{next_steps_section}
259
315
  """
260
316
 
261
317
 
@@ -454,13 +510,17 @@ def add_session(
454
510
  title: str,
455
511
  commit: str = "-",
456
512
  summary: str = "Session summary was not supplied.",
457
- extra_content: str = DEFAULT_MAIN_CHANGES,
513
+ changes: list[str] | None = None,
514
+ extra_content: str | None = None,
515
+ tests: list[str] | None = None,
516
+ next_steps: list[str] | None = None,
458
517
  auto_commit: bool = True,
459
518
  package: str | None = None,
460
519
  branch: str | None = None,
461
520
  ) -> int:
462
521
  """Add a new session."""
463
522
  repo_root = get_repo_root()
523
+ warn_if_parallel_worktree(repo_root)
464
524
  ensure_developer(repo_root)
465
525
 
466
526
  developer = get_developer(repo_root)
@@ -483,8 +543,9 @@ def add_session(
483
543
  new_session = current_session + 1
484
544
 
485
545
  session_content = generate_session_content(
486
- new_session, title, commit, summary, extra_content, today, package,
487
- branch,
546
+ new_session, title, commit, summary, today, package, branch,
547
+ changes=changes, extra_content=extra_content, tests=tests,
548
+ next_steps=next_steps,
488
549
  )
489
550
  content_lines = len(session_content.splitlines())
490
551
 
@@ -565,6 +626,9 @@ def main() -> int:
565
626
  parser.add_argument("--content-file", help="Path to file with detailed content")
566
627
  parser.add_argument("--package", help="Package name tag (e.g., cli, docs-site)")
567
628
  parser.add_argument("--branch", help="Branch name (auto-detected if omitted)")
629
+ parser.add_argument("--change", action="append", help="Main Changes bullet (repeatable)")
630
+ parser.add_argument("--test", action="append", help="Testing bullet (repeatable)")
631
+ parser.add_argument("--next-step", action="append", help="Next Steps bullet (repeatable)")
568
632
  parser.add_argument("--no-commit", action="store_true",
569
633
  help="Skip auto-commit of workspace changes")
570
634
  parser.add_argument("--stdin", action="store_true",
@@ -572,7 +636,7 @@ def main() -> int:
572
636
 
573
637
  args = parser.parse_args()
574
638
 
575
- extra_content = DEFAULT_MAIN_CHANGES
639
+ extra_content: str | None = None
576
640
  if args.content_file:
577
641
  content_path = Path(args.content_file)
578
642
  if content_path.is_file():
@@ -604,7 +668,9 @@ def main() -> int:
604
668
  branch = resolve_session_branch(repo_root, args.branch, task_data)
605
669
 
606
670
  return add_session(
607
- args.title, args.commit, args.summary, extra_content,
671
+ args.title, args.commit, args.summary,
672
+ changes=args.change, extra_content=extra_content, tests=args.test,
673
+ next_steps=args.next_step,
608
674
  auto_commit=not args.no_commit,
609
675
  package=package,
610
676
  branch=branch,
@@ -44,6 +44,10 @@ _KNOWN_PLATFORMS = {
44
44
  "copilot",
45
45
  "pi",
46
46
  "trae",
47
+ "grok",
48
+ "kimi",
49
+ "zcode",
50
+ "snow",
47
51
  }
48
52
 
49
53
  _ENV_SESSION_KEYS: tuple[tuple[str, tuple[str, ...]], ...] = (
@@ -59,6 +63,14 @@ _ENV_SESSION_KEYS: tuple[tuple[str, tuple[str, ...]], ...] = (
59
63
  ("copilot", ("COPILOT_SESSION_ID", "COPILOT_SESSIONID")),
60
64
  ("pi", ("PI_SESSION_ID", "PI_SESSIONID")),
61
65
  ("trae", ("TRAE_SESSION_ID",)),
66
+ # ZCode reuses CLAUDE_SESSION_ID (it does not document a ZCODE_SESSION_ID).
67
+ # Platform-scoped lookup (_iter_env_keys filters by platform name), so this
68
+ # only fires when the resolver already detected "zcode" — no collision with
69
+ # the claude entry above.
70
+ ("zcode", ("CLAUDE_SESSION_ID",)),
71
+ # Snow CLI exports SNOW_SESSION_ID into hook/terminal/sub-agent children.
72
+ # TRELLIS_CONTEXT_ID remains the preferred override when present.
73
+ ("snow", ("SNOW_SESSION_ID",)),
62
74
  )
63
75
  _ENV_CONVERSATION_KEYS: tuple[tuple[str, tuple[str, ...]], ...] = (
64
76
  ("cursor", ("CURSOR_CONVERSATION_ID", "CURSOR_CONVERSATIONID")),
@@ -78,6 +90,12 @@ _ENV_PLATFORM_ALIASES = {
78
90
  "factory-ai": "droid",
79
91
  "github-copilot": "copilot",
80
92
  }
93
+ # ZCode intentionally reuses CLAUDE_SESSION_ID. Hooks know the host is ZCode,
94
+ # while later shell commands see only the shared env name and resolve it through
95
+ # the Claude entry. Canonicalize both paths to one runtime filename.
96
+ _CONTEXT_KEY_PLATFORM_ALIASES = {
97
+ "zcode": "claude",
98
+ }
81
99
 
82
100
 
83
101
  @dataclass(frozen=True)
@@ -191,6 +209,7 @@ def _detect_platform(platform_input: dict[str, Any] | None, platform: str | None
191
209
 
192
210
 
193
211
  def _context_key(platform_name: str, kind: str, value: str) -> str:
212
+ platform_name = _CONTEXT_KEY_PLATFORM_ALIASES.get(platform_name, platform_name)
194
213
  if kind == "transcript":
195
214
  return f"{platform_name}_transcript_{_hash_value(value)}"
196
215
  safe_value = _sanitize_key(value)
@@ -382,15 +401,18 @@ def _lookup_cursor_shell_ticket_context_key() -> str | None:
382
401
  def resolve_context_key(
383
402
  platform_input: dict[str, Any] | None = None,
384
403
  platform: str | None = None,
404
+ *,
405
+ allow_environment_context: bool = True,
385
406
  ) -> str | None:
386
407
  """Resolve a stable session/window context key, if one is available.
387
408
 
388
409
  `TRELLIS_CONTEXT_ID` is an explicit context-key override used by CLI
389
410
  scripts and subprocesses. It does not store the task itself.
390
411
  """
391
- override = _string_value(os.environ.get("TRELLIS_CONTEXT_ID"))
392
- if override:
393
- return _sanitize_key(override) or _hash_value(override)
412
+ if allow_environment_context:
413
+ override = _string_value(os.environ.get("TRELLIS_CONTEXT_ID"))
414
+ if override:
415
+ return _sanitize_key(override) or _hash_value(override)
394
416
 
395
417
  data = _as_dict(platform_input)
396
418
  platform_name = _detect_platform(data, platform) if data or platform else None
@@ -408,11 +430,12 @@ def resolve_context_key(
408
430
  if transcript_path:
409
431
  return _context_key(platform_name or "session", "transcript", transcript_path)
410
432
 
411
- env_context_key = _lookup_env_context_key(platform_name)
412
- if env_context_key:
413
- return env_context_key
433
+ if allow_environment_context:
434
+ env_context_key = _lookup_env_context_key(platform_name)
435
+ if env_context_key:
436
+ return env_context_key
414
437
 
415
- if platform_name in (None, "session", "cursor"):
438
+ if allow_environment_context and platform_name in (None, "session", "cursor"):
416
439
  return _lookup_cursor_shell_ticket_context_key()
417
440
  return None
418
441
 
@@ -471,17 +494,24 @@ def resolve_active_task(
471
494
  repo_root: Path,
472
495
  platform_input: dict[str, Any] | None = None,
473
496
  platform: str | None = None,
497
+ *,
498
+ allow_single_session_fallback: bool = True,
499
+ allow_environment_context: bool = True,
474
500
  ) -> ActiveTask:
475
501
  """Resolve the active task from session runtime state only.
476
502
 
477
503
  A stale session task is returned as stale. Missing context identity or a
478
504
  missing/empty session context falls back to single-session inference: if
479
505
  exactly one session file exists in the runtime, return its task with
480
- source_type="session-fallback" — covers class-2 platform sub-agents (codex,
481
- copilot, gemini, qoder) that don't inherit the parent's session id. ≥2
506
+ source_type="session-fallback" — covers pull-based platform sub-agents
507
+ (copilot, gemini, qoder) that don't inherit the parent's session id. ≥2
482
508
  files or 0 files yield ActiveTask(None) — refuses to guess across windows.
483
509
  """
484
- context_key = resolve_context_key(platform_input, platform)
510
+ context_key = resolve_context_key(
511
+ platform_input,
512
+ platform,
513
+ allow_environment_context=allow_environment_context,
514
+ )
485
515
  if context_key:
486
516
  context = _read_json(_context_path(repo_root, context_key)) or {}
487
517
  task_ref = _string_value(context.get("current_task"))
@@ -489,9 +519,10 @@ def resolve_active_task(
489
519
  if active:
490
520
  return active
491
521
 
492
- fallback = _resolve_single_session_fallback(repo_root)
493
- if fallback is not None:
494
- return fallback
522
+ if allow_single_session_fallback:
523
+ fallback = _resolve_single_session_fallback(repo_root)
524
+ if fallback is not None:
525
+ return fallback
495
526
 
496
527
  return ActiveTask(None, "none", context_key)
497
528