oh-my-codex 0.19.1 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. package/Cargo.lock +6 -6
  2. package/Cargo.toml +1 -1
  3. package/README.md +3 -1
  4. package/crates/omx-api/src/lib.rs +3 -3
  5. package/crates/omx-api/tests/cli.rs +4 -4
  6. package/crates/omx-explore/src/main.rs +4 -4
  7. package/crates/omx-sparkshell/src/codex_bridge.rs +2 -2
  8. package/dist/agents/__tests__/definitions.test.js +3 -3
  9. package/dist/agents/__tests__/definitions.test.js.map +1 -1
  10. package/dist/agents/__tests__/native-config.test.js +71 -42
  11. package/dist/agents/__tests__/native-config.test.js.map +1 -1
  12. package/dist/agents/definitions.d.ts +1 -1
  13. package/dist/agents/definitions.d.ts.map +1 -1
  14. package/dist/agents/definitions.js +3 -3
  15. package/dist/agents/definitions.js.map +1 -1
  16. package/dist/agents/native-config.d.ts +2 -2
  17. package/dist/agents/native-config.d.ts.map +1 -1
  18. package/dist/agents/native-config.js +7 -5
  19. package/dist/agents/native-config.js.map +1 -1
  20. package/dist/autopilot/__tests__/planner-routing.test.js +19 -12
  21. package/dist/autopilot/__tests__/planner-routing.test.js.map +1 -1
  22. package/dist/autopilot/__tests__/ralplan-gate.test.js +151 -0
  23. package/dist/autopilot/__tests__/ralplan-gate.test.js.map +1 -1
  24. package/dist/autopilot/planner-routing.d.ts.map +1 -1
  25. package/dist/autopilot/planner-routing.js +4 -2
  26. package/dist/autopilot/planner-routing.js.map +1 -1
  27. package/dist/autopilot/ralplan-gate.d.ts +1 -0
  28. package/dist/autopilot/ralplan-gate.d.ts.map +1 -1
  29. package/dist/autopilot/ralplan-gate.js +38 -2
  30. package/dist/autopilot/ralplan-gate.js.map +1 -1
  31. package/dist/autoresearch/runtime.d.ts +2 -0
  32. package/dist/autoresearch/runtime.d.ts.map +1 -1
  33. package/dist/autoresearch/runtime.js +8 -0
  34. package/dist/autoresearch/runtime.js.map +1 -1
  35. package/dist/capabilities/__tests__/lockfile.test.d.ts +2 -0
  36. package/dist/capabilities/__tests__/lockfile.test.d.ts.map +1 -0
  37. package/dist/capabilities/__tests__/lockfile.test.js +115 -0
  38. package/dist/capabilities/__tests__/lockfile.test.js.map +1 -0
  39. package/dist/capabilities/lockfile.d.ts +102 -0
  40. package/dist/capabilities/lockfile.d.ts.map +1 -0
  41. package/dist/capabilities/lockfile.js +334 -0
  42. package/dist/capabilities/lockfile.js.map +1 -0
  43. package/dist/cli/__tests__/agents.test.js +5 -5
  44. package/dist/cli/__tests__/agents.test.js.map +1 -1
  45. package/dist/cli/__tests__/capabilities.test.d.ts +2 -0
  46. package/dist/cli/__tests__/capabilities.test.d.ts.map +1 -0
  47. package/dist/cli/__tests__/capabilities.test.js +135 -0
  48. package/dist/cli/__tests__/capabilities.test.js.map +1 -0
  49. package/dist/cli/__tests__/codex-plugin-layout.test.js +237 -6
  50. package/dist/cli/__tests__/codex-plugin-layout.test.js.map +1 -1
  51. package/dist/cli/__tests__/doctor-context-window-warning.test.js +9 -9
  52. package/dist/cli/__tests__/doctor-context-window-warning.test.js.map +1 -1
  53. package/dist/cli/__tests__/doctor-invalid-config.test.js +1 -1
  54. package/dist/cli/__tests__/doctor-spark-routing.test.js +22 -6
  55. package/dist/cli/__tests__/doctor-spark-routing.test.js.map +1 -1
  56. package/dist/cli/__tests__/index.test.js +53 -18
  57. package/dist/cli/__tests__/index.test.js.map +1 -1
  58. package/dist/cli/__tests__/plugin-marketplace-idempotent.test.js +3 -3
  59. package/dist/cli/__tests__/plugin-marketplace-idempotent.test.js.map +1 -1
  60. package/dist/cli/__tests__/resume.test.js +95 -6
  61. package/dist/cli/__tests__/resume.test.js.map +1 -1
  62. package/dist/cli/__tests__/setup-install-mode.test.js +46 -18
  63. package/dist/cli/__tests__/setup-install-mode.test.js.map +1 -1
  64. package/dist/cli/__tests__/setup-prompts-overwrite.test.js +3 -3
  65. package/dist/cli/__tests__/setup-refresh.test.js +29 -7
  66. package/dist/cli/__tests__/setup-refresh.test.js.map +1 -1
  67. package/dist/cli/__tests__/uninstall.test.js +4 -4
  68. package/dist/cli/__tests__/uninstall.test.js.map +1 -1
  69. package/dist/cli/agents.js +1 -1
  70. package/dist/cli/agents.js.map +1 -1
  71. package/dist/cli/capabilities.d.ts +3 -0
  72. package/dist/cli/capabilities.d.ts.map +1 -0
  73. package/dist/cli/capabilities.js +118 -0
  74. package/dist/cli/capabilities.js.map +1 -0
  75. package/dist/cli/doctor.d.ts +1 -1
  76. package/dist/cli/doctor.d.ts.map +1 -1
  77. package/dist/cli/doctor.js +9 -4
  78. package/dist/cli/doctor.js.map +1 -1
  79. package/dist/cli/index.d.ts +7 -4
  80. package/dist/cli/index.d.ts.map +1 -1
  81. package/dist/cli/index.js +77 -19
  82. package/dist/cli/index.js.map +1 -1
  83. package/dist/cli/plugin-marketplace.d.ts +1 -0
  84. package/dist/cli/plugin-marketplace.d.ts.map +1 -1
  85. package/dist/cli/plugin-marketplace.js +31 -0
  86. package/dist/cli/plugin-marketplace.js.map +1 -1
  87. package/dist/cli/setup.d.ts.map +1 -1
  88. package/dist/cli/setup.js +7 -4
  89. package/dist/cli/setup.js.map +1 -1
  90. package/dist/config/__tests__/generator-idempotent.test.js +23 -23
  91. package/dist/config/__tests__/generator-idempotent.test.js.map +1 -1
  92. package/dist/config/__tests__/generator-notify.test.js +9 -9
  93. package/dist/config/__tests__/generator-notify.test.js.map +1 -1
  94. package/dist/config/__tests__/models.test.js +51 -26
  95. package/dist/config/__tests__/models.test.js.map +1 -1
  96. package/dist/config/generator.d.ts +1 -1
  97. package/dist/config/generator.d.ts.map +1 -1
  98. package/dist/config/models.d.ts +16 -6
  99. package/dist/config/models.d.ts.map +1 -1
  100. package/dist/config/models.js +19 -8
  101. package/dist/config/models.js.map +1 -1
  102. package/dist/hooks/__tests__/keyword-detector.test.js +12 -4
  103. package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
  104. package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +1 -1
  105. package/dist/hooks/__tests__/prometheus-strict-contract.test.js +2 -2
  106. package/dist/hooks/__tests__/prometheus-strict-contract.test.js.map +1 -1
  107. package/dist/hooks/__tests__/tmux-hook-engine.test.js +2 -2
  108. package/dist/leader/__tests__/contract.test.js +108 -1
  109. package/dist/leader/__tests__/contract.test.js.map +1 -1
  110. package/dist/leader/contract.d.ts +26 -0
  111. package/dist/leader/contract.d.ts.map +1 -1
  112. package/dist/leader/contract.js +170 -0
  113. package/dist/leader/contract.js.map +1 -1
  114. package/dist/modes/base.d.ts +1 -1
  115. package/dist/modes/base.d.ts.map +1 -1
  116. package/dist/pipeline/__tests__/stages.test.js +27 -1
  117. package/dist/pipeline/__tests__/stages.test.js.map +1 -1
  118. package/dist/pipeline/stages/ralplan.d.ts +2 -1
  119. package/dist/pipeline/stages/ralplan.d.ts.map +1 -1
  120. package/dist/pipeline/stages/ralplan.js +1 -0
  121. package/dist/pipeline/stages/ralplan.js.map +1 -1
  122. package/dist/pipeline/stages/ultragoal.d.ts +5 -1
  123. package/dist/pipeline/stages/ultragoal.d.ts.map +1 -1
  124. package/dist/pipeline/stages/ultragoal.js +14 -4
  125. package/dist/pipeline/stages/ultragoal.js.map +1 -1
  126. package/dist/ralplan/__tests__/runtime.test.js +132 -0
  127. package/dist/ralplan/__tests__/runtime.test.js.map +1 -1
  128. package/dist/ralplan/runtime.d.ts +17 -0
  129. package/dist/ralplan/runtime.d.ts.map +1 -1
  130. package/dist/ralplan/runtime.js +97 -1
  131. package/dist/ralplan/runtime.js.map +1 -1
  132. package/dist/scripts/__tests__/codex-native-hook.test.js +412 -0
  133. package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -1
  134. package/dist/scripts/codex-native-hook.d.ts.map +1 -1
  135. package/dist/scripts/codex-native-hook.js +238 -12
  136. package/dist/scripts/codex-native-hook.js.map +1 -1
  137. package/dist/state/__tests__/operations.test.js +450 -0
  138. package/dist/state/__tests__/operations.test.js.map +1 -1
  139. package/dist/state/__tests__/workflow-transition.test.js +14 -0
  140. package/dist/state/__tests__/workflow-transition.test.js.map +1 -1
  141. package/dist/state/operations.d.ts.map +1 -1
  142. package/dist/state/operations.js +72 -11
  143. package/dist/state/operations.js.map +1 -1
  144. package/dist/state/terminal-normalization.d.ts +8 -0
  145. package/dist/state/terminal-normalization.d.ts.map +1 -0
  146. package/dist/state/terminal-normalization.js +127 -0
  147. package/dist/state/terminal-normalization.js.map +1 -0
  148. package/dist/state/workflow-transition-reconcile.d.ts.map +1 -1
  149. package/dist/state/workflow-transition-reconcile.js +3 -1
  150. package/dist/state/workflow-transition-reconcile.js.map +1 -1
  151. package/dist/team/__tests__/delegation-policy.test.js +2 -2
  152. package/dist/team/__tests__/delegation-policy.test.js.map +1 -1
  153. package/dist/team/__tests__/model-contract.test.js +25 -25
  154. package/dist/team/__tests__/model-contract.test.js.map +1 -1
  155. package/dist/team/__tests__/runtime.test.js +28 -28
  156. package/dist/team/__tests__/runtime.test.js.map +1 -1
  157. package/dist/team/__tests__/scaling.test.js +7 -7
  158. package/dist/team/__tests__/scaling.test.js.map +1 -1
  159. package/dist/team/__tests__/tmux-claude-workers-demo.test.js +5 -5
  160. package/dist/team/__tests__/tmux-claude-workers-demo.test.js.map +1 -1
  161. package/dist/team/__tests__/tmux-session.test.js +12 -12
  162. package/dist/team/__tests__/tmux-session.test.js.map +1 -1
  163. package/dist/team/__tests__/worker-bootstrap.test.js +57 -9
  164. package/dist/team/__tests__/worker-bootstrap.test.js.map +1 -1
  165. package/dist/team/__tests__/worker-runtime-identity.test.js +3 -3
  166. package/dist/team/__tests__/worker-runtime-identity.test.js.map +1 -1
  167. package/dist/team/model-contract.d.ts +1 -1
  168. package/dist/team/model-contract.d.ts.map +1 -1
  169. package/dist/team/runtime.d.ts.map +1 -1
  170. package/dist/team/runtime.js +11 -0
  171. package/dist/team/runtime.js.map +1 -1
  172. package/dist/team/worker-bootstrap.d.ts +2 -0
  173. package/dist/team/worker-bootstrap.d.ts.map +1 -1
  174. package/dist/team/worker-bootstrap.js +6 -1
  175. package/dist/team/worker-bootstrap.js.map +1 -1
  176. package/dist/ultragoal/__tests__/artifacts.test.js +68 -1
  177. package/dist/ultragoal/__tests__/artifacts.test.js.map +1 -1
  178. package/dist/ultragoal/artifacts.d.ts +5 -1
  179. package/dist/ultragoal/artifacts.d.ts.map +1 -1
  180. package/dist/ultragoal/artifacts.js +41 -9
  181. package/dist/ultragoal/artifacts.js.map +1 -1
  182. package/dist/utils/__tests__/agents-model-table.test.js +7 -7
  183. package/dist/utils/__tests__/agents-model-table.test.js.map +1 -1
  184. package/dist/utils/__tests__/worktree-tool-context.test.d.ts +2 -0
  185. package/dist/utils/__tests__/worktree-tool-context.test.d.ts.map +1 -0
  186. package/dist/utils/__tests__/worktree-tool-context.test.js +118 -0
  187. package/dist/utils/__tests__/worktree-tool-context.test.js.map +1 -0
  188. package/dist/utils/worktree-tool-context.d.ts +25 -0
  189. package/dist/utils/worktree-tool-context.d.ts.map +1 -0
  190. package/dist/utils/worktree-tool-context.js +116 -0
  191. package/dist/utils/worktree-tool-context.js.map +1 -0
  192. package/package.json +1 -1
  193. package/plugins/oh-my-codex/.codex-plugin/plugin.json +1 -1
  194. package/plugins/oh-my-codex/hooks/codex-native-hook.mjs +96 -10
  195. package/plugins/oh-my-codex/skills/ai-slop-cleaner/SKILL.md +1 -1
  196. package/plugins/oh-my-codex/skills/code-review/SKILL.md +1 -1
  197. package/plugins/oh-my-codex/skills/omx-setup/SKILL.md +5 -5
  198. package/plugins/oh-my-codex/skills/prometheus-strict/SKILL.md +3 -3
  199. package/plugins/oh-my-codex/skills/ralplan/SKILL.md +1 -1
  200. package/plugins/oh-my-codex/skills/team/SKILL.md +1 -1
  201. package/plugins/oh-my-codex/skills/ultrawork/references/agent-tiers.md +2 -2
  202. package/prompts/prometheus-strict-metis.md +1 -1
  203. package/skills/ai-slop-cleaner/SKILL.md +1 -1
  204. package/skills/code-review/SKILL.md +1 -1
  205. package/skills/ecomode/references/agent-tiers.md +1 -1
  206. package/skills/omx-setup/SKILL.md +5 -5
  207. package/skills/prometheus-strict/SKILL.md +3 -3
  208. package/skills/ralplan/SKILL.md +1 -1
  209. package/skills/team/SKILL.md +1 -1
  210. package/skills/ultrawork/references/agent-tiers.md +2 -2
  211. package/src/scripts/__tests__/codex-native-hook.test.ts +477 -0
  212. package/src/scripts/codex-native-hook.ts +272 -11
