@qodeca/xezar 0.13.0 → 0.14.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 (250) hide show
  1. package/README.md +72 -39
  2. package/dist/agent-config/account-identity.d.ts +2 -8
  3. package/dist/agent-config/account-identity.js +54 -10
  4. package/dist/agent-config/account-identity.js.map +1 -1
  5. package/dist/agent-config/catalog.d.ts +49 -7
  6. package/dist/agent-config/catalog.js +107 -0
  7. package/dist/agent-config/catalog.js.map +1 -1
  8. package/dist/agent-config/model-settings/pi.d.ts +12 -6
  9. package/dist/agent-config/model-settings/pi.js +12 -6
  10. package/dist/agent-config/model-settings/pi.js.map +1 -1
  11. package/dist/agent-config/seed.js +10 -0
  12. package/dist/agent-config/seed.js.map +1 -1
  13. package/dist/contract/github.d.ts +15 -0
  14. package/dist/contract/index.d.ts +9 -0
  15. package/dist/contract/index.js +1527 -895
  16. package/dist/contract/mcp-api-reference.d.ts +174 -0
  17. package/dist/contract/mcp-audit.d.ts +103 -0
  18. package/dist/contract/mcp-discovery.d.ts +257 -0
  19. package/dist/contract/mcp-event-catalog.d.ts +121 -0
  20. package/dist/contract/mcp-event-catalog.test.d.ts +1 -0
  21. package/dist/contract/mcp-idempotency.d.ts +200 -0
  22. package/dist/contract/mcp-journal.d.ts +268 -0
  23. package/dist/contract/mcp-leader.d.ts +88 -0
  24. package/dist/contract/mcp-ownership.d.ts +78 -0
  25. package/dist/contract/mcp-versioning.d.ts +139 -0
  26. package/dist/contract/runs.d.ts +81 -0
  27. package/dist/core/agent-profiles.d.ts +15 -4
  28. package/dist/core/agent-profiles.js +22 -8
  29. package/dist/core/agent-profiles.js.map +1 -1
  30. package/dist/core/opencode-server-runner.js +71 -11
  31. package/dist/core/opencode-server-runner.js.map +1 -1
  32. package/dist/core/secret-redaction.d.ts +7 -1
  33. package/dist/core/secret-redaction.js +44 -10
  34. package/dist/core/secret-redaction.js.map +1 -1
  35. package/dist/index.js +138 -27
  36. package/dist/index.js.map +1 -1
  37. package/dist/machine-identity.d.ts +66 -0
  38. package/dist/machine-identity.js +96 -0
  39. package/dist/machine-identity.js.map +1 -0
  40. package/dist/mcp/adapters/claude-code.d.ts +41 -0
  41. package/dist/mcp/adapters/claude-code.js +40 -0
  42. package/dist/mcp/adapters/claude-code.js.map +1 -0
  43. package/dist/mcp/adapters/codex.d.ts +140 -0
  44. package/dist/mcp/adapters/codex.js +323 -0
  45. package/dist/mcp/adapters/codex.js.map +1 -0
  46. package/dist/mcp/adapters/opencode.d.ts +148 -0
  47. package/dist/mcp/adapters/opencode.js +528 -0
  48. package/dist/mcp/adapters/opencode.js.map +1 -0
  49. package/dist/mcp/adapters/pi-link.d.ts +102 -0
  50. package/dist/mcp/adapters/pi-link.js +235 -0
  51. package/dist/mcp/adapters/pi-link.js.map +1 -0
  52. package/dist/mcp/adapters/pi.d.ts +188 -0
  53. package/dist/mcp/adapters/pi.js +418 -0
  54. package/dist/mcp/adapters/pi.js.map +1 -0
  55. package/dist/mcp/api-reference.d.ts +26 -0
  56. package/dist/mcp/api-reference.js +133 -0
  57. package/dist/mcp/api-reference.js.map +1 -0
  58. package/dist/mcp/audit-trail.d.ts +162 -0
  59. package/dist/mcp/audit-trail.js +306 -0
  60. package/dist/mcp/audit-trail.js.map +1 -0
  61. package/dist/mcp/bridge.d.ts +81 -0
  62. package/dist/mcp/bridge.js +407 -0
  63. package/dist/mcp/bridge.js.map +1 -0
  64. package/dist/mcp/connection-file.d.ts +49 -0
  65. package/dist/mcp/connection-file.js +63 -0
  66. package/dist/mcp/connection-file.js.map +1 -0
  67. package/dist/mcp/echo-guard.d.ts +94 -0
  68. package/dist/mcp/echo-guard.js +160 -0
  69. package/dist/mcp/echo-guard.js.map +1 -0
  70. package/dist/mcp/event-catalog.d.ts +120 -0
  71. package/dist/mcp/event-catalog.js +306 -0
  72. package/dist/mcp/event-catalog.js.map +1 -0
  73. package/dist/mcp/event-controller.d.ts +230 -0
  74. package/dist/mcp/event-controller.js +596 -0
  75. package/dist/mcp/event-controller.js.map +1 -0
  76. package/dist/mcp/event-journal.d.ts +57 -0
  77. package/dist/mcp/event-journal.js +423 -0
  78. package/dist/mcp/event-journal.js.map +1 -0
  79. package/dist/mcp/index.d.ts +63 -0
  80. package/dist/mcp/index.js +386 -0
  81. package/dist/mcp/index.js.map +1 -0
  82. package/dist/mcp/ipc.d.ts +202 -0
  83. package/dist/mcp/ipc.js +206 -0
  84. package/dist/mcp/ipc.js.map +1 -0
  85. package/dist/mcp/leader-delivery.d.ts +119 -0
  86. package/dist/mcp/leader-delivery.js +450 -0
  87. package/dist/mcp/leader-delivery.js.map +1 -0
  88. package/dist/mcp/operation-receipts.d.ts +210 -0
  89. package/dist/mcp/operation-receipts.js +723 -0
  90. package/dist/mcp/operation-receipts.js.map +1 -0
  91. package/dist/mcp/project-catalogs.d.ts +23 -0
  92. package/dist/mcp/project-catalogs.js +25 -0
  93. package/dist/mcp/project-catalogs.js.map +1 -0
  94. package/dist/mcp/project-leaders.d.ts +26 -0
  95. package/dist/mcp/project-leaders.js +17 -0
  96. package/dist/mcp/project-leaders.js.map +1 -0
  97. package/dist/mcp/protocol.d.ts +50 -0
  98. package/dist/mcp/protocol.js +47 -0
  99. package/dist/mcp/protocol.js.map +1 -0
  100. package/dist/mcp/reconnect.d.ts +297 -0
  101. package/dist/mcp/reconnect.js +465 -0
  102. package/dist/mcp/reconnect.js.map +1 -0
  103. package/dist/mcp/resource-ownership.d.ts +228 -0
  104. package/dist/mcp/resource-ownership.js +390 -0
  105. package/dist/mcp/resource-ownership.js.map +1 -0
  106. package/dist/mcp/service-adapter.d.ts +16488 -0
  107. package/dist/mcp/service-adapter.js +148 -0
  108. package/dist/mcp/service-adapter.js.map +1 -0
  109. package/dist/mcp/service.d.ts +83 -0
  110. package/dist/mcp/service.js +233 -0
  111. package/dist/mcp/service.js.map +1 -0
  112. package/dist/mcp/session-binding.d.ts +105 -0
  113. package/dist/mcp/session-binding.js +163 -0
  114. package/dist/mcp/session-binding.js.map +1 -0
  115. package/dist/mcp/stale-write.d.ts +145 -0
  116. package/dist/mcp/stale-write.js +219 -0
  117. package/dist/mcp/stale-write.js.map +1 -0
  118. package/dist/mcp/tool.d.ts +48 -0
  119. package/dist/mcp/tool.js +24 -0
  120. package/dist/mcp/tool.js.map +1 -0
  121. package/dist/mcp/tools/discovery.d.ts +40 -0
  122. package/dist/mcp/tools/discovery.js +232 -0
  123. package/dist/mcp/tools/discovery.js.map +1 -0
  124. package/dist/mcp/tools/execution-control.d.ts +171 -0
  125. package/dist/mcp/tools/execution-control.js +513 -0
  126. package/dist/mcp/tools/execution-control.js.map +1 -0
  127. package/dist/mcp/tools/handoff-git.d.ts +26 -0
  128. package/dist/mcp/tools/handoff-git.js +544 -0
  129. package/dist/mcp/tools/handoff-git.js.map +1 -0
  130. package/dist/mcp/tools/index.d.ts +2 -0
  131. package/dist/mcp/tools/index.js +23 -0
  132. package/dist/mcp/tools/index.js.map +1 -0
  133. package/dist/mcp/tools/leader-events.d.ts +46 -0
  134. package/dist/mcp/tools/leader-events.js +126 -0
  135. package/dist/mcp/tools/leader-events.js.map +1 -0
  136. package/dist/mcp/tools/local-handoff.d.ts +102 -0
  137. package/dist/mcp/tools/local-handoff.js +306 -0
  138. package/dist/mcp/tools/local-handoff.js.map +1 -0
  139. package/dist/mcp/tools/project-config.d.ts +340 -0
  140. package/dist/mcp/tools/project-config.js +1075 -0
  141. package/dist/mcp/tools/project-config.js.map +1 -0
  142. package/dist/mcp/tools/results-evidence.d.ts +112 -0
  143. package/dist/mcp/tools/results-evidence.js +1045 -0
  144. package/dist/mcp/tools/results-evidence.js.map +1 -0
  145. package/dist/mcp/tools/task-create.d.ts +70 -0
  146. package/dist/mcp/tools/task-create.js +473 -0
  147. package/dist/mcp/tools/task-create.js.map +1 -0
  148. package/dist/mcp/tools/task-reads.d.ts +102 -0
  149. package/dist/mcp/tools/task-reads.js +689 -0
  150. package/dist/mcp/tools/task-reads.js.map +1 -0
  151. package/dist/mcp/tools/work-organisation.d.ts +2 -0
  152. package/dist/mcp/tools/work-organisation.js +502 -0
  153. package/dist/mcp/tools/work-organisation.js.map +1 -0
  154. package/dist/paths.d.ts +17 -7
  155. package/dist/paths.js +18 -8
  156. package/dist/paths.js.map +1 -1
  157. package/dist/runs/project-writer.js +76 -11
  158. package/dist/runs/project-writer.js.map +1 -1
  159. package/dist/runs/retention.d.ts +25 -2
  160. package/dist/runs/retention.js +63 -2
  161. package/dist/runs/retention.js.map +1 -1
  162. package/dist/server/forge/github.js +44 -0
  163. package/dist/server/forge/github.js.map +1 -1
  164. package/dist/server/forge/types.d.ts +16 -0
  165. package/dist/server/project-context.d.ts +81 -8
  166. package/dist/server/project-context.js +143 -35
  167. package/dist/server/project-context.js.map +1 -1
  168. package/dist/server/server.d.ts +1050 -53
  169. package/dist/server/server.js +326 -120
  170. package/dist/server/server.js.map +1 -1
  171. package/dist/server/validators.d.ts +26 -6
  172. package/dist/server/validators.js +17 -0
  173. package/dist/server/validators.js.map +1 -1
  174. package/dist/skills-remote.js +64 -6
  175. package/dist/skills-remote.js.map +1 -1
  176. package/dist/workflows/run.d.ts +277 -12
  177. package/dist/workflows/run.js +599 -79
  178. package/dist/workflows/run.js.map +1 -1
  179. package/dist/workspace/agent-profiles.d.ts +30 -3
  180. package/dist/workspace/agent-profiles.js +39 -4
  181. package/dist/workspace/agent-profiles.js.map +1 -1
  182. package/dist/workspace/config.js +25 -4
  183. package/dist/workspace/config.js.map +1 -1
  184. package/dist/workspace/project-owner.d.ts +210 -0
  185. package/dist/workspace/project-owner.js +518 -0
  186. package/dist/workspace/project-owner.js.map +1 -0
  187. package/package.json +5 -3
  188. package/scripts/pi-leader-extension.ts +420 -0
  189. package/scripts/sync-readme.mjs +83 -2
  190. package/web/dist/assets/{alert-dialog-BVsVcbFy.js → alert-dialog-D6rP6d39.js} +1 -1
  191. package/web/dist/assets/arrow-down-DMOfFIzW.js +1 -0
  192. package/web/dist/assets/arrow-left-C4Ec2BUg.js +1 -0
  193. package/web/dist/assets/{centered-state-Djgly6Ni.js → centered-state-B0ZqrPaa.js} +12 -12
  194. package/web/dist/assets/chevron-right-mHJ-crvn.js +1 -0
  195. package/web/dist/assets/{collapsible-DZ4D-DHG.js → collapsible-DchEHgUM.js} +1 -1
  196. package/web/dist/assets/{commit-list-B-z1JL9G.js → commit-list-BpMim1Rv.js} +1 -1
  197. package/web/dist/assets/{compare-variants-CdS8r8E2.js → compare-variants-D5ItQbAq.js} +1 -1
  198. package/web/dist/assets/{diff-BKew9rQX.js → diff-HqqZ_WDR.js} +2 -2
  199. package/web/dist/assets/{diff-stat-D0mc5V6Z.js → diff-stat-NsU-3ecr.js} +1 -1
  200. package/web/dist/assets/{diff-view-xpIcuLIC.js → diff-view-B7c11Xux.js} +1 -1
  201. package/web/dist/assets/{dropdown-menu-CEQziH7X.js → dropdown-menu-CtTpnyod.js} +1 -1
  202. package/web/dist/assets/{editable-title-BCX3T2BY.js → editable-title-BXtuGQry.js} +1 -1
  203. package/web/dist/assets/{ellipsis-vertical-ByVdDc4z.js → ellipsis-vertical-MHtGZSH6.js} +1 -1
  204. package/web/dist/assets/{file-xBSB5hXO.js → file-DKLw5SOb.js} +1 -1
  205. package/web/dist/assets/{folder-CldgbZ5A.js → folder-Drw6-ufH.js} +1 -1
  206. package/web/dist/assets/{git-toolbar-BYlnf4qf.js → git-toolbar-BQH8bORV.js} +1 -1
  207. package/web/dist/assets/github-ynnpKFCJ.js +1 -0
  208. package/web/dist/assets/{image-preview-Cv5mZr0n.js → image-preview-DLhMN_R9.js} +1 -1
  209. package/web/dist/assets/index-BEsrNdXt.js +29 -0
  210. package/web/dist/assets/index-Da8DOBau.css +2 -0
  211. package/web/dist/assets/{markdown-CgEEE2ND.js → markdown-q365eN6Y.js} +1 -1
  212. package/web/dist/assets/{new-task-form-1r2bgsdD.js → new-task-form-CW-hNIWQ.js} +1 -1
  213. package/web/dist/assets/{pill-q-x22_ej.js → pill-B_TFulXa.js} +1 -1
  214. package/web/dist/assets/{project-router-VDN4jQM8.js → project-router-CLPc-ImZ.js} +1 -1
  215. package/web/dist/assets/{prompt-templates-BmZtCe-L.js → prompt-templates-CLc4RxyO.js} +1 -1
  216. package/web/dist/assets/{repo-git-C2On8SlI.js → repo-git-Is7R6-Tj.js} +1 -1
  217. package/web/dist/assets/{run-diff-vguEMJzh.js → run-diff-DHMvDlVo.js} +2 -2
  218. package/web/dist/assets/run-header-DvZJbQ8I.js +1 -0
  219. package/web/dist/assets/{search-x-QmhaAbg5.js → search-x-Ce2MMetu.js} +1 -1
  220. package/web/dist/assets/{skill-empty-hint-BrzUwByZ.js → skill-empty-hint-C_xCSvzB.js} +1 -1
  221. package/web/dist/assets/skills-CivqD4si.js +1 -0
  222. package/web/dist/assets/{sparkles-CP8QDOgX.js → sparkles-BCqPoj5g.js} +1 -1
  223. package/web/dist/assets/{square-terminal-CGypshSD.js → square-terminal-ikj5g-oK.js} +1 -1
  224. package/web/dist/assets/{tab-link-D4lFzzI1.js → tab-link-VsEjFV1Y.js} +1 -1
  225. package/web/dist/assets/{task-changes-6aopqAmV.js → task-changes-CH-E81-_.js} +1 -1
  226. package/web/dist/assets/{task-commits-u-dwaCyw.js → task-commits-DqfkMFxp.js} +1 -1
  227. package/web/dist/assets/{task-files-IMOZnIUK.js → task-files-D_nkHZ_a.js} +2 -2
  228. package/web/dist/assets/task-thread-bxQompxJ.js +9 -0
  229. package/web/dist/assets/{textarea-CyBCyKIk.js → textarea-xajuW1L_.js} +1 -1
  230. package/web/dist/assets/{thread-loading-Cuq2jchC.js → thread-loading-C3JQZbIE.js} +1 -1
  231. package/web/dist/assets/{trash-2-B6Dp3ZNs.js → trash-2-hJrBhpUD.js} +1 -1
  232. package/web/dist/assets/{triangle-alert-xBya8FUp.js → triangle-alert-D1u82y1a.js} +1 -1
  233. package/web/dist/assets/{upload-D6MXEB9p.js → upload-Bn6FBZ59.js} +1 -1
  234. package/web/dist/assets/{use-desktop-fLDKEJoB.js → use-desktop-DOIMfHfY.js} +1 -1
  235. package/web/dist/assets/{use-submit-shortcut-JTpNzU-u.js → use-submit-shortcut-Dj4DHTdE.js} +1 -1
  236. package/web/dist/assets/utils-YwBpOoRN.js +64 -0
  237. package/web/dist/assets/{workflows-BY3KTkFw.js → workflows-CTaAKz2m.js} +3 -3
  238. package/web/dist/assets/{zoomable-image-GTYwLtkS.js → zoomable-image-C1-6P3tg.js} +1 -1
  239. package/web/dist/index.html +23 -23
  240. package/web/dist/assets/arrow-down-CYgAlZtW.js +0 -1
  241. package/web/dist/assets/arrow-left-BOqE0a3k.js +0 -1
  242. package/web/dist/assets/chevron-right-Cc9BWnbN.js +0 -1
  243. package/web/dist/assets/github-CqGK62Lw.js +0 -1
  244. package/web/dist/assets/index-3nxVmdn5.css +0 -2
  245. package/web/dist/assets/index-qX7n11FX.js +0 -9
  246. package/web/dist/assets/refresh-cw-DcNCj2nu.js +0 -1
  247. package/web/dist/assets/run-header-DM7MiKj9.js +0 -1
  248. package/web/dist/assets/skills-Bj-uG_Hz.js +0 -1
  249. package/web/dist/assets/task-thread-CbMPmrWq.js +0 -9
  250. package/web/dist/assets/utils--z9hRtl3.js +0 -64
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Claude Code and push delivery (#108, Phase 6 of #67): what xezar can do to wake a Claude Code
3
+ * leader, walked through the agreed hierarchy (requirements § 12; not reordered here). The runtime
4
+ * evidence is `docs/features/mcp-server/mcp-adapter-evidence-claude-code.md`.
5
+ *
6
+ * 1. Native mechanism, only where the client DEMONSTRABLY reacts. Not demonstrated: generic MCP
7
+ * notifications start no turn (D-05 § 4, spike T04), and a Channels push
8
+ * (`notifications/claude/channel`) did not register under isolated fixtures on 2.1.268 —
9
+ * Channels is a research preview behind account and organisation eligibility.
10
+ * 2. The official programmatic session interface (`claude -p --input-format stream-json`). It only
11
+ * reaches a session whose stdin the caller owns, which means a `claude` process xezar started
12
+ * itself. #108 built that path and #309 connected it; the owner then REMOVED it before release
13
+ * 0.14.0 (decision on #311): xezar does not start agent processes — the person runs their own
14
+ * leader, in their own terminal, and connects it to xezar over MCP. So this rung is unavailable.
15
+ * 3. Terminal text input. REFUSED. Nothing proves project/session targeting, separation from
16
+ * approval prompts, the shell, user typing and active turns, or duplicate prevention for a
17
+ * terminal, and xezar never simulates keystrokes.
18
+ *
19
+ * The result: a Claude Code leader gets NO push. It reads its events with the `leader_events` tool
20
+ * (#251) — the pull that works today — and `GET /api/v1/mcp/leader` states the blocker. This module
21
+ * is the recorded verdict; there is no Claude Code reaction adapter to construct.
22
+ */
23
+ /** A condition the user can resolve. Never a secret, never an account. */
24
+ export interface ClaudeCodeBlocker {
25
+ readonly code: 'native-session-untargetable';
26
+ readonly recoverable: true;
27
+ readonly message: string;
28
+ readonly fix: string;
29
+ }
30
+ export interface ClaudeCodeRouteStep {
31
+ readonly step: 1 | 2 | 3;
32
+ readonly mechanism: 'claude-channels' | 'stream-json-session' | 'terminal-input';
33
+ readonly outcome: 'not-demonstrated' | 'unavailable' | 'refused';
34
+ }
35
+ export interface ClaudeCodeRoute {
36
+ readonly route: 'none';
37
+ readonly steps: readonly ClaudeCodeRouteStep[];
38
+ readonly blocker: ClaudeCodeBlocker;
39
+ }
40
+ /** The hierarchy, walked in order, for the only Claude Code leader there is: one the person runs. */
41
+ export declare function claudeCodeRoute(): ClaudeCodeRoute;
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Claude Code and push delivery (#108, Phase 6 of #67): what xezar can do to wake a Claude Code
3
+ * leader, walked through the agreed hierarchy (requirements § 12; not reordered here). The runtime
4
+ * evidence is `docs/features/mcp-server/mcp-adapter-evidence-claude-code.md`.
5
+ *
6
+ * 1. Native mechanism, only where the client DEMONSTRABLY reacts. Not demonstrated: generic MCP
7
+ * notifications start no turn (D-05 § 4, spike T04), and a Channels push
8
+ * (`notifications/claude/channel`) did not register under isolated fixtures on 2.1.268 —
9
+ * Channels is a research preview behind account and organisation eligibility.
10
+ * 2. The official programmatic session interface (`claude -p --input-format stream-json`). It only
11
+ * reaches a session whose stdin the caller owns, which means a `claude` process xezar started
12
+ * itself. #108 built that path and #309 connected it; the owner then REMOVED it before release
13
+ * 0.14.0 (decision on #311): xezar does not start agent processes — the person runs their own
14
+ * leader, in their own terminal, and connects it to xezar over MCP. So this rung is unavailable.
15
+ * 3. Terminal text input. REFUSED. Nothing proves project/session targeting, separation from
16
+ * approval prompts, the shell, user typing and active turns, or duplicate prevention for a
17
+ * terminal, and xezar never simulates keystrokes.
18
+ *
19
+ * The result: a Claude Code leader gets NO push. It reads its events with the `leader_events` tool
20
+ * (#251) — the pull that works today — and `GET /api/v1/mcp/leader` states the blocker. This module
21
+ * is the recorded verdict; there is no Claude Code reaction adapter to construct.
22
+ */
23
+ /** The hierarchy, walked in order, for the only Claude Code leader there is: one the person runs. */
24
+ export function claudeCodeRoute() {
25
+ return {
26
+ route: 'none',
27
+ steps: [
28
+ { step: 1, mechanism: 'claude-channels', outcome: 'not-demonstrated' },
29
+ { step: 2, mechanism: 'stream-json-session', outcome: 'unavailable' },
30
+ { step: 3, mechanism: 'terminal-input', outcome: 'refused' },
31
+ ],
32
+ blocker: {
33
+ code: 'native-session-untargetable',
34
+ recoverable: true,
35
+ message: 'xezar cannot wake a Claude Code session you run yourself: Claude Code did not react to MCP notifications, Channels did not register under tested conditions, xezar does not start agent processes, and typing into your terminal is refused.',
36
+ fix: 'Read events from your leader with the leader_events tool, or run the leader in OpenCode and attach it to xezar.',
37
+ },
38
+ };
39
+ }
40
+ //# sourceMappingURL=claude-code.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-code.js","sourceRoot":"","sources":["../../../src/mcp/adapters/claude-code.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAsBH,qGAAqG;AACrG,MAAM,UAAU,eAAe;IAC7B,OAAO;QACL,KAAK,EAAE,MAAM;QACb,KAAK,EAAE;YACL,EAAE,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,iBAAiB,EAAE,OAAO,EAAE,kBAAkB,EAAE;YACtE,EAAE,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,qBAAqB,EAAE,OAAO,EAAE,aAAa,EAAE;YACrE,EAAE,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,gBAAgB,EAAE,OAAO,EAAE,SAAS,EAAE;SAC7D;QACD,OAAO,EAAE;YACP,IAAI,EAAE,6BAA6B;YACnC,WAAW,EAAE,IAAI;YACjB,OAAO,EACL,8OAA8O;YAChP,GAAG,EAAE,iHAAiH;SACvH;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,140 @@
1
+ import type { CodexAppServerMessage } from '../../core/codex-app-server-transport.ts';
2
+ import type { EventDispatch, ReactionAdapter } from '../event-controller.ts';
3
+ /**
4
+ * The Codex reaction adapter (#109, Phase 6 of #67): the client-specific half the event controller
5
+ * (#107) hands significant events to, for a leader running in Codex.
6
+ *
7
+ * WHICH RUNG OF THE DELIVERY HIERARCHY, AND WHY (requirements § 12, not reorderable). The evidence
8
+ * is `docs/features/mcp-server/mcp-adapter-evidence-codex.md`; every claim below names its row.
9
+ *
10
+ * 1. **Native MCP notification — not used.** Executed against codex-cli 0.154.0: after the leader's
11
+ * tool call was accepted, `notifications/message`, `resources/updated`, `resources/list_changed`
12
+ * and `claude/channel` reached Codex and no turn started (evidence X1, and D-05 § 4 / the #85
13
+ * spike T06 before it). A rung the client does not demonstrably react to is not a rung.
14
+ * 2. **The official programmatic session interface — used.** Codex's app-server: `turn/start`
15
+ * begins generation on an idle thread and `turn/steer` adds input to the thread's active turn,
16
+ * guarded by `expectedTurnId`. Executed: an event appended to the real journal went through the
17
+ * real controller and this adapter and the model's next request carried it, with no model request
18
+ * between the tool result and the event (X2). This adapter only speaks to an app-server
19
+ * connection it was handed — it never finds, resumes or attaches to a thread some other process
20
+ * has loaded, because a second live writer of the same thread is the "secretly create a second
21
+ * leader" the contract forbids. #309 handed it one xezar spawned; the owner then REMOVED that
22
+ * spawn path before release 0.14.0 (decision on #311: xezar does not start agent processes), so
23
+ * nothing in the product constructs this adapter today and a Codex leader gets no push — it
24
+ * reads its events with `leader_events`. The adapter stays for a Codex session the person runs
25
+ * that xezar can one day be pointed at; see #323 and #324.
26
+ * 3. **Terminal text input — refused.** Nothing here can type into a terminal, and
27
+ * `codexTerminalDelivery()` answers with the recoverable blocker the contract requires, because
28
+ * none of its preconditions (project and session targeting, separation from approval prompts,
29
+ * the shell, user typing and active turns, duplicate prevention) has been proven for a Codex TUI.
30
+ *
31
+ * A CONTROL ADAPTER, NOT A RUNNER. It implements `ReactionAdapter` and adds no backend: nothing here
32
+ * is an `AgentRunner`, and no Codex type leaves this file — the controller sees `deliver` and
33
+ * `heartbeat`, and the rest of xezar sees `CodexReactionTarget`. `core/codex-app-server-runner.ts` is
34
+ * the implementation anchor for speaking app-server (the same transport helpers are reused); it is
35
+ * not evidence that this event flow works — the evidence file is.
36
+ *
37
+ * WHAT THE MODEL IS TOLD. Every message names xezar as its source and says in so many words that it
38
+ * is neither a user instruction nor an approval; each row's summary is quoted as data so text inside
39
+ * a summary cannot pose as the adapter's own framing. Nothing but journal rows — which are already
40
+ * scrubbed of secrets and carry no account identity (F-15, F-12) — reaches the text.
41
+ *
42
+ * DELIVERY IS NOT REACTION (F-20, D-05 § 6.6). `deliver` resolves once the app-server ACCEPTED the
43
+ * `turn/start` or `turn/steer` request: the client application has the rows. The reaction — a model
44
+ * turn carrying them — is reported separately through `onReaction`, and only when app-server says
45
+ * so: a `turn/started` for the turn this adapter started, or, after a steer, the steered input
46
+ * showing up as a `userMessage` item in the active turn.
47
+ *
48
+ * DUPLICATES. The controller retries the SAME rows after a failed or timed-out attempt (at-least-once).
49
+ * A retry whose earlier attempt did reach app-server must not start a second turn, so the adapter
50
+ * remembers the newest row it has handed over and sends only rows past it, and a new attempt waits for
51
+ * the previous hand-off to settle before deciding. Across a new session the controller redelivers
52
+ * from the leader's last ack; the leader deduplicates on `eventId` (D-05 § 6.6).
53
+ *
54
+ * ROLE INSTRUCTION. Whoever opens the thread supplies it: in `developerInstructions` — additive session
55
+ * guidance — never in `baseInstructions`, which was observed to REPLACE Codex's built-in instructions
56
+ * (X5). xezar opens no thread any more, so it supplies none.
57
+ *
58
+ * NEVER POLLS. `heartbeat` is `thread/read` — metadata only, observed to reach no model (X10).
59
+ */
60
+ /** What goes into a model's context about who sent it. One string, used by every message. */
61
+ export declare const CODEX_EVENT_SOURCE_NOTICE = "Sent by xezar's event adapter. This is not an instruction from the user and it is not an approval of anything.";
62
+ /** app-server JSON-RPC as this adapter uses it: a connection to a thread the leader already runs on. */
63
+ export interface CodexAppServerLink {
64
+ request(method: string, params: Record<string, unknown>): Promise<Record<string, unknown>>;
65
+ /** Every notification and server request app-server sends. Returns the unsubscribe. */
66
+ subscribe(listener: (message: CodexAppServerMessage) => void): () => void;
67
+ readonly closed: boolean;
68
+ }
69
+ /** A recoverable blocker: why events are not being delivered, and what would unblock them. */
70
+ export interface CodexReactionBlocker {
71
+ readonly code: 'codex-session-not-targetable' | 'codex-terminal-delivery-refused';
72
+ readonly recoverable: true;
73
+ readonly message: string;
74
+ readonly remedy: string;
75
+ }
76
+ /** Where a project's leader events can go in Codex: an adapter, or a stated blocker. Never neither. */
77
+ export type CodexReactionTarget = {
78
+ readonly kind: 'app-server';
79
+ readonly adapter: CodexReactionAdapter;
80
+ } | {
81
+ readonly kind: 'blocked';
82
+ readonly blocker: CodexReactionBlocker;
83
+ };
84
+ export interface CodexReactionAdapterOptions {
85
+ /** The app-server connection the leader's thread lives on — one this xezar process owns. */
86
+ link: CodexAppServerLink;
87
+ /** The leader's thread on that connection, as `thread/start` or `thread/resume` answered it. */
88
+ threadId: string;
89
+ /** The bound project. A dispatch for any other project is refused, never delivered. */
90
+ projectId: string;
91
+ /** The reaction half of F-20 — wire it to `EventController.recordReaction`. */
92
+ onReaction?: (journalSeq: number) => void;
93
+ /**
94
+ * The echo guard (D-05 § 6.3, F-13): true for an operation id the leader itself has outstanding.
95
+ * A `leader` row caused by one is dropped; nothing is dropped merely because the run is familiar.
96
+ * Absent: no row is ever dropped.
97
+ */
98
+ isOwnOperation?: (operationId: string) => boolean;
99
+ }
100
+ export declare class CodexReactionAdapter implements ReactionAdapter {
101
+ #private;
102
+ readonly projectId: string;
103
+ readonly threadId: string;
104
+ constructor(opts: CodexReactionAdapterOptions);
105
+ /** The newest row app-server accepted from this adapter. Not a reaction; see `onReaction`. */
106
+ get handedThrough(): number;
107
+ /** True while app-server waits on an approval or user-input prompt for the leader's thread. */
108
+ get promptOpen(): boolean;
109
+ /** Stop listening. The link itself belongs to whoever opened it. */
110
+ dispose(): void;
111
+ deliver(dispatch: EventDispatch, signal: AbortSignal): Promise<void>;
112
+ /** Non-model liveness (N-06): a metadata read of the leader's thread. Reaches no model (X10). */
113
+ heartbeat(signal: AbortSignal): Promise<void>;
114
+ }
115
+ /**
116
+ * The text a Codex leader receives for one dispatch. Exported for tests and for the evidence record;
117
+ * pure — the same dispatch always renders the same text.
118
+ */
119
+ export declare function renderCodexEventMessage(dispatch: EventDispatch): string;
120
+ /**
121
+ * Terminal text input is the last rung, and it stays refused: no runtime evidence proves project and
122
+ * session targeting, separation from approval prompts, the shell, user typing and active turns, or
123
+ * duplicate prevention for a Codex terminal. The answer is a blocker the cockpit can show, never an
124
+ * attempt.
125
+ */
126
+ export declare function codexTerminalDelivery(): {
127
+ readonly kind: 'refused';
128
+ readonly blocker: CodexReactionBlocker;
129
+ };
130
+ /**
131
+ * Where a project's leader events go. `link` and `threadId` present: an app-server session this
132
+ * process holds, so events are delivered through it. Absent — the leader is an interactive `codex`
133
+ * session xezar did not start (known, at most, through the thread id Codex sends in a tool call's
134
+ * `_meta`) — a recoverable blocker: that thread is live in another process, and neither attaching a
135
+ * second writer to it nor typing into its terminal is a proven, supported path (evidence X9, blocker B1).
136
+ */
137
+ export declare function codexReactionTarget(opts: Omit<CodexReactionAdapterOptions, 'link' | 'threadId'> & {
138
+ link?: CodexAppServerLink;
139
+ threadId?: string;
140
+ }): CodexReactionTarget;
@@ -0,0 +1,323 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ /**
3
+ * The Codex reaction adapter (#109, Phase 6 of #67): the client-specific half the event controller
4
+ * (#107) hands significant events to, for a leader running in Codex.
5
+ *
6
+ * WHICH RUNG OF THE DELIVERY HIERARCHY, AND WHY (requirements § 12, not reorderable). The evidence
7
+ * is `docs/features/mcp-server/mcp-adapter-evidence-codex.md`; every claim below names its row.
8
+ *
9
+ * 1. **Native MCP notification — not used.** Executed against codex-cli 0.154.0: after the leader's
10
+ * tool call was accepted, `notifications/message`, `resources/updated`, `resources/list_changed`
11
+ * and `claude/channel` reached Codex and no turn started (evidence X1, and D-05 § 4 / the #85
12
+ * spike T06 before it). A rung the client does not demonstrably react to is not a rung.
13
+ * 2. **The official programmatic session interface — used.** Codex's app-server: `turn/start`
14
+ * begins generation on an idle thread and `turn/steer` adds input to the thread's active turn,
15
+ * guarded by `expectedTurnId`. Executed: an event appended to the real journal went through the
16
+ * real controller and this adapter and the model's next request carried it, with no model request
17
+ * between the tool result and the event (X2). This adapter only speaks to an app-server
18
+ * connection it was handed — it never finds, resumes or attaches to a thread some other process
19
+ * has loaded, because a second live writer of the same thread is the "secretly create a second
20
+ * leader" the contract forbids. #309 handed it one xezar spawned; the owner then REMOVED that
21
+ * spawn path before release 0.14.0 (decision on #311: xezar does not start agent processes), so
22
+ * nothing in the product constructs this adapter today and a Codex leader gets no push — it
23
+ * reads its events with `leader_events`. The adapter stays for a Codex session the person runs
24
+ * that xezar can one day be pointed at; see #323 and #324.
25
+ * 3. **Terminal text input — refused.** Nothing here can type into a terminal, and
26
+ * `codexTerminalDelivery()` answers with the recoverable blocker the contract requires, because
27
+ * none of its preconditions (project and session targeting, separation from approval prompts,
28
+ * the shell, user typing and active turns, duplicate prevention) has been proven for a Codex TUI.
29
+ *
30
+ * A CONTROL ADAPTER, NOT A RUNNER. It implements `ReactionAdapter` and adds no backend: nothing here
31
+ * is an `AgentRunner`, and no Codex type leaves this file — the controller sees `deliver` and
32
+ * `heartbeat`, and the rest of xezar sees `CodexReactionTarget`. `core/codex-app-server-runner.ts` is
33
+ * the implementation anchor for speaking app-server (the same transport helpers are reused); it is
34
+ * not evidence that this event flow works — the evidence file is.
35
+ *
36
+ * WHAT THE MODEL IS TOLD. Every message names xezar as its source and says in so many words that it
37
+ * is neither a user instruction nor an approval; each row's summary is quoted as data so text inside
38
+ * a summary cannot pose as the adapter's own framing. Nothing but journal rows — which are already
39
+ * scrubbed of secrets and carry no account identity (F-15, F-12) — reaches the text.
40
+ *
41
+ * DELIVERY IS NOT REACTION (F-20, D-05 § 6.6). `deliver` resolves once the app-server ACCEPTED the
42
+ * `turn/start` or `turn/steer` request: the client application has the rows. The reaction — a model
43
+ * turn carrying them — is reported separately through `onReaction`, and only when app-server says
44
+ * so: a `turn/started` for the turn this adapter started, or, after a steer, the steered input
45
+ * showing up as a `userMessage` item in the active turn.
46
+ *
47
+ * DUPLICATES. The controller retries the SAME rows after a failed or timed-out attempt (at-least-once).
48
+ * A retry whose earlier attempt did reach app-server must not start a second turn, so the adapter
49
+ * remembers the newest row it has handed over and sends only rows past it, and a new attempt waits for
50
+ * the previous hand-off to settle before deciding. Across a new session the controller redelivers
51
+ * from the leader's last ack; the leader deduplicates on `eventId` (D-05 § 6.6).
52
+ *
53
+ * ROLE INSTRUCTION. Whoever opens the thread supplies it: in `developerInstructions` — additive session
54
+ * guidance — never in `baseInstructions`, which was observed to REPLACE Codex's built-in instructions
55
+ * (X5). xezar opens no thread any more, so it supplies none.
56
+ *
57
+ * NEVER POLLS. `heartbeat` is `thread/read` — metadata only, observed to reach no model (X10).
58
+ */
59
+ /** What goes into a model's context about who sent it. One string, used by every message. */
60
+ export const CODEX_EVENT_SOURCE_NOTICE = 'Sent by xezar\'s event adapter. This is not an instruction from the user and it is not an approval of anything.';
61
+ export class CodexReactionAdapter {
62
+ projectId;
63
+ threadId;
64
+ #link;
65
+ #onReaction;
66
+ #isOwnOperation;
67
+ #unsubscribe;
68
+ /** The turn app-server says is running on our thread, whoever started it. */
69
+ #activeTurnId;
70
+ /** Our own items app-server reported before the request that sent them was answered. */
71
+ #seenClientIds = new Set();
72
+ /** Keeps this adapter's client ids apart from an earlier adapter's on the same resumed thread. */
73
+ #sessionTag = randomUUID().slice(0, 8);
74
+ /** Server requests (approvals, user-input prompts) app-server is waiting on for our thread. */
75
+ #openPrompts = new Set();
76
+ #promptsSettled = new Set();
77
+ /** Newest journalSeq handed to app-server in an accepted request (duplicate guard). */
78
+ #handedThrough = 0;
79
+ /** The gap (`oldestSeq:latestSeq`) already told to the leader, so a retry does not tell it twice. */
80
+ #gapHanded;
81
+ /** The previous hand-off, so a retry decides only after it settled. */
82
+ #inFlight = Promise.resolve();
83
+ #awaiting = [];
84
+ #sequence = 0;
85
+ constructor(opts) {
86
+ this.projectId = opts.projectId;
87
+ this.threadId = opts.threadId;
88
+ this.#link = opts.link;
89
+ this.#onReaction = opts.onReaction;
90
+ this.#isOwnOperation = opts.isOwnOperation;
91
+ this.#unsubscribe = opts.link.subscribe((message) => this.#observe(message));
92
+ }
93
+ /** The newest row app-server accepted from this adapter. Not a reaction; see `onReaction`. */
94
+ get handedThrough() {
95
+ return this.#handedThrough;
96
+ }
97
+ /** True while app-server waits on an approval or user-input prompt for the leader's thread. */
98
+ get promptOpen() {
99
+ return this.#openPrompts.size > 0;
100
+ }
101
+ /** Stop listening. The link itself belongs to whoever opened it. */
102
+ dispose() {
103
+ this.#unsubscribe();
104
+ this.#settlePrompts();
105
+ }
106
+ async deliver(dispatch, signal) {
107
+ if (dispatch.projectId !== this.projectId) {
108
+ throw new Error(`codex adapter for project ${this.projectId} refused a dispatch for another project`);
109
+ }
110
+ // A retry decides only once the attempt before it settled, so it can see what that one handed over.
111
+ await abortable(this.#inFlight, signal);
112
+ if (this.#link.closed)
113
+ throw new Error('the codex app-server connection is closed');
114
+ const fresh = dispatch.events.filter((row) => row.journalSeq > this.#handedThrough);
115
+ const newest = fresh.at(-1)?.journalSeq;
116
+ const shown = fresh.filter((row) => !this.#isEcho(row));
117
+ // A gap is told once: a retried dispatch carries the same recovery, and it was already handed over.
118
+ const gap = dispatch.recovery;
119
+ const gapKey = gap === undefined ? undefined : `${gap.oldestSeq}:${gap.latestSeq}`;
120
+ const tellGap = gapKey !== undefined && gapKey !== this.#gapHanded;
121
+ if (shown.length === 0 && !tellGap) {
122
+ // Nothing the leader has not been handed already, or only its own echoes: no turn to start.
123
+ if (newest !== undefined)
124
+ this.#handedThrough = newest;
125
+ return;
126
+ }
127
+ // Separation from approval prompts: never hand an event to a thread that is waiting on one.
128
+ await this.#promptsClear(signal);
129
+ const { recovery: _told, ...rest } = dispatch;
130
+ const text = renderCodexEventMessage(tellGap && gap !== undefined ? { ...rest, events: shown, recovery: gap } : { ...rest, events: shown });
131
+ const handOff = this.#handOff(text, newest).then(() => {
132
+ if (tellGap)
133
+ this.#gapHanded = gapKey;
134
+ });
135
+ this.#inFlight = handOff.catch(() => undefined);
136
+ await abortable(handOff, signal);
137
+ }
138
+ /** Non-model liveness (N-06): a metadata read of the leader's thread. Reaches no model (X10). */
139
+ async heartbeat(signal) {
140
+ if (this.#link.closed)
141
+ throw new Error('the codex app-server connection is closed');
142
+ await abortable(this.#link.request('thread/read', { threadId: this.threadId }), signal);
143
+ }
144
+ async #handOff(text, newest) {
145
+ const input = [{ type: 'text', text, text_elements: [] }];
146
+ // Echoed back as the `userMessage` item's `clientId` (X6), which is how the reaction is matched.
147
+ const clientId = `xezar-event:${this.projectId}:${this.#sessionTag}:${++this.#sequence}`;
148
+ const active = this.#activeTurnId;
149
+ if (active !== undefined) {
150
+ try {
151
+ await this.#link.request('turn/steer', { threadId: this.threadId, input, expectedTurnId: active, clientUserMessageId: clientId });
152
+ this.#handed(newest, clientId);
153
+ return;
154
+ }
155
+ catch {
156
+ // `expectedTurnId` is a precondition and app-server refuses a mismatch (X3). The turn ended
157
+ // between our read and the request, so the documented way in is now a new turn.
158
+ if (this.#activeTurnId === active)
159
+ this.#activeTurnId = undefined;
160
+ }
161
+ }
162
+ // On a thread whose turn is still running, codex-cli 0.154.0 folds this into that turn as a steer
163
+ // and answers with the running turn's id (X3); the reaction match below covers both cases.
164
+ await this.#link.request('turn/start', { threadId: this.threadId, input, clientUserMessageId: clientId });
165
+ this.#handed(newest, clientId);
166
+ }
167
+ #handed(newest, clientId) {
168
+ if (newest !== undefined)
169
+ this.#handedThrough = Math.max(this.#handedThrough, newest);
170
+ if (this.#seenClientIds.delete(clientId)) {
171
+ if (newest !== undefined)
172
+ this.#reacted(newest);
173
+ return;
174
+ }
175
+ if (newest !== undefined)
176
+ this.#awaiting.push({ seq: newest, clientId });
177
+ }
178
+ #reacted(seq) {
179
+ this.#awaiting = this.#awaiting.filter((entry) => entry.seq > seq);
180
+ this.#onReaction?.(seq);
181
+ }
182
+ #isEcho(row) {
183
+ return row.origin === 'leader' && row.causedBy !== null && this.#isOwnOperation?.(row.causedBy) === true;
184
+ }
185
+ #observe(message) {
186
+ const params = (message.params ?? {});
187
+ const threadId = typeof params.threadId === 'string' ? params.threadId : undefined;
188
+ // app-server multiplexes every thread on one connection; only the leader's thread concerns us.
189
+ if (threadId !== undefined && threadId !== this.threadId)
190
+ return;
191
+ if (message.id !== undefined && typeof message.method === 'string') {
192
+ if (threadId === this.threadId)
193
+ this.#openPrompts.add(String(message.id));
194
+ return;
195
+ }
196
+ switch (message.method) {
197
+ case 'turn/started': {
198
+ this.#activeTurnId = turnIdOf(params) ?? this.#activeTurnId;
199
+ return;
200
+ }
201
+ case 'turn/completed':
202
+ case 'turn/failed': {
203
+ if (turnIdOf(params) === this.#activeTurnId)
204
+ this.#activeTurnId = undefined;
205
+ return;
206
+ }
207
+ case 'item/started': {
208
+ // Our input becoming a `userMessage` item is app-server starting model work on it: at once for
209
+ // an idle thread, and at the turn's next model request for a steer (X3). That is the reaction.
210
+ const item = (params.item ?? {});
211
+ if (item.type !== 'userMessage' || typeof item.clientId !== 'string')
212
+ return;
213
+ const clientId = item.clientId;
214
+ const entry = this.#awaiting.find((awaiting) => awaiting.clientId === clientId);
215
+ if (entry !== undefined)
216
+ this.#reacted(entry.seq);
217
+ else if (clientId.startsWith(`xezar-event:${this.projectId}:${this.#sessionTag}:`))
218
+ this.#seenClientIds.add(clientId);
219
+ return;
220
+ }
221
+ case 'serverRequest/resolved': {
222
+ this.#openPrompts.delete(String(params.requestId));
223
+ if (this.#openPrompts.size === 0)
224
+ this.#settlePrompts();
225
+ return;
226
+ }
227
+ default:
228
+ return;
229
+ }
230
+ }
231
+ #promptsClear(signal) {
232
+ if (this.#openPrompts.size === 0)
233
+ return Promise.resolve();
234
+ return abortable(new Promise((resolve) => this.#promptsSettled.add(resolve)), signal);
235
+ }
236
+ #settlePrompts() {
237
+ for (const resolve of this.#promptsSettled)
238
+ resolve();
239
+ this.#promptsSettled.clear();
240
+ }
241
+ }
242
+ /**
243
+ * The text a Codex leader receives for one dispatch. Exported for tests and for the evidence record;
244
+ * pure — the same dispatch always renders the same text.
245
+ */
246
+ export function renderCodexEventMessage(dispatch) {
247
+ const count = dispatch.events.length;
248
+ const lines = [
249
+ `[xezar event — project ${dispatch.projectId}, ${count} significant event${count === 1 ? '' : 's'}] ${CODEX_EVENT_SOURCE_NOTICE}`,
250
+ ];
251
+ if (dispatch.recovery !== undefined)
252
+ lines.push(`Gap: ${dispatch.recovery.message}`);
253
+ for (const row of dispatch.events) {
254
+ const subject = `${row.subject.type} ${row.subject.id}${row.subject.version === null ? '' : ` @${row.subject.version}`}`;
255
+ const cause = row.causedBy === null ? '' : `, caused by operation ${row.causedBy}`;
256
+ lines.push(`- ${row.eventId} ${row.category} ${row.kind} on ${subject} (origin ${row.origin}${cause}): ${JSON.stringify(row.summary)}`);
257
+ }
258
+ const last = dispatch.events.at(-1)?.journalSeq;
259
+ lines.push(last === undefined
260
+ ? 'Read the current state with xezar\'s tools before deciding anything.'
261
+ : `Read the current state with xezar's tools before deciding anything. These events run through journalSeq ${last}; acknowledge them once you have taken them into account.`);
262
+ return lines.join('\n');
263
+ }
264
+ /**
265
+ * Terminal text input is the last rung, and it stays refused: no runtime evidence proves project and
266
+ * session targeting, separation from approval prompts, the shell, user typing and active turns, or
267
+ * duplicate prevention for a Codex terminal. The answer is a blocker the cockpit can show, never an
268
+ * attempt.
269
+ */
270
+ export function codexTerminalDelivery() {
271
+ return {
272
+ kind: 'refused',
273
+ blocker: {
274
+ code: 'codex-terminal-delivery-refused',
275
+ recoverable: true,
276
+ message: 'xezar does not type into a Codex terminal. Targeting, separation from approval prompts, the shell, your typing and an active turn, and duplicate prevention are not proven for it.',
277
+ remedy: 'Run the leader in a Codex session xezar reaches through app-server, where events are delivered as turns.',
278
+ },
279
+ };
280
+ }
281
+ /**
282
+ * Where a project's leader events go. `link` and `threadId` present: an app-server session this
283
+ * process holds, so events are delivered through it. Absent — the leader is an interactive `codex`
284
+ * session xezar did not start (known, at most, through the thread id Codex sends in a tool call's
285
+ * `_meta`) — a recoverable blocker: that thread is live in another process, and neither attaching a
286
+ * second writer to it nor typing into its terminal is a proven, supported path (evidence X9, blocker B1).
287
+ */
288
+ export function codexReactionTarget(opts) {
289
+ if (opts.link !== undefined && opts.threadId !== undefined && !opts.link.closed) {
290
+ return { kind: 'app-server', adapter: new CodexReactionAdapter({ ...opts, link: opts.link, threadId: opts.threadId }) };
291
+ }
292
+ return {
293
+ kind: 'blocked',
294
+ blocker: {
295
+ code: 'codex-session-not-targetable',
296
+ recoverable: true,
297
+ message: 'This Codex session was not started through app-server by xezar, so xezar cannot start a turn in it. Events wait in the project journal and nothing is lost.',
298
+ remedy: 'Read events from your leader with the leader_events tool; nothing is lost while push is unavailable.',
299
+ },
300
+ };
301
+ }
302
+ function abortable(work, signal) {
303
+ if (signal.aborted)
304
+ return Promise.reject(new Error('aborted'));
305
+ return new Promise((resolve, reject) => {
306
+ const onAbort = () => reject(new Error('aborted'));
307
+ signal.addEventListener('abort', onAbort, { once: true });
308
+ work.then((value) => {
309
+ signal.removeEventListener('abort', onAbort);
310
+ resolve(value);
311
+ }, (err) => {
312
+ signal.removeEventListener('abort', onAbort);
313
+ reject(err instanceof Error ? err : new Error(String(err)));
314
+ });
315
+ });
316
+ }
317
+ function turnIdOf(obj) {
318
+ const turn = obj.turn;
319
+ if (typeof turn?.id === 'string')
320
+ return turn.id;
321
+ return typeof obj.turnId === 'string' ? obj.turnId : undefined;
322
+ }
323
+ //# sourceMappingURL=codex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../../src/mcp/adapters/codex.ts"],"names":[],"mappings":"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"}