@mindfoldhq/trellis 0.6.0-beta.0 → 0.6.0-beta.1

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.
@@ -9,7 +9,7 @@
9
9
  {
10
10
  "file": ".trellis/config.yaml",
11
11
  "sentinel": "codex:",
12
- "sectionHeading": "Codex (sub-agent dispatch behavior)"
12
+ "sectionHeading": "Codex (dispatch behavior)"
13
13
  }
14
14
  ],
15
15
  "notes": "Patch on top of 0.5.6. Run `trellis update` (no `--migrate` needed). Codex users get the new `dispatch_mode` knob (default unchanged), hardened sub-agent role files, plus the previously-init-only `trellis-start` skill on the update path. Kiro users get an agent JSON that Kiro CLI no longer rejects. Codex 0.129+ users should run `/hooks` once after upgrading Codex to approve the Trellis `UserPromptSubmit` hook."
@@ -0,0 +1,9 @@
1
+ {
2
+ "version": "0.5.9",
3
+ "description": "Patch: codex dispatch defaults to inline + workflow.md namespaced into codex-inline / codex-sub-agent.",
4
+ "breaking": false,
5
+ "recommendMigrate": false,
6
+ "changelog": "**Bug Fixes:**\n- fix(codex): default `codex.dispatch_mode` flipped from `sub-agent` to `inline`. Codex sub-agents run with `fork_turns=\"none\"` isolation and can't inherit the parent session's task context, so they exit silently or recursively dispatch. Inline keeps the main Codex agent in charge so context isn't lost. Set `codex.dispatch_mode: sub-agent` in `.trellis/config.yaml` to opt back into the legacy dispatch flow. Invalid values fall back to inline.\n- fix(workflow): namespace `--platform codex` into virtual platforms `codex-inline` / `codex-sub-agent` so `workflow.md` `[Platform A, B, ...]` blocks render the correct guidance per mode. `inject-workflow-state.py` emits a `<codex-mode>` banner in the per-turn UserPromptSubmit prompt so Codex knows which mode it is in, and `[workflow-state:STATUS-inline]` blocks now drive the breadcrumb path for inline mode.\n\n**Internal:**\n- chore(manifests): restore `0.6.0-beta.0.json` on main. The version was published from `feat/v0.6.0-beta` but its manifest never landed on main, breaking adjacent-version update chains for users who hop between stable and beta lines.",
7
+ "migrations": [],
8
+ "notes": "Patch on top of 0.5.8. Run `trellis update` (no `--migrate` needed). Existing Codex projects keep working: if you previously uncommented `dispatch_mode: sub-agent`, that opt-in still routes to the legacy dispatch flow; if the line is commented (the default), behavior switches to inline."
9
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "version": "0.6.0-beta.1",
3
+ "description": "Beta patch: same Codex dispatch fix as 0.5.9 — defaults to inline + workflow.md namespaced into codex-inline / codex-sub-agent.",
4
+ "breaking": false,
5
+ "recommendMigrate": false,
6
+ "changelog": "**Bug Fixes:** (mirrors 0.5.9)\n- fix(codex): default `codex.dispatch_mode` flipped from `sub-agent` to `inline`. Codex sub-agents run with `fork_turns=\"none\"` isolation and can't inherit the parent session's task context, so they exit silently or recursively dispatch. Inline keeps the main Codex agent in charge so context isn't lost. Set `codex.dispatch_mode: sub-agent` in `.trellis/config.yaml` to opt back into the legacy dispatch flow. Invalid values fall back to inline.\n- fix(workflow): namespace `--platform codex` into virtual platforms `codex-inline` / `codex-sub-agent` so `workflow.md` `[Platform A, B, ...]` blocks render the correct guidance per mode. `inject-workflow-state.py` emits a `<codex-mode>` banner in the per-turn UserPromptSubmit prompt so Codex knows which mode it is in, and `[workflow-state:STATUS-inline]` blocks now drive the breadcrumb path for inline mode.",
7
+ "migrations": [],
8
+ "notes": "Beta patch on top of 0.6.0-beta.0. Run `trellis update` (no `--migrate` needed). Behavior change matches 0.5.9 — if you previously uncommented `dispatch_mode: sub-agent`, that opt-in still routes to the legacy dispatch flow; if commented (the default), behavior switches to inline."
9
+ }
@@ -227,20 +227,49 @@ def _read_trellis_config(root: Path) -> dict:
227
227
  return {}
