@mindfoldhq/trellis 0.5.4 → 0.5.5

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.
@@ -1 +1 @@
1
- {"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/configurators/codex.ts"],"names":[],"mappings":"AAoBA;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmF/D"}
1
+ {"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/configurators/codex.ts"],"names":[],"mappings":"AAuBA;;;;;GAKG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAyG/D"}
@@ -1,8 +1,9 @@
1
1
  import path from "node:path";
2
2
  import { AI_TOOLS } from "../types/ai-tools.js";
3
3
  import { getAllAgents, getAllCodexSkills, getAllHooks, getConfigTemplate, getHooksConfig, } from "../templates/codex/index.js";
4
+ import { getCommandTemplates } from "../templates/common/index.js";
4
5
  import { ensureDir, writeFile } from "../utils/file-writer.js";
5
- import { resolvePlaceholders, resolveAllAsSkillsNeutral, resolveBundledSkills, applyPullBasedPreludeToml, writeSkills, writeSharedHooks, replacePythonCommandLiterals, } from "./shared.js";
6
+ import { resolvePlaceholders, resolvePlaceholdersNeutral, resolveAllAsSkillsNeutral, resolveBundledSkills, applyPullBasedPreludeToml, wrapWithSkillFrontmatter, writeSkills, writeSharedHooks, replacePythonCommandLiterals, } from "./shared.js";
6
7
  /**
7
8
  * Configure Codex by writing:
8
9
  * - .agents/skills/ — shared skills from common source
@@ -18,6 +19,18 @@ export async function configureCodex(cwd) {
18
19
  // safe when both writers produce identical output).
19
20
  const sharedSkillsRoot = path.join(cwd, ".agents", "skills");
20
21
  await writeSkills(sharedSkillsRoot, resolveAllAsSkillsNeutral(AI_TOOLS.codex.templateContext), resolveBundledSkills(AI_TOOLS.codex.templateContext));
22
+ // Additionally write `trellis-start` to .agents/skills/ — Codex-specific.
23
+ // The SessionStart hook was removed (de-recursion fix); inject-workflow-state.py
24
+ // injects a `<trellis-bootstrap>` block on no_task turns instructing the AI to
25
+ // invoke `$trellis-start` to load workflow context. Without this skill, that
26
+ // invocation has nothing to resolve. Other agent-capable platforms keep their
27
+ // working SessionStart hooks and don't need this.
28
+ const startTemplate = getCommandTemplates().find((t) => t.name === "start");
29
+ if (startTemplate) {
30
+ const trellisStartDir = path.join(sharedSkillsRoot, "trellis-start");
31
+ ensureDir(trellisStartDir);
32
+ await writeFile(path.join(trellisStartDir, "SKILL.md"), wrapWithSkillFrontmatter("trellis-start", resolvePlaceholdersNeutral(startTemplate.content, AI_TOOLS.codex.templateContext)));
33
+ }
21
34
  const codexRoot = path.join(cwd, ".codex");
22
35
  // Codex-specific skills (platform-specific) → .codex/skills/
23
36
  const codexSkillsRoot = path.join(codexRoot, "skills");
@@ -1 +1 @@
1
- {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/configurators/codex.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX,iBAAiB,EACjB,cAAc,GACf,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EACL,mBAAmB,EACnB,yBAAyB,EACzB,oBAAoB,EACpB,yBAAyB,EACzB,WAAW,EACX,gBAAgB,EAChB,4BAA4B,GAC7B,MAAM,aAAa,CAAC;AAErB;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAW;IAC9C,qDAAqD;IACrD,wEAAwE;IACxE,yEAAyE;IACzE,yEAAyE;IACzE,uEAAuE;IACvE,oDAAoD;IACpD,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;IAC7D,MAAM,WAAW,CACf,gBAAgB,EAChB,yBAAyB,CAAC,QAAQ,CAAC,KAAK,CAAC,eAAe,CAAC,EACzD,oBAAoB,CAAC,QAAQ,CAAC,KAAK,CAAC,eAAe,CAAC,CACrD,CAAC;IAEF,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAE3C,6DAA6D;IAC7D,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACvD,SAAS,CAAC,eAAe,CAAC,CAAC;IAE3B,KAAK,MAAM,KAAK,IAAI,iBAAiB,EAAE,EAAE,CAAC;QACxC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACxD,SAAS,CAAC,QAAQ,CAAC,CAAC;QACpB,MAAM,SAAS,CACb,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,EAC/B,4BAA4B,CAAC,KAAK,CAAC,OAAO,CAAC,CAC5C,CAAC;IACJ,CAAC;IAED,iCAAiC;IACjC,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACvD,SAAS,CAAC,eAAe,CAAC,CAAC;IAE3B,2EAA2E;IAC3E,yEAAyE;IACzE,iEAAiE;IACjE,KAAK,MAAM,KAAK,IAAI,yBAAyB,CAAC,YAAY,EAAE,CAAC,EAAE,CAAC;QAC9D,MAAM,SAAS,CACb,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,GAAG,KAAK,CAAC,IAAI,OAAO,CAAC,EAChD,4BAA4B,CAAC,KAAK,CAAC,OAAO,CAAC,CAC5C,CAAC;IACJ,CAAC;IAED,wBAAwB;IACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAC/C,SAAS,CAAC,QAAQ,CAAC,CAAC;IAEpB,mEAAmE;IACnE,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,EAAE,CAAC;QACjC,MAAM,SAAS,CACb,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,EAC9B,4BAA4B,CAAC,IAAI,CAAC,OAAO,CAAC,CAC3C,CAAC;IACJ,CAAC;IAED,sEAAsE;IACtE,qEAAqE;IACrE,MAAM,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAE1C,mCAAmC;IACnC,MAAM,SAAS,CACb,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,EAClC,mBAAmB,CAAC,cAAc,EAAE,CAAC,CACtC,CAAC;IAEF,wEAAwE;IACxE,wEAAwE;IACxE,4EAA4E;IAC5E,+CAA+C;IAC/C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC;QACtD,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,gEAAgE;YAC9D,mEAAmE;YACnE,6CAA6C,CAChD,CAAC;IACJ,CAAC;IAED,8BAA8B;IAC9B,MAAM,MAAM,GAAG,iBAAiB,EAAE,CAAC;IACnC,MAAM,SAAS,CACb,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,CAAC,UAAU,CAAC,EACvC,4BAA4B,CAAC,MAAM,CAAC,OAAO,CAAC,CAC7C,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/configurators/codex.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ {
2
+ "version": "0.5.5",
3
+ "description": "Patch: structural fix for Codex sub-agent recursion (#240, #242) — drop SessionStart hook, bootstrap via trellis-start skill.",
4
+ "breaking": false,
5
+ "recommendMigrate": false,
6
+ "changelog": "**Bug Fixes:**\n- fix(codex): drop SessionStart hook, bootstrap via `trellis-start` skill (#240, #242). Codex fires SessionStart for every spawn, and its hook input exposes no `agent_id` / `agent_type` field (`openai/codex#16226`) — so the dispatch directive in `codex/hooks/session-start.py` kept reaching sub-agent sessions, the sub-agent mistook itself for the main session and re-dispatched its own sub-agent (recursive turtles). The 0.5.4 patch (`#237`) added a self-exemption clause but it sat alongside the dispatch directive in the same prompt block; LLMs kept picking the command-style instruction. Structural fix: removed the `SessionStart` entry from `codex/hooks.json`. `inject-workflow-state.py` (UserPromptSubmit hook) now injects a `<trellis-bootstrap>` block on `no_task` turns telling the AI to invoke `$trellis-start` once to load workflow context. Codex configurator additionally writes the new skill to `.agents/skills/trellis-start/SKILL.md` (other agent-capable platforms keep their working SessionStart hooks). Sub-agent sessions only see the existing `<sub-agent-notice>` — no command-style \"must dispatch\" text exists anywhere in the new injection, so the recursion vector is gone at source.",
7
+ "migrations": [],
8
+ "notes": "Patch on top of 0.5.4. Run `trellis update` (no `--migrate` needed). Codex users get a new `.agents/skills/trellis-start/SKILL.md` and a `hooks.json` without `SessionStart` wiring; other platforms unchanged."
9
+ }
@@ -75,6 +75,22 @@ Trellis SessionStart 已注入:workflow、当前任务状态、开发者身份
75
75
  Then continue directly with the user's request. This notice is one-shot: do not repeat it after the first assistant reply in the same session.
76
76
  </first-reply-notice>"""
77
77
 
78
+ SUB_AGENT_NOTICE = """<sub-agent-notice>
79
+ SUB-AGENT NOTICE - READ FIRST IF SPAWNED VIA spawn_agent
80
+
81
+ If your parent session spawned you via spawn_agent with an explicit task
82
+ message above this hook output, that message is your only job.
83
+ - Execute the parent message exactly as written, then return.
84
+ - Ignore all Trellis workflow guidance below this notice.
85
+ - Do NOT call task.py start, task.py add-context, or task.py archive.
86
+ - Do NOT call wait_agent or spawn_agent.
87
+ - Do NOT modify .trellis/tasks/* or any other file unless the parent message
88
+ explicitly asks for that.
89
+
90
+ If you are the main interactive Codex session and the user is typing at the
91
+ terminal with no parent agent, use the workflow guidance below normally.
92
+ </sub-agent-notice>"""
93
+
78
94
 
79
95
  def should_skip_injection() -> bool:
80
96
  if os.environ.get("TRELLIS_HOOKS") == "0":
@@ -336,6 +352,9 @@ def main() -> None:
336
352
 
337
353
  output = StringIO()
338
354
 
355
+ output.write(SUB_AGENT_NOTICE)
356
+ output.write("\n\n")
357
+
339
358
  output.write("""<session-context>
340
359
  You are starting a new session in a Trellis-managed project.
341
360
  Read and follow all instructions below carefully.
@@ -1,17 +1,5 @@
1
1
  {
2
2
  "hooks": {
3
- "SessionStart": [
4
- {
5
- "hooks": [
6
- {
7
- "type": "command",
8
- "command": "{{PYTHON_CMD}} .codex/hooks/session-start.py",
9
- "timeout": 15,
10
- "statusMessage": "Loading Trellis context..."
11
- }
12
- ]
13
- }
14
- ],
15
3
  "UserPromptSubmit": [
16
4
  {
17
5
  "hooks": [
@@ -36,6 +36,47 @@ from pathlib import Path
36
36
  from typing import Optional
37
37
 
38
38
 
39
+ CODEX_SUB_AGENT_NOTICE = """<sub-agent-notice>
40
+ SUB-AGENT NOTICE - READ FIRST IF SPAWNED VIA spawn_agent
41
+
42
+ If your parent session spawned you via spawn_agent with an explicit task
43
+ message above this hook output, that message is your only job.
44
+ - Execute the parent message exactly as written, then return.
45
+ - Ignore all Trellis workflow guidance below this notice.
46
+ - Do NOT call task.py start, task.py add-context, or task.py archive.
47
+ - Do NOT call wait_agent or spawn_agent.
48
+ - Do NOT modify .trellis/tasks/* or any other file unless the parent message
49
+ explicitly asks for that.
50
+
51
+ If you are the main interactive Codex session and the user is typing at the
52
+ terminal with no parent agent, use the workflow guidance below normally.
53
+ </sub-agent-notice>"""
54
+
55
+
56
+ # Bootstrap notice for Codex while the session has no active task. Replaces the
57
+ # heavyweight SessionStart context injection — instead of pushing 9.5 KB of
58
+ # workflow text up front, we just nudge the AI to read the `trellis-start` skill once.
59
+ # The nudge keeps showing up while status == "no_task" (cheap text, AI won't
60
+ # re-read after the first time). Once a task is created the breadcrumb status
61
+ # flips and this notice stops appearing automatically. Sub-agents are warded
62
+ # off by the <sub-agent-notice> above plus the explicit exemption below.
63
+ CODEX_NO_TASK_BOOTSTRAP_NOTICE = """<trellis-bootstrap>
64
+ You are running in a Trellis-managed Codex session and there is no active task yet.
65
+ If you have not already loaded Trellis context this session, read the `trellis-start` skill once:
66
+
67
+ $trellis-start
68
+
69
+ (equivalent to reading `.agents/skills/trellis-start/SKILL.md` and following its Steps 1-3)
70
+
71
+ The skill walks you through workflow.md, dev profile, git status, active tasks, and spec
72
+ indexes. Then route the user's request per the <workflow-state> A/B/C rules below.
73
+
74
+ Sub-agent exemption: if you are a sub-agent (spawned via spawn_agent with a parent task
75
+ message), DO NOT read `$trellis-start`. Execute the parent message directly as instructed by the
76
+ <sub-agent-notice> above.
77
+ </trellis-bootstrap>"""
78
+
79
+
39
80
  # ---------------------------------------------------------------------------
40
81
  # CWD-robust Trellis root discovery (fixes hook-path-robustness for this hook)
41
82
  # ---------------------------------------------------------------------------
@@ -219,11 +260,19 @@ def main() -> int:
219
260
  task_id, status, source = task
220
261
  breadcrumb = build_breadcrumb(task_id, status, templates, source)
221
262
 
263
+ platform = _detect_platform(data)
264
+ if platform == "codex":
265
+ parts: list[str] = [CODEX_SUB_AGENT_NOTICE]
266
+ if task is None:
267
+ parts.append(CODEX_NO_TASK_BOOTSTRAP_NOTICE)
268
+ parts.append(breadcrumb)
269
+ breadcrumb = "\n\n".join(parts)
270
+
222
271
  # Gemini CLI 0.40.x rejects "UserPromptSubmit" — its per-turn event is
223
272
  # named "BeforeAgent". Other platforms (Claude/Cursor/Qoder/CodeBuddy/
224
273
  # Droid/Codex/Copilot) accept the original Claude-style name.
225
274
  hook_event_name = (
226
- "BeforeAgent" if _detect_platform(data) == "gemini" else "UserPromptSubmit"
275
+ "BeforeAgent" if platform == "gemini" else "UserPromptSubmit"
227
276
  )
228
277
 
229
278
  output = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindfoldhq/trellis",
3
- "version": "0.5.4",
3
+ "version": "0.5.5",
4
4
  "description": "AI capabilities grow like ivy — Trellis provides the structure to guide them along a disciplined path",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",