@qodeca/xezar 0.13.1 → 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 +45 -15
  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 +24 -1
  160. package/dist/runs/retention.js +62 -1
  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 +554 -59
  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-D62m4j3B.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-DJANqg7Y.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-btG0sdbO.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-BtZId14z.js → task-changes-CH-E81-_.js} +1 -1
  226. package/web/dist/assets/{task-commits-BoeyJXrv.js → task-commits-DqfkMFxp.js} +1 -1
  227. package/web/dist/assets/{task-files-DIy2oUnj.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-CPBwzQ7M.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-DG115scU.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-D6vK0jFn.js +0 -1
  244. package/web/dist/assets/index-CkmR6h7s.css +0 -2
  245. package/web/dist/assets/index-DVDqF4bM.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-DMfxQtrD.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,596 @@
1
+ import { mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
2
+ import { dirname, join } from 'node:path';
3
+ import { z } from 'zod';
4
+ import { OWNER_ACQUIRE_ATTEMPTS, OWNER_BACKOFF_CAP_MS, projectOccupiedError, sessionExpiredError, } from '../workspace/project-owner.js';
5
+ import { McpJournalCursorError } from './event-journal.js';
6
+ /**
7
+ * The non-model event controller (#107): it follows ONE project's event journal (#103) on behalf
8
+ * of the logical MCP session that owns the project (#99), and hands significant events to a
9
+ * client-specific reaction adapter (#108–#110). It never starts a model turn of its own.
10
+ *
11
+ * WHAT IT CONSUMES, AND DOES NOT DECIDE. The event identity, order, replay and acknowledgement
12
+ * model are D-05 (`docs/features/mcp-server/mcp-d05-async-event-contract-decision.md` § 6); the
13
+ * numbers are D-09 (`mcp-d09-limits-retention-packaging-decision.md` § 3). Every constant below
14
+ * names the one it reuses.
15
+ *
16
+ * - **Source.** The project journal only (`EventJournal`), never the workspace stream — requirements
17
+ * § 8 forbids an unfiltered workspace stream reaching MCP, and the journal already holds exactly
18
+ * E-01–E-06 for exactly one project. The journal is also the QUEUE: undelivered rows are the
19
+ * journal between this controller's position and its head, so the queue is durable, gapless and
20
+ * bounded by B-19 retention, and no event lives only in this object's memory.
21
+ * - **Coalescing.** D-05 N3 decided *no coalescing window*: rows are never merged, delayed or
22
+ * dropped. What coalesces is DISPATCHES: at most one is in flight, and every row that arrived
23
+ * before it starts rides in it, up to one journal page (B-20, 100 rows; B-01, 40 000 bytes).
24
+ * So a burst of N rows appended in one tick reaches the adapter as `ceil(N / 100)` dispatches,
25
+ * each row intact and in `journalSeq` order, and rows that arrive while a dispatch is in flight
26
+ * go out together in the next one.
27
+ * WHOSE FACTS ARE WHOSE. This controller serves one SESSION, and its cursors belong to the project's
28
+ * journal. Whether the leader is reachable is a fact about the LEADER, so it is not kept here: the
29
+ * adapter records it (`LeaderDelivery`), and it therefore survives a session change and is never
30
+ * inherited by a leader that has just been attached (QA on #311, round five, both directions).
31
+ *
32
+ * - **Delivery is not reaction (F-20).** `deliver` hands rows to the client application and is
33
+ * non-model. Whether a model turn then starts is the adapter's own, client-specific decision, and
34
+ * it reports that separately through `recordReaction`. The three D-05 § 6.6 cursors are kept
35
+ * apart: `deliveredSeq` (this controller, on a resolved `deliver`), `ackedSeq` (the leader,
36
+ * through an explicit tool call — `ack`) and `reactedSeq` (the adapter, when a turn carrying the
37
+ * rows really started). `reactedSeq` lagging `deliveredSeq` is a normal state, not a fault.
38
+ * - **Non-model traffic only (N-06).** The heartbeat, a transport retry and an acknowledgement
39
+ * never call anything that can start a turn: the heartbeat calls the adapter's optional
40
+ * `heartbeat`, a retry re-sends the SAME undelivered rows, and `ack` touches only a number.
41
+ * Rows already delivered in this session are never dispatched again.
42
+ * - **At-least-once (D-05 § 6.6).** A new session resumes after the leader's last ACK, not after
43
+ * the last delivery: a row handed to a previous client that the leader never acknowledged is
44
+ * outstanding, and F-21 says reconnect delivers it. In production the leader acknowledges through
45
+ * the pull tool (`leader_events ack`), so that record is the ACK read here (`acknowledged`, #332):
46
+ * one source of truth, not two cursors that can disagree. The leader deduplicates on `eventId`. The
47
+ * echo guard (drop a `leader` row whose `causedBy` is the adapter's own operation) is the
48
+ * adapter's, per D-05 § 6.3: rows reach it whole.
49
+ *
50
+ * ONE LOGICAL OWNER. This controller and the MCP bridge are one client, not two (compatibility
51
+ * report, "Recommended architecture"; F-18). So the controller never acquires: it is handed the
52
+ * project's `ProjectOwnership` and the session key the transport acquired with, starts only while
53
+ * that session is the live owner, and re-checks it before every dispatch and at every heartbeat.
54
+ * It never calls `acquire` or `release` — the lease is the transport's, released on connection
55
+ * close (D-02.4) — so it can neither create a second claim nor end the session it serves. A
56
+ * second controller for the same project is refused: a competing session with project-occupied,
57
+ * and a second controller for the SAME session too, because two dispatchers over one journal are
58
+ * the "two independent streams delivering duplicates" risk of requirements § 12.
59
+ *
60
+ * INERT WITHOUT A CLIENT (N-07). With no adapter the controller subscribes to nothing, starts no
61
+ * timer, reads no ownership and writes no file. The journal keeps accumulating rows exactly as it
62
+ * does with no controller at all.
63
+ *
64
+ * ## Every state, and who fires each exit
65
+ *
66
+ * No exit below is a human action, and no state holds a queued row without an on-by-default path
67
+ * to the adapter.
68
+ *
69
+ * | State | Exit | Who fires it | If nobody fires it |
70
+ * | --- | --- | --- | --- |
71
+ * | inert | — (terminal for this object) | — | correct: no client, nothing is owed; rows stay in the journal |
72
+ * | idle | → dispatching | a journal append (subscription) or the heartbeat tick | the heartbeat tick (B-17, 30 s) re-reads the journal, so a missed wakeup costs at most one interval |
73
+ * | idle | → disconnected | a failed heartbeat probe | stays idle — the correct resting state |
74
+ * | dispatching | → idle | `deliver` resolving | the attempt is aborted after one heartbeat interval and counts as a transport drop |
75
+ * | dispatching | → recovering | `deliver` rejecting, or the attempt timing out | — (the timeout above always fires) |
76
+ * | recovering | → idle / → disconnected | the round itself: at most 5 attempts, full-jitter backoff ≤ 200 ms | — (bounded) |
77
+ * | disconnected | → dispatching | the heartbeat tick (one new bounded round per interval) or the adapter's `wake` on reconnect | the heartbeat timer is on by default, so rows are retried every 30 s for as long as the session owns the project |
78
+ * | any active state | → ended | `close` (the transport, on connection close), or losing ownership, found at the next dispatch or heartbeat | lease expiry (30 s, B-14) makes the owner check fail at the next heartbeat |
79
+ * | ended | — (terminal) | — | rows stay in the journal and the persisted cursors; the next session's controller resumes after the last ack |
80
+ *
81
+ * What reaches a terminal state BECAUSE of this controller: nothing but this object. It holds no
82
+ * run, queue slot, lease or worktree, and ending it touches none.
83
+ *
84
+ * ## Where its state lives
85
+ *
86
+ * `<dataDir>/mcp/event-controller.json`, beside the journal: `{ v, projectId, epoch, deliveredSeq,
87
+ * ackedSeq, reactedSeq, floorSeq }`, written by atomic tmp+rename after every change (D-05 N4:
88
+ * persisted per delivery, not batched). Written, never required. With a leader record (production)
89
+ * the file keeps only real history — what was pushed and what reacted — and WHERE pushing starts
90
+ * comes from the leader's record. Standalone, no file means a first session that starts at the
91
+ * journal head (nothing was ever owed to a leader that did not exist; it reads current state, F-21),
92
+ * and an unreadable file starts at the head WITH a stated gap. Either way no reported cursor is ever
93
+ * set to a position nothing reached (QA on #311): a start is a floor, not a delivery. An unwritable
94
+ * directory keeps the cursors in memory with one warning.
95
+ */
96
+ /** Heartbeat and liveness period. B-17 / D-05 N6, reusing the hub's `HEARTBEAT_MS` (`server/ws.ts`). */
97
+ export const EVENT_CONTROLLER_HEARTBEAT_MS = 30_000;
98
+ /**
99
+ * Delivery attempts per recovery round, and the cap on the doubling full-jitter backoff between them.
100
+ * D-01, D-05 and D-09 fix no delivery-retry numbers (B-16 is the bridge's own "no retry" on a dead
101
+ * socket, which this is not), so the bounded-recovery shape is the one D-02 measured and D-09 adopted
102
+ * as B-15 for the same kind of local contention, rather than a new one.
103
+ */
104
+ export const EVENT_DELIVERY_ATTEMPTS = OWNER_ACQUIRE_ATTEMPTS;
105
+ export const EVENT_DELIVERY_BACKOFF_CAP_MS = OWNER_BACKOFF_CAP_MS;
106
+ /** The doubling start `project-owner.ts` uses (25, 50, 100, 200 ms). */
107
+ const BACKOFF_BASE_MS = 25;
108
+ const savedSchema = z.object({
109
+ v: z.literal(1),
110
+ projectId: z.string(),
111
+ epoch: z.string(),
112
+ deliveredSeq: z.number().int().nonnegative(),
113
+ ackedSeq: z.number().int().nonnegative(),
114
+ reactedSeq: z.number().int().nonnegative(),
115
+ /** Where pushing resumes. Absent in files written before #332's fix: the ack stood in for it. */
116
+ floorSeq: z.number().int().nonnegative().optional(),
117
+ });
118
+ /** Journal files that have a live controller in this process. One dispatcher per journal. */
119
+ const liveControllers = new Set();
120
+ export class EventController {
121
+ projectId;
122
+ #journal;
123
+ #ownership;
124
+ #sessionKey;
125
+ #adapter;
126
+ #leaderRecord;
127
+ #statePath;
128
+ #heartbeatMs;
129
+ #random;
130
+ #sleep;
131
+ #warn;
132
+ #closed = new AbortController();
133
+ #state;
134
+ /** Read strictly after this cursor next; `undefined` reads from the oldest retained row. */
135
+ #position;
136
+ /** The newest row really handed to the client, in this or an earlier session of this epoch. */
137
+ #delivered = 0;
138
+ /** An explicit acknowledgement through `ack()` — only when there is no leader record. */
139
+ #acked = 0;
140
+ /** The newest row a model turn was really seen to carry. */
141
+ #reacted = 0;
142
+ /**
143
+ * Rows at or below this are not owed to this session, so they are never pushed. It is WHERE PUSHING
144
+ * STARTS, not something that happened, so no status field ever reports it (#332, QA on #311).
145
+ */
146
+ #floor = 0;
147
+ /** The newest row this session has handed to `deliver`, delivered or still in flight. */
148
+ #handedOut = 0;
149
+ #recovery;
150
+ #busy = false;
151
+ /** A wakeup arrived while busy; whoever clears `#busy` re-schedules, so no row is stranded. */
152
+ #again = false;
153
+ #scheduled = false;
154
+ #unsubscribe;
155
+ #timer;
156
+ #warnedWrite = false;
157
+ #warnedDelivery = false;
158
+ #warnedFault = false;
159
+ constructor(opts, state) {
160
+ this.projectId = opts.journal.projectId;
161
+ this.#journal = opts.journal;
162
+ this.#ownership = opts.ownership;
163
+ this.#sessionKey = opts.sessionKey;
164
+ this.#adapter = opts.adapter;
165
+ this.#leaderRecord = opts.leaderRecord;
166
+ this.#statePath = join(dirname(opts.journal.rowsPath), 'event-controller.json');
167
+ this.#heartbeatMs = opts.heartbeatMs ?? EVENT_CONTROLLER_HEARTBEAT_MS;
168
+ this.#random = opts.random ?? Math.random;
169
+ this.#sleep = opts.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
170
+ this.#warn = opts.warn ?? ((message) => console.warn(message));
171
+ this.#state = state;
172
+ }
173
+ /**
174
+ * Start the controller for the session `sessionKey`, which must already own the project through
175
+ * the transport's own acquisition. Throws only on a caller bug (journal and owner slot of two
176
+ * different projects); every runtime condition is an answer.
177
+ */
178
+ static start(opts) {
179
+ if (opts.journal.projectId !== opts.ownership.projectId) {
180
+ throw new Error('event controller: the journal and the owner slot belong to different projects');
181
+ }
182
+ if (opts.adapter === undefined)
183
+ return { outcome: 'inert', controller: new EventController(opts, 'inert') };
184
+ const projectId = opts.journal.projectId;
185
+ if (liveControllers.has(opts.journal.rowsPath))
186
+ return { outcome: 'refused', error: projectOccupiedError(projectId) };
187
+ if (opts.ownership.sessionToken(opts.sessionKey) === undefined) {
188
+ const error = opts.ownership.state() === 'owned' ? projectOccupiedError(projectId) : sessionExpiredError(projectId);
189
+ return { outcome: 'refused', error };
190
+ }
191
+ liveControllers.add(opts.journal.rowsPath);
192
+ const controller = new EventController(opts, 'idle');
193
+ controller.#resume();
194
+ controller.#unsubscribe = opts.journal.subscribe(() => controller.#schedule());
195
+ controller.#timer = setInterval(() => void controller.#tick().catch((err) => controller.#fault(err)), controller.#heartbeatMs);
196
+ controller.#timer.unref?.();
197
+ controller.#schedule();
198
+ return { outcome: 'started', controller };
199
+ }
200
+ get state() {
201
+ return this.#state;
202
+ }
203
+ status() {
204
+ return {
205
+ state: this.#state,
206
+ deliveredSeq: this.#delivered,
207
+ // Only an explicit acknowledgement, as its owner records it now (#332).
208
+ ackedSeq: this.#ackedNow(),
209
+ reactedSeq: this.#reacted,
210
+ latestSeq: this.#journal.latestSeq,
211
+ };
212
+ }
213
+ /**
214
+ * The leader's acknowledgement (D-05 § 6.6): monotonic and idempotent. At or below the current
215
+ * ack it is a successful no-op, never a rewind; past the journal head it changes nothing. It
216
+ * calls no adapter, so it can never cost a model turn.
217
+ */
218
+ ack(journalSeq) {
219
+ if (!this.#active())
220
+ return { status: 'inactive', seq: this.#acked };
221
+ assertSeq(journalSeq);
222
+ if (journalSeq <= this.#acked)
223
+ return { status: 'unchanged', seq: this.#acked };
224
+ if (journalSeq > this.#journal.latestSeq)
225
+ return { status: 'ahead', seq: this.#acked };
226
+ this.#acked = journalSeq;
227
+ this.#floor = Math.max(this.#floor, journalSeq);
228
+ this.#persist();
229
+ return { status: 'advanced', seq: this.#acked };
230
+ }
231
+ /**
232
+ * The adapter's report that a model turn carrying rows up to `journalSeq` really started — the
233
+ * reaction half of F-20, recorded apart from delivery. Monotonic; never past a row the adapter was
234
+ * handed. A turn may start before `deliver` has resolved, so a row still in flight counts as handed.
235
+ */
236
+ recordReaction(journalSeq) {
237
+ if (!this.#active())
238
+ return { status: 'inactive', seq: this.#reacted };
239
+ assertSeq(journalSeq);
240
+ if (journalSeq <= this.#reacted)
241
+ return { status: 'unchanged', seq: this.#reacted };
242
+ if (journalSeq > Math.max(this.#delivered, this.#handedOut))
243
+ return { status: 'ahead', seq: this.#reacted };
244
+ this.#reacted = journalSeq;
245
+ this.#persist();
246
+ return { status: 'advanced', seq: this.#reacted };
247
+ }
248
+ /** The adapter's transport came back: start a recovery round now instead of at the next tick. */
249
+ wake() {
250
+ if (this.#state === 'disconnected')
251
+ this.#state = 'idle';
252
+ this.#schedule();
253
+ }
254
+ /**
255
+ * Confirmed end of the session's connection — fired by the transport where it releases the lease.
256
+ * Ends this controller only: the lease, the journal and every run are untouched.
257
+ */
258
+ close() {
259
+ this.#end();
260
+ }
261
+ #active() {
262
+ return this.#state !== 'inert' && this.#state !== 'ended';
263
+ }
264
+ #end() {
265
+ if (!this.#active())
266
+ return;
267
+ this.#state = 'ended';
268
+ this.#closed.abort();
269
+ if (this.#timer)
270
+ clearInterval(this.#timer);
271
+ this.#timer = undefined;
272
+ this.#unsubscribe?.();
273
+ this.#unsubscribe = undefined;
274
+ liveControllers.delete(this.#journal.rowsPath);
275
+ }
276
+ /** Ownership is xezar's to enforce, so it is re-read, never remembered. Losing it ends us. */
277
+ #stillOwner() {
278
+ if (!this.#active())
279
+ return false;
280
+ if (this.#ownership.sessionToken(this.#sessionKey) !== undefined)
281
+ return true;
282
+ this.#end();
283
+ return false;
284
+ }
285
+ #schedule() {
286
+ if (this.#scheduled || !this.#active())
287
+ return;
288
+ this.#scheduled = true;
289
+ // A microtask, not a timer: rows appended in the same tick share a dispatch, and nothing waits.
290
+ queueMicrotask(() => {
291
+ this.#scheduled = false;
292
+ void this.#drain().catch((err) => this.#fault(err));
293
+ });
294
+ }
295
+ /** A bug inside a background step is logged once, never thrown into the cockpit (N-07). The next
296
+ * tick tries again, because every step re-reads the journal and the owner from scratch. */
297
+ #fault(err) {
298
+ if (this.#warnedFault)
299
+ return;
300
+ this.#warnedFault = true;
301
+ this.#warn(`[xez] MCP event controller for project ${this.projectId} hit an internal error: ${err instanceof Error ? err.message : String(err)}`);
302
+ }
303
+ #release() {
304
+ this.#busy = false;
305
+ if (this.#again) {
306
+ this.#again = false;
307
+ this.#schedule();
308
+ }
309
+ }
310
+ async #drain() {
311
+ if (this.#busy) {
312
+ this.#again = true;
313
+ return;
314
+ }
315
+ // A disconnected transport waits for the tick or `wake`, so a burst cannot fire rounds back to back.
316
+ if (this.#state !== 'idle')
317
+ return;
318
+ this.#busy = true;
319
+ try {
320
+ for (;;) {
321
+ if (!this.#stillOwner())
322
+ return;
323
+ // The leader may have acknowledged through the pull tool since the last dispatch (#332).
324
+ this.#syncFloor();
325
+ const next = this.#next();
326
+ if (next === undefined)
327
+ return;
328
+ if (next.lastSeq !== undefined)
329
+ this.#handedOut = Math.max(this.#handedOut, next.lastSeq);
330
+ const delivered = await this.#deliverBounded(next.dispatch);
331
+ if (!this.#active())
332
+ return;
333
+ if (delivered === false) {
334
+ this.#state = 'disconnected';
335
+ if (!this.#warnedDelivery) {
336
+ this.#warnedDelivery = true;
337
+ this.#warn(`[xez] MCP event delivery for project ${this.projectId} failed ${EVENT_DELIVERY_ATTEMPTS} times — retrying every ${this.#heartbeatMs / 1000}s while the session owns the project`);
338
+ }
339
+ return;
340
+ }
341
+ this.#warnedDelivery = false;
342
+ this.#state = 'idle';
343
+ this.#position = next.nextCursor;
344
+ this.#recovery = undefined;
345
+ if (next.lastSeq !== undefined) {
346
+ // Only rows REALLY handed over count as delivered; a receipt says which (the leader's own
347
+ // echoes are settled but never delivered). A redelivery never lowers the count.
348
+ const handed = delivered.receipt === undefined ? next.lastSeq : delivered.receipt.handedThrough;
349
+ if (handed !== null)
350
+ this.#delivered = Math.max(this.#delivered, handed);
351
+ }
352
+ this.#persist();
353
+ }
354
+ }
355
+ finally {
356
+ this.#release();
357
+ }
358
+ }
359
+ /** The next dispatch, read from the journal itself. `undefined` when nothing is outstanding. */
360
+ #next() {
361
+ for (;;) {
362
+ let page;
363
+ try {
364
+ page = this.#journal.read(this.#position === undefined ? {} : { cursor: this.#position });
365
+ }
366
+ catch (err) {
367
+ if (!(err instanceof McpJournalCursorError))
368
+ throw err;
369
+ // Our own cursor refused: state the gap and start again from the oldest retained row.
370
+ this.#position = undefined;
371
+ this.#recovery = this.#gap();
372
+ continue;
373
+ }
374
+ if (page.status === 'cursor_too_old') {
375
+ this.#position = page.resumeCursor;
376
+ this.#recovery = this.#gap();
377
+ continue;
378
+ }
379
+ // Rows at or below the floor are not owed (the leader acknowledged them, or they predate it).
380
+ const events = page.events.filter((row) => row.journalSeq > this.#floor);
381
+ if (events.length === 0 && page.events.length > 0) {
382
+ this.#position = page.nextCursor;
383
+ continue;
384
+ }
385
+ if (events.length === 0 && this.#recovery === undefined)
386
+ return undefined;
387
+ const dispatch = {
388
+ projectId: this.projectId,
389
+ events,
390
+ ...(this.#recovery === undefined ? {} : { recovery: this.#recovery }),
391
+ };
392
+ const lastSeq = events.at(-1)?.journalSeq;
393
+ return { dispatch, nextCursor: page.nextCursor, ...(lastSeq === undefined ? {} : { lastSeq }) };
394
+ }
395
+ }
396
+ /**
397
+ * One bounded recovery round over the SAME rows. No attempt can start a turn on its own. Every
398
+ * attempt's outcome is a fact about the LEADER, and the adapter records it (`LeaderDelivery`).
399
+ */
400
+ async #deliverBounded(dispatch) {
401
+ const adapter = this.#adapter;
402
+ for (let attempt = 0; attempt < EVENT_DELIVERY_ATTEMPTS; attempt++) {
403
+ if (!this.#active())
404
+ return false;
405
+ this.#state = attempt === 0 ? 'dispatching' : 'recovering';
406
+ const outcome = await this.#attempt((signal) => adapter.deliver(dispatch, signal));
407
+ if (outcome.ok)
408
+ return { receipt: outcome.value === undefined ? undefined : outcome.value };
409
+ if (attempt < EVENT_DELIVERY_ATTEMPTS - 1) {
410
+ await this.#sleep(this.#random() * Math.min(EVENT_DELIVERY_BACKOFF_CAP_MS, BACKOFF_BASE_MS * 2 ** attempt));
411
+ }
412
+ }
413
+ return false;
414
+ }
415
+ /**
416
+ * One call into the adapter, bounded by one heartbeat interval: an attempt that has not settled in
417
+ * a whole liveness period is a dead transport, and it must not hold the queue behind it.
418
+ */
419
+ async #attempt(call) {
420
+ const attempt = new AbortController();
421
+ const abort = () => attempt.abort();
422
+ this.#closed.signal.addEventListener('abort', abort, { once: true });
423
+ const timer = setTimeout(abort, this.#heartbeatMs);
424
+ timer.unref?.();
425
+ const gaveUp = new Promise((_, reject) => {
426
+ attempt.signal.addEventListener('abort', () => reject(new Error('aborted')), { once: true });
427
+ });
428
+ const work = Promise.resolve().then(() => call(attempt.signal));
429
+ // Whichever loses the race settles later with nobody listening; neither may surface as unhandled.
430
+ work.catch(() => { });
431
+ gaveUp.catch(() => { });
432
+ try {
433
+ return { ok: true, value: await Promise.race([work, gaveUp]) };
434
+ }
435
+ catch {
436
+ return { ok: false };
437
+ }
438
+ finally {
439
+ clearTimeout(timer);
440
+ this.#closed.signal.removeEventListener('abort', abort);
441
+ }
442
+ }
443
+ /** The heartbeat: owner check, a recovery round when disconnected, then a non-model liveness probe. */
444
+ async #tick() {
445
+ if (!this.#stillOwner() || this.#busy)
446
+ return;
447
+ if (this.#state === 'disconnected')
448
+ this.#state = 'idle';
449
+ // Re-reading the journal here is also the backstop for a wakeup that never arrived.
450
+ await this.#drain();
451
+ const probe = this.#adapter?.heartbeat;
452
+ if (probe === undefined || this.#state !== 'idle' || this.#busy)
453
+ return;
454
+ this.#busy = true;
455
+ const alive = (await this.#attempt((signal) => probe.call(this.#adapter, signal))).ok;
456
+ if (this.#active() && !alive)
457
+ this.#state = 'disconnected';
458
+ this.#release();
459
+ }
460
+ /**
461
+ * Where a starting controller reads from, and what it reports. The two are kept apart, because
462
+ * conflating them is how a first session once reported rows as delivered, acknowledged and
463
+ * reacted to that never reached anyone (QA on #311, D-05 § 6.6):
464
+ * - REPORTED cursors come only from things that happened: `deliveredSeq` and `reactedSeq` from
465
+ * this file's record of real pushes and turns in the SAME journal epoch (0 otherwise), and
466
+ * `ackedSeq` from an explicit acknowledgement.
467
+ * - The FLOOR is where pushing resumes: with a leader record, after what the leader is owed
468
+ * (`owedAfter`); standalone (#107), after the file's last ack, or the head for a first session.
469
+ */
470
+ #resume() {
471
+ const journal = this.#journal;
472
+ const saved = this.#load();
473
+ const own = typeof saved === 'object' && saved.epoch === journal.epoch ? saved : undefined;
474
+ this.#delivered = own ? Math.min(own.deliveredSeq, journal.latestSeq) : 0;
475
+ this.#reacted = own ? Math.min(own.reactedSeq, this.#delivered) : 0;
476
+ this.#acked = own && this.#leaderRecord === undefined ? Math.min(own.ackedSeq, journal.latestSeq) : 0;
477
+ const firstRetained = journal.oldestSeq ?? journal.latestSeq + 1;
478
+ this.#position = undefined;
479
+ let gap;
480
+ if (this.#leaderRecord !== undefined) {
481
+ // One acknowledgement (#332): owed is what the leader's own record says, never this file.
482
+ const owed = this.#owedAfter();
483
+ this.#floor = owed.sameEpoch ? owed.seq : 0;
484
+ gap = !owed.sameEpoch || this.#floor < firstRetained - 1;
485
+ }
486
+ else if (saved === 'absent' || saved === 'unreadable') {
487
+ // Standalone first session: nothing was owed to a leader that did not exist; it reads current state (F-21).
488
+ this.#floor = journal.latestSeq;
489
+ this.#position = journal.headCursor();
490
+ gap = saved === 'unreadable';
491
+ }
492
+ else {
493
+ this.#floor = own ? Math.max(own.ackedSeq, own.floorSeq ?? own.ackedSeq) : 0;
494
+ gap = own === undefined || this.#floor > journal.latestSeq || this.#floor < firstRetained - 1;
495
+ }
496
+ if (gap) {
497
+ // Rows this session was owed are gone (journal recreated, or evicted unacknowledged): say so, and
498
+ // resume at the oldest row that still exists — or, for an unreadable file, at the head.
499
+ if (this.#position === undefined)
500
+ this.#floor = Math.min(Math.max(this.#floor, 0), firstRetained - 1);
501
+ this.#recovery = this.#gap();
502
+ }
503
+ this.#persist();
504
+ }
505
+ /** The leader record's owed-after position, clamped to this journal; nothing readable owes everything. */
506
+ #owedAfter() {
507
+ try {
508
+ const owed = this.#leaderRecord.owedAfter();
509
+ const seq = Number.isSafeInteger(owed.seq) && owed.seq > 0 ? Math.min(owed.seq, this.#journal.latestSeq) : 0;
510
+ return { seq, sameEpoch: owed.sameEpoch };
511
+ }
512
+ catch {
513
+ return { seq: 0, sameEpoch: true }; // an unreadable record owes everything retained: at-least-once, never a skipped row
514
+ }
515
+ }
516
+ /** The explicit acknowledgement as its owner records it now; 0 when there is none. */
517
+ #ackedNow() {
518
+ if (this.#leaderRecord === undefined)
519
+ return this.#acked;
520
+ try {
521
+ const seq = this.#leaderRecord.acknowledged();
522
+ return Number.isSafeInteger(seq) && seq > 0 ? Math.min(seq, this.#journal.latestSeq) : 0;
523
+ }
524
+ catch {
525
+ return 0;
526
+ }
527
+ }
528
+ /** Raise the floor to what the leader's record says it is owed after. Monotonic; reports nothing. */
529
+ #syncFloor() {
530
+ if (this.#leaderRecord === undefined)
531
+ return;
532
+ const owed = this.#owedAfter();
533
+ if (!owed.sameEpoch || owed.seq <= this.#floor)
534
+ return;
535
+ this.#floor = owed.seq;
536
+ this.#persist();
537
+ }
538
+ #gap() {
539
+ return {
540
+ required: 'current-state',
541
+ oldestSeq: this.#journal.oldestSeq,
542
+ latestSeq: this.#journal.latestSeq,
543
+ message: 'Some events this session was owed are no longer retained. Read the current state before acting on these events.',
544
+ };
545
+ }
546
+ #load() {
547
+ let raw;
548
+ try {
549
+ raw = readFileSync(this.#statePath, 'utf8');
550
+ }
551
+ catch (err) {
552
+ if (err.code === 'ENOENT')
553
+ return 'absent';
554
+ raw = '';
555
+ }
556
+ try {
557
+ const parsed = savedSchema.safeParse(JSON.parse(raw));
558
+ if (parsed.success && parsed.data.projectId === this.projectId)
559
+ return parsed.data;
560
+ }
561
+ catch {
562
+ /* reported below */
563
+ }
564
+ this.#warn(`[xez] MCP event controller state for project ${this.projectId} is unreadable — its cursors restart at 0${this.#leaderRecord ? '' : ', pushing from the journal head with a stated gap'}`);
565
+ return 'unreadable';
566
+ }
567
+ #persist() {
568
+ const body = {
569
+ v: 1,
570
+ projectId: this.projectId,
571
+ epoch: this.#journal.epoch,
572
+ deliveredSeq: this.#delivered,
573
+ ackedSeq: this.#acked,
574
+ reactedSeq: this.#reacted,
575
+ floorSeq: this.#floor,
576
+ };
577
+ const tmp = `${this.#statePath}.tmp`;
578
+ try {
579
+ mkdirSync(dirname(this.#statePath), { recursive: true, mode: 0o700 });
580
+ writeFileSync(tmp, `${JSON.stringify(body)}\n`, { encoding: 'utf8', mode: 0o600 });
581
+ renameSync(tmp, this.#statePath);
582
+ }
583
+ catch (err) {
584
+ if (this.#warnedWrite)
585
+ return;
586
+ this.#warnedWrite = true;
587
+ const message = err instanceof Error ? err.message : String(err);
588
+ this.#warn(`[xez] MCP event controller state for project ${this.projectId} cannot be written (${message}) — cursors are kept in memory only`);
589
+ }
590
+ }
591
+ }
592
+ function assertSeq(seq) {
593
+ if (!Number.isSafeInteger(seq) || seq < 0)
594
+ throw new RangeError('a journal sequence number is a non-negative integer');
595
+ }
596
+ //# sourceMappingURL=event-controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-controller.js","sourceRoot":"","sources":["../../src/mcp/event-controller.ts"],"names":[],"mappings":"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"}