@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,465 @@
1
+ import { chmodSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { z } from 'zod';
4
+ import { MCP_JOURNAL_PAGE_ROWS, mcpJournalCursorSchema, mcpJournalProjectIdSchema, operationIdSchema, } from '../contract/index.js';
5
+ import { atomicTmpPath } from '../workspace/config.js';
6
+ import { runVersion } from './stale-write.js';
7
+ /**
8
+ * Reconnect for the MCP project leader (#105): on reconnection the leader receives its OUTSTANDING
9
+ * significant events plus the CURRENT AUTHORITATIVE STATE; duplicates and out-of-order delivery
10
+ * cause no repeated effect; a gap is stated, never skipped. Built over #103's journal
11
+ * (`event-journal.ts`) and #101's operation receipts (`operation-receipts.ts`). Every rule below was
12
+ * decided by D-05 (`docs/features/mcp-server/mcp-d05-async-event-contract-decision.md`) and every
13
+ * number by D-09 (`mcp-d09-limits-retention-packaging-decision.md`); nothing here picks its own.
14
+ *
15
+ * THE NUMBERS, as given (none is new, none is a knob, no `XEZ_*` variable):
16
+ * - retention: 10 000 rows per project, and a row younger than 14 days is never evicted (D-05 N1,
17
+ * D-09 B-19) — enforced by the journal; a cursor behind it gets the explicit `cursor_too_old`;
18
+ * - replay page: 100 rows (D-05 N2, D-09 B-02/B-20) and 40 000 bytes (B-01), whichever first;
19
+ * - the current-state snapshot: at most 100 tasks, the same B-02 page bound;
20
+ * - coalescing window: none (D-05 N3) — every new row is its own delivery;
21
+ * - the delivered cursor is persisted per delivery, not batched across deliveries (D-05 N4).
22
+ *
23
+ * THE FIVE GUARANTEES, and where each lives:
24
+ *
25
+ * 1. A disconnect never stops, cancels or loses a started task (F-21, N-05 — mandatory). Client
26
+ * occupancy is separate from executor lifetime BY CONSTRUCTION: nothing in this module holds
27
+ * the run manager, and `LeaderFeed.disconnect` only drops the journal subscription. The journal
28
+ * keeps recording while no client is connected, because its writer lives with the project, not
29
+ * with a leader connection; a reconnect then reads what was written meanwhile.
30
+ * 2. Outstanding events plus current state (F-21). `reconnect` replays strictly after the leader's
31
+ * acknowledged cursor, in `journalSeq` order, THEN reads the current state — D-05 § 6.5's order,
32
+ * the same one `GET /api/v1/runs/:id/events` uses (replay, dedupe with `>`, then snapshot), and
33
+ * the same shape as the cockpit's `reconcile()` in `packages/web/src/api/global-events.tsx`:
34
+ * after a reconnect the local picture is a guess, so the authoritative state is re-read.
35
+ * 3. At-least-once delivery, no repeated effect (D-05 § 6.6, N-10). The server may deliver a row
36
+ * again — after a lost acknowledgement or a restart. The consumer's `LeaderInbox` drops a row
37
+ * it has already delivered (identity is the `eventId`, D-05 § 6.1) and releases rows only in
38
+ * `journalSeq` order, so a duplicate or a reordered row is never a second decision point. A
39
+ * reaction that MUTATES carries `reactionOperationId`, so a second delivery that does reach
40
+ * the leader (a restart lost the inbox) is answered from the #101 receipt — replayed, no second
41
+ * effect. There is no second deduplication store here; the receipts are that store.
42
+ * 4. Explicit gaps (A-21). A cursor whose rows retention has evicted, or one from a journal that
43
+ * was recreated, gets the journal's own `cursor_too_old` answer — oldest retained seq, a resume
44
+ * cursor and the current-state recovery — with the state snapshot beside it. Nothing is
45
+ * replayed partially, because a partial replay reads as "nothing happened in between".
46
+ * 5. No polling, no heartbeat (F-20, N-06). `LeaderFeed` wakes the leader only from the journal's
47
+ * own append signal. It starts no timer and no interval; with no significant event, it never
48
+ * wakes anyone. A leader that is told `hasMore` reads the next page because it was told to —
49
+ * that is bounded recovery, not a status poll.
50
+ *
51
+ * COMPLETION AFTER A HUMAN CANCELLATION OR CHANGE — the documented resolution (the case the
52
+ * compatibility report names). Order is the journal's, never arrival order: `LeaderInbox` holds a
53
+ * row that arrives ahead of a missing one, so a late completion is released in its own place.
54
+ * Authority is the CURRENT state, never the event: every row carries `subject.version` (D-05
55
+ * § 6.3), and a row whose version is no longer the subject's current version is delivered with
56
+ * `standing: 'superseded'`. It is history the leader may read, not a fact to act on. The human's
57
+ * action stands: a leader mutation built on the superseded row carries the stale version and is
58
+ * refused by #100's stale-write check (`stale-write.ts`), with nothing applied. The engine itself
59
+ * keeps cancellation final — a step that finishes after cancellation is recorded `cancelled`
60
+ * (`workflows/run.ts`, the `state.cancelled` branch after a step ends; read from source) — and
61
+ * nothing here resurrects, re-completes or resumes a task because of a late event.
62
+ *
63
+ * WHAT THIS IS NOT. It emits no significant event: deriving E-01–E-06 from status transitions and
64
+ * human actions is #104. It is not a tool (no entry in `tools/index.ts`), opens no socket and adds
65
+ * no channel: the transport is D-01's, and the cockpit keeps its one SSE stream and one WebSocket.
66
+ * It adds no run queue and no process controller: `RunManager`, `RunStore` and the semaphore keep
67
+ * task lifecycle.
68
+ *
69
+ * Retention: D-05's table marks `ackedSeq` as the cursor that drives retention. D-09 adopted
70
+ * retention as B-19's count-and-age bound, which the journal enforces whatever has been acked; a
71
+ * leader that is offline longer than that gets `cursor_too_old`, never a silent skip. The ack is
72
+ * persisted here so a leader resumes where it stopped across reconnects and restarts.
73
+ */
74
+ /** The leader's cursors, beside the journal in `<dataDir>/mcp/` (inside `.local/`, blanket-ignored). */
75
+ export const LEADER_CURSORS_FILE = 'leader-cursors.json';
76
+ /** D-09 B-02: the current-state snapshot is bounded like every other MCP list. */
77
+ export const RECONNECT_STATE_MAX_TASKS = MCP_JOURNAL_PAGE_ROWS;
78
+ // ---- persisted acknowledgement (D-05 § 6.6) ----------------------------------------------------
79
+ const cursorsFileSchema = z.looseObject({
80
+ v: z.literal(1),
81
+ projectId: mcpJournalProjectIdSchema,
82
+ /** The journal epoch `deliveredSeq` and `reactedSeq` count in. */
83
+ epoch: z.string().min(1).max(64),
84
+ deliveredSeq: z.number().int().nonnegative(),
85
+ reactedSeq: z.number().int().nonnegative(),
86
+ /**
87
+ * False when `acked` is only where the record BEGAN (a leader with no acknowledgement yet), true once
88
+ * the leader acknowledged through the tool. Absent in files written before QA on #311: treated as an
89
+ * acknowledgement, which is what those files meant.
90
+ */
91
+ ackedByLeader: z.boolean().optional(),
92
+ /** The acknowledged position: a cursor the journal minted, its seq, and the epoch it counts in. */
93
+ acked: z.object({
94
+ epoch: z.string().min(1).max(64),
95
+ seq: z.number().int().nonnegative(),
96
+ cursor: mcpJournalCursorSchema,
97
+ }),
98
+ });
99
+ /**
100
+ * The leader's delivered / acked / reacted positions for one project, persisted (tmp+rename,
101
+ * `0600`). Written, never required: a missing file is a leader that has never connected, and it
102
+ * starts at the journal head — recorded as where rows begin to be owed, and reported as nothing
103
+ * delivered, acknowledged or reacted, because none of that happened. A corrupt one does the same with ONE warning, set aside as `.corrupt`,
104
+ * and the reconnect answer says `fresh: true` so a start from "now" is stated rather than implied.
105
+ * An unwritable directory keeps the positions in memory with one warning; nothing throws.
106
+ */
107
+ export class LeaderCursors {
108
+ path;
109
+ #state;
110
+ #fresh = false;
111
+ #warned = false;
112
+ #journal;
113
+ #warn;
114
+ constructor(opts) {
115
+ this.path = join(opts.dataDir, 'mcp', LEADER_CURSORS_FILE);
116
+ this.#journal = opts.journal;
117
+ this.#warn = opts.warn ?? ((message) => console.warn(message));
118
+ this.#state = this.#load(mcpJournalProjectIdSchema.parse(opts.projectId));
119
+ }
120
+ static open(opts) {
121
+ if (opts.journal.projectId !== opts.projectId) {
122
+ throw new Error('leader cursors and the event journal must belong to the same project');
123
+ }
124
+ return new LeaderCursors(opts);
125
+ }
126
+ /** True when no stored position existed, so the leader started at the journal head. */
127
+ get fresh() {
128
+ return this.#fresh;
129
+ }
130
+ /** The cursor a reconnect replays after — a cursor the journal minted, never one built here. */
131
+ get ackedCursor() {
132
+ return this.#state.acked.cursor;
133
+ }
134
+ /** Positions in the CURRENT journal. A position from a recreated journal counts as 0 here. */
135
+ position() {
136
+ const same = this.#state.epoch === this.#journal.epoch;
137
+ return {
138
+ deliveredSeq: same ? this.#state.deliveredSeq : 0,
139
+ // Only an explicit acknowledgement: where a new record began is not one (QA on #311).
140
+ ackedSeq: this.#state.acked.epoch === this.#journal.epoch && this.#state.ackedByLeader !== false ? this.#state.acked.seq : 0,
141
+ reactedSeq: same ? this.#state.reactedSeq : 0,
142
+ };
143
+ }
144
+ /**
145
+ * Where rows start being OWED to the leader — its last acknowledgement, or where its record began —
146
+ * for push delivery (`LeaderRecord`, #332). A record from a recreated journal owes the new one from
147
+ * its start: `sameEpoch` false, and the reader states the gap.
148
+ */
149
+ owedAfter() {
150
+ const sameEpoch = this.#state.acked.epoch === this.#journal.epoch;
151
+ return { seq: sameEpoch ? this.#state.acked.seq : 0, sameEpoch };
152
+ }
153
+ /** The last row the leader acknowledged through the tool; 0 when it never has (`LeaderRecord`). */
154
+ acknowledged() {
155
+ return this.position().ackedSeq;
156
+ }
157
+ /** Non-model: the transport handed rows through `seq` to the client (D-05 § 6.6). Monotonic. */
158
+ markDelivered(seq) {
159
+ this.#rebase();
160
+ if (seq <= this.#state.deliveredSeq)
161
+ return;
162
+ this.#state = { ...this.#state, deliveredSeq: seq };
163
+ this.#save();
164
+ }
165
+ /** Non-model: a model turn carrying rows through `seq` was actually started (D-05 § 6.6). */
166
+ markReacted(seq) {
167
+ this.#rebase();
168
+ if (seq <= this.#state.reactedSeq)
169
+ return;
170
+ this.#state = { ...this.#state, reactedSeq: seq };
171
+ this.#save();
172
+ }
173
+ /**
174
+ * The leader has durably taken every row up to `cursor` into account — the `nextCursor` of a
175
+ * page, or the `resumeCursor` of a gap. Monotonic and idempotent: a cursor at or below the
176
+ * current ack is a successful no-op, never a rewind and never an error (D-05 § 6.6). Replaying
177
+ * from an earlier position is a different request — `reconnect` with an explicit cursor — and it
178
+ * never moves the ack. A malformed or foreign cursor throws `McpJournalCursorError`.
179
+ */
180
+ ack(cursor) {
181
+ // The journal is the one reader of its own cursor format; a one-row read resolves the position.
182
+ const probe = this.#journal.read({ cursor, limit: 1 });
183
+ const current = this.position().ackedSeq;
184
+ if (probe.status === 'cursor_too_old')
185
+ return { status: 'no-op', ackedSeq: current };
186
+ const seq = probe.events[0] === undefined ? probe.latestSeq : probe.events[0].journalSeq - 1;
187
+ const epoch = this.#journal.epoch;
188
+ if (this.#state.acked.epoch === epoch && seq <= this.#state.acked.seq) {
189
+ return { status: 'no-op', ackedSeq: current };
190
+ }
191
+ this.#rebase();
192
+ // An acknowledged row was, necessarily, delivered.
193
+ this.#state = {
194
+ ...this.#state,
195
+ deliveredSeq: Math.max(this.#state.deliveredSeq, seq),
196
+ ackedByLeader: true,
197
+ acked: { epoch, seq, cursor },
198
+ };
199
+ this.#save();
200
+ return { status: 'acked', ackedSeq: seq };
201
+ }
202
+ /** A recreated journal restarts its numbers at 1; counts from the old one mean nothing in it. */
203
+ #rebase() {
204
+ if (this.#state.epoch === this.#journal.epoch)
205
+ return;
206
+ this.#state = { ...this.#state, epoch: this.#journal.epoch, deliveredSeq: 0, reactedSeq: 0 };
207
+ }
208
+ #load(projectId) {
209
+ const atHead = () => {
210
+ this.#fresh = true;
211
+ const seq = this.#journal.latestSeq;
212
+ const epoch = this.#journal.epoch;
213
+ // The record BEGINS at the head: rows before it are not owed (F-21, a new leader reads current
214
+ // state). That is a starting point, not a delivery, an acknowledgement or a reaction, so all
215
+ // three report 0 until they really happen (QA on #311).
216
+ return { v: 1, projectId, epoch, deliveredSeq: 0, reactedSeq: 0, ackedByLeader: false, acked: { epoch, seq, cursor: this.#journal.headCursor() } };
217
+ };
218
+ if (!existsSync(this.path)) {
219
+ const state = atHead();
220
+ this.#state = state;
221
+ this.#save();
222
+ return state;
223
+ }
224
+ let parsed;
225
+ try {
226
+ const result = cursorsFileSchema.safeParse(JSON.parse(readFileSync(this.path, 'utf8')));
227
+ if (result.success && result.data.projectId === projectId)
228
+ parsed = result.data;
229
+ }
230
+ catch {
231
+ parsed = undefined;
232
+ }
233
+ if (parsed)
234
+ return parsed;
235
+ this.#warn(`[xez] MCP leader cursors for project ${projectId} are unreadable — the leader restarts at the journal head; the old file is kept as ${this.path}.corrupt`);
236
+ try {
237
+ renameSync(this.path, `${this.path}.corrupt`);
238
+ }
239
+ catch { /* the save below overwrites it instead */ }
240
+ const state = atHead();
241
+ this.#state = state;
242
+ this.#save();
243
+ return state;
244
+ }
245
+ #save() {
246
+ try {
247
+ mkdirSync(join(this.path, '..'), { recursive: true, mode: 0o700 });
248
+ const tmp = atomicTmpPath(this.path);
249
+ writeFileSync(tmp, `${JSON.stringify(this.#state)}\n`, { encoding: 'utf8', mode: 0o600 });
250
+ renameSync(tmp, this.path);
251
+ try {
252
+ chmodSync(this.path, 0o600);
253
+ }
254
+ catch { /* best-effort on filesystems without modes */ }
255
+ }
256
+ catch (err) {
257
+ if (this.#warned)
258
+ return;
259
+ this.#warned = true;
260
+ const message = err instanceof Error ? err.message : String(err);
261
+ this.#warn(`[xez] MCP leader cursors cannot be written (${message}) — positions are kept in memory only`);
262
+ }
263
+ }
264
+ }
265
+ const IN_FLIGHT = new Set(['queued', 'running', 'waiting', 'review']);
266
+ /**
267
+ * The default state reader over the project's own `RunStore` — the store the cockpit reads (N-02).
268
+ * A projection only — id, status and version — so no title, prompt, transcript or account detail
269
+ * reaches a model (F-15, N-01); the task read tool (#91) is where a leader reads more.
270
+ */
271
+ export function runStateReader(store, journal) {
272
+ return (subjects) => {
273
+ const ids = [];
274
+ const seen = new Set();
275
+ const add = (id) => {
276
+ if (seen.has(id))
277
+ return;
278
+ seen.add(id);
279
+ ids.push(id);
280
+ };
281
+ for (const subject of subjects)
282
+ if (subject.type === 'run')
283
+ add(subject.id);
284
+ for (const run of store.listRuns())
285
+ if (IN_FLIGHT.has(run.status))
286
+ add(run.id);
287
+ const tasks = ids.slice(0, RECONNECT_STATE_MAX_TASKS).map((id) => {
288
+ const run = store.getRun(id);
289
+ return run ? { id, status: run.status, version: runVersion(store, id) ?? null } : { id, status: null, version: null };
290
+ });
291
+ return { latestSeq: journal.latestSeq, tasks, complete: ids.length <= RECONNECT_STATE_MAX_TASKS };
292
+ };
293
+ }
294
+ /**
295
+ * Everything a reconnecting leader needs in one answer: the outstanding rows after its
296
+ * acknowledged position (or after `cursor`), then the current state — or, when the rows it needs
297
+ * are gone, the explicit gap plus the current state. A malformed or foreign cursor throws
298
+ * `McpJournalCursorError`: it is never read as "start from zero" (D-05 § 6.5).
299
+ */
300
+ export function reconnect(opts) {
301
+ const from = opts.cursor ?? opts.cursors.ackedCursor;
302
+ const result = opts.journal.read({ cursor: from, ...(opts.limit === undefined ? {} : { limit: opts.limit }) });
303
+ const common = {
304
+ position: opts.cursors.position(),
305
+ fresh: opts.cursors.fresh,
306
+ journalEpoch: opts.journal.epoch,
307
+ };
308
+ if (result.status === 'cursor_too_old') {
309
+ return { status: 'cursor_too_old', gap: result, state: opts.readState([]), ...common };
310
+ }
311
+ // D-05 § 6.5: replay first, THEN the snapshot, so the state is never older than the rows.
312
+ const state = opts.readState(result.events.map((row) => row.subject));
313
+ return {
314
+ status: 'ok',
315
+ events: judge(result.events, state),
316
+ nextCursor: result.nextCursor,
317
+ hasMore: result.hasMore,
318
+ state,
319
+ ...common,
320
+ };
321
+ }
322
+ /** Stand each row against the current state — see the module comment's completion-after-cancel rule. */
323
+ export function judge(rows, state) {
324
+ const tasks = new Map(state.tasks.map((task) => [task.id, task]));
325
+ return rows.map((row) => {
326
+ const task = row.subject.type === 'run' ? tasks.get(row.subject.id) : undefined;
327
+ if (!task || row.subject.version === null)
328
+ return { row, standing: 'unjudged' };
329
+ return { row, standing: task.version === row.subject.version ? 'current' : 'superseded' };
330
+ });
331
+ }
332
+ /**
333
+ * The connection-scoped half: one live subscription to the journal while a leader is connected.
334
+ * No timer, no interval, no heartbeat — liveness of the CLIENT is the transport's ping (D-09 B-17),
335
+ * never a model turn and never this class. `disconnect` touches nothing but the subscription.
336
+ */
337
+ export class LeaderFeed {
338
+ #unsubscribe;
339
+ /** Delivered-through position for the live half: a cursor the journal minted. */
340
+ #deliveredCursor;
341
+ #opts;
342
+ constructor(opts) {
343
+ this.#opts = opts;
344
+ }
345
+ get connected() {
346
+ return this.#unsubscribe !== undefined;
347
+ }
348
+ /**
349
+ * Connect (or reconnect): subscribe to live appends, then answer with the outstanding rows and
350
+ * the current state. The subscription goes first, so no row appended during the answer can fall
351
+ * between the replay and the live half; the live half reads strictly after the answer's cursor,
352
+ * so no row can arrive twice either. The answer goes back to the caller — the leader asked for
353
+ * it — and does not itself wake anyone.
354
+ */
355
+ connect(cursor) {
356
+ this.disconnect();
357
+ this.#unsubscribe = this.#opts.journal.subscribe(() => this.#onAppend());
358
+ const answer = reconnect({ ...this.#opts, ...(cursor === undefined ? {} : { cursor }) });
359
+ if (answer.status !== 'ok') {
360
+ // The gap is in the answer; live delivery continues from where the journal resumes.
361
+ this.#deliveredCursor = answer.gap.resumeCursor;
362
+ return answer;
363
+ }
364
+ this.#deliveredCursor = answer.nextCursor;
365
+ const last = answer.events.at(-1)?.row.journalSeq;
366
+ if (last === undefined)
367
+ return answer;
368
+ this.#opts.cursors.markDelivered(last);
369
+ return { ...answer, position: this.#opts.cursors.position() };
370
+ }
371
+ /** Client occupancy ends here and ONLY here. No task is touched: executor lifetime is not ours. */
372
+ disconnect() {
373
+ this.#unsubscribe?.();
374
+ this.#unsubscribe = undefined;
375
+ this.#deliveredCursor = undefined;
376
+ }
377
+ #onAppend() {
378
+ if (this.#deliveredCursor === undefined)
379
+ return;
380
+ const result = this.#opts.journal.read({ cursor: this.#deliveredCursor });
381
+ // Unreachable while connected — this listener runs right after an append, which evicts from the
382
+ // head only — but a gap is stated through the next reconnect rather than skipped here.
383
+ if (result.status !== 'ok' || result.events.length === 0)
384
+ return;
385
+ this.#deliveredCursor = result.nextCursor;
386
+ this.#opts.cursors.markDelivered(result.events.at(-1).journalSeq);
387
+ const isOwn = this.#opts.isOwnOperation ?? (() => false);
388
+ const wakeRows = result.events.filter((row) => !(row.origin === 'leader' && row.causedBy !== null && isOwn(row.causedBy)));
389
+ if (wakeRows.length === 0)
390
+ return;
391
+ const state = this.#opts.readState(wakeRows.map((row) => row.subject));
392
+ try {
393
+ this.#opts.wake({
394
+ events: judge(wakeRows, state),
395
+ nextCursor: result.nextCursor,
396
+ hasMore: result.hasMore,
397
+ state,
398
+ journalEpoch: this.#opts.journal.epoch,
399
+ });
400
+ }
401
+ catch {
402
+ // The adapter's failure to start a turn is `reactedSeq` lagging, a reportable state — never
403
+ // a reason to undo a durable delivery or to retry on a timer.
404
+ }
405
+ }
406
+ }
407
+ /**
408
+ * The consumer's half of at-least-once delivery (D-05 § 6.6: "the leader deduplicates on
409
+ * `eventId`"). Deduplication is on the `eventId` alone, and within one project a gapless
410
+ * `journalSeq` is that identity's order: a row at or below the delivered position is a duplicate,
411
+ * a row ahead of a missing one is held until the gap fills, and the gap is reported. Start it at
412
+ * the acknowledged position; after a restart it may therefore release a row again — the reaction's
413
+ * `reactionOperationId` is what keeps that second look from becoming a second effect.
414
+ */
415
+ export class LeaderInbox {
416
+ projectId;
417
+ #deliveredSeq;
418
+ #held = new Map();
419
+ constructor(opts) {
420
+ this.projectId = mcpJournalProjectIdSchema.parse(opts.projectId);
421
+ this.#deliveredSeq = opts.afterSeq;
422
+ }
423
+ get deliveredSeq() {
424
+ return this.#deliveredSeq;
425
+ }
426
+ accept(rows) {
427
+ let duplicates = 0;
428
+ for (const row of rows) {
429
+ // Another project's row is not this leader's business (N-01); it is not even a duplicate.
430
+ if (row.projectId !== this.projectId || row.eventId !== `${this.projectId}:${row.journalSeq}`)
431
+ continue;
432
+ if (row.journalSeq <= this.#deliveredSeq || this.#held.has(row.journalSeq)) {
433
+ duplicates++;
434
+ continue;
435
+ }
436
+ this.#held.set(row.journalSeq, row);
437
+ }
438
+ const deliver = [];
439
+ for (let next = this.#held.get(this.#deliveredSeq + 1); next; next = this.#held.get(this.#deliveredSeq + 1)) {
440
+ this.#held.delete(next.journalSeq);
441
+ this.#deliveredSeq = next.journalSeq;
442
+ deliver.push(next);
443
+ }
444
+ let missing = null;
445
+ if (this.#held.size > 0) {
446
+ const firstHeld = Math.min(...this.#held.keys());
447
+ missing = { fromSeq: this.#deliveredSeq + 1, toSeq: firstHeld - 1 };
448
+ }
449
+ return { deliver, duplicates, missing };
450
+ }
451
+ }
452
+ /** A label that tells apart two different reactions to one event. */
453
+ const reactionLabelSchema = z.string().regex(/^[a-z0-9][a-z0-9-]{0,31}$/);
454
+ /**
455
+ * The operation id of the leader's reaction to one event (N-10, D-06 § 5.2). Deterministic, so a
456
+ * second delivery of the same row produces the same id and #101's receipt store answers it as a
457
+ * replay with no second effect. The journal epoch is part of it because `journalSeq` restarts at 1
458
+ * in a recreated journal: without it a genuinely new event would replay an old event's result.
459
+ * `label` separates different reactions to one event (`start-review`, `cancel`); deliberately new
460
+ * identical work takes a new id, as N-10 requires, and never this one.
461
+ */
462
+ export function reactionOperationId(journalEpoch, row, label) {
463
+ return operationIdSchema.parse(`react.${journalEpoch}.${row.journalSeq}.${reactionLabelSchema.parse(label)}`);
464
+ }
465
+ //# sourceMappingURL=reconnect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reconnect.js","sourceRoot":"","sources":["../../src/mcp/reconnect.ts"],"names":[],"mappings":"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"}