228
228
 
229
229
 
230
+ def _codex_mode_banner(config: dict) -> str:
231
+ """Emit a `<codex-mode>` banner for the additionalContext payload.
232
+
233
+ Reads `codex.dispatch_mode` from .trellis/config.yaml; defaults to
234
+ `inline` when missing or invalid because Codex sub-agents run with
235
+ `fork_turns="none"` isolation and can't inherit the parent session's
236
+ task context. The banner makes the active mode explicit to Codex AI
237
+ per turn, complementing the workflow-state body which is per-status.
238
+ Mode tells AI which dispatch protocol to follow; workflow-state tells
239
+ AI what step it's at.
240
+ """
241
+ mode = "inline"
242
+ if isinstance(config, dict):
243
+ codex_cfg = config.get("codex")
244
+ if isinstance(codex_cfg, dict):
245
+ cfg_mode = codex_cfg.get("dispatch_mode")
246
+ if cfg_mode in ("inline", "sub-agent"):
247
+ mode = cfg_mode
248
+ return f"<codex-mode>{mode}</codex-mode>"
249
+
250
+
230
251
  def resolve_breadcrumb_key(
231
252
  status: str, platform: str | None, config: dict
232
253
  ) -> str:
233
254
  """Pick the breadcrumb tag key based on Codex dispatch_mode.
234
255
 
235
- Codex users may opt into ``codex.dispatch_mode: inline`` to have the main
236
- agent edit code directly. When the opt-in is set, route to the parallel
237
- ``<status>-inline`` tag block so the breadcrumb body matches the inline
238
- workflow. Other platforms / modes return the plain status unchanged.
256
+ Codex defaults to ``inline`` because sub-agents run with ``fork_turns="none"``
257
+ isolation and can't inherit the parent session's task context. Users can
258
+ opt into ``codex.dispatch_mode: sub-agent`` in ``.trellis/config.yaml``
259
+ to use the parallel ``<status>-inline`` tag ``<status>`` flip. Invalid
260
+ or missing values fall back to inline.
261
+
262
+ Non-codex platforms return the plain status unchanged.
239
263
  """
240
- if platform == "codex" and isinstance(config, dict):
241
- codex_cfg = config.get("codex")
242
- if isinstance(codex_cfg, dict) and codex_cfg.get("dispatch_mode") == "inline":
243
- return f"{status}-inline"
264
+ if platform == "codex":
265
+ mode = "inline"
266
+ if isinstance(config, dict):
267
+ codex_cfg = config.get("codex")
268
+ if isinstance(codex_cfg, dict):
269
+ cfg_mode = codex_cfg.get("dispatch_mode")
270
+ if cfg_mode in ("inline", "sub-agent"):
271
+ mode = cfg_mode
272
+ return f"{status}-inline" if mode == "inline" else status
244
273
  return status
245
274
 
246
275
 
@@ -311,6 +340,7 @@ def main() -> int:
311
340
  parts: list[str] = [CODEX_SUB_AGENT_NOTICE]
312
341
  if task is None:
313
342
  parts.append(CODEX_NO_TASK_BOOTSTRAP_NOTICE)
343
+ parts.append(_codex_mode_banner(config))
314
344
  parts.append(breadcrumb)
315
345
  breadcrumb = "\n\n".join(parts)
316
346
 
@@ -59,12 +59,14 @@ max_journal_lines: 2000
59
59
  # default_package: frontend
60
60
 
61
61
  #-------------------------------------------------------------------------------
62
- # Codex (sub-agent dispatch behavior)
62
+ # Codex (dispatch behavior)
63
63
  #-------------------------------------------------------------------------------
