@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,518 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { closeSync, fstatSync, ftruncateSync, mkdirSync, openSync, readFileSync, readdirSync, rmdirSync, statSync, unlinkSync, writeSync } from 'node:fs';
3
+ import { hostname } from 'node:os';
4
+ import { join } from 'node:path';
5
+ import { z } from 'zod';
6
+ import { MCP_PROJECT_OCCUPIED_CODE, MCP_PROJECT_OCCUPIED_REASON, MCP_SESSION_EXPIRED_CODE, MCP_SESSION_EXPIRED_REASON, } from '../contract/index.js';
7
+ /**
8
+ * Exclusive per-project MCP ownership (#99), implementing decision D-02
9
+ * (`docs/features/mcp-server/mcp-d02-session-binding-decision.md`). Every number and rule below
10
+ * was fixed there, or adopted by D-09 as B-13 to B-15; none is a knob.
11
+ *
12
+ * One logical MCP session owns a project. The xezar SERVICE holds the owner record on that
13
+ * session's behalf (D-02.1), because the service is where every write is gated — a claim held by
14
+ * something that does not check it before a mutation is decoration. Cross-process exclusion of the
15
+ * service itself is already `ownProjectData`'s job (`runs/project-writer.ts`); this module decides
16
+ * which session INSIDE the owning service may write, and what a returning client is told.
17
+ *
18
+ * Mechanism, in the order a session meets it:
19
+ *
20
+ * - **Acquire** (D-02.2): publish a uniquely named claim with `openSync(path, 'wx', 0o600)`, THEN
21
+ * scan for peers. A live peer means "not the owner", always; dead or expired peers are reaped,
22
+ * which is safe only because the reaper has already published its own claim. Two simultaneous
23
+ * contenders may both refuse, never both succeed, so a refusal retries: 5 attempts, full-jitter
24
+ * backoff over a doubling window capped at 200 ms. Exhaustion answers *project-occupied*.
25
+ * NOT the `mergeWriteWorkspaceConfig` read-modify-write shape, and NOT the unlink-and-retry
26
+ * stale reclaim of `AutomationStore.acquireLease`: D-02 measured both admitting two owners.
27
+ * - **Fence** (D-02.3): acquisition MINTS a token, `<wall-clock ms>-<UUIDv4>`, and every mutation
28
+ * is checked for EQUALITY against the current live owner's token (`checkMutation`). Never
29
+ * derived from what is on disk — reaping deletes exactly what a `max + 1` counter would read, so
30
+ * a derived generation hands the next owner the number the previous owner still holds. The
31
+ * wall-clock prefix is for humans reading logs; nothing fences on it.
32
+ * - **Renew** (D-02.5): a background timer rewrites the claim every 5 s; the lease is 30 s. The
33
+ * timer consumes no model turn, so MODEL SILENCE IS NOT SESSION DEATH — an owner that says
34
+ * nothing for an hour is still the owner.
35
+ * - **Resumed owner** (D-02.5): a renewal that finds the lease already lapsed — a frozen process,
36
+ * a suspended laptop, a claim that vanished — must NOT renew. Renewing a lease that may already
37
+ * have been reclaimed is how two owners are made. It drops its claim and re-runs acquisition
38
+ * from scratch under a NEW token; if it loses, its session is expired.
39
+ * - **Release** (D-02.4, D-02.7): only on confirmed termination (`release`, fired by the transport
40
+ * when the bridge's connection closes — never by one request ending or one stream closing) or
41
+ * expiry. Releasing touches the claim file and this object's own memory, and NOTHING else: this
42
+ * module imports nothing that can reach a run, so a started task keeps running across every
43
+ * handover (N-05). The inverse holds too — a task ending or parking at `waiting` releases
44
+ * nothing.
45
+ *
46
+ * There is no manual disconnect and no forced takeover (F-18): nothing here lets one session evict
47
+ * another. `occupied` is left only by the real owner ending or expiring.
48
+ *
49
+ * ## Every state, and who fires each exit
50
+ *
51
+ * No exit below is a human action, so no state is a dead end.
52
+ *
53
+ * | State | Exit | Who fires it | If nobody fires it |
54
+ * | --- | --- | --- | --- |
55
+ * | unowned | → owned | a client's `initialize`, via `acquire` | stays unowned — the correct resting state; nothing is blocked |
56
+ * | acquiring | → owned / → occupied | the acquiring call itself | bounded: 5 attempts, ≤ 200 ms per backoff |
57
+ * | owned | → unowned | the transport, on connection close (`release`) | falls through to expiry |
58
+ * | owned | → expired | lease arithmetic at every read (`checkMutation`, `state`, the next `acquire`) | no timer is needed: expiry is derived, not stored |
59
+ * | owned, process frozen | → expired | nothing but the lease | the lease IS the exit — the reason it exists |
60
+ * | owner resumed after lost time | → owned (new token) / → expired | the owner's own renewal tick | mandatory, not best-effort: skipping it renews a lost lease |
61
+ * | expired | → unowned / → owned by another | the next `acquire`, which reaps the claim | nothing waits on an expired claim except a would-be owner, whose arrival is the trigger |
62
+ * | fenced session | → a fresh session | the bridge, automatically, on the session-expired error | not a dead end: reconnecting is the client's own protocol obligation |
63
+ * | occupied (a refused second client) | → owned by it, later | that client retrying | the real owner and the cockpit keep working |
64
+ *
65
+ * What reaches a terminal state BECAUSE of this lease: an MCP session (fenced or expired), and
66
+ * nothing else. No run, queue, worktree or executor does.
67
+ *
68
+ * ## Known limits, named rather than hidden
69
+ *
70
+ * - **The wall clock, on purpose.** Leases compare `Date.now()` values, because a monotonic clock
71
+ * stops while a laptop sleeps and would hide exactly the suspension the resumed-owner rule
72
+ * exists for. The cost: a clock set BACKWARDS makes a claim read as fresh until the clock
73
+ * catches up. A dead holder is still freed by the pid probe; only a frozen-but-alive holder
74
+ * waits longer.
75
+ * - **Check, then act.** The fence runs before a mutation starts. A mutation that passed it is not
76
+ * re-checked part-way through its own asynchronous work.
77
+ * - **The lease boundary between processes.** A peer that reads a claim a microsecond after its
78
+ * lease lapsed may reap it while the owner is mid-renewal. The owner detects an unlinked claim
79
+ * after writing (`nlink === 0`) and re-acquires; a reap landing after that check is caught on
80
+ * the next tick. Two services cannot both hold a project's data anyway (`ownProjectData`).
81
+ * - **A connected but wedged bridge** keeps ownership until its transport closes: D-02.4 leaves an
82
+ * application-level `ping` Open, and this module implements the three signals D-02 decided.
83
+ *
84
+ * ## Where the claim lives (D-02.8)
85
+ *
86
+ * `<dataDir>/mcp-owner-claims/<pid>-<uuid>.json`, `0600`, in the bound project's own `.local/xezar`
87
+ * — gitignored, per project, deletable at any moment (the next acquisition rebuilds it, and the
88
+ * minted token keeps a pre-deletion owner fenced). Not in `~/.xezar/config.json`: that file merges
89
+ * additively, and mutual exclusion is not additive. D-02 left the exact directory name open and
90
+ * D-04 did not claim it; `mcp-owner-claims` is the smallest name that says what it holds.
91
+ */
92
+ /** Renewal interval. D-02.5; D-09 B-13. */
93
+ export const OWNER_RENEW_INTERVAL_MS = 5_000;
94
+ /** Owner lease. D-02.5; D-09 B-14. */
95
+ export const OWNER_LEASE_MS = 30_000;
96
+ /** Acquisition attempts before answering project-occupied. D-02.2; D-09 B-15. */
97
+ export const OWNER_ACQUIRE_ATTEMPTS = 5;
98
+ /** Cap on the doubling full-jitter backoff window. D-02.2; D-09 B-15. */
99
+ export const OWNER_BACKOFF_CAP_MS = 200;
100
+ /**
101
+ * The window the doubling starts from. D-02 fixed the attempts and the cap but not the start;
102
+ * 25 ms doubles to the cap at the last retry (25, 50, 100, 200), so the whole budget waits at most
103
+ * 375 ms — inside the same order as the 98 ms worst case D-02 measured at eight contenders.
104
+ */
105
+ const OWNER_BACKOFF_BASE_MS = 25;
106
+ /** The claim directory's name inside the project's data directory. */
107
+ export const OWNER_CLAIM_DIR = 'mcp-owner-claims';
108
+ const CLAIM_NAME = /^([1-9]\d*)-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.json$/;
109
+ /** The on-disk claim — local runtime state, never an API shape, so it lives here. It holds no
110
+ * session key: the file identifies a holder process and a lease, not a client. */
111
+ const claimSchema = z.object({
112
+ v: z.literal(1),
113
+ token: z.string(),
114
+ pid: z.number().int().positive(),
115
+ host: z.string(),
116
+ acquiredAt: z.number(),
117
+ renewedAt: z.number(),
118
+ });
119
+ /** The project-occupied error. Carries the project's own id and nothing about the owner (N-01). */
120
+ export function projectOccupiedError(projectId) {
121
+ return {
122
+ code: MCP_PROJECT_OCCUPIED_CODE,
123
+ message: 'This project is occupied: it is already connected to another MCP client. It becomes available when that client disconnects or its session expires; try again then.',
124
+ data: { reason: MCP_PROJECT_OCCUPIED_REASON, projectId, retryable: true },
125
+ };
126
+ }
127
+ /** The session-expired error a fenced or expired owner receives on any later call. */
128
+ export function sessionExpiredError(projectId) {
129
+ return {
130
+ code: MCP_SESSION_EXPIRED_CODE,
131
+ message: 'This MCP session no longer owns the project. Reconnect to start a new session.',
132
+ data: { reason: MCP_SESSION_EXPIRED_REASON, projectId, retryable: true },
133
+ };
134
+ }
135
+ /** `process.kill(pid, 0)`: only `ESRCH` confirms death. `EPERM` is a live process we may not
136
+ * signal, and anything else is not proof of death either. */
137
+ function processAlive(pid) {
138
+ try {
139
+ process.kill(pid, 0);
140
+ return true;
141
+ }
142
+ catch (error) {
143
+ return error.code !== 'ESRCH';
144
+ }
145
+ }
146
+ function isNotFound(error) {
147
+ return error?.code === 'ENOENT';
148
+ }
149
+ function unlinkIfPresent(path) {
150
+ try {
151
+ unlinkSync(path);
152
+ }
153
+ catch (error) {
154
+ if (!isNotFound(error))
155
+ throw error;
156
+ }
157
+ }
158
+ /** One project's owner slot. The service keeps one per bound project. */
159
+ export class ProjectOwnership {
160
+ projectId;
161
+ dir;
162
+ now;
163
+ random;
164
+ sleep;
165
+ pid;
166
+ host;
167
+ isAlive;
168
+ autoRenew;
169
+ holding;
170
+ timer;
171
+ /** Serialises this object's acquisitions, so two sessions in one process never interleave an
172
+ * attempt. Cross-process exclusion is the claim file's job, not this chain's. */
173
+ tail = Promise.resolve();
174
+ pending = new Set();
175
+ warnedRenewal = false;
176
+ disposed = false;
177
+ constructor(options) {
178
+ this.projectId = options.projectId;
179
+ this.dir = join(options.dataDir, OWNER_CLAIM_DIR);
180
+ this.now = options.now ?? Date.now;
181
+ this.random = options.random ?? Math.random;
182
+ this.sleep = options.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
183
+ this.pid = options.pid ?? process.pid;
184
+ this.host = options.host ?? hostname();
185
+ this.isAlive = options.isAlive ?? processAlive;
186
+ this.autoRenew = options.autoRenew ?? true;
187
+ }
188
+ /**
189
+ * Make `sessionKey` the owner, or say why not. Idempotent for the owner: every request and
190
+ * stream of the SAME logical session gets the same token back, because they are not additional
191
+ * clients. A different session is refused with the project-occupied error.
192
+ */
193
+ acquire(sessionKey) {
194
+ // After `dispose` the service is going away: nothing may claim on its behalf any more.
195
+ const ticket = { sessionKey, closed: this.disposed };
196
+ this.pending.add(ticket);
197
+ const run = this.tail.then(() => this.acquireSerial(ticket));
198
+ this.tail = run.catch(() => undefined);
199
+ return run.finally(() => this.pending.delete(ticket));
200
+ }
201
+ /**
202
+ * The fence. Call it before EVERY mutation with the token the request was bound to; proceed
203
+ * only on `ok: true`. Equality with the current live owner's token, and nothing weaker: a stale
204
+ * token is refused even when its process is alive and even when its lease has not lapsed in its
205
+ * own memory.
206
+ */
207
+ checkMutation(token) {
208
+ const holding = this.liveHolding();
209
+ if (!holding || holding.token !== token)
210
+ return { ok: false, error: sessionExpiredError(this.projectId) };
211
+ return { ok: true };
212
+ }
213
+ /** The token a new request from `sessionKey` binds to, or `undefined` when that session does not
214
+ * own the project (never did, released, fenced or expired) — the transport answers
215
+ * session-expired then. */
216
+ sessionToken(sessionKey) {
217
+ const holding = this.liveHolding();
218
+ return holding?.sessionKey === sessionKey ? holding.token : undefined;
219
+ }
220
+ /**
221
+ * Confirmed termination of `sessionKey`: the transport observed its connection close. Frees the
222
+ * project at once. Touches the claim file and this object's memory only — never a run (N-05).
223
+ * Not to be called when one request completes or one stream closes; those are not session death.
224
+ */
225
+ release(sessionKey) {
226
+ for (const ticket of this.pending)
227
+ if (ticket.sessionKey === sessionKey)
228
+ ticket.closed = true;
229
+ if (this.holding?.sessionKey === sessionKey)
230
+ this.dropHolding();
231
+ }
232
+ /**
233
+ * Occupancy as the cockpit renders it, derived at read time by the same classifier acquisition
234
+ * uses — a dead owner's claim reads `expired` the moment it is true, never a stale `owned`.
235
+ * Reads only; reaping stays with the next acquirer, who has published its own claim first.
236
+ */
237
+ state() {
238
+ if (this.holding)
239
+ return this.liveHolding() ? 'owned' : 'expired';
240
+ let names;
241
+ try {
242
+ names = readdirSync(this.dir);
243
+ }
244
+ catch (error) {
245
+ if (isNotFound(error))
246
+ return 'unowned';
247
+ throw error;
248
+ }
249
+ let sawStale = false;
250
+ for (const name of names) {
251
+ const match = CLAIM_NAME.exec(name);
252
+ if (!match)
253
+ continue;
254
+ const pid = Number(match[1]);
255
+ // Our own process's only real ownership is `holding`; any other claim of ours is an
256
+ // acquisition in flight, which must not flicker the display to `owned`.
257
+ if (pid === this.pid)
258
+ continue;
259
+ const verdict = this.classify(join(this.dir, name), pid);
260
+ if (verdict === 'live')
261
+ return 'owned';
262
+ if (verdict === 'dead' || verdict === 'expired')
263
+ sawStale = true;
264
+ }
265
+ return sawStale ? 'expired' : 'unowned';
266
+ }
267
+ /**
268
+ * One renewal. The timer fires it every `OWNER_RENEW_INTERVAL_MS`; tests call it directly.
269
+ * The resumed-owner rule lives here: a lease that has already lapsed is NEVER renewed.
270
+ */
271
+ renewalTick() {
272
+ const holding = this.holding;
273
+ if (!holding) {
274
+ this.stopTimer();
275
+ return;
276
+ }
277
+ const at = this.now();
278
+ if (at - holding.renewedAt > OWNER_LEASE_MS) {
279
+ this.reacquire(holding.sessionKey);
280
+ return;
281
+ }
282
+ let descriptor;
283
+ try {
284
+ // `r+`, never a create: a claim that was reaped while we were away must not be resurrected
285
+ // beside the owner that reaped it.
286
+ descriptor = openSync(holding.claimPath, 'r+');
287
+ }
288
+ catch (error) {
289
+ if (isNotFound(error)) {
290
+ this.reacquire(holding.sessionKey);
291
+ return;
292
+ }
293
+ this.warnRenewal(error);
294
+ return;
295
+ }
296
+ let reaped = false;
297
+ try {
298
+ const bytes = Buffer.from(JSON.stringify(this.claimBody(holding.token, holding.acquiredAt, at)));
299
+ writeSync(descriptor, bytes, 0, bytes.length, 0);
300
+ ftruncateSync(descriptor, bytes.length);
301
+ // A peer may have unlinked the claim between our open and our write; the write then landed
302
+ // on an inode nobody can see, and extending our lease on it would be a lie.
303
+ reaped = fstatSync(descriptor).nlink === 0;
304
+ if (!reaped)
305
+ holding.renewedAt = at;
306
+ }
307
+ catch (error) {
308
+ // The on-disk lease was not extended, so neither is ours: we fence ourselves at the same
309
+ // moment a peer may reap us, instead of writing on a lease nobody else can see.
310
+ this.warnRenewal(error);
311
+ }
312
+ finally {
313
+ closeSync(descriptor);
314
+ }
315
+ if (reaped)
316
+ this.reacquire(holding.sessionKey);
317
+ }
318
+ /** Service shutdown: every session ends (D-02 § 5), and the claim goes with it. */
319
+ dispose() {
320
+ this.disposed = true;
321
+ for (const ticket of this.pending)
322
+ ticket.closed = true;
323
+ this.dropHolding();
324
+ }
325
+ async acquireSerial(ticket) {
326
+ for (let attempt = 0; attempt < OWNER_ACQUIRE_ATTEMPTS; attempt += 1) {
327
+ if (ticket.closed)
328
+ return { outcome: 'closed' };
329
+ const live = this.liveHolding();
330
+ if (live) {
331
+ if (live.sessionKey === ticket.sessionKey)
332
+ return { outcome: 'owner', token: live.token };
333
+ return { outcome: 'occupied', error: projectOccupiedError(this.projectId) };
334
+ }
335
+ // Whoever notices first ends an expired holding; its claim is ours to remove.
336
+ if (this.holding)
337
+ this.dropHolding();
338
+ const won = this.attemptOnce();
339
+ if (won) {
340
+ this.holding = { sessionKey: ticket.sessionKey, ...won };
341
+ this.startTimer();
342
+ return { outcome: 'owner', token: won.token };
343
+ }
344
+ if (attempt < OWNER_ACQUIRE_ATTEMPTS - 1) {
345
+ const window = Math.min(OWNER_BACKOFF_CAP_MS, OWNER_BACKOFF_BASE_MS * 2 ** attempt);
346
+ await this.sleep(this.random() * window);
347
+ }
348
+ }
349
+ return { outcome: 'occupied', error: projectOccupiedError(this.projectId) };
350
+ }
351
+ /** Publish, then scan. Synchronous from the create to the verdict, so nothing in this process
352
+ * can interleave with one attempt. */
353
+ attemptOnce() {
354
+ mkdirSync(this.dir, { recursive: true, mode: 0o700 });
355
+ const at = this.now();
356
+ const token = `${at}-${randomUUID()}`;
357
+ const claimPath = join(this.dir, `${this.pid}-${randomUUID()}.json`);
358
+ let published = false;
359
+ try {
360
+ const descriptor = openSync(claimPath, 'wx', 0o600);
361
+ published = true; // The exclusive create is the publication, even if the write below fails.
362
+ try {
363
+ writeSync(descriptor, JSON.stringify(this.claimBody(token, at, at)));
364
+ }
365
+ finally {
366
+ closeSync(descriptor);
367
+ }
368
+ for (const name of readdirSync(this.dir)) {
369
+ const path = join(this.dir, name);
370
+ if (path === claimPath)
371
+ continue;
372
+ const match = CLAIM_NAME.exec(name);
373
+ if (!match)
374
+ continue; // Every claim carries this name; anything else is not a claim.
375
+ const verdict = this.classify(path, Number(match[1]));
376
+ if (verdict === 'live') {
377
+ unlinkIfPresent(claimPath);
378
+ published = false;
379
+ return undefined;
380
+ }
381
+ // Safe to reap only because our own claim is already published: a contender arriving now
382
+ // sees us and stands down. Names are unique, so this can never remove a replacement's claim.
383
+ // The verdict is what admits us, not the unlink: a dead or expired claim we cannot remove
384
+ // (a read-only entry) blocks nobody, and every other contender reads the same verdict.
385
+ if (verdict === 'dead' || verdict === 'expired') {
386
+ try {
387
+ unlinkIfPresent(path);
388
+ }
389
+ catch {
390
+ /* Left for the next acquirer; it is not an owner either way. */
391
+ }
392
+ }
393
+ }
394
+ return { token, claimPath, acquiredAt: at, renewedAt: at };
395
+ }
396
+ catch (error) {
397
+ if (published) {
398
+ try {
399
+ unlinkSync(claimPath);
400
+ }
401
+ catch {
402
+ /* Never remove anything but our own claim. */
403
+ }
404
+ }
405
+ throw error;
406
+ }
407
+ }
408
+ /**
409
+ * The one classifier acquisition and `state` share. Fails closed: an unreadable or half-written
410
+ * claim is live until its pid is confirmed dead or its file outlives the lease.
411
+ */
412
+ classify(path, pid) {
413
+ let raw;
414
+ try {
415
+ raw = readFileSync(path, 'utf8');
416
+ }
417
+ catch (error) {
418
+ if (isNotFound(error))
419
+ return 'gone'; // A refused contender removed its own claim.
420
+ // Unreadable (EACCES, EISDIR, …): judged like a half-written claim, by pid and age, so one
421
+ // odd entry can neither block the project forever nor be mistaken for a free slot.
422
+ }
423
+ let claim;
424
+ try {
425
+ const parsed = raw === undefined ? undefined : claimSchema.safeParse(JSON.parse(raw));
426
+ if (parsed?.success)
427
+ claim = parsed.data;
428
+ }
429
+ catch {
430
+ /* A contender mid-write, or a torn renewal. Judged by pid and mtime below. */
431
+ }
432
+ // A pid is only meaningful on the host that issued it.
433
+ if ((!claim || claim.host === this.host) && !this.isAlive(pid))
434
+ return 'dead';
435
+ let renewedAt = claim?.renewedAt;
436
+ if (renewedAt === undefined) {
437
+ try {
438
+ renewedAt = statSync(path).mtimeMs;
439
+ }
440
+ catch (error) {
441
+ if (isNotFound(error))
442
+ return 'gone';
443
+ throw error;
444
+ }
445
+ }
446
+ return this.now() - renewedAt > OWNER_LEASE_MS ? 'expired' : 'live';
447
+ }
448
+ /** The holding, if its lease has not lapsed. Expiry is arithmetic, not an event: a frozen
449
+ * process that wakes up reads itself expired before any timer has had a chance to run. */
450
+ liveHolding() {
451
+ const holding = this.holding;
452
+ if (!holding || this.now() - holding.renewedAt > OWNER_LEASE_MS)
453
+ return undefined;
454
+ return holding;
455
+ }
456
+ /** Lost time or a lost claim: drop what we held and run acquisition from scratch. The old token
457
+ * is fenced whatever happens next, because a win mints a new one. */
458
+ reacquire(sessionKey) {
459
+ this.dropHolding();
460
+ void this.acquire(sessionKey).catch((error) => {
461
+ console.warn(`[xezar] MCP owner re-acquisition failed for project ${this.projectId}: ${String(error)}`);
462
+ });
463
+ }
464
+ dropHolding() {
465
+ const holding = this.holding;
466
+ this.holding = undefined;
467
+ this.stopTimer();
468
+ if (!holding)
469
+ return;
470
+ try {
471
+ unlinkIfPresent(holding.claimPath);
472
+ }
473
+ catch (error) {
474
+ // The claim outlives us on disk; its lease ages out and the next acquirer reaps it.
475
+ console.warn(`[xezar] could not remove MCP owner claim for project ${this.projectId}: ${String(error)}`);
476
+ return;
477
+ }
478
+ // A project nobody owns keeps no owner directory: an MCP session leaves no trace in the
479
+ // project's data once it ends. Only an EMPTY directory goes — `rmdir` refuses anything else, so
480
+ // a peer's claim is never touched — and the next acquisition recreates it (D-02.8).
481
+ try {
482
+ rmdirSync(this.dir);
483
+ }
484
+ catch {
485
+ /* Not empty, already gone, or not ours to remove: all fine. */
486
+ }
487
+ }
488
+ claimBody(token, acquiredAt, renewedAt) {
489
+ return { v: 1, token, pid: this.pid, host: this.host, acquiredAt, renewedAt };
490
+ }
491
+ startTimer() {
492
+ if (!this.autoRenew || this.timer)
493
+ return;
494
+ // A throw here would be an uncaught exception in the service. A failed tick leaves the lease
495
+ // un-renewed, which expires on its own: the fail-closed outcome.
496
+ this.timer = setInterval(() => {
497
+ try {
498
+ this.renewalTick();
499
+ }
500
+ catch (error) {
501
+ this.warnRenewal(error);
502
+ }
503
+ }, OWNER_RENEW_INTERVAL_MS);
504
+ this.timer.unref();
505
+ }
506
+ stopTimer() {
507
+ if (this.timer)
508
+ clearInterval(this.timer);
509
+ this.timer = undefined;
510
+ }
511
+ warnRenewal(error) {
512
+ if (this.warnedRenewal)
513
+ return;
514
+ this.warnedRenewal = true;
515
+ console.warn(`[xezar] MCP owner lease renewal failed for project ${this.projectId}: ${String(error)}`);
516
+ }
517
+ }
518
+ //# sourceMappingURL=project-owner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-owner.js","sourceRoot":"","sources":["../../src/workspace/project-owner.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qodeca/xezar",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "Local cockpit for running and tracking AI agent tasks in your repo. Uses your logged-in `claude` CLI and `gh` — zero config, zero database.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -50,8 +50,10 @@
50
50
  "zod": "^4.4.3"
51
51
  },
52
52
  "devDependencies": {
53
- "@qodeca/xezar-api-client": "^0.13.0",
54
- "@qodeca/xezar-contract": "^0.13.0",
53
+ "@qodeca/xezar-api-client": "^0.14.0",
54
+ "@qodeca/xezar-contract": "^0.14.0",
55
+ "@stryker-mutator/core": "^9.6.1",
56
+ "@stryker-mutator/vitest-runner": "^9.6.1",
55
57
  "@types/node": "^20.14.0",
56
58
  "@types/ws": "^8.18.1",
57
59
  "esbuild": "^0.28.1",