@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.
- package/README.md +72 -39
- package/dist/agent-config/account-identity.d.ts +2 -8
- package/dist/agent-config/account-identity.js +54 -10
- package/dist/agent-config/account-identity.js.map +1 -1
- package/dist/agent-config/catalog.d.ts +49 -7
- package/dist/agent-config/catalog.js +107 -0
- package/dist/agent-config/catalog.js.map +1 -1
- package/dist/agent-config/model-settings/pi.d.ts +12 -6
- package/dist/agent-config/model-settings/pi.js +12 -6
- package/dist/agent-config/model-settings/pi.js.map +1 -1
- package/dist/agent-config/seed.js +10 -0
- package/dist/agent-config/seed.js.map +1 -1
- package/dist/contract/github.d.ts +15 -0
- package/dist/contract/index.d.ts +9 -0
- package/dist/contract/index.js +1527 -895
- package/dist/contract/mcp-api-reference.d.ts +174 -0
- package/dist/contract/mcp-audit.d.ts +103 -0
- package/dist/contract/mcp-discovery.d.ts +257 -0
- package/dist/contract/mcp-event-catalog.d.ts +121 -0
- package/dist/contract/mcp-event-catalog.test.d.ts +1 -0
- package/dist/contract/mcp-idempotency.d.ts +200 -0
- package/dist/contract/mcp-journal.d.ts +268 -0
- package/dist/contract/mcp-leader.d.ts +88 -0
- package/dist/contract/mcp-ownership.d.ts +78 -0
- package/dist/contract/mcp-versioning.d.ts +139 -0
- package/dist/contract/runs.d.ts +81 -0
- package/dist/core/agent-profiles.d.ts +15 -4
- package/dist/core/agent-profiles.js +22 -8
- package/dist/core/agent-profiles.js.map +1 -1
- package/dist/core/opencode-server-runner.js +71 -11
- package/dist/core/opencode-server-runner.js.map +1 -1
- package/dist/core/secret-redaction.d.ts +7 -1
- package/dist/core/secret-redaction.js +44 -10
- package/dist/core/secret-redaction.js.map +1 -1
- package/dist/index.js +138 -27
- package/dist/index.js.map +1 -1
- package/dist/machine-identity.d.ts +66 -0
- package/dist/machine-identity.js +96 -0
- package/dist/machine-identity.js.map +1 -0
- package/dist/mcp/adapters/claude-code.d.ts +41 -0
- package/dist/mcp/adapters/claude-code.js +40 -0
- package/dist/mcp/adapters/claude-code.js.map +1 -0
- package/dist/mcp/adapters/codex.d.ts +140 -0
- package/dist/mcp/adapters/codex.js +323 -0
- package/dist/mcp/adapters/codex.js.map +1 -0
- package/dist/mcp/adapters/opencode.d.ts +148 -0
- package/dist/mcp/adapters/opencode.js +528 -0
- package/dist/mcp/adapters/opencode.js.map +1 -0
- package/dist/mcp/adapters/pi-link.d.ts +102 -0
- package/dist/mcp/adapters/pi-link.js +235 -0
- package/dist/mcp/adapters/pi-link.js.map +1 -0
- package/dist/mcp/adapters/pi.d.ts +188 -0
- package/dist/mcp/adapters/pi.js +418 -0
- package/dist/mcp/adapters/pi.js.map +1 -0
- package/dist/mcp/api-reference.d.ts +26 -0
- package/dist/mcp/api-reference.js +133 -0
- package/dist/mcp/api-reference.js.map +1 -0
- package/dist/mcp/audit-trail.d.ts +162 -0
- package/dist/mcp/audit-trail.js +306 -0
- package/dist/mcp/audit-trail.js.map +1 -0
- package/dist/mcp/bridge.d.ts +81 -0
- package/dist/mcp/bridge.js +407 -0
- package/dist/mcp/bridge.js.map +1 -0
- package/dist/mcp/connection-file.d.ts +49 -0
- package/dist/mcp/connection-file.js +63 -0
- package/dist/mcp/connection-file.js.map +1 -0
- package/dist/mcp/echo-guard.d.ts +94 -0
- package/dist/mcp/echo-guard.js +160 -0
- package/dist/mcp/echo-guard.js.map +1 -0
- package/dist/mcp/event-catalog.d.ts +120 -0
- package/dist/mcp/event-catalog.js +306 -0
- package/dist/mcp/event-catalog.js.map +1 -0
- package/dist/mcp/event-controller.d.ts +230 -0
- package/dist/mcp/event-controller.js +596 -0
- package/dist/mcp/event-controller.js.map +1 -0
- package/dist/mcp/event-journal.d.ts +57 -0
- package/dist/mcp/event-journal.js +423 -0
- package/dist/mcp/event-journal.js.map +1 -0
- package/dist/mcp/index.d.ts +63 -0
- package/dist/mcp/index.js +386 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/ipc.d.ts +202 -0
- package/dist/mcp/ipc.js +206 -0
- package/dist/mcp/ipc.js.map +1 -0
- package/dist/mcp/leader-delivery.d.ts +119 -0
- package/dist/mcp/leader-delivery.js +450 -0
- package/dist/mcp/leader-delivery.js.map +1 -0
- package/dist/mcp/operation-receipts.d.ts +210 -0
- package/dist/mcp/operation-receipts.js +723 -0
- package/dist/mcp/operation-receipts.js.map +1 -0
- package/dist/mcp/project-catalogs.d.ts +23 -0
- package/dist/mcp/project-catalogs.js +25 -0
- package/dist/mcp/project-catalogs.js.map +1 -0
- package/dist/mcp/project-leaders.d.ts +26 -0
- package/dist/mcp/project-leaders.js +17 -0
- package/dist/mcp/project-leaders.js.map +1 -0
- package/dist/mcp/protocol.d.ts +50 -0
- package/dist/mcp/protocol.js +47 -0
- package/dist/mcp/protocol.js.map +1 -0
- package/dist/mcp/reconnect.d.ts +297 -0
- package/dist/mcp/reconnect.js +465 -0
- package/dist/mcp/reconnect.js.map +1 -0
- package/dist/mcp/resource-ownership.d.ts +228 -0
- package/dist/mcp/resource-ownership.js +390 -0
- package/dist/mcp/resource-ownership.js.map +1 -0
- package/dist/mcp/service-adapter.d.ts +16488 -0
- package/dist/mcp/service-adapter.js +148 -0
- package/dist/mcp/service-adapter.js.map +1 -0
- package/dist/mcp/service.d.ts +83 -0
- package/dist/mcp/service.js +233 -0
- package/dist/mcp/service.js.map +1 -0
- package/dist/mcp/session-binding.d.ts +105 -0
- package/dist/mcp/session-binding.js +163 -0
- package/dist/mcp/session-binding.js.map +1 -0
- package/dist/mcp/stale-write.d.ts +145 -0
- package/dist/mcp/stale-write.js +219 -0
- package/dist/mcp/stale-write.js.map +1 -0
- package/dist/mcp/tool.d.ts +48 -0
- package/dist/mcp/tool.js +24 -0
- package/dist/mcp/tool.js.map +1 -0
- package/dist/mcp/tools/discovery.d.ts +40 -0
- package/dist/mcp/tools/discovery.js +232 -0
- package/dist/mcp/tools/discovery.js.map +1 -0
- package/dist/mcp/tools/execution-control.d.ts +171 -0
- package/dist/mcp/tools/execution-control.js +513 -0
- package/dist/mcp/tools/execution-control.js.map +1 -0
- package/dist/mcp/tools/handoff-git.d.ts +26 -0
- package/dist/mcp/tools/handoff-git.js +544 -0
- package/dist/mcp/tools/handoff-git.js.map +1 -0
- package/dist/mcp/tools/index.d.ts +2 -0
- package/dist/mcp/tools/index.js +23 -0
- package/dist/mcp/tools/index.js.map +1 -0
- package/dist/mcp/tools/leader-events.d.ts +46 -0
- package/dist/mcp/tools/leader-events.js +126 -0
- package/dist/mcp/tools/leader-events.js.map +1 -0
- package/dist/mcp/tools/local-handoff.d.ts +102 -0
- package/dist/mcp/tools/local-handoff.js +306 -0
- package/dist/mcp/tools/local-handoff.js.map +1 -0
- package/dist/mcp/tools/project-config.d.ts +340 -0
- package/dist/mcp/tools/project-config.js +1075 -0
- package/dist/mcp/tools/project-config.js.map +1 -0
- package/dist/mcp/tools/results-evidence.d.ts +112 -0
- package/dist/mcp/tools/results-evidence.js +1045 -0
- package/dist/mcp/tools/results-evidence.js.map +1 -0
- package/dist/mcp/tools/task-create.d.ts +70 -0
- package/dist/mcp/tools/task-create.js +473 -0
- package/dist/mcp/tools/task-create.js.map +1 -0
- package/dist/mcp/tools/task-reads.d.ts +102 -0
- package/dist/mcp/tools/task-reads.js +689 -0
- package/dist/mcp/tools/task-reads.js.map +1 -0
- package/dist/mcp/tools/work-organisation.d.ts +2 -0
- package/dist/mcp/tools/work-organisation.js +502 -0
- package/dist/mcp/tools/work-organisation.js.map +1 -0
- package/dist/paths.d.ts +17 -7
- package/dist/paths.js +18 -8
- package/dist/paths.js.map +1 -1
- package/dist/runs/project-writer.js +76 -11
- package/dist/runs/project-writer.js.map +1 -1
- package/dist/runs/retention.d.ts +25 -2
- package/dist/runs/retention.js +63 -2
- package/dist/runs/retention.js.map +1 -1
- package/dist/server/forge/github.js +44 -0
- package/dist/server/forge/github.js.map +1 -1
- package/dist/server/forge/types.d.ts +16 -0
- package/dist/server/project-context.d.ts +81 -8
- package/dist/server/project-context.js +143 -35
- package/dist/server/project-context.js.map +1 -1
- package/dist/server/server.d.ts +1050 -53
- package/dist/server/server.js +326 -120
- package/dist/server/server.js.map +1 -1
- package/dist/server/validators.d.ts +26 -6
- package/dist/server/validators.js +17 -0
- package/dist/server/validators.js.map +1 -1
- package/dist/skills-remote.js +64 -6
- package/dist/skills-remote.js.map +1 -1
- package/dist/workflows/run.d.ts +277 -12
- package/dist/workflows/run.js +599 -79
- package/dist/workflows/run.js.map +1 -1
- package/dist/workspace/agent-profiles.d.ts +30 -3
- package/dist/workspace/agent-profiles.js +39 -4
- package/dist/workspace/agent-profiles.js.map +1 -1
- package/dist/workspace/config.js +25 -4
- package/dist/workspace/config.js.map +1 -1
- package/dist/workspace/project-owner.d.ts +210 -0
- package/dist/workspace/project-owner.js +518 -0
- package/dist/workspace/project-owner.js.map +1 -0
- package/package.json +5 -3
- package/scripts/pi-leader-extension.ts +420 -0
- package/scripts/sync-readme.mjs +83 -2
- package/web/dist/assets/{alert-dialog-BVsVcbFy.js → alert-dialog-D6rP6d39.js} +1 -1
- package/web/dist/assets/arrow-down-DMOfFIzW.js +1 -0
- package/web/dist/assets/arrow-left-C4Ec2BUg.js +1 -0
- package/web/dist/assets/{centered-state-Djgly6Ni.js → centered-state-B0ZqrPaa.js} +12 -12
- package/web/dist/assets/chevron-right-mHJ-crvn.js +1 -0
- package/web/dist/assets/{collapsible-DZ4D-DHG.js → collapsible-DchEHgUM.js} +1 -1
- package/web/dist/assets/{commit-list-B-z1JL9G.js → commit-list-BpMim1Rv.js} +1 -1
- package/web/dist/assets/{compare-variants-CdS8r8E2.js → compare-variants-D5ItQbAq.js} +1 -1
- package/web/dist/assets/{diff-BKew9rQX.js → diff-HqqZ_WDR.js} +2 -2
- package/web/dist/assets/{diff-stat-D0mc5V6Z.js → diff-stat-NsU-3ecr.js} +1 -1
- package/web/dist/assets/{diff-view-xpIcuLIC.js → diff-view-B7c11Xux.js} +1 -1
- package/web/dist/assets/{dropdown-menu-CEQziH7X.js → dropdown-menu-CtTpnyod.js} +1 -1
- package/web/dist/assets/{editable-title-BCX3T2BY.js → editable-title-BXtuGQry.js} +1 -1
- package/web/dist/assets/{ellipsis-vertical-ByVdDc4z.js → ellipsis-vertical-MHtGZSH6.js} +1 -1
- package/web/dist/assets/{file-xBSB5hXO.js → file-DKLw5SOb.js} +1 -1
- package/web/dist/assets/{folder-CldgbZ5A.js → folder-Drw6-ufH.js} +1 -1
- package/web/dist/assets/{git-toolbar-BYlnf4qf.js → git-toolbar-BQH8bORV.js} +1 -1
- package/web/dist/assets/github-ynnpKFCJ.js +1 -0
- package/web/dist/assets/{image-preview-Cv5mZr0n.js → image-preview-DLhMN_R9.js} +1 -1
- package/web/dist/assets/index-BEsrNdXt.js +29 -0
- package/web/dist/assets/index-Da8DOBau.css +2 -0
- package/web/dist/assets/{markdown-CgEEE2ND.js → markdown-q365eN6Y.js} +1 -1
- package/web/dist/assets/{new-task-form-1r2bgsdD.js → new-task-form-CW-hNIWQ.js} +1 -1
- package/web/dist/assets/{pill-q-x22_ej.js → pill-B_TFulXa.js} +1 -1
- package/web/dist/assets/{project-router-VDN4jQM8.js → project-router-CLPc-ImZ.js} +1 -1
- package/web/dist/assets/{prompt-templates-BmZtCe-L.js → prompt-templates-CLc4RxyO.js} +1 -1
- package/web/dist/assets/{repo-git-C2On8SlI.js → repo-git-Is7R6-Tj.js} +1 -1
- package/web/dist/assets/{run-diff-vguEMJzh.js → run-diff-DHMvDlVo.js} +2 -2
- package/web/dist/assets/run-header-DvZJbQ8I.js +1 -0
- package/web/dist/assets/{search-x-QmhaAbg5.js → search-x-Ce2MMetu.js} +1 -1
- package/web/dist/assets/{skill-empty-hint-BrzUwByZ.js → skill-empty-hint-C_xCSvzB.js} +1 -1
- package/web/dist/assets/skills-CivqD4si.js +1 -0
- package/web/dist/assets/{sparkles-CP8QDOgX.js → sparkles-BCqPoj5g.js} +1 -1
- package/web/dist/assets/{square-terminal-CGypshSD.js → square-terminal-ikj5g-oK.js} +1 -1
- package/web/dist/assets/{tab-link-D4lFzzI1.js → tab-link-VsEjFV1Y.js} +1 -1
- package/web/dist/assets/{task-changes-6aopqAmV.js → task-changes-CH-E81-_.js} +1 -1
- package/web/dist/assets/{task-commits-u-dwaCyw.js → task-commits-DqfkMFxp.js} +1 -1
- package/web/dist/assets/{task-files-IMOZnIUK.js → task-files-D_nkHZ_a.js} +2 -2
- package/web/dist/assets/task-thread-bxQompxJ.js +9 -0
- package/web/dist/assets/{textarea-CyBCyKIk.js → textarea-xajuW1L_.js} +1 -1
- package/web/dist/assets/{thread-loading-Cuq2jchC.js → thread-loading-C3JQZbIE.js} +1 -1
- package/web/dist/assets/{trash-2-B6Dp3ZNs.js → trash-2-hJrBhpUD.js} +1 -1
- package/web/dist/assets/{triangle-alert-xBya8FUp.js → triangle-alert-D1u82y1a.js} +1 -1
- package/web/dist/assets/{upload-D6MXEB9p.js → upload-Bn6FBZ59.js} +1 -1
- package/web/dist/assets/{use-desktop-fLDKEJoB.js → use-desktop-DOIMfHfY.js} +1 -1
- package/web/dist/assets/{use-submit-shortcut-JTpNzU-u.js → use-submit-shortcut-Dj4DHTdE.js} +1 -1
- package/web/dist/assets/utils-YwBpOoRN.js +64 -0
- package/web/dist/assets/{workflows-BY3KTkFw.js → workflows-CTaAKz2m.js} +3 -3
- package/web/dist/assets/{zoomable-image-GTYwLtkS.js → zoomable-image-C1-6P3tg.js} +1 -1
- package/web/dist/index.html +23 -23
- package/web/dist/assets/arrow-down-CYgAlZtW.js +0 -1
- package/web/dist/assets/arrow-left-BOqE0a3k.js +0 -1
- package/web/dist/assets/chevron-right-Cc9BWnbN.js +0 -1
- package/web/dist/assets/github-CqGK62Lw.js +0 -1
- package/web/dist/assets/index-3nxVmdn5.css +0 -2
- package/web/dist/assets/index-qX7n11FX.js +0 -9
- package/web/dist/assets/refresh-cw-DcNCj2nu.js +0 -1
- package/web/dist/assets/run-header-DM7MiKj9.js +0 -1
- package/web/dist/assets/skills-Bj-uG_Hz.js +0 -1
- package/web/dist/assets/task-thread-CbMPmrWq.js +0 -9
- package/web/dist/assets/utils--z9hRtl3.js +0 -64
|
@@ -0,0 +1,450 @@
|
|
|
1
|
+
import { projectDataDir } from '../project-data-paths.js';
|
|
2
|
+
import { OpenCodeReactionAdapter } from './adapters/opencode.js';
|
|
3
|
+
import { connectPiLeaderLink, readPiLeaderDescriptor } from './adapters/pi-link.js';
|
|
4
|
+
import { piReactionTarget } from './adapters/pi.js';
|
|
5
|
+
import { EventController } from './event-controller.js';
|
|
6
|
+
/**
|
|
7
|
+
* Push delivery, connected (#309, Phase 6 of #73). Until this module, `EventController` (#107) and
|
|
8
|
+
* the reaction adapters (#108–#110) were complete, tested — and constructed by nothing outside their
|
|
9
|
+
* own tests, so no event ever reached a client. This is the one place the running service builds
|
|
10
|
+
* the controller, composed once per project by `startMcpService`.
|
|
11
|
+
*
|
|
12
|
+
* WHAT IS ON BY DEFAULT. Every MCP session that becomes the project's owner (`session/open`,
|
|
13
|
+
* D-02.2) gets an event controller at once, with this object as its adapter; the controller ends
|
|
14
|
+
* when that session's connection closes (D-02.4). No flag, no setting: an owner session always has
|
|
15
|
+
* a dispatcher following the journal for it.
|
|
16
|
+
*
|
|
17
|
+
* WHO IT CAN REACH, AND WHY ONLY THEM. A dispatch must reach a MODEL, and generic MCP notifications
|
|
18
|
+
* start no turn in Claude Code, Codex, OpenCode or pi (D-05 § 4; #330 run A for pi; each adapter's
|
|
19
|
+
* evidence record). xezar NEVER starts an agent process for a leader (owner decision on #311): the
|
|
20
|
+
* person runs their own leader and connects it to xezar over MCP. So an event reaches a model only
|
|
21
|
+
* through a session the person runs AND tells xezar where to find — `attach`. Two clients can be
|
|
22
|
+
* told today:
|
|
23
|
+
*
|
|
24
|
+
* - **OpenCode** names an `opencode serve` session by URL and session id (#110).
|
|
25
|
+
* - **pi** names nothing, because it cannot: pi's RPC is stdio-only and spawn-only, so a pi the
|
|
26
|
+
* person started has no address. The address therefore comes from INSIDE it — xezar's pi leader
|
|
27
|
+
* extension opens a socket and announces it in the project's data directory, and `#piTarget()`
|
|
28
|
+
* dials that (#330 WP2, `adapters/pi-link.ts`). With no extension running there is no descriptor
|
|
29
|
+
* and the attach is refused with pi's own recoverable reason, which is exactly the behaviour that
|
|
30
|
+
* existed before the extension did.
|
|
31
|
+
*
|
|
32
|
+
* A Claude Code or Codex session in a terminal still has no address at all: for it the controller
|
|
33
|
+
* keeps the rows in the journal, reports `disconnected`, retries at its heartbeat, and
|
|
34
|
+
* `status().blocker` says so. Nothing is lost either way — such a leader reads its events with the
|
|
35
|
+
* `leader_events` tool (#251), and the next session resumes after its last acknowledgement.
|
|
36
|
+
*
|
|
37
|
+
* THE ECHO GUARD HOLDS HERE, FOR EVERY CLIENT. The door records each mutation's operation id as the
|
|
38
|
+
* leader's own before it runs (`EchoGuard.issue`, #106), including the ids it mints for tools that
|
|
39
|
+
* carry no `operationId`. A `leader` row caused by one of them is dropped before the adapter sees it,
|
|
40
|
+
* so a client's own guard — which knows only the ids it saw — cannot miss a door-minted one. Only the
|
|
41
|
+
* echo rule: the guard's `duplicate` rule must NOT be applied, because redelivery after a reconnect
|
|
42
|
+
* is at-least-once by contract.
|
|
43
|
+
*
|
|
44
|
+
* ## Every state this relies on, and who fires each exit
|
|
45
|
+
*
|
|
46
|
+
* Controller states (`EventControllerState`), as wired here:
|
|
47
|
+
*
|
|
48
|
+
* | State | Exit | Who fires it (on by default) |
|
|
49
|
+
* | --- | --- | --- |
|
|
50
|
+
* | inert | — | never entered: this object is always the adapter |
|
|
51
|
+
* | idle | → dispatching | a journal append, or the 30 s heartbeat tick |
|
|
52
|
+
* | dispatching | → idle / → recovering | `deliver` resolving / rejecting or timing out (one heartbeat) |
|
|
53
|
+
* | recovering | → idle / → disconnected | the bounded round itself (5 attempts) |
|
|
54
|
+
* | disconnected | → dispatching | the heartbeat tick, every 30 s; or `wake()`, which `attach` fires at once |
|
|
55
|
+
* | any | → ended | the session's connection closing (`sessionClosed`), another session taking the project (`sessionOpened`), the lease lapsing (found at the next tick), or the service closing |
|
|
56
|
+
*
|
|
57
|
+
* `disconnected` with nothing attached is the one state that waits on something outside xezar, and
|
|
58
|
+
* it does not wait on a human alone: the heartbeat retries it for as long as the session owns the
|
|
59
|
+
* project, at no model cost (N-06). It is the recoverable blocker the requirements ask for.
|
|
60
|
+
*
|
|
61
|
+
* Leader states: none → attached (`act` attach); attached → none (`act` stop, or the service
|
|
62
|
+
* closing). An attached OpenCode session that goes away is the adapter's own recoverable blocker,
|
|
63
|
+
* reported by `status()`; the controller retries it at the heartbeat. A pi leader that goes away
|
|
64
|
+
* takes its socket with it, which closes the link and reports the same way.
|
|
65
|
+
*
|
|
66
|
+
* What xezar OPENS to reach a leader is released on every one of those exits: `#detach` closes the
|
|
67
|
+
* adapter and then its `dispose` (pi's socket today), and `close()` goes through `#detach`.
|
|
68
|
+
*
|
|
69
|
+
* What reaches a terminal state BECAUSE of this module: its controllers. No process, run, lease,
|
|
70
|
+
* queue slot or worktree — it starts nothing and stops nothing but its own objects.
|
|
71
|
+
*/
|
|
72
|
+
/** xezar's base role, sent with every event to an attached leader. Per-project customisation is not built yet. */
|
|
73
|
+
export const LEADER_ROLE_INSTRUCTION = [
|
|
74
|
+
'You are the project leader for this xezar project.',
|
|
75
|
+
'You plan and coordinate the work through the xezar MCP tools: start tasks, read their results, answer their questions and hand finished work off.',
|
|
76
|
+
'You do not edit files yourself; tasks do the work in their own worktrees.',
|
|
77
|
+
].join('\n');
|
|
78
|
+
const NO_LEADER = {
|
|
79
|
+
code: 'no-leader-session',
|
|
80
|
+
message: 'No leader session is attached to this project, so events are kept in the journal, not pushed. A Claude Code, Codex or pi session in a terminal has no address xezar can attach to, and MCP notifications start no turn — that leader reads its events with the leader_events tool.',
|
|
81
|
+
fix: 'Keep using leader_events from your own leader, or attach the OpenCode session you run with `opencode serve`.',
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Every blocker about an ATTACHED leader is written in that leader's client's own words.
|
|
85
|
+
*
|
|
86
|
+
* It used to be written in OpenCode's, for all of them, so a pi user who hit one was told to check
|
|
87
|
+
* an `opencode serve` they are not running (QA on #358, finding 3) — at the exact moment they needed
|
|
88
|
+
* the right thing to check. The two clients are reached in completely different ways: OpenCode's
|
|
89
|
+
* leader is an HTTP server the person runs, pi's is a Unix socket xezar's leader extension opens
|
|
90
|
+
* from INSIDE the person's own pi, so "check the server" has no shared spelling.
|
|
91
|
+
*
|
|
92
|
+
* Only these two can be attached at all (`mcpLeaderAttachInputSchema` in the contract). A Claude Code
|
|
93
|
+
* or Codex leader has no address to attach, which is `NO_LEADER`'s case above and names all four
|
|
94
|
+
* clients itself. Typed `Record<McpLeaderSession['client'], …>` on purpose: a third attachable client
|
|
95
|
+
* is then a compile error here, rather than a message that quietly names the wrong server again.
|
|
96
|
+
*/
|
|
97
|
+
const CLIENT_WORDS = {
|
|
98
|
+
opencode: {
|
|
99
|
+
name: 'OpenCode',
|
|
100
|
+
lazyMcp: ' OpenCode connects its xezar MCP server only when it first needs it.',
|
|
101
|
+
check: 'check that `opencode serve` is running and answering (a paused process still accepts connections)',
|
|
102
|
+
checkShort: 'check that `opencode serve` is running and answering',
|
|
103
|
+
reattach: 'attach the session again',
|
|
104
|
+
},
|
|
105
|
+
pi: {
|
|
106
|
+
// Nothing is claimed about WHEN pi opens its MCP connection, because nothing here measured it;
|
|
107
|
+
// the fix below works whenever it does.
|
|
108
|
+
name: 'pi',
|
|
109
|
+
lazyMcp: '',
|
|
110
|
+
check: 'check that the pi you attached is still running with xezar’s leader extension loaded (a paused process still holds its socket open)',
|
|
111
|
+
checkShort: 'check that the pi you attached is still running with xezar’s leader extension loaded',
|
|
112
|
+
reattach: 'attach it again',
|
|
113
|
+
},
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* #331: a leader is attached, but no MCP session owns the project, so no controller follows the
|
|
117
|
+
* journal and nothing is delivered. The ORDINARY first state: OpenCode connects its MCP servers
|
|
118
|
+
* lazily, so "attach first, MCP session later" is what a first user sees.
|
|
119
|
+
*/
|
|
120
|
+
const noOwnerSession = (client) => {
|
|
121
|
+
const words = CLIENT_WORDS[client];
|
|
122
|
+
return {
|
|
123
|
+
code: 'no-owner-session',
|
|
124
|
+
message: `A ${words.name} leader is attached, but no MCP session owns this project yet, so nothing follows the event journal and nothing is delivered.${words.lazyMcp} Events are kept in the journal meanwhile.`,
|
|
125
|
+
fix: `Let the attached ${words.name} session call a xezar tool once (for example leader_events), so its MCP connection opens; it then receives every event it has not acknowledged.`,
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
/**
|
|
129
|
+
* Events are waiting and the last attempt to hand them to THIS leader did not get through — a
|
|
130
|
+
* refused request, a dropped connection, a server that accepts and never answers, or a leader busy
|
|
131
|
+
* in a long turn. xezar cannot tell those apart (the adapter waits for the session to be free, and a
|
|
132
|
+
* long turn looks exactly like silence), so the text names both and diagnoses neither (QA on #311,
|
|
133
|
+
* round five). The fact behind it is recorded against the LEADER, so it survives a session change and
|
|
134
|
+
* is never inherited by a leader that has just been attached.
|
|
135
|
+
*/
|
|
136
|
+
const deliveryFailing = (client) => {
|
|
137
|
+
const words = CLIENT_WORDS[client];
|
|
138
|
+
return {
|
|
139
|
+
code: 'delivery-failing',
|
|
140
|
+
message: `Events are waiting, and the last attempt to hand them to the attached ${words.name} leader did not get through. It may be busy in a long turn, or it may have stopped answering — xezar cannot tell those apart, and keeps retrying while this MCP session owns the project. Nothing is lost: the events stay in the journal.`,
|
|
141
|
+
fix: `If the leader is working, nothing is needed: the events go as soon as it is free. Otherwise ${words.check}, or ${words.reattach}.`,
|
|
142
|
+
};
|
|
143
|
+
};
|
|
144
|
+
/** The same fact with nothing waiting: the leader did not answer xezar’s last liveness check. */
|
|
145
|
+
const leaderNotAnswering = (client) => {
|
|
146
|
+
const words = CLIENT_WORDS[client];
|
|
147
|
+
return {
|
|
148
|
+
code: 'leader-not-answering',
|
|
149
|
+
message: `The attached ${words.name} leader did not answer xezar’s last liveness check — it may be busy, or gone. Nothing is waiting right now; the next event would be retried until it answers.`,
|
|
150
|
+
fix: `If the leader is working, nothing is needed. Otherwise ${words.checkShort}, or ${words.reattach}.`,
|
|
151
|
+
};
|
|
152
|
+
};
|
|
153
|
+
/** #309 O-3: a journal that records nothing has nothing to deliver, so a leader would never hear a thing. */
|
|
154
|
+
const JOURNAL_UNWRITABLE = {
|
|
155
|
+
code: 'journal-unwritable',
|
|
156
|
+
message: 'xezar cannot write this project’s event journal, so no event is recorded and none can be delivered. The cockpit log names the file and the error.',
|
|
157
|
+
fix: 'Make the project’s .local/xezar/mcp folder writable, then restart xezar.',
|
|
158
|
+
};
|
|
159
|
+
export class LeaderDelivery {
|
|
160
|
+
projectId;
|
|
161
|
+
#opts;
|
|
162
|
+
/** Keyed by the transport's session key. At most one is live: the project has one owner. */
|
|
163
|
+
#controllers = new Map();
|
|
164
|
+
/** The attached OpenCode session and the facts observed against it. xezar never started it. */
|
|
165
|
+
#leader;
|
|
166
|
+
/** One `act` at a time: two concurrent attaches must not leave two adapters behind. */
|
|
167
|
+
#acting = Promise.resolve();
|
|
168
|
+
#closed = false;
|
|
169
|
+
constructor(opts) {
|
|
170
|
+
this.projectId = opts.projectId;
|
|
171
|
+
this.#opts = opts;
|
|
172
|
+
}
|
|
173
|
+
// ---- the transport's side: one controller per owner session ------------------------------
|
|
174
|
+
/** `session/open` made `sessionKey` the owner. Never throws into the transport (N-07). */
|
|
175
|
+
sessionOpened(sessionKey) {
|
|
176
|
+
if (this.#closed || this.#controllers.has(sessionKey))
|
|
177
|
+
return;
|
|
178
|
+
// Only one session owns the project, so any other controller serves a session that lost it —
|
|
179
|
+
// one whose lease lapsed while its connection stayed open. End it now rather than at its next
|
|
180
|
+
// tick: the journal allows one dispatcher, and it must be the owner's.
|
|
181
|
+
for (const [key, controller] of this.#controllers) {
|
|
182
|
+
controller.close();
|
|
183
|
+
this.#controllers.delete(key);
|
|
184
|
+
}
|
|
185
|
+
const started = EventController.start({
|
|
186
|
+
journal: this.#opts.journal,
|
|
187
|
+
ownership: this.#opts.ownership,
|
|
188
|
+
sessionKey,
|
|
189
|
+
adapter: this,
|
|
190
|
+
warn: this.#opts.warn,
|
|
191
|
+
...(this.#opts.leaderRecord === undefined ? {} : { leaderRecord: this.#opts.leaderRecord }),
|
|
192
|
+
...(this.#opts.heartbeatMs === undefined ? {} : { heartbeatMs: this.#opts.heartbeatMs }),
|
|
193
|
+
});
|
|
194
|
+
if (started.outcome === 'started')
|
|
195
|
+
this.#controllers.set(sessionKey, started.controller);
|
|
196
|
+
else if (started.outcome === 'refused')
|
|
197
|
+
this.#opts.warn(`[xez] MCP event delivery not started for project ${this.projectId}: ${started.error.message}`);
|
|
198
|
+
}
|
|
199
|
+
/** The session's connection closed (D-02.4): its controller ends. The journal keeps every row. */
|
|
200
|
+
sessionClosed(sessionKey) {
|
|
201
|
+
this.#controllers.get(sessionKey)?.close();
|
|
202
|
+
this.#controllers.delete(sessionKey);
|
|
203
|
+
}
|
|
204
|
+
// ---- the controller's side: `ReactionAdapter` ----------------------------------------------
|
|
205
|
+
async deliver(dispatch, signal) {
|
|
206
|
+
const leader = this.#leader;
|
|
207
|
+
if (leader === undefined)
|
|
208
|
+
throw new Error(NO_LEADER.message);
|
|
209
|
+
const events = dispatch.events.filter((row) => !this.#isEcho(row));
|
|
210
|
+
const last = dispatch.events.at(-1)?.journalSeq;
|
|
211
|
+
// Only the leader's own echoes: nothing to tell it, so nothing is handed over — and the receipt
|
|
212
|
+
// says so, so deliveredSeq never counts a row the leader was not sent (QA on #311). It is still
|
|
213
|
+
// settled, so nothing is waiting for it.
|
|
214
|
+
if (events.length === 0 && dispatch.recovery === undefined) {
|
|
215
|
+
if (last !== undefined)
|
|
216
|
+
leader.settledThrough = Math.max(leader.settledThrough, last);
|
|
217
|
+
return { handedThrough: null };
|
|
218
|
+
}
|
|
219
|
+
await this.#observed(leader, signal, () => leader.adapter.deliver({ ...dispatch, events }, signal));
|
|
220
|
+
if (last !== undefined)
|
|
221
|
+
leader.settledThrough = Math.max(leader.settledThrough, last);
|
|
222
|
+
return { handedThrough: events.at(-1)?.journalSeq ?? null };
|
|
223
|
+
}
|
|
224
|
+
async heartbeat(signal) {
|
|
225
|
+
const leader = this.#leader;
|
|
226
|
+
if (leader === undefined)
|
|
227
|
+
throw new Error(NO_LEADER.message);
|
|
228
|
+
await this.#observed(leader, signal, () => leader.adapter.heartbeat(signal));
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Run one attempt against `leader` and record how it went, AGAINST THAT LEADER: the first failure
|
|
232
|
+
* with none succeeding since, cleared by the next success. An attempt the caller abandons (its
|
|
233
|
+
* signal aborts — a server that accepts and never answers) counts as a failure, and a late success
|
|
234
|
+
* after that abort does not clear it.
|
|
235
|
+
*/
|
|
236
|
+
async #observed(leader, signal, call) {
|
|
237
|
+
let abandoned = signal.aborted;
|
|
238
|
+
const onAbort = () => {
|
|
239
|
+
abandoned = true;
|
|
240
|
+
leader.failingSince ??= Date.now();
|
|
241
|
+
};
|
|
242
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
243
|
+
try {
|
|
244
|
+
const value = await call();
|
|
245
|
+
if (!abandoned)
|
|
246
|
+
leader.failingSince = null;
|
|
247
|
+
return value;
|
|
248
|
+
}
|
|
249
|
+
catch (err) {
|
|
250
|
+
leader.failingSince ??= Date.now();
|
|
251
|
+
throw err;
|
|
252
|
+
}
|
|
253
|
+
finally {
|
|
254
|
+
signal.removeEventListener('abort', onAbort);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
/** Is a row waiting for the attached leader? Its own settled position, and what the leader acknowledged. */
|
|
258
|
+
#owed(leader) {
|
|
259
|
+
const owedAfter = this.#opts.leaderRecord?.owedAfter();
|
|
260
|
+
const acknowledged = owedAfter?.sameEpoch === true ? owedAfter.seq : 0;
|
|
261
|
+
return this.#opts.journal.latestSeq > Math.max(leader.settledThrough, acknowledged);
|
|
262
|
+
}
|
|
263
|
+
// ---- the cockpit's side: `ProjectLeaderPort` -----------------------------------------------
|
|
264
|
+
status() {
|
|
265
|
+
const controller = this.#liveController();
|
|
266
|
+
return {
|
|
267
|
+
available: true,
|
|
268
|
+
leader: this.#leaderSession(),
|
|
269
|
+
delivery: controller ? controller.status() : null,
|
|
270
|
+
blocker: this.#blocker(),
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
act(input) {
|
|
274
|
+
const next = this.#acting.then(() => this.#act(input));
|
|
275
|
+
this.#acting = next.catch(() => undefined);
|
|
276
|
+
return next;
|
|
277
|
+
}
|
|
278
|
+
/** The service is stopping: every controller ends and the attached session is let go. */
|
|
279
|
+
close() {
|
|
280
|
+
if (this.#closed)
|
|
281
|
+
return;
|
|
282
|
+
this.#closed = true;
|
|
283
|
+
for (const controller of this.#controllers.values())
|
|
284
|
+
controller.close();
|
|
285
|
+
this.#controllers.clear();
|
|
286
|
+
this.#detach();
|
|
287
|
+
}
|
|
288
|
+
// ---- internals ----------------------------------------------------------------------------
|
|
289
|
+
async #act(input) {
|
|
290
|
+
if (this.#closed)
|
|
291
|
+
return { ok: false, error: 'the MCP service for this project is stopping' };
|
|
292
|
+
if (input.action === 'stop') {
|
|
293
|
+
this.#detach();
|
|
294
|
+
return { ok: true, status: this.status() };
|
|
295
|
+
}
|
|
296
|
+
// Attaching a leader that can never receive an event would answer 200 with a blocker-free status
|
|
297
|
+
// for a path that delivers nothing (#309 O-3). Refuse, and say why.
|
|
298
|
+
if (!this.#opts.journal.writable)
|
|
299
|
+
return { ok: false, error: JOURNAL_UNWRITABLE.message };
|
|
300
|
+
if (input.client === 'pi') {
|
|
301
|
+
// pi's adapter (#330 WP2) is built the same way the OpenCode one is, and from the same kind of
|
|
302
|
+
// thing: an address the person's own leader offers. pi's RPC is stdio-only, so that address
|
|
303
|
+
// cannot be pi itself — it is the socket xezar's pi leader extension opens from INSIDE the
|
|
304
|
+
// person's pi and announces in this project's data directory (`adapters/pi-link.ts`). No
|
|
305
|
+
// extension running, no descriptor, no link: `piReactionTarget` answers with its own
|
|
306
|
+
// recoverable reason and the events stay in the journal, exactly as before this existed. The
|
|
307
|
+
// previous leader is kept either way — a refused attach must not detach one that is working.
|
|
308
|
+
const { target, dispose } = this.#piTarget();
|
|
309
|
+
if (target.kind === 'blocked') {
|
|
310
|
+
dispose?.();
|
|
311
|
+
return { ok: false, error: target.blocker.message };
|
|
312
|
+
}
|
|
313
|
+
this.#detach();
|
|
314
|
+
this.#leader = {
|
|
315
|
+
client: 'pi',
|
|
316
|
+
adapter: target.adapter,
|
|
317
|
+
failingSince: null,
|
|
318
|
+
settledThrough: 0,
|
|
319
|
+
...(dispose ? { dispose } : {}),
|
|
320
|
+
};
|
|
321
|
+
this.#liveController()?.wake();
|
|
322
|
+
return { ok: true, status: this.status() };
|
|
323
|
+
}
|
|
324
|
+
// Re-attaching replaces the previous target; xezar owns no process, so nothing else changes.
|
|
325
|
+
this.#detach();
|
|
326
|
+
// A new leader with no history: whatever happened before it was attached was not about it.
|
|
327
|
+
this.#leader = {
|
|
328
|
+
client: 'opencode',
|
|
329
|
+
adapter: new OpenCodeReactionAdapter({
|
|
330
|
+
target: { baseUrl: input.baseUrl, sessionId: input.sessionId },
|
|
331
|
+
projectRoot: this.#opts.projectRoot,
|
|
332
|
+
roleInstruction: LEADER_ROLE_INSTRUCTION,
|
|
333
|
+
onReaction: (seq) => this.#recordReaction(seq),
|
|
334
|
+
...this.#ownOperation(),
|
|
335
|
+
}),
|
|
336
|
+
failingSince: null,
|
|
337
|
+
settledThrough: 0,
|
|
338
|
+
};
|
|
339
|
+
// Deliver now, not at the next heartbeat.
|
|
340
|
+
this.#liveController()?.wake();
|
|
341
|
+
return { ok: true, status: this.status() };
|
|
342
|
+
}
|
|
343
|
+
/** Stop talking to the attached session. The OpenCode process and session are the person's. */
|
|
344
|
+
#detach() {
|
|
345
|
+
const leaving = this.#leader;
|
|
346
|
+
this.#leader = undefined;
|
|
347
|
+
leaving?.adapter.close();
|
|
348
|
+
// The transport last, and never skipped when `close()` throws: a socket xezar opened and then
|
|
349
|
+
// leaked would keep a pi process's peer alive with nothing reading it.
|
|
350
|
+
try {
|
|
351
|
+
leaving?.dispose?.();
|
|
352
|
+
}
|
|
353
|
+
catch (err) {
|
|
354
|
+
this.#opts.warn(`[xez] the pi leader link did not close cleanly (${err instanceof Error ? err.message : String(err)})`);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Build pi's target, and whatever has to be released with it. The ONE place a `PiRpcLink` is
|
|
359
|
+
* produced in this process — the answer to "who constructs the adapter", which for one round of
|
|
360
|
+
* review was nobody.
|
|
361
|
+
*
|
|
362
|
+
* Every failure is the blocker, never a throw: this is the `attach` path and the person reads the
|
|
363
|
+
* reason. A descriptor that names a dead socket is the ordinary case (a pi that exited), so it is
|
|
364
|
+
* reported as its own recoverable reason rather than as an error.
|
|
365
|
+
*/
|
|
366
|
+
#piTarget() {
|
|
367
|
+
const base = {
|
|
368
|
+
projectId: this.projectId,
|
|
369
|
+
roleInstruction: LEADER_ROLE_INSTRUCTION,
|
|
370
|
+
onReaction: (seq) => this.#recordReaction(seq),
|
|
371
|
+
...this.#ownOperation(),
|
|
372
|
+
};
|
|
373
|
+
const dataDir = this.#opts.dataDir ?? projectDataDir(this.#opts.projectRoot);
|
|
374
|
+
const read = this.#opts.piLeader?.read ?? readPiLeaderDescriptor;
|
|
375
|
+
const found = read(dataDir);
|
|
376
|
+
if (!found.ok)
|
|
377
|
+
return { target: piReactionTarget({ ...base, unreachable: found.reason }) };
|
|
378
|
+
const connect = this.#opts.piLeader?.connect ?? connectPiLeaderLink;
|
|
379
|
+
let link;
|
|
380
|
+
try {
|
|
381
|
+
link = connect(found.descriptor, { warn: this.#opts.warn });
|
|
382
|
+
}
|
|
383
|
+
catch (err) {
|
|
384
|
+
return {
|
|
385
|
+
target: piReactionTarget({
|
|
386
|
+
...base,
|
|
387
|
+
unreachable: `its socket could not be reached: ${err instanceof Error ? err.message : String(err)}`,
|
|
388
|
+
}),
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
const target = piReactionTarget({ ...base, link });
|
|
392
|
+
// A link that was already closed gives a blocked target; do not leak the socket behind it.
|
|
393
|
+
if (target.kind === 'blocked') {
|
|
394
|
+
link.close();
|
|
395
|
+
return { target };
|
|
396
|
+
}
|
|
397
|
+
return { target, dispose: () => link.close() };
|
|
398
|
+
}
|
|
399
|
+
#ownOperation() {
|
|
400
|
+
const guard = this.#opts.guard;
|
|
401
|
+
return guard === undefined ? {} : { isOwnOperation: (operationId) => guard.isOwn(operationId) };
|
|
402
|
+
}
|
|
403
|
+
#isEcho(row) {
|
|
404
|
+
return row.origin === 'leader' && row.causedBy !== null && this.#opts.guard?.isOwn(row.causedBy) === true;
|
|
405
|
+
}
|
|
406
|
+
#liveController() {
|
|
407
|
+
for (const controller of this.#controllers.values())
|
|
408
|
+
if (controller.state !== 'ended')
|
|
409
|
+
return controller;
|
|
410
|
+
return undefined;
|
|
411
|
+
}
|
|
412
|
+
#recordReaction(seq) {
|
|
413
|
+
return this.#liveController()?.recordReaction(seq) ?? { status: 'inactive', seq: 0 };
|
|
414
|
+
}
|
|
415
|
+
#leaderSession() {
|
|
416
|
+
return this.#leader === undefined ? null : { client: this.#leader.client, state: 'attached' };
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* The blocker is a rule over FACTS, in order: the journal can be written; a leader is attached; a
|
|
420
|
+
* session owns the project; the adapter named no problem; no attempt has failed since the last
|
|
421
|
+
* success. It reads no controller state, so a state added later cannot slip past it.
|
|
422
|
+
*/
|
|
423
|
+
#blocker() {
|
|
424
|
+
// Before anything about the leader: with no journal, even an attached leader hears nothing.
|
|
425
|
+
if (!this.#opts.journal.writable)
|
|
426
|
+
return JOURNAL_UNWRITABLE;
|
|
427
|
+
const leader = this.#leader;
|
|
428
|
+
if (leader === undefined)
|
|
429
|
+
return NO_LEADER;
|
|
430
|
+
// Attached, but nobody owns the project: no controller, so nothing is delivered (#331).
|
|
431
|
+
const controller = this.#liveController();
|
|
432
|
+
if (controller === undefined)
|
|
433
|
+
return noOwnerSession(leader.client);
|
|
434
|
+
const blocker = leader.adapter.status().blocker;
|
|
435
|
+
if (blocker) {
|
|
436
|
+
// The adapter's own `fix` when it has one (pi's does; `PiReactionAdapter.#block` always sets
|
|
437
|
+
// one, and `piReactionTarget`'s own blocker carries `PI_EXTENSION_FIX`), otherwise the
|
|
438
|
+
// OpenCode wording, which is the only adapter whose blockers name no remedy of their own.
|
|
439
|
+
const fix = blocker.fix ?? 'Check that `opencode serve` is running in this project and the session id is right, then attach it again.';
|
|
440
|
+
return { code: blocker.code, message: blocker.message, fix };
|
|
441
|
+
}
|
|
442
|
+
// From FACTS observed against THIS leader, never from the controller's state machine (rounds four
|
|
443
|
+
// and five): a failed attempt with no success since is a blocker in every state, it survives the
|
|
444
|
+
// session being replaced, and a leader just attached has none. `state` is shown, and decides nothing.
|
|
445
|
+
if (leader.failingSince !== null)
|
|
446
|
+
return this.#owed(leader) ? deliveryFailing(leader.client) : leaderNotAnswering(leader.client);
|
|
447
|
+
return null;
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
//# sourceMappingURL=leader-delivery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"leader-delivery.js","sourceRoot":"","sources":["../../src/mcp/leader-delivery.ts"],"names":[],"mappings":"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"}
|