@@ -1 +1 @@
1
- {"version":3,"file":"codex-native-hook.d.ts","sourceRoot":"","sources":["../../src/scripts/codex-native-hook.ts"],"names":[],"mappings":"AA8CA,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,8BAA8B,CAAC;AAiCtC,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAoDlE,KAAK,kBAAkB,GACnB,cAAc,GACd,YAAY,GACZ,aAAa,GACb,kBAAkB,GAClB,YAAY,GACZ,aAAa,GACb,MAAM,CAAC;AAEX,KAAK,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEhD,UAAU,yBAAyB;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,6BAA6B,CAAC,EAAE,OAAO,2BAA2B,CAAC;CACpE;AAED,MAAM,WAAW,wBAAwB;IACvC,aAAa,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACzC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACpC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC5C;AAmfD,wBAAgB,2BAA2B,CACzC,aAAa,EAAE,kBAAkB,GAAG,IAAI,GACvC,MAAM,GAAG,IAAI,CAmBf;AAsxBD,wBAAgB,kCAAkC,CAChD,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;IACP,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAC/C,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;CACzC,GACL,MAAM,GAAG,IAAI,CAuBf;AA2mCD,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAMnE;AAymKD,wBAAsB,wCAAwC,CAC5D,OAAO,EAAE,gBAAgB,EACzB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,iBAAiB,CAAC,EAAE,MAAM,GACzB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAyCzC;AA83CD,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,gBAAgB,EACzB,OAAO,GAAE,yBAA8B,GACtC,OAAO,CAAC,wBAAwB,CAAC,CA4VnC;AA6BD,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,OAAO,CAGT;AAyOD,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAyC3D"}
1
+ {"version":3,"file":"codex-native-hook.d.ts","sourceRoot":"","sources":["../../src/scripts/codex-native-hook.ts"],"names":[],"mappings":"AA+CA,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,8BAA8B,CAAC;AAiCtC,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAyDlE,KAAK,kBAAkB,GACnB,cAAc,GACd,YAAY,GACZ,aAAa,GACb,kBAAkB,GAClB,YAAY,GACZ,aAAa,GACb,MAAM,CAAC;AAEX,KAAK,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEhD,UAAU,yBAAyB;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,6BAA6B,CAAC,EAAE,OAAO,2BAA2B,CAAC;CACpE;AAED,MAAM,WAAW,wBAAwB;IACvC,aAAa,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACzC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACpC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC5C;AAmfD,wBAAgB,2BAA2B,CACzC,aAAa,EAAE,kBAAkB,GAAG,IAAI,GACvC,MAAM,GAAG,IAAI,CAmBf;AAsxBD,wBAAgB,kCAAkC,CAChD,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;IACP,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAC/C,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;CACzC,GACL,MAAM,GAAG,IAAI,CAuBf;AA4tCD,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAMnE;AA0uKD,wBAAsB,wCAAwC,CAC5D,OAAO,EAAE,gBAAgB,EACzB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,iBAAiB,CAAC,EAAE,MAAM,GACzB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAqDzC;AA83CD,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,gBAAgB,EACzB,OAAO,GAAE,yBAA8B,GACtC,OAAO,CAAC,wBAAwB,CAAC,CA6VnC;AA6BD,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,OAAO,CAGT;AAyOD,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAyC3D"}
@@ -6,7 +6,7 @@ import { pathToFileURL } from "url";
6
6
  import { readModeStateForActiveDecision, readModeStateForSession, updateModeState } from "../modes/base.js";