64
- # Opt out of "main session must dispatch trellis-implement / trellis-check
65
- # sub-agents" and let the main agent edit code inline. Codex-only knob;
66
- # other platforms ignore it. Default ("sub-agent") preserves existing
67
- # behavior, so nothing changes unless you uncomment the block below.
64
+ # Codex-only knob; other platforms ignore it. Default ("inline") makes the
65
+ # main Codex agent edit code directly because Codex sub-agents run with
66
+ # `fork_turns="none"` isolation and can't inherit the parent session's
67
+ # task context. Set to "sub-agent" to opt into the legacy dispatch model
68
+ # (main agent spawns trellis-implement / trellis-check / trellis-research
69
+ # sub-agents).
68
70
  #
69
71
  # codex:
70
- # dispatch_mode: sub-agent # or "inline" to let the main agent edit code directly
72
+ # dispatch_mode: inline # or "sub-agent" to dispatch trellis-* sub-agents
@@ -145,17 +145,29 @@ def _platform_matches(platform: str, block_names: list[str]) -> bool:
145
145
 
146
146
 
147
147
  def resolve_effective_platform(platform: str, config: dict) -> str:
148
- """Map platform name through codex inline-mode opt-in.
148
+ """Map ``codex`` to a dispatch-mode-namespaced virtual platform name.
149
149
 
150
- When ``codex.dispatch_mode`` is set to ``"inline"`` in .trellis/config.yaml
151
- and the caller is running with ``--platform codex``, swap the name to
152
- ``"kilo"`` so ``filter_platform`` surfaces the inline workflow content
153
- that already lives in the ``[Kilo, Antigravity, Windsurf]`` blocks.
150
+ When ``--platform codex`` is passed, return ``"codex-inline"`` (default)
151
+ or ``"codex-sub-agent"`` based on ``.trellis/config.yaml`` ``codex.dispatch_mode``.
152
+ ``filter_platform`` then surfaces blocks whose marker lists include the
153
+ namespaced name (e.g. ``[codex-sub-agent, ...]`` or ``[codex-inline, Kilo,
154
+ Antigravity, Windsurf]``).
155
+
156
+ Default is ``inline`` because Codex sub-agents run with ``fork_turns="none"``
157
+ isolation and can't inherit the parent session's task context — inline
158
+ keeps the main agent in charge so context isn't lost. Invalid / missing
159
+ values also fall back to inline.
160
+
161
+ Other platforms are returned unchanged.
154
162
  """
155
163
  if platform == "codex":
164
+ mode = "inline"
156
165
  codex_cfg = config.get("codex") if isinstance(config, dict) else None
157
- if isinstance(codex_cfg, dict) and codex_cfg.get("dispatch_mode") == "inline":
158
- return "kilo"
166
+ if isinstance(codex_cfg, dict):
167
+ cfg_mode = codex_cfg.get("dispatch_mode")
168
+ if cfg_mode in ("inline", "sub-agent"):
169
+ mode = cfg_mode
170
+ return f"codex-{mode}"
159
171
  return platform
160
172
 
161
173
 
@@ -245,7 +245,7 @@ If you reach this state with uncommitted code, return to Phase 3.4 first — `/f
245
245
 
246
246
  When a user request matches one of these intents, load the corresponding skill (or dispatch the corresponding sub-agent) first — do not skip skills.
247
247
 
248
- [Claude Code, Cursor, OpenCode, Codex, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
248
+ [Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
249
249
 
250
250
  | User intent | Route |
251
251
  |---|---|
@@ -257,9 +257,9 @@ When a user request matches one of these intents, load the corresponding skill (
257
257
 
258
258
  **Why `trellis-before-dev` is NOT in this table:** you are not the one writing code — the `trellis-implement` sub-agent is. Sub-agent platforms get spec context via `implement.jsonl` injection / prelude, not via the main thread loading `trellis-before-dev`.
259
259
 
260
- [/Claude Code, Cursor, OpenCode, Codex, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
260
+ [/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
261
261
 
262
- [Kilo, Antigravity, Windsurf]
262
+ [codex-inline, Kilo, Antigravity, Windsurf]
263
263
 
264
264
  | User intent | Skill |
265
265
  |---|---|
@@ -269,11 +269,11 @@ When a user request matches one of these intents, load the corresponding skill (
269
269
  | Stuck / fixed same bug several times | `trellis-break-loop` |
270
270
  | Spec needs update | `trellis-update-spec` |
271
271
 
272
- [/Kilo, Antigravity, Windsurf]
272
+ [/codex-inline, Kilo, Antigravity, Windsurf]
273
273
 
274
274
  ### DO NOT skip skills
275
275
 
276
- [Claude Code, Cursor, OpenCode, Codex, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
276
+ [Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
277
277
 
278
278
  | What you're thinking | Why it's wrong |
279
279
  |---|---|
@@ -282,9 +282,9 @@ When a user request matches one of these intents, load the corresponding skill (
282
282
  | "I already know the spec" | The spec may have been updated since you last read it; the sub-agent gets the fresh copy, you may not |
283
283
  | "Code first, check later" | `trellis-check` surfaces issues you won't notice yourself; earlier is cheaper |
284
284
 
285
- [/Claude Code, Cursor, OpenCode, Codex, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
285
+ [/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
286
286
 
287
- [Kilo, Antigravity, Windsurf]
287
+ [codex-inline, Kilo, Antigravity, Windsurf]
288
288
 
289
289
  | What you're thinking | Why it's wrong |
290
290
  |---|---|
@@ -293,7 +293,7 @@ When a user request matches one of these intents, load the corresponding skill (
293
293
  | "I already know the spec" | The spec may have been updated since you last read it; read again |
294
294
  | "Code first, check later" | `trellis-check` surfaces issues you won't notice yourself; earlier is cheaper |
295
295
 
296
- [/Kilo, Antigravity, Windsurf]
296
+ [/codex-inline, Kilo, Antigravity, Windsurf]
297
297
 
298
298
  ### Loading Step Detail
299
299
 
@@ -342,7 +342,7 @@ Return to this step whenever requirements change and revise `prd.md`.
342
342
 
343
343
  Research can happen at any time during requirement exploration. It isn't limited to local code — you can use any available tool (MCP servers, skills, web search, etc.) to look up external information, including third-party library docs, industry practices, API references, etc.
344
344
 
345
- [Claude Code, Cursor, OpenCode, Codex, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
345
+ [Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
346
346
 
347
347
  Spawn the research sub-agent:
348
348
 
@@ -350,13 +350,13 @@ Spawn the research sub-agent:
350
350
  - **Task description**: Research <specific question>
351
351
  - **Key requirement**: Research output MUST be persisted to `{TASK_DIR}/research/`
352
352
 
353
- [/Claude Code, Cursor, OpenCode, Codex, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
353
+ [/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
354
354
 
355
- [Kilo, Antigravity, Windsurf]
355
+ [codex-inline, Kilo, Antigravity, Windsurf]
356
356
 
357
- Do the research in the main session directly and write findings into `{TASK_DIR}/research/`.
357
+ Do the research in the main session directly and write findings into `{TASK_DIR}/research/`. (For `codex-inline` this avoids the `fork_turns="none"` isolation that prevents `trellis-research` sub-agents from resolving the active task path.)
358
358
 
359
- [/Kilo, Antigravity, Windsurf]
359
+ [/codex-inline, Kilo, Antigravity, Windsurf]
360
360
 
361
361
  **Research artifact conventions**:
362
362
  - One file per research topic (e.g. `research/auth-library-comparison.md`)
@@ -369,7 +369,7 @@ Brainstorm and research can interleave freely — pause to research a technical
369
369
 
370
370
  #### 1.3 Configure context `[required · once]`
371
371
 
372
- [Claude Code, Cursor, OpenCode, Codex, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
372
+ [Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
373
373
 
374
374
  Curate `implement.jsonl` and `check.jsonl` so the Phase 2 sub-agents get the right spec context. These files were seeded on `task create` with a single self-describing `_example` line; your job here is to fill in real entries.
375
375
 
@@ -410,13 +410,13 @@ Delete the seed `_example` line once real entries exist (optional — it's skipp
410
410
 
411
411
  Skip when: `implement.jsonl` has agent-curated entries (the seed row alone doesn't count).
412
412
 
413
- [/Claude Code, Cursor, OpenCode, Codex, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
413
+ [/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
414
414
 
415
- [Kilo, Antigravity, Windsurf]
415
+ [codex-inline, Kilo, Antigravity, Windsurf]
416
416
 
417
417
  Skip this step. Context is loaded directly by the `trellis-before-dev` skill in Phase 2.
418
418
 
419
- [/Kilo, Antigravity, Windsurf]
419
+ [/codex-inline, Kilo, Antigravity, Windsurf]
420
420
 
421
421
  #### 1.4 Activate task `[required · once]`
422
422
 
@@ -440,11 +440,11 @@ If `task.py start` errors with a session-identity message (no context key from h
440
440
  | `research/` has artifacts (complex tasks) | recommended |
441
441
  | `info.md` technical design (complex tasks) | optional |
442
442
 
443
- [Claude Code, Cursor, OpenCode, Codex, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
443
+ [Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
444
444
 
445
445
  | `implement.jsonl` has agent-curated entries (not just the seed row) | ✅ |
446
446
 
447
- [/Claude Code, Cursor, OpenCode, Codex, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
447
+ [/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
448
448
 
449
449
  ---
450
450
 
@@ -468,7 +468,7 @@ The platform hook/plugin auto-handles:
468
468
 
469
469
  [/Claude Code, Cursor, OpenCode, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
470
470
 
471
- [Codex]
471
+ [codex-sub-agent]
472
472
 
473
473
  Spawn the implement sub-agent:
474
474
 
@@ -480,7 +480,7 @@ The Codex sub-agent definition auto-handles the context load requirement:
480
480
  - Resolves the active task with `task.py current --source`, then reads `prd.md` and `info.md` if present
481
481
  - Reads `implement.jsonl` and requires the agent to load each referenced spec file before coding
482
482
 
483
- [/Codex]
483
+ [/codex-sub-agent]
484
484
 
485
485
  [Kiro]
486
486
 
@@ -496,7 +496,7 @@ The platform prelude auto-handles the context load requirement:
496
496
 
497
497
  [/Kiro]
498
498
 
499
- [Kilo, Antigravity, Windsurf]
499
+ [codex-inline, Kilo, Antigravity, Windsurf]
500
500
 
501
501
  1. Load the `trellis-before-dev` skill to read project guidelines
502
502
  2. Read `{TASK_DIR}/prd.md` for requirements
@@ -504,11 +504,11 @@ The platform prelude auto-handles the context load requirement:
504
504
  4. Implement the code per requirements
505
505
  5. Run project lint and type-check
506
506
 
507
- [/Kilo, Antigravity, Windsurf]
507
+ [/codex-inline, Kilo, Antigravity, Windsurf]
508
508
 
509
509
  #### 2.2 Quality check `[required · repeatable]`
510
510
 
511
- [Claude Code, Cursor, OpenCode, Codex, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
511
+ [Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
512
512
 
513
513
  Spawn the check sub-agent:
514
514
 
@@ -521,9 +521,9 @@ The check agent's job:
521
521
  - Auto-fix issues it finds
522
522
  - Run lint and typecheck to verify
523
523
 
524
- [/Claude Code, Cursor, OpenCode, Codex, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
524
+ [/Claude Code, Cursor, OpenCode, codex-sub-agent, Kiro, Gemini, Qoder, CodeBuddy, Copilot, Droid, Pi]
525
525
 
526
- [Kilo, Antigravity, Windsurf]
526
+ [codex-inline, Kilo, Antigravity, Windsurf]
527
527
 
528
528
  Load the `trellis-check` skill and verify the code per its guidance:
529
529
  - Spec compliance
@@ -532,7 +532,7 @@ Load the `trellis-check` skill and verify the code per its guidance:
532
532
 
533
533
  If issues are found → fix → re-check, until green.
534
534
 
535
- [/Kilo, Antigravity, Windsurf]
535
+ [/codex-inline, Kilo, Antigravity, Windsurf]
536
536
 
537
537
  #### 2.3 Rollback `[on demand]`
538
538
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindfoldhq/trellis",
3
- "version": "0.6.0-beta.0",
3
+ "version": "0.6.0-beta.1",
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",