7
7
  import { redactAuthSecrets } from "../auth/redact.js";
8
8
  import { SKILL_ACTIVE_STATE_FILE, extractSessionIdFromInitializedStatePath, getSkillActiveStatePathsForStateDir, listActiveSkills, readSkillActiveState, readVisibleSkillActiveStateForStateDir, } from "../state/skill-active.js";
9
- import { isTrustedSubagentThread, readSubagentSessionSummary, readSubagentTrackingState, recordSubagentTurnForSession, } from "../subagents/tracker.js";
9
+ import { isTrustedSubagentThread, readSubagentSessionSummary, readSubagentSessionLedger, readSubagentTrackingState, recordSubagentTurnForSession, } from "../subagents/tracker.js";
10
10
  import { resolveCanonicalTeamStateRoot, resolveWorkerNotifyTeamStateRootPath } from "../team/state-root.js";
11
11
  import { inferTerminalLifecycleOutcome } from "../runtime/run-outcome.js";
12
12
  import { appendToLog, isSessionStale, isSessionStateUsable, readSessionState, readUsableSessionState, reconcileNativeSessionStart, } from "../hooks/session.js";
@@ -31,7 +31,7 @@ import { onPreCompact as buildWikiPreCompactContext, onSessionStart as buildWiki
31
31
  import { readAutoresearchCompletionStatus, readAutoresearchModeStateForActiveDecision } from "../autoresearch/skill-validation.js";
32
32
  import { AGENT_DEFINITIONS } from "../agents/definitions.js";
33
33
  import { deriveAutopilotChildPhase, normalizeAutopilotPhase } from "../autopilot/fsm.js";
34
- import { CONDUCTOR_ORCHESTRATION_METADATA_PREFIXES, LEADER_CONDUCTOR_BLOCK, LEADER_CONDUCTOR_REUSE_AND_LEDGER_GUIDANCE, actionKindForConductorArtifact, authorizeConductorAction, classifyConductorArtifactKind, } from "../leader/contract.js";
34
+ import { CONDUCTOR_ORCHESTRATION_METADATA_PREFIXES, LEADER_CONDUCTOR_BLOCK, LEADER_CONDUCTOR_REUSE_AND_LEDGER_GUIDANCE, NATIVE_SUBAGENT_SUPPORT_BLOCKER_FILE, actionKindForConductorArtifact, authorizeConductorAction, buildUnsupportedNativeSubagentGuidance, classifyConductorArtifactKind, isUnsupportedNativeSubagentEvidence, resolveNativeSubagentSupportStatus, } from "../leader/contract.js";
35
35
  import { readRunState } from "../runtime/run-state.js";
36
36
  import { evaluateRalphCompletionAuditEvidence, isRalphCompletePhase } from "../ralph/completion-audit.js";
37
37
  import { buildCodexGoalTerminalCleanupNotice, } from "../goal-workflows/codex-goal-snapshot.js";
@@ -1463,6 +1463,76 @@ async function ensureOmxLocalIgnoreEntry(cwd) {
1463
1463
  await writeFile(excludePath, next);
1464
1464
  return { changed: true, excludePath };
1465
1465
  }
1466
+ function readSessionStartSource(payload) {
1467
+ return safeString(payload?.source ?? payload?.session_start_source ?? payload?.sessionStartSource).trim().toLowerCase();
1468
+ }
1469
+ function shouldBuildSubagentReopenContext(options) {
1470
+ if (options.hookEventName !== "SessionStart")
1471
+ return false;
1472
+ const source = readSessionStartSource(options.payload);
1473
+ return source === "startup" || source === "resume";
1474
+ }
1475
+ function formatSubagentLedgerMetadata(entry) {
1476
+ const metadata = [
1477
+ entry.role ? `role: ${entry.role}` : null,
1478
+ entry.laneId ? `lane: ${entry.laneId}` : null,
1479
+ entry.scope ? `scope: ${entry.scope}` : null,
1480
+ entry.status ? `status: ${entry.status}` : null,
1481
+ entry.lastHandoffSummary ? `handoff: ${entry.lastHandoffSummary.slice(0, 120)}` : null,
1482
+ entry.resumeFailureReason ? `last failure: ${entry.resumeFailureReason.slice(0, 120)}` : null,
1483
+ ].filter((item) => Boolean(item));
1484
+ return metadata.length > 0 ? ` (${metadata.join("; ")})` : "";
1485
+ }
1486
+ async function buildPersistedSubagentReopenContext(cwd, sessionId, options) {
1487
+ if (!shouldBuildSubagentReopenContext(options))
1488
+ return null;
1489
+ const ledger = await readSubagentSessionLedger(cwd, sessionId).catch(() => null);
1490
+ if (!ledger || ledger.savedSubagents.length === 0)
1491
+ return null;
1492
+ const source = readSessionStartSource(options.payload);
1493
+ const reopenTargets = ledger.resumeTargets.filter((entry) => entry.status !== "unavailable");
1494
+ const unavailableTargets = ledger.unavailableSubagents;
1495
+ const failedTargets = ledger.savedSubagents.filter((entry) => entry.resumeFailedAt || entry.resumeFailureReason);
1496
+ const nowIso = new Date().toISOString();
1497
+ await Promise.all(reopenTargets.map((entry) => recordSubagentTurnForSession(cwd, {
1498
+ sessionId,
1499
+ threadId: entry.threadId,
1500
+ kind: "subagent",
1501
+ role: entry.role,
1502
+ laneId: entry.laneId,
1503
+ scope: entry.scope,
1504
+ agentNickname: entry.agentNickname,
1505
+ status: entry.status,
1506
+ resumeRequestedAt: nowIso,
1507
+ preserveCompletionEvidence: true,
1508
+ }).catch(() => null)));
1509
+ const lines = [
1510
+ "[Persisted subagent reopen]",
1511
+ `- SessionStart source: ${source}; saved subagent ids found: ${ledger.savedSubagents.length}.`,
1512
+ ];
1513
+ if (reopenTargets.length > 0) {
1514
+ lines.push("- Reopen these persisted subagents by id before continuing work or spawning any same-role/same-lane replacement:");
1515
+ for (const entry of reopenTargets.slice(0, 12)) {
1516
+ lines.push(` - resume_agent(${JSON.stringify(entry.agentId)})${formatSubagentLedgerMetadata(entry)}`);
1517
+ }
1518
+ if (reopenTargets.length > 12) {
1519
+ lines.push(` - ... ${reopenTargets.length - 12} more saved subagent id(s) omitted from this compact SessionStart context; consult .omx/state/subagent-tracking.json before spawning replacements.`);
1520
+ }
1521
+ }
1522
+ else {
1523
+ lines.push("- No compatible saved subagent id is currently marked reopenable; do not spawn a replacement merely because reopen was unavailable.");
1524
+ }
1525
+ lines.push("- Silver rule: when follow-up work targets an existing role/lane, reuse the matching reopened id; avoid duplicate same-type subagent spawns.");
1526
+ lines.push("- If resume_agent fails, surface a clear warning with the id and reason, then continue in the root or another compatible existing lane; do not spawn a new agent solely because reopen failed.");
1527
+ const warningEntries = [...new Map([...unavailableTargets, ...failedTargets].map((entry) => [entry.agentId, entry])).values()];
1528
+ if (warningEntries.length > 0) {
1529
+ lines.push("- Reopen warnings:");
1530
+ for (const entry of warningEntries.slice(0, 8)) {
1531
+ lines.push(` - ${entry.agentId}${formatSubagentLedgerMetadata(entry)}`);
1532
+ }
1533
+ }
1534
+ return lines.join("\n");
1535
+ }
1466
1536
  async function buildSessionStartContext(cwd, sessionId, options = {}) {
1467
1537
  const sections = [];
1468
1538
  sections.push(buildExecutionEnvironmentSection(cwd, {
@@ -1560,6 +1630,13 @@ async function buildSessionStartContext(cwd, sessionId, options = {}) {
1560
1630
  if (subagentSummary && subagentSummary.activeSubagentThreadIds.length > 0) {
1561
1631
  sections.push(`[Subagents]\n- active subagent threads: ${subagentSummary.activeSubagentThreadIds.length}`);
1562
1632
  }
1633
+ const persistedSubagentReopenContext = await buildPersistedSubagentReopenContext(cwd, sessionId, {
1634
+ hookEventName: options.hookEventName,
1635
+ payload: options.payload,
1636
+ });
1637
+ if (persistedSubagentReopenContext) {
1638
+ sections.push(persistedSubagentReopenContext);
1639
+ }
1563
1640
  return sections.length > 0 ? sections.join("\n\n") : null;
1564
1641
  }
1565
1642
  function resolveExecutionEnvironment(cwd, options = {}) {
@@ -1722,6 +1799,17 @@ function buildAutopilotPromptActivationNote(skillState, options = {}) {
1722
1799
  const teamHandoff = readTeamModeConfig(options.cwd).enabled
1723
1800
  ? " (+ $team if needed)"
1724
1801
  : "";
1802
+ const stateDir = getBaseStateDir(options.cwd);
1803
+ const nativeSubagentSupport = resolveNativeSubagentSupportStatus({
1804
+ payload: options.payload,
1805
+ persistedSupportBlocker: readJsonSyncIfExists(nativeSubagentSupportBlockerPath(stateDir)),
1806
+ persistedCapacityBlocker: readJsonSyncIfExists(nativeSubagentCapacityBlockerPath(stateDir)),
1807
+ cwd: options.cwd,
1808
+ sessionId: options.sessionId,
1809
+ });
1810
+ const conductorGuidance = nativeSubagentSupport.status === "unsupported"
1811
+ ? buildUnsupportedNativeSubagentGuidance(nativeSubagentSupport)
1812
+ : `${LEADER_CONDUCTOR_BLOCK} ${LEADER_CONDUCTOR_REUSE_AND_LEDGER_GUIDANCE}`;
1725
1813
  return [
1726
1814
  `Autopilot protocol: the durable default chain is $deep-interview -> $ralplan -> $ultragoal${teamHandoff} -> $code-review -> $ultraqa (deep-interview -> ralplan -> ultragoal -> code-review -> ultraqa).`,
1727
1815
  "Start/resume at current_phase=deep-interview unless the task is clear and bounded; if deep-interview is intentionally skipped, persist and state an explicit deep_interview_gate.skip_reason before moving to ralplan.",
@@ -1733,8 +1821,7 @@ function buildAutopilotPromptActivationNote(skillState, options = {}) {
1733
1821
  "The ralplan phase is not complete until Planner output has been reviewed sequentially by Architect and then Critic; do not hand off to Ultragoal or implementation until the ralplan state/artifact records both ralplan_architect_review and ralplan_critic_review with approval or an explicit blocker.",
1734
1822
  "Do not silently fall back to ordinary $plan/ralplan-only handling; keep autopilot-state.json, skill-active-state.json, HUD/statusline, and Codex goal-mode handoff guidance visible while the workflow is active.",
1735
1823
  "When Codex goal tools are available, call get_goal/create_goal only from the active thread handoff and treat the active goal as the completion contract until code-review and ultraqa are clean.",
1736
- LEADER_CONDUCTOR_BLOCK,
1737
- LEADER_CONDUCTOR_REUSE_AND_LEDGER_GUIDANCE,
1824
+ conductorGuidance,
1738
1825
  ].filter(Boolean).join(" ");
1739
1826
  }
1740
1827
  function formatExecutionHandoffList(cwd) {
@@ -1761,7 +1848,7 @@ function buildAdditionalContextMessage(prompt, skillState, cwd = process.cwd(),
1761
1848
  : null;
1762
1849
  const deepInterviewConfigPromptActivationNote = buildDeepInterviewConfigInstruction(cwd, skillState);
1763
1850
  const markedQuestionAnswer = /^\s*\[omx question answered\]/i.test(prompt);
1764
- const autopilotPromptActivationNote = buildAutopilotPromptActivationNote(skillState, { markedQuestionAnswer, cwd });
1851
+ const autopilotPromptActivationNote = buildAutopilotPromptActivationNote(skillState, { markedQuestionAnswer, cwd, payload, sessionId: safeString(skillState?.session_id).trim() });
1765
1852
  return [
1766
1853
  `OMX native UserPromptSubmit continued active workflow skill "${continuedSkill}".`,
1767
1854
  promptPriorityMessage,
@@ -1785,7 +1872,7 @@ function buildAdditionalContextMessage(prompt, skillState, cwd = process.cwd(),
1785
1872
  ? buildDeepInterviewQuestionBridgeInstruction(cwd, payload)
1786
1873
  : null;
1787
1874
  const deepInterviewConfigPromptActivationNote = buildDeepInterviewConfigInstruction(cwd, skillState);
1788
- const autopilotPromptActivationNote = buildAutopilotPromptActivationNote(skillState, { markedQuestionAnswer: true, cwd });
1875
+ const autopilotPromptActivationNote = buildAutopilotPromptActivationNote(skillState, { markedQuestionAnswer: true, cwd, payload, sessionId: safeString(skillState?.session_id).trim() });
1789
1876
  return [
1790
1877
  `OMX native UserPromptSubmit continued active workflow skill "${continuedSkill}"; workflow-like tokens inside the marked omx question answer are treated as answer text, not a new workflow activation.`,
1791
1878
  promptPriorityMessage,
@@ -1818,7 +1905,7 @@ function buildAdditionalContextMessage(prompt, skillState, cwd = process.cwd(),
1818
1905
  const ultragoalPromptActivationNote = match.skill === "ultragoal"
1819
1906
  ? "Ultragoal protocol: use `omx ultragoal create-goals` / `complete-goals` / `checkpoint` for `.omx/ultragoal` artifacts, then use Codex goal model tools only from the active agent handoff (`get_goal`, `create_goal`, `update_goal`) and never overwrite a different active Codex goal. Ultragoal does not call `/goal clear`; for multiple sequential ultragoal runs in one Codex session/thread, manually clear the completed Codex goal in the UI before creating the next aggregate goal."
1820
1907
  : null;
1821
- const autopilotPromptActivationNote = buildAutopilotPromptActivationNote(skillState, { cwd });
1908
+ const autopilotPromptActivationNote = buildAutopilotPromptActivationNote(skillState, { cwd, payload, sessionId: safeString(skillState?.session_id).trim() });
1822
1909
  const combinedTransitionMessage = (() => {
1823
1910
  if (!skillState?.transition_message)
1824
1911
  return null;
@@ -2574,6 +2661,17 @@ function readPayloadTurnId(payload) {
2574
2661
  function nativeSubagentCapacityBlockerPath(stateDir) {
2575
2662
  return join(stateDir, NATIVE_SUBAGENT_CAPACITY_BLOCKER_FILE);
2576
2663
  }
2664
+ function nativeSubagentSupportBlockerPath(stateDir) {
2665
+ return join(stateDir, NATIVE_SUBAGENT_SUPPORT_BLOCKER_FILE);
2666
+ }
2667
+ function readJsonSyncIfExists(path) {
2668
+ try {
2669
+ return JSON.parse(readFileSync(path, "utf-8"));
2670
+ }
2671
+ catch {
2672
+ return null;
2673
+ }
2674
+ }
2577
2675
  function stringifyUnknown(value) {
2578
2676
  if (typeof value === "string")
2579
2677
  return value;
@@ -2602,6 +2700,44 @@ function isNativeSubagentCapacityFailure(payload) {
2602
2700
  const toolName = safeString(payload.tool_name).trim();
2603
2701
  return !toolName || /(?:spawn_agent|multi_agent|subagent|collab|agent)/i.test(toolName);
2604
2702
  }
2703
+ function nativeSubagentFailureReason(payload) {
2704
+ const evidence = payloadEvidenceText(payload);
2705
+ const toolName = safeString(payload.tool_name).trim();
2706
+ if (toolName && !/(?:spawn_agent|multi_agent|subagent|collab|agent)/i.test(toolName))
2707
+ return null;
2708
+ if (/\bagent thread limit reached\b/i.test(evidence))
2709
+ return null;
2710
+ if (/\bnative subagents? (?:unsupported|disabled|not enabled|unavailable|not found)\b/i.test(evidence))
2711
+ return "native_subagents_unsupported";
2712
+ if (/\bmulti_agent_v1\b/i.test(evidence) && /\b(?:unavailable|unknown tool|disabled|not enabled|not found|unsupported)\b/i.test(evidence))
2713
+ return "multi_agent_v1_unavailable";
2714
+ if (/\b(?:unknown tool|tool not found|not enabled|disabled|unavailable|unsupported)\b/i.test(evidence))
2715
+ return "multi_agent_v1_unavailable";
2716
+ return null;
2717
+ }
2718
+ function summarizeNativeSubagentSupportFailure(text) {
2719
+ const normalized = text.replace(/\s+/g, " ").trim();
2720
+ return (normalized || "native subagent support unavailable").slice(0, 500);
2721
+ }
2722
+ async function recordNativeSubagentSupportBlocker(cwd, stateDir, payload) {
2723
+ const reason = nativeSubagentFailureReason(payload);
2724
+ if (!reason)
2725
+ return;
2726
+ const nowIso = new Date().toISOString();
2727
+ await mkdir(stateDir, { recursive: true });
2728
+ await writeFile(nativeSubagentSupportBlockerPath(stateDir), JSON.stringify({
2729
+ schema_version: 1,
2730
+ status: "unsupported",
2731
+ reason,
2732
+ ...(readPayloadSessionId(payload) ? { session_id: readPayloadSessionId(payload) } : {}),
2733
+ ...(readPayloadThreadId(payload) ? { thread_id: readPayloadThreadId(payload) } : {}),
2734
+ ...(readPayloadTurnId(payload) ? { turn_id: readPayloadTurnId(payload) } : {}),
2735
+ ...(safeString(payload.tool_name).trim() ? { tool_name: safeString(payload.tool_name).trim() } : {}),
2736
+ evidence: summarizeNativeSubagentSupportFailure(payloadEvidenceText(payload)),
2737
+ observed_at: nowIso,
2738
+ cwd,
2739
+ }, null, 2));
2740
+ }
2605
2741
  function summarizeCapacityFailure(text) {
2606
2742
  const normalized = text.replace(/\s+/g, " ").trim();
2607
2743
  if (!normalized)
@@ -2791,6 +2927,7 @@ const PROTECTED_PLANNING_STATE_FILE_NAMES = new Set([
2791
2927
  "ralplan-state.json",
2792
2928
  "skill-active-state.json",
2793
2929
  ]);
2930
+ const RUNTIME_SESSION_ID_SEGMENT_PATTERN = /^[A-Za-z0-9_-]{1,64}$/;
2794
2931
  const PLANNING_MODE_IMPLEMENTATION_TOOL_NAMES = new Set([
2795
2932
  "Write",
2796
2933
  "Edit",
@@ -2875,6 +3012,33 @@ function isProtectedPlanningStatePath(relativePath) {
2875
3012
  const fileName = relativePath.split("/").pop() ?? "";
2876
3013
  return PROTECTED_PLANNING_STATE_FILE_NAMES.has(fileName);
2877
3014
  }
3015
+ function isAllowedAuthoritativeRuntimePlanningStatePath(cwd, rawPath) {
3016
+ const trimmed = rawPath.trim().replace(/^['"]|['"]$/g, "");
3017
+ if (!trimmed || trimmed.includes("\0"))
3018
+ return false;
3019
+ let targetPath;
3020
+ let baseStateDir;
3021
+ try {
3022
+ targetPath = resolve(cwd, trimmed);
3023
+ baseStateDir = resolve(getBaseStateDir(cwd));
3024
+ }
3025
+ catch {
3026
+ return false;
3027
+ }
3028
+ const localStateDir = resolve(cwd, ".omx", "state");
3029
+ if (baseStateDir === localStateDir)
3030
+ return false;
3031
+ const relativeToBase = relative(baseStateDir, targetPath).replace(/\\/g, "/");
3032
+ if (!relativeToBase || relativeToBase.startsWith("..") || relativeToBase.startsWith("/"))
3033
+ return false;
3034
+ const segments = relativeToBase.split("/");
3035
+ if (segments.length !== 3 || segments[0] !== "sessions")
3036
+ return false;
3037
+ const sessionId = segments[1] ?? "";
3038
+ const fileName = segments[2] ?? "";
3039
+ return RUNTIME_SESSION_ID_SEGMENT_PATTERN.test(sessionId)
3040
+ && PROTECTED_PLANNING_STATE_FILE_NAMES.has(fileName);
3041
+ }
2878
3042
  function isPlanningTmpRelativePath(relativePath) {
2879
3043
  return relativePath === ".omx/tmp" || relativePath.startsWith(".omx/tmp/");
2880
3044
  }
@@ -2890,9 +3054,9 @@ function isAllowedPlanningTmpScratchPath(relativePath) {
2890
3054
  function isAllowedPlanningArtifactPath(cwd, rawPath, allowedPrefixes) {
2891
3055
  const relativePath = normalizePlanningArtifactRelativePath(cwd, rawPath);
2892
3056
  if (!relativePath)
2893
- return false;
3057
+ return isAllowedAuthoritativeRuntimePlanningStatePath(cwd, rawPath);
2894
3058
  if (isProtectedPlanningStatePath(relativePath))
2895
- return false;
3059
+ return isAllowedAuthoritativeRuntimePlanningStatePath(cwd, rawPath);
2896
3060
  if (isPlanningTmpRelativePath(relativePath)) {
2897
3061
  return allowedPrefixes.includes(".omx/tmp") && isAllowedPlanningTmpScratchPath(relativePath);
2898
3062
  }
@@ -5271,6 +5435,56 @@ function isPackageManagerCommandWord(word) {
5271
5435
  const base = shellWordBaseName(word);
5272
5436
  return base === "npm" || base === "pnpm" || base === "yarn" || base === "npx" || base === "pnpx";
5273
5437
  }
5438
+ function isStructuredUltragoalSteeringShellCommand(command) {
5439
+ const segments = splitShellCommandSegments(stripHeredocBodiesForCommandScan(command));
5440
+ let sawStructuredSteer = false;
5441
+ for (const segment of segments) {
5442
+ const words = tokenizeShellWords(segment);
5443
+ let commandStart = true;
5444
+ let inForHeader = false;
5445
+ for (let index = 0; index < words.length; index += 1) {
5446
+ const word = words[index] ?? "";
5447
+ if (!word)
5448
+ continue;
5449
+ if (isShellCommandSeparator(word)) {
5450
+ commandStart = true;
5451
+ continue;
5452
+ }
5453
+ if (inForHeader) {
5454
+ if (word === "do") {
5455
+ inForHeader = false;
5456
+ commandStart = true;
5457
+ }
5458
+ continue;
5459
+ }
5460
+ if (isShellGroupingSyntaxWord(word))
5461
+ continue;
5462
+ if (commandStart && isEnvironmentAssignmentWord(word))
5463
+ continue;
5464
+ if (commandStart && CONDUCTOR_BASH_COMPOUND_SYNTAX_WORDS.has(word)) {
5465
+ if (word === "for")
5466
+ inForHeader = true;
5467
+ continue;
5468
+ }
5469
+ if (commandStart && word.startsWith("-"))
5470
+ continue;
5471
+ if (!commandStart)
5472
+ continue;
5473
+ const commandName = commandNameFromShellWord(word);
5474
+ if (commandName === "read" || commandName === "true" || commandName === ":") {
5475
+ commandStart = false;
5476
+ continue;
5477
+ }
5478
+ if (commandName === "omx" && words[index + 1] === "ultragoal" && words[index + 2] === "steer") {
5479
+ sawStructuredSteer = true;
5480
+ commandStart = false;
5481
+ continue;
5482
+ }
5483
+ return false;
5484
+ }
5485
+ }
5486
+ return sawStructuredSteer;
5487
+ }
5274
5488
  function hasDynamicNestedShellExecution(command) {
5275
5489
  const commands = splitShellCommandSegments(stripHeredocBodiesForCommandScan(command));
5276
5490
  for (const segment of commands) {
@@ -5298,13 +5512,13 @@ function hasDynamicNestedShellExecution(command) {
5298
5512
  return true;
5299
5513
  if (commandStringIndex !== null) {
5300
5514
  const nestedCommand = words[commandStringIndex] ?? "";
5301
- if (isDynamicNestedCommandString(nestedCommand))
5515
+ if (isDynamicNestedCommandString(nestedCommand) && !isStructuredUltragoalSteeringShellCommand(nestedCommand))
5302
5516
  return true;
5303
5517
  }
5304
5518
  }
5305
5519
  if (word === "eval") {
5306
5520
  const nestedCommand = words.slice(index + 1).join(" ");
5307
- if (isDynamicNestedCommandString(nestedCommand))
5521
+ if (isDynamicNestedCommandString(nestedCommand) && !isStructuredUltragoalSteeringShellCommand(nestedCommand))
5308
5522
  return true;
5309
5523
  }
5310
5524
  }
@@ -7228,6 +7442,13 @@ export async function buildConductorPreToolUseWriteGuardOutput(payload, cwd, sta
7228
7442
  const activeState = await readActiveMainRootConductorStateForPreToolUse(payload, cwd, stateDir, resolvedSessionId);
7229
7443
  if (!activeState)
7230
7444
  return null;
7445
+ const nativeSubagentSupport = resolveNativeSubagentSupportStatus({
7446
+ payload,
7447
+ persistedSupportBlocker: await readJsonIfExists(nativeSubagentSupportBlockerPath(stateDir)),
7448
+ persistedCapacityBlocker: await readJsonIfExists(nativeSubagentCapacityBlockerPath(stateDir)),
7449
+ cwd,
7450
+ sessionId: resolvedSessionId || readPayloadSessionId(payload),
7451
+ });
7231
7452
  const toolName = safeString(payload.tool_name).trim();
7232
7453
  const command = readPreToolUseCommand(payload);
7233
7454
  const pathCandidates = readPreToolUsePathCandidates(payload);
@@ -7254,6 +7475,9 @@ export async function buildConductorPreToolUseWriteGuardOutput(payload, cwd, sta
7254
7475
  }
7255
7476
  if (!blocked)
7256
7477
  return null;
7478
+ const unsupportedNativeGuidance = isUnsupportedNativeSubagentEvidence(nativeSubagentSupport)
7479
+ ? ` ${buildUnsupportedNativeSubagentGuidance(nativeSubagentSupport)} Treat the active conductor workflow as blocked/cancelled for native delegation recovery; do not call multi_agent_v1.close_agent.`
7480
+ : "";
7257
7481
  return {
7258
7482
  decision: "block",
7259
7483
  reason: `Main-root Conductor mode is active (${activeState.mode} phase: ${formatPhase(activeState.phase, "active")}); direct plan/code writes are blocked and must be delegated; ${blockedDetail}.`,
@@ -7262,7 +7486,8 @@ export async function buildConductorPreToolUseWriteGuardOutput(payload, cwd, sta
7262
7486
  additionalContext: `${LEADER_CONDUCTOR_GOLDEN_RULE} `
7263
7487
  + "Use specialized agents for source edits and plan/spec authorship. "
7264
7488
  + `Main-root Conductor may write only orchestration metadata/transport/ledger artifacts under ${CONDUCTOR_ORCHESTRATION_METADATA_PREFIXES.join(", ")}; path location alone is not authorization for substantive deliverables. `
7265
- + "Autopilot rework and typed subagent/worker lanes are exempt from this guard.",
7489
+ + unsupportedNativeGuidance
7490
+ + " Autopilot rework and typed subagent/worker lanes are exempt from this guard.",
7266
7491
  },
7267
7492
  };
7268
7493
  }
@@ -8512,6 +8737,7 @@ export async function dispatchCodexNativeHook(payload, options = {}) {
8512
8737
  }
8513
8738
  else if (hookEventName === "PostToolUse") {
8514
8739
  await recordNativeSubagentCapacityBlocker(cwd, stateDir, payload).catch(() => { });
8740
+ await recordNativeSubagentSupportBlocker(cwd, stateDir, payload).catch(() => { });
8515
8741
  if (detectMcpTransportFailure(payload)) {
8516
8742
  await markTeamTransportFailure(cwd, payload);
8517
8743
  }