@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
package/README.md
CHANGED
|
@@ -19,8 +19,9 @@ your phone, working your backlog while you're away.
|
|
|
19
19
|
|
|
20
20
|
[A look inside](#a-look-inside) · [What xezar does best](#what-xezar-does-best) · [What it solves](#what-it-solves) · [Who it's for](#who-its-for) · [Quick start](#quick-start) · [How it works](#how-it-works) · [Core concepts](#core-concepts) · [Cockpit tour](#cockpit-tour) · [Agent backends](#coding-agent-backends) · [Remote access](#remote-access-host-xezar-on-a-server)
|
|
21
21
|
|
|
22
|
+
[](https://github.com/qodeca/xezar/actions/workflows/ci.yml)
|
|
22
23
|
[](https://www.npmjs.com/package/@qodeca/xezar)
|
|
23
|
-
[](LICENSE)
|
|
24
|
+
[](https://github.com/qodeca/xezar/blob/main/LICENSE)
|
|
24
25
|

|
|
25
26
|

|
|
26
27
|

|
|
@@ -28,6 +29,10 @@ your phone, working your backlog while you're away.
|
|
|
28
29
|
|
|
29
30
|
</div>
|
|
30
31
|
|
|
32
|
+
> **Project status: early.** xezar is 0.x and moves fast. This repository opened on 2026-09-07; the
|
|
33
|
+
> code is older and shipped before under the name Cezar. Expect rough edges, and expect breaking
|
|
34
|
+
> changes in minor releases – each one is called out in the [CHANGELOG](https://github.com/qodeca/xezar/blob/main/CHANGELOG.md).
|
|
35
|
+
|
|
31
36
|
---
|
|
32
37
|
|
|
33
38
|
```bash
|
|
@@ -46,10 +51,10 @@ Click any thumbnail for the full-size screenshot.
|
|
|
46
51
|
|
|
47
52
|
| Orchestrate parallel agents | Watch a run live | Parallel variants |
|
|
48
53
|
|:--:|:--:|:--:|
|
|
49
|
-
| [](docs/screenshots/task-view.png) | [](docs/screenshots/live-run.png) | [](docs/screenshots/variants-compare.png) |
|
|
54
|
+
| [](https://raw.githubusercontent.com/qodeca/xezar/main/docs/screenshots/task-view.png) | [](https://raw.githubusercontent.com/qodeca/xezar/main/docs/screenshots/live-run.png) | [](https://raw.githubusercontent.com/qodeca/xezar/main/docs/screenshots/variants-compare.png) |
|
|
50
55
|
| *Run and queue many tasks at once — each in its own worktree — with live status, cost and peak memory per run.* | *Every step, tool call, token and screenshot — streamed as it happens.* | *Run a task ×2/×3 in isolated worktrees, compare the diffs, keep one.* |
|
|
51
56
|
| **Workflow builder** | **GitHub, one click away** | **Skills + fire-and-forget** |
|
|
52
|
-
| [](docs/screenshots/workflow-builder.png) | [](docs/screenshots/github-issues.png) | [](docs/screenshots/skills-autonomous.png) |
|
|
57
|
+
| [](https://raw.githubusercontent.com/qodeca/xezar/main/docs/screenshots/workflow-builder.png) | [](https://raw.githubusercontent.com/qodeca/xezar/main/docs/screenshots/github-issues.png) | [](https://raw.githubusercontent.com/qodeca/xezar/main/docs/screenshots/skills-autonomous.png) |
|
|
53
58
|
| *Stitch skills and shell checks into a reusable YAML chain, no code.* | *Open issues and PRs via your `gh` — run the agent straight on an issue.* | *Pick a Markdown skill and flip **Autonomous** — the run never stops to ask, so you can walk away.* |
|
|
54
59
|
|
|
55
60
|
---
|
|
@@ -113,7 +118,7 @@ and an orchestrator keeps a whole queue of them moving.
|
|
|
113
118
|
Take it over interactively in one click (`claude --resume <id>`), or continue it
|
|
114
119
|
in-process from the cockpit.
|
|
115
120
|
- 🔀 **Locked into one agent vendor.** Most tools wed you to a single CLI. xezar
|
|
116
|
-
drives **Claude Code, Codex and
|
|
121
|
+
drives **Claude Code, Codex, OpenCode and pi (the last two experimental)** through one runner seam — set a
|
|
117
122
|
default, pick a backend per task, or mix them inside one workflow (implement
|
|
118
123
|
with one agent, review with another) — and through **OpenCode** you can point
|
|
119
124
|
a run at **open-source or local models**, not just the big vendors. See
|
|
@@ -147,8 +152,9 @@ and an orchestrator keeps a whole queue of them moving.
|
|
|
147
152
|
|
|
148
153
|
**Prerequisites:** Node 20+, at least one logged-in agent CLI — the
|
|
149
154
|
[`claude` CLI](https://github.com/anthropics/claude-code) (Pro/Max subscription),
|
|
150
|
-
the [`codex` CLI](https://github.com/openai/codex),
|
|
151
|
-
[OpenCode](https://opencode.ai)
|
|
155
|
+
the [`codex` CLI](https://github.com/openai/codex),
|
|
156
|
+
[OpenCode](https://opencode.ai), or [pi](https://github.com/badlogic/pi-mono) —
|
|
157
|
+
and, optionally, `git` and the `gh` CLI.
|
|
152
158
|
|
|
153
159
|
Install it once, then run it in any repo:
|
|
154
160
|
|
|
@@ -192,8 +198,8 @@ To upgrade later: `npm install -g @qodeca/xezar@latest`.
|
|
|
192
198
|
|
|
193
199
|
You describe a task. xezar runs it as a **workflow** — an ordered list of agent
|
|
194
200
|
steps and shell checks — shelling out to your locally installed agent CLI
|
|
195
|
-
(Claude Code by default; Codex and
|
|
196
|
-
or per step). In a git repo each task gets its own worktree by default — switch
|
|
201
|
+
(Claude Code by default; Codex, OpenCode and pi are drop-in alternatives, per
|
|
202
|
+
task or per step). In a git repo each task gets its own worktree by default — switch
|
|
197
203
|
the composer's **Worktree** toggle off to run in the repo working tree (under
|
|
198
204
|
xezar's repository-root lease), and a non-git directory runs in place. A git
|
|
199
205
|
task that asks for a worktree it cannot create stops as `failed`; it never falls
|
|
@@ -259,7 +265,7 @@ Three words, no jargon — **task**, **skill**, **chain**:
|
|
|
259
265
|
AI draft a chain for your task that you review, trim and start. The built-in
|
|
260
266
|
`quick-task` (one agent step) works with zero setup.
|
|
261
267
|
|
|
262
|
-
|
|
268
|
+
Six moves that make the cockpit worth the browser tab:
|
|
263
269
|
|
|
264
270
|
- 🗃️ **Queue + orchestration.** Start as many tasks as you like: xezar runs up to
|
|
265
271
|
`maxParallel` at once across every project (default **2**; a non-git directory
|
|
@@ -316,7 +322,7 @@ Nine views, one browser window, all live over Server-Sent Events (seven by defau
|
|
|
316
322
|
| **Automations** | **Opt-in** (`XEZ_AUTOMATIONS=1`; hidden by default). Scheduled GitHub watches: each automation polls on its own interval and launches a task when its bounded filter matches. Test a filter before enabling it, and read the per-check log. |
|
|
317
323
|
| **Skills** | Local skills plus the team skills repo, with a rendered body + prompt preview. Refresh pulls the latest from the remote. |
|
|
318
324
|
| **Workflows** | Build a chain by drag-ordering skills, save it as portable YAML, import/export, or delete. Built-ins always come back. |
|
|
319
|
-
| **Settings** | Appearance (dark/light theme, accent, density), agent backends, notifications, and
|
|
325
|
+
| **Settings** | Appearance (dark/light theme, accent, density), agent backends and their own config files, agent accounts, notifications, machine resources, projects, and skill-update checks. |
|
|
320
326
|
|
|
321
327
|
The cockpit is a React app served pre-built from the package — running `xezar`
|
|
322
328
|
needs no dev server on your machine — with a dark/light
|
|
@@ -373,10 +379,11 @@ These read and write `~/.xezar/config.json` directly, so they work with the
|
|
|
373
379
|
server stopped, and `XEZ_HOME` selects which workspace they operate on.
|
|
374
380
|
|
|
375
381
|
Settings split along the same line: **General** (the project's folder, its
|
|
376
|
-
registry facts, its parallel-task ceiling, and Remove), **Agents**,
|
|
377
|
-
**
|
|
378
|
-
repo and live under
|
|
379
|
-
**Notifications**, **Resources**,
|
|
382
|
+
registry facts, its parallel-task ceiling, and Remove), **Agents**, **Agent
|
|
383
|
+
config** (each agent's own settings, MCP and memory files), **Worktrees**,
|
|
384
|
+
**Bookmarklets** and **Prompt templates** describe one repo and live under
|
|
385
|
+
`/p/<projectId>/settings`; **Appearance**, **Notifications**, **Resources**,
|
|
386
|
+
**Skills** (update checks), **Agent accounts** and **Projects** are yours or the
|
|
380
387
|
machine's and live at `/settings/global`.
|
|
381
388
|
|
|
382
389
|
### Grouping connected repositories: tags and the All tasks page
|
|
@@ -453,7 +460,7 @@ segment.
|
|
|
453
460
|
|
|
454
461
|
## Workflow format
|
|
455
462
|
|
|
456
|
-
See [project layout and legacy migration](docs/project-layout.md) for directory precedence and the offline migration command.
|
|
463
|
+
See [project layout and legacy migration](https://github.com/qodeca/xezar/blob/main/docs/project-layout.md) for directory precedence and the offline migration command.
|
|
457
464
|
|
|
458
465
|
A workflow is a small YAML file in `.xezar/workflows/`:
|
|
459
466
|
|
|
@@ -546,9 +553,10 @@ Useful environment variables:
|
|
|
546
553
|
| `XEZ_AUTOSAVE=1` | Re-enable the periodic (90 s) autosave commit in task worktrees. Off by default (#471) — turn-end and pre-PR flushes always run, so branches still end complete. Every autosave names its trigger in the commit subject (`xezar autosave (periodic)` vs `(turn end)` / `(run finalize)` / `(pre-PR)`), so the flushes you keep are distinguishable from the timer you disabled. |
|
|
547
554
|
| `XEZ_CLAUDE_BIN=/path/to/claude` | Override which `claude` binary is used. |
|
|
548
555
|
| `XEZ_CODEX_BIN=/path/to/codex` | Override which `codex` binary is used. |
|
|
556
|
+
| `XEZ_CODEX_REASONING=concise` | The reasoning summary Codex is asked for on each turn: `auto` (the default, so the reasoning thread is visible), `concise`, `detailed`, or `none` to opt out. An unrecognised value falls back to `auto`. |
|
|
549
557
|
| `XEZ_OPENCODE_BIN=/path/to/opencode` | Override which `opencode` binary is used. |
|
|
550
558
|
| `XEZ_PI_BIN=/path/to/pi` | Override which `pi` binary is used. |
|
|
551
|
-
| `CLAUDE_CONFIG_DIR`, `CODEX_HOME` | The agents' **own** variables, honoured where the vendor documents one. Setting one moves that agent's **default account** — the config folder xezar discovers, credentials included. A *second* login of the same CLI is deliberately not an environment setting, since one process-wide value cannot differ per project: add it under **Settings → Agent accounts** and pick it per project. |
|
|
559
|
+
| `CLAUDE_CONFIG_DIR`, `CODEX_HOME`, `PI_CODING_AGENT_DIR` | The agents' **own** variables, honoured where the vendor documents one. Setting one moves that agent's **default account** — the config folder xezar discovers, credentials included. pi's variable moves its whole `~/.pi/agent` (settings, models **and** `auth.json`), which is why pi can carry accounts and OpenCode cannot; re-verified against pi 0.85.1 on 2026-09-12. A *second* login of the same CLI is deliberately not an environment setting, since one process-wide value cannot differ per project: add it under **Settings → Agent accounts** and pick it per project. |
|
|
552
560
|
| `OPENCODE_CONFIG_DIR` | Where xezar looks for OpenCode's config, ahead of `$XDG_CONFIG_HOME/opencode` (default `~/.config/opencode`). Config **only** — OpenCode keeps credentials in `~/.local/share/opencode`, so this moves settings without moving the account, which is why OpenCode cannot carry Agent accounts. |
|
|
553
561
|
| `XEZ_BROWSE_ROOT=~/` | Default root for **Add project → Open local folder…**. The picker cannot navigate above it; a saved workspace value overrides the environment default and must name an existing folder. |
|
|
554
562
|
| `XEZ_PROJECTS_DIR=~/xezar/projects` | Default destination for **Clone from GitHub**. Saved workspace settings override it, and missing directories are created recursively. |
|
|
@@ -568,7 +576,7 @@ Useful environment variables:
|
|
|
568
576
|
| `XEZ_TITLE_UPDATES=0` | Turn off the live task-title refresh (namer re-runs on each turn end). The Settings → Agents toggle overrides this default. |
|
|
569
577
|
| `XEZ_AUTONAME=0` | Disable ALL LLM task naming (creation + live) — titles stay heuristic (`437: /om-auto-review-pr`). Under `XEZ_DRY_RUN=1` naming is already off unless forced with `XEZ_AUTONAME=1`. |
|
|
570
578
|
| `XEZ_REVIEW_GATE=1` | Turn ON the optional diff-first review gate (#489): a successful, non-autonomous run with changes parks at `review` (Accept / Send back / Draft PR) instead of finishing. Off by default — changed runs settle to `done` with the diff left in the worktree. Only `1` enables. The Settings → Agents toggle overrides this; autonomous runs always skip it. |
|
|
571
|
-
| `XEZ_NO_BANNER=1` | Skip the `open-mercato/skills` banner on `xezar serve` startup. (The cockpit no longer shows a banner — its skills now live on the Skills page's Manage panel — so this env var is the terminal banner's only switch.) |
|
|
579
|
+
| `XEZ_NO_BANNER=1` | Skip the `open-mercato/skills` banner on `xezar serve` startup. That is the default team skills repository — a separate, maintained repository, not a leftover of the rename from Cezar. (The cockpit no longer shows a banner — its skills now live on the Skills page's Manage panel — so this env var is the terminal banner's only switch.) |
|
|
572
580
|
| `VITE_XEZ_API_BASE=http://localhost:4321` | **Build time only**, and only when the cockpit bundle is deployed apart from the service it talks to. Empty (the default) means "the origin that served this page", which is right for both normal cases: the CLI serves the bundle itself, and `npm run dev` proxies `/api` to the local service. A deployment that must be configured without a rebuild can put `<meta name="xez-api-base" content="…">` in the served HTML instead, which wins over this. |
|
|
573
581
|
|
|
574
582
|
### Troubleshooting: the agent's shell returns nothing
|
|
@@ -623,16 +631,17 @@ On startup xezar probes which CLIs are installed and the cockpit only offers
|
|
|
623
631
|
the backends it found — install any one of the four and you're operational.
|
|
624
632
|
|
|
625
633
|
**Models come from your own machine.** The model picker does not ship a list of
|
|
626
|
-
vendor releases that goes stale between xezar versions. For
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
`
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
and
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
634
|
+
vendor releases that goes stale between xezar versions. For each backend xezar
|
|
635
|
+
reads what *your host* currently offers — Claude Code's `list_models` control
|
|
636
|
+
request, the Codex app-server's `model/list`, `opencode models`, and for pi its
|
|
637
|
+
own `models.json` and `settings.json` (in `~/.pi/agent`, or wherever
|
|
638
|
+
`PI_CODING_AGENT_DIR` points) — and shows exactly that, in
|
|
639
|
+
that order, so a model your account gained yesterday is selectable today with no
|
|
640
|
+
xezar release, and one your provider retired stops being offered. Discovery is
|
|
641
|
+
read-only, costs no tokens, and is cached briefly in memory. If a CLI is
|
|
642
|
+
missing, logged out, too old or slow — or pi has no providers configured yet —
|
|
643
|
+
the picker quietly falls back to that runner's built-in entries (`auto` plus
|
|
644
|
+
Claude's tier aliases) and says so in a status row. `auto` — send no
|
|
636
645
|
model at all and let the CLI decide — is always available, and a model you
|
|
637
646
|
pinned by hand stays selectable even when it is no longer advertised.
|
|
638
647
|
|
|
@@ -688,8 +697,8 @@ happens per task and per step, not inside a variant group.
|
|
|
688
697
|
|
|
689
698
|
The seam is deliberately small: a backend is one class implementing the
|
|
690
699
|
`AgentRunner` interface (`packages/xezar/src/core/agent-runner.ts`) that turns a prompt into
|
|
691
|
-
a stream of normalized events.
|
|
692
|
-
can slot
|
|
700
|
+
a stream of normalized events. `pi` was added exactly that way; other CLIs —
|
|
701
|
+
aider, whatever ships next — can slot into the same seam.
|
|
693
702
|
|
|
694
703
|
---
|
|
695
704
|
|
|
@@ -726,15 +735,15 @@ xezar server-install --platform ubuntu-vps \
|
|
|
726
735
|
`--bind-host` is only needed when the proxy runs in a **container** (Traefik
|
|
727
736
|
can't reach the host's loopback); a host-installed proxy uses the `127.0.0.1`
|
|
728
737
|
default. In this mode **your proxy must enforce authentication** — xezar has
|
|
729
|
-
none of its own. [Details →](docs/server-install/ubuntu-vps.md#the-box-already-has-a-reverse-proxy-dokploy-coolify-caddy)
|
|
738
|
+
none of its own. [Details →](https://github.com/qodeca/xezar/blob/main/docs/server-install/ubuntu-vps.md#the-box-already-has-a-reverse-proxy-dokploy-coolify-caddy)
|
|
730
739
|
|
|
731
740
|
| Provider | `--platform` | Public front | Guide |
|
|
732
741
|
|----------|--------------|--------------|-------|
|
|
733
|
-
| Ubuntu / Debian VPS | `ubuntu-vps` | nginx + Let's Encrypt HTTPS, htpasswd login, systemd | [Step-by-step →](docs/server-install/ubuntu-vps.md) |
|
|
734
|
-
| Ubuntu + existing proxy | `ubuntu-vps --external-proxy` | your Dokploy/Traefik/Caddy front; xezar ships the service only | [Step-by-step →](docs/server-install/ubuntu-vps.md#the-box-already-has-a-reverse-proxy-dokploy-coolify-caddy) |
|
|
735
|
-
| macOS + ngrok | `macosx-ngrok` | ngrok tunnel + `--basic-auth`, launchd | [Step-by-step →](docs/server-install/macosx-ngrok.md) |
|
|
742
|
+
| Ubuntu / Debian VPS | `ubuntu-vps` | nginx + Let's Encrypt HTTPS, htpasswd login, systemd | [Step-by-step →](https://github.com/qodeca/xezar/blob/main/docs/server-install/ubuntu-vps.md) |
|
|
743
|
+
| Ubuntu + existing proxy | `ubuntu-vps --external-proxy` | your Dokploy/Traefik/Caddy front; xezar ships the service only | [Step-by-step →](https://github.com/qodeca/xezar/blob/main/docs/server-install/ubuntu-vps.md#the-box-already-has-a-reverse-proxy-dokploy-coolify-caddy) |
|
|
744
|
+
| macOS + ngrok | `macosx-ngrok` | ngrok tunnel + `--basic-auth`, launchd | [Step-by-step →](https://github.com/qodeca/xezar/blob/main/docs/server-install/macosx-ngrok.md) |
|
|
736
745
|
|
|
737
|
-
See the **[Remote access overview](docs/server-install/README.md)** for how it
|
|
746
|
+
See the **[Remote access overview](https://github.com/qodeca/xezar/blob/main/docs/server-install/README.md)** for how it
|
|
738
747
|
works and how to redeploy new versions.
|
|
739
748
|
|
|
740
749
|
---
|
|
@@ -748,6 +757,7 @@ never blocks startup):
|
|
|
748
757
|
```jsonc
|
|
749
758
|
{
|
|
750
759
|
"skillsRepos": [{ "repo": "open-mercato/skills", "ref": "main" }], // team skills; [] disables
|
|
760
|
+
// open-mercato/skills is a separate, maintained skills repository, not a leftover of the Cezar rename.
|
|
751
761
|
// Team-skill repos are code-trusted: a skill body becomes an agent system prompt.
|
|
752
762
|
// Only owner/name, https/ssh URLs, or local paths (`/abs`, `./rel`, `~/dir`,
|
|
753
763
|
// `C:\dir`) are accepted — no ext::/fd:: transport helpers. Write a relative
|
|
@@ -795,7 +805,7 @@ the workspace ceiling for runs in that repo.
|
|
|
795
805
|
### Editing the agents' own config (Settings → Agent config)
|
|
796
806
|
|
|
797
807
|
xezar picks *which* agent runs; **Settings → Agent config** lets you edit *how* it
|
|
798
|
-
behaves — the raw config files Claude, Codex and
|
|
808
|
+
behaves — the raw config files Claude, Codex, OpenCode and pi read for settings,
|
|
799
809
|
MCP, and memory. In the multi-project cockpit the section is project-scoped:
|
|
800
810
|
repo-relative files resolve from the selected project's root, while user-scope
|
|
801
811
|
files continue to resolve from the agent's home.
|
|
@@ -805,6 +815,13 @@ files reach task worktrees after commit; Claude's gitignored personal layer is
|
|
|
805
815
|
seeded into each run's worktree. Editing is a local-machine capability, so a
|
|
806
816
|
hosted cockpit (`XEZ_REMOTE=1`) is read-only and never serves home-file contents.
|
|
807
817
|
|
|
818
|
+
Only files whose whole contents are safe to hand back are listed. pi keeps its
|
|
819
|
+
credentials (`auth.json`) and its custom-provider catalogue with the API keys in
|
|
820
|
+
it (`models.json`) in the same folder as its settings, and neither is editable
|
|
821
|
+
here or anywhere else in the cockpit. pi's MCP files are listed because the
|
|
822
|
+
`pi-mcp-adapter` extension reads them — pi itself reads no MCP config, which is
|
|
823
|
+
what **Settings → MCP connection** walks you through installing.
|
|
824
|
+
|
|
808
825
|
---
|
|
809
826
|
|
|
810
827
|
## Local development
|
|
@@ -823,8 +840,9 @@ cd xezar
|
|
|
823
840
|
npm install
|
|
824
841
|
```
|
|
825
842
|
|
|
826
|
-
**3. Build** — compiles the
|
|
827
|
-
|
|
843
|
+
**3. Build** — compiles the server (`tsc → packages/xezar/dist/`), folds the
|
|
844
|
+
contract into `dist/contract/` so the published tarball resolves it, and builds
|
|
845
|
+
the cockpit (`vite build → packages/xezar/web/dist/`), then runs the pack gate:
|
|
828
846
|
|
|
829
847
|
```bash
|
|
830
848
|
npm run build
|
|
@@ -889,7 +907,10 @@ npm run test:e2e # real-browser cockpit suite (agent-browser)
|
|
|
889
907
|
Coverage is measured separately, and is not part of the validation gate:
|
|
890
908
|
`npm run test:coverage` runs the vitest suites under the v8 provider and writes line and branch
|
|
891
909
|
numbers to `.local/coverage/`. The behaviour-led gap analysis built from it lives in
|
|
892
|
-
[docs/testing/coverage-gaps.md](docs/testing/coverage-gaps.md).
|
|
910
|
+
[docs/testing/coverage-gaps.md](https://github.com/qodeca/xezar/blob/main/docs/testing/coverage-gaps.md).
|
|
911
|
+
The MCP server is the one scope held to a floor: `npm run test:coverage:mcp` measures it alone
|
|
912
|
+
and fails any file under 80 % lines or branches – see
|
|
913
|
+
[SDLC.md § The MCP test floor](https://github.com/qodeca/xezar/blob/main/SDLC.md#the-mcp-test-floor).
|
|
893
914
|
|
|
894
915
|
The stack is deliberately small: **TypeScript** (strict, ESM), **Hono** + SSE for
|
|
895
916
|
the server, **Zod** at every boundary, **YAML** for workflows, and a **React 19 +
|
|
@@ -897,8 +918,20 @@ Vite + Tailwind v4 + shadcn/ui** cockpit shipped pre-built in `packages/xezar/we
|
|
|
897
918
|
published package carries the built app, so `npx` users never run a bundler.
|
|
898
919
|
Every module is meant to be read in one sitting.
|
|
899
920
|
|
|
921
|
+
What lives where under `docs/`, and who each part is for, is mapped in
|
|
922
|
+
[docs/README.md](https://github.com/qodeca/xezar/blob/main/docs/README.md). `docs/features/` is the internal engineering and decision
|
|
923
|
+
record, not a user guide.
|
|
924
|
+
|
|
925
|
+
---
|
|
926
|
+
|
|
927
|
+
## Contributing
|
|
928
|
+
|
|
929
|
+
Bug reports, ideas and pull requests are welcome. [CONTRIBUTING.md](https://github.com/qodeca/xezar/blob/main/CONTRIBUTING.md) is the short path
|
|
930
|
+
from a change to a merged pull request. Report security problems privately, as described in
|
|
931
|
+
[SECURITY.md](https://github.com/qodeca/xezar/blob/main/SECURITY.md).
|
|
932
|
+
|
|
900
933
|
---
|
|
901
934
|
|
|
902
935
|
## License
|
|
903
936
|
|
|
904
|
-
**MIT** © Patryk Lewczuk — full text in [LICENSE](LICENSE).
|
|
937
|
+
**MIT** © Patryk Lewczuk — full text in [LICENSE](https://github.com/qodeca/xezar/blob/main/LICENSE).
|
|
@@ -6,7 +6,8 @@ import type { ProviderId } from '../core/provider-auth.ts';
|
|
|
6
6
|
* This is the second place vendor knowledge lives about an agent's home, beside
|
|
7
7
|
* `catalog.ts` (which config FILES exist) and `core/agent-profiles.ts` (which env var relocates
|
|
8
8
|
* the home). This one knows where each agent writes its own identity. Facts verified against the
|
|
9
|
-
* files on disk 2026-07-29; re-verify
|
|
9
|
+
* files on disk 2026-07-29, and the pi row against pi 0.85.1 on 2026-09-12 (#329); re-verify
|
|
10
|
+
* before changing them.
|
|
10
11
|
*
|
|
11
12
|
* ## Two rules that are not negotiable
|
|
12
13
|
*
|
|
@@ -34,11 +35,4 @@ export interface AccountIdentity {
|
|
|
34
35
|
reason?: string;
|
|
35
36
|
fields: AccountIdentityField[];
|
|
36
37
|
}
|
|
37
|
-
/**
|
|
38
|
-
* What this account is logged in as, or an honest reason there is nothing to show.
|
|
39
|
-
*
|
|
40
|
-
* Never throws. OpenCode answers "unsupported": its credentials live in a SQLite DB outside the
|
|
41
|
-
* config dir (see `core/agent-profiles.ts`), so there is nothing in a config folder to read — and
|
|
42
|
-
* guessing from the default login would attribute one account's identity to another.
|
|
43
|
-
*/
|
|
44
38
|
export declare function readAccountIdentity(provider: ProviderId, configDir: string): Promise<AccountIdentity>;
|
|
@@ -94,6 +94,41 @@ async function readCodexIdentity(configDir) {
|
|
|
94
94
|
? { available: true, fields }
|
|
95
95
|
: { available: false, reason: NOT_SIGNED_IN, fields: [] };
|
|
96
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* pi keeps its login in `auth.json` INSIDE the agent dir — that is the fact #329 is about, and it
|
|
99
|
+
* is why pi can carry an account at all. But the file holds no account identity: it is
|
|
100
|
+
* `Record<providerId, Credential>`, and a `Credential` is `{type: 'api_key', key?, env?}` or
|
|
101
|
+
* `{type: 'oauth', refresh, access, expires}` — no email, no name, no plan anywhere in it
|
|
102
|
+
* (pi 0.85.1, `dist/core/auth-storage.d.ts` plus `@earendil-works/pi-ai` `dist/auth/types.d.ts`,
|
|
103
|
+
* read on 2026-09-12).
|
|
104
|
+
*
|
|
105
|
+
* What the file DOES carry is what pi-ai itself labels "non-secret credential metadata for
|
|
106
|
+
* account/status enumeration": which model providers this account is logged in to, and by which
|
|
107
|
+
* method. That is the thing that tells two pi accounts apart, so that is what this shows — the
|
|
108
|
+
* map's KEYS and each entry's `type`, both by name. `key`, `access`, `refresh` and `env` are
|
|
109
|
+
* never read, and the value is rebuilt from scratch rather than forwarded.
|
|
110
|
+
*
|
|
111
|
+
* A fresh pi writes `auth.json` as `{}` before any login (observed, #329), so an empty map is the
|
|
112
|
+
* ordinary not-signed-in case and not a parse failure.
|
|
113
|
+
*/
|
|
114
|
+
async function readPiIdentity(configDir) {
|
|
115
|
+
const auth = await readJsonCapped(join(configDir, 'auth.json'));
|
|
116
|
+
if (auth === null)
|
|
117
|
+
return { available: false, reason: NOT_SIGNED_IN, fields: [] };
|
|
118
|
+
const logins = [];
|
|
119
|
+
for (const [providerId, credential] of Object.entries(auth)) {
|
|
120
|
+
const name = text(providerId);
|
|
121
|
+
if (name === undefined || !credential || typeof credential !== 'object')
|
|
122
|
+
continue;
|
|
123
|
+
const type = credential.type;
|
|
124
|
+
const method = type === 'oauth' ? 'OAuth' : type === 'api_key' ? 'API key' : undefined;
|
|
125
|
+
logins.push(method === undefined ? name : `${name} (${method})`);
|
|
126
|
+
}
|
|
127
|
+
logins.sort();
|
|
128
|
+
return logins.length > 0
|
|
129
|
+
? { available: true, fields: [{ label: 'Signed in to', value: logins.join(', ') }] }
|
|
130
|
+
: { available: false, reason: NOT_SIGNED_IN, fields: [] };
|
|
131
|
+
}
|
|
97
132
|
/** A JWT's payload claims, or null when it is not a readable three-part token. */
|
|
98
133
|
function decodeJwtClaims(token) {
|
|
99
134
|
const parts = token.split('.');
|
|
@@ -110,19 +145,28 @@ function decodeJwtClaims(token) {
|
|
|
110
145
|
/**
|
|
111
146
|
* What this account is logged in as, or an honest reason there is nothing to show.
|
|
112
147
|
*
|
|
113
|
-
* Never throws.
|
|
114
|
-
*
|
|
115
|
-
*
|
|
148
|
+
* Never throws. An exhaustive `Record<ProviderId, …>` rather than a chain of `if`s, and that is
|
|
149
|
+
* the fix rather than the style: the chain this replaced fell through to OpenCode's refusal for
|
|
150
|
+
* ANY provider it did not name, so a pi account's "Show details" answered with a sentence about
|
|
151
|
+
* OpenCode — a provider the user had not asked about, and a claim that is false of pi, whose
|
|
152
|
+
* login really is inside its config folder (#329, 2026-09-12). Each provider now answers in its
|
|
153
|
+
* own words, and a fifth provider is a compile error instead of a borrowed refusal.
|
|
154
|
+
*
|
|
155
|
+
* Only OpenCode is genuinely unreadable: its credentials live outside the config dir (see
|
|
156
|
+
* `core/agent-profiles.ts`), so there is nothing in a config folder to read — and guessing from
|
|
157
|
+
* the default login would attribute one account's identity to another.
|
|
116
158
|
*/
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
return {
|
|
159
|
+
const READ_IDENTITY = {
|
|
160
|
+
claude: readClaudeIdentity,
|
|
161
|
+
codex: readCodexIdentity,
|
|
162
|
+
pi: readPiIdentity,
|
|
163
|
+
opencode: async () => ({
|
|
123
164
|
available: false,
|
|
124
165
|
reason: 'OpenCode keeps its login outside its config folder, so xezar cannot read it.',
|
|
125
166
|
fields: [],
|
|
126
|
-
}
|
|
167
|
+
}),
|
|
168
|
+
};
|
|
169
|
+
export async function readAccountIdentity(provider, configDir) {
|
|
170
|
+
return READ_IDENTITY[provider](configDir);
|
|
127
171
|
}
|
|
128
172
|
//# sourceMappingURL=account-identity.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account-identity.js","sourceRoot":"","sources":["../../src/agent-config/account-identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"account-identity.js","sourceRoot":"","sources":["../../src/agent-config/account-identity.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,7 +9,44 @@ import type { RunnerId } from '../core/agent-runner.ts';
|
|
|
9
9
|
* and what the docs say; an unknown file is not shown rather than guessed at.
|
|
10
10
|
* A raw editor cannot drift on a vendor's *schema*; it can drift on *paths and
|
|
11
11
|
* precedence strings*, so every entry carries a `docsUrl` and this table is the
|
|
12
|
-
* single maintenance surface. Facts verified against primary docs 2026-07-16
|
|
12
|
+
* single maintenance surface. Facts verified against primary docs 2026-07-16;
|
|
13
|
+
* the pi block against the docs shipped with pi 0.85.1 on 2026-09-12 (#330 WP4).
|
|
14
|
+
*
|
|
15
|
+
* WHAT MAY GO IN THIS TABLE AT ALL. An entry is a file the API hands to a caller
|
|
16
|
+
* verbatim and writes back verbatim, so a file that can hold a credential is not
|
|
17
|
+
* eligible however useful editing it would be (F-15: no secret in a tool
|
|
18
|
+
* response). Two files in pi's home are excluded for exactly that reason and
|
|
19
|
+
* must stay excluded:
|
|
20
|
+
*
|
|
21
|
+
* - `auth.json` — pi's stored provider credentials.
|
|
22
|
+
* - `models.json` — pi's custom-provider catalogue. `apiKey` is OPTIONAL on a
|
|
23
|
+
* provider entry (`apiKey?: string`, `custom-provider.md`) and its value may
|
|
24
|
+
* be an `$ENV_VAR` reference or a `!command` rather than a literal, so "this
|
|
25
|
+
* file always holds a secret" would be too strong a claim. The exclusion does
|
|
26
|
+
* not rest on that claim: on a real 0.85.1 home here, a provider entry carries
|
|
27
|
+
* a literal `apiKey` (`providers.<id>.apiKey`, mode `0600`, checked
|
|
28
|
+
* 2026-09-12), so the file is credential-BEARING in practice, and a catalog
|
|
29
|
+
* entry hands a file over WHOLE. #152's model discovery reads the same file
|
|
30
|
+
* and deliberately touches only `name`, `models[].id` and `models[].name`
|
|
31
|
+
* (`core/pi-model-catalog.ts`); that is the shape a reader of this file needs.
|
|
32
|
+
* Wanting a model editor is not a reason to catalog it.
|
|
33
|
+
*
|
|
34
|
+
* The same directory holds more than those two, and none of the rest may become
|
|
35
|
+
* an entry either. On a real 0.85.1 home, checked 2026-09-12: pi's own rotation
|
|
36
|
+
* copies `models.json.bak-<timestamp>` (mode `0600`, carrying the same literal
|
|
37
|
+
* `apiKey` as the file they copy) and `settings.json.bak-*` (mode `0644`, no
|
|
38
|
+
* `apiKey` observed), plus `models-store.json` (mode `0600`). They are
|
|
39
|
+
* unreachable today for a structural reason worth keeping: every `resolve` below
|
|
40
|
+
* is a fixed `join` of known segments, so the catalog never globs and never lists
|
|
41
|
+
* a directory, and a file becomes reachable only by being written into this table
|
|
42
|
+
* by hand. Rotation copies are the trap that makes this worth stating — excluding
|
|
43
|
+
* `models.json` by name would not exclude `models.json.bak-20260910-114604`.
|
|
44
|
+
*
|
|
45
|
+
* `mcp.json` IS eligible on the same terms as the three MCP files already here:
|
|
46
|
+
* an MCP server definition can carry a token in `env`/`headers`, and Claude's
|
|
47
|
+
* `.mcp.json`, Codex's `[mcp_servers]` and OpenCode's `"mcp"` key have always
|
|
48
|
+
* been in this table with that property. A user typing a secret into a config
|
|
49
|
+
* file is not the same risk as xezar cataloging a file whose PURPOSE is secrets.
|
|
13
50
|
*/
|
|
14
51
|
export type ConfigFormat = 'json' | 'jsonc' | 'toml' | 'markdown';
|
|
15
52
|
export type ConfigScope = 'user' | 'project' | 'local';
|
|
@@ -29,13 +66,18 @@ export interface AgentHomePaths {
|
|
|
29
66
|
/** `$XDG_CONFIG_HOME/opencode` or `~/.config/opencode` */
|
|
30
67
|
opencodeConfig: string;
|
|
31
68
|
/**
|
|
32
|
-
* `~/.pi/agent` — pi's whole per-user directory (`models.json`,
|
|
33
|
-
* `
|
|
34
|
-
*
|
|
69
|
+
* `$PI_CODING_AGENT_DIR` or `~/.pi/agent` — pi's whole per-user directory (`models.json`,
|
|
70
|
+
* `settings.json`, and `auth.json`, which `account-identity.ts` reads for its non-secret
|
|
71
|
+
* credential metadata and nothing else). The variable IS documented and the binary does read
|
|
72
|
+
* it (re-verified against pi 0.85.1, 2026-09-12, #329); the note that used to sit here denying
|
|
73
|
+
* it was wrong, and dated 2026-09-10.
|
|
35
74
|
*
|
|
36
|
-
* `CONFIG_FILES`
|
|
37
|
-
*
|
|
38
|
-
*
|
|
75
|
+
* `CONFIG_FILES` resolves `pi.user.settings`, `pi.user.mcp` and `pi.user.memory` through this
|
|
76
|
+
* slot (#330 WP4), which is also what makes a pi ACCOUNT's files resolve inside the account's
|
|
77
|
+
* folder: `accountFiles` in `server/server.ts` patches this slot via `accountHomePatch`. Model
|
|
78
|
+
* discovery (#152) reads the same slot. It lives here so pi's home is derived in the one place
|
|
79
|
+
* every other agent's is. `auth.json` and `models.json` sit in this dir and are deliberately
|
|
80
|
+
* NOT catalog entries — see the file header.
|
|
39
81
|
*/
|
|
40
82
|
pi: string;
|
|
41
83
|
}
|
|
@@ -6,6 +6,35 @@ const CODEX_CONFIG_DOCS = 'https://developers.openai.com/codex/config-reference'
|
|
|
6
6
|
const CODEX_AGENTS_DOCS = 'https://developers.openai.com/codex/guides/agents-md';
|
|
7
7
|
const OPENCODE_CONFIG_DOCS = 'https://opencode.ai/docs/config/';
|
|
8
8
|
const OPENCODE_RULES_DOCS = 'https://opencode.ai/docs/rules/';
|
|
9
|
+
/**
|
|
10
|
+
* pi ships its docs INSIDE the npm package (`docs/` in `@earendil-works/pi-coding-agent`) AND
|
|
11
|
+
* serves them at `pi.dev`. An earlier note here said it served no docs site, on the strength of
|
|
12
|
+
* `https://pi.dev/docs/settings` → 404; that URL shape was simply wrong. What is true, checked
|
|
13
|
+
* 2026-09-12: `https://pi.dev/docs` → 302 → `/docs/latest`, and `/docs/latest/settings` and
|
|
14
|
+
* `/docs/latest/usage` both answer 200 and contain the sentences quoted below, verbatim.
|
|
15
|
+
*
|
|
16
|
+
* These point at the vendor's own pages rather than at `github.com/.../blob/main/...`, which
|
|
17
|
+
* tracked a moving branch. `latest` moves too — pi publishes no version-pinned path
|
|
18
|
+
* (`/docs/0.85.1/settings` → 404, checked) — so the guard against silent drift is the date, not
|
|
19
|
+
* the URL: every quote below was taken from the docs shipped with pi **0.85.1** on 2026-09-12,
|
|
20
|
+
* and each was re-read in the npm package AND on the page above.
|
|
21
|
+
*/
|
|
22
|
+
const PI_SETTINGS_DOCS = 'https://pi.dev/docs/latest/settings';
|
|
23
|
+
const PI_USAGE_DOCS = 'https://pi.dev/docs/latest/usage';
|
|
24
|
+
/**
|
|
25
|
+
* pi core reads NO MCP config: MCP arrives through the third-party `pi-mcp-adapter` extension
|
|
26
|
+
* (#341/#343 shipped the cockpit's setup card for it), so the adapter's README is the vendor doc
|
|
27
|
+
* for these two files and pi's own docs never mention `mcp.json`. Verified against
|
|
28
|
+
* `pi-mcp-adapter@2.32.1` on 2026-09-12.
|
|
29
|
+
*/
|
|
30
|
+
const PI_MCP_DOCS = 'https://github.com/nicobailon/pi-mcp-adapter';
|
|
31
|
+
/**
|
|
32
|
+
* The adapter's own ordering sentence and list, quoted rather than restated because the two pi MCP
|
|
33
|
+
* entries have to agree about it and a paraphrase in one of them would be the drift this table
|
|
34
|
+
* exists to prevent. It is also the sentence WP3's setup card (#343) built its “yours wins” claim
|
|
35
|
+
* on, so the two surfaces now quote one string.
|
|
36
|
+
*/
|
|
37
|
+
const PI_MCP_PRECEDENCE = '“Precedence is (later entries win): 1. ~/.config/mcp/mcp.json 2. ~/.agents/mcp.json 3. ~/.agents/mcp/mcp.json 4. <Pi agent dir>/mcp.json 5. .mcp.json 6. .pi/mcp.json”.';
|
|
9
38
|
/**
|
|
10
39
|
* The table. Order is presentation order: per runner, then user → project →
|
|
11
40
|
* local so each scope ladder reads top (broad) to bottom (specific).
|
|
@@ -198,6 +227,84 @@ export const CONFIG_FILES = [
|
|
|
198
227
|
precedence: 'Global rules. First match wins across scopes: if a project AGENTS.md exists, this global file is not read at all.',
|
|
199
228
|
docsUrl: OPENCODE_RULES_DOCS,
|
|
200
229
|
},
|
|
230
|
+
// ---- pi (#330 WP4) ----
|
|
231
|
+
// Two files pi itself reads (settings, context) and two the `pi-mcp-adapter` extension reads.
|
|
232
|
+
// Nothing else in `~/.pi/agent` is listed: `auth.json` and `models.json` both hold credentials
|
|
233
|
+
// (file header), and `models-store.json`, `mcp-cache.json`, `trust.json` and `sessions/` are
|
|
234
|
+
// pi's own runtime state rather than config a person edits.
|
|
235
|
+
//
|
|
236
|
+
// No pi entry carries `modelKey`/`modelPriority`, so `readNativeSettingsFiles('pi', …)` still
|
|
237
|
+
// finds nothing and `piModelSettingsStrategy` still reports "no native default". That is
|
|
238
|
+
// deliberate and is NOT an oversight to fix by adding the key: pi's model ids are
|
|
239
|
+
// `provider/model` composites (`core/pi-model-catalog.ts`, and `pi --model` is handed one),
|
|
240
|
+
// while its settings split the halves across `defaultProvider` and `defaultModel`, so
|
|
241
|
+
// `modelKey: 'defaultModel'` alone would report a bare half that `pi --model` does not name.
|
|
242
|
+
// And `.pi/settings.json` only applies in a folder pi has TRUSTED, a decision recorded in
|
|
243
|
+
// `~/.pi/agent/trust.json` that xezar does not read, so a project-scope model default would be
|
|
244
|
+
// a claim xezar cannot check. Wiring pi's native default is its own change: compose the two
|
|
245
|
+
// halves the way `model-settings/codex.ts` already does, and settle the trust question first.
|
|
246
|
+
{
|
|
247
|
+
id: 'pi.user.settings',
|
|
248
|
+
runners: ['pi'],
|
|
249
|
+
kind: 'settings',
|
|
250
|
+
scope: 'user',
|
|
251
|
+
resolve: (_repo, home) => join(home.pi, 'settings.json'),
|
|
252
|
+
label: '~/.pi/agent/settings.json',
|
|
253
|
+
format: 'json',
|
|
254
|
+
tracked: 'outside-repo',
|
|
255
|
+
precedence: 'Global (all projects). “Pi uses JSON settings files with project settings overriding global settings.” A project’s .pi/settings.json overrides this, but only in a folder pi has trusted; defaultProjectTrust and httpProxy are marked “Global setting only” and cannot be overridden at project scope.',
|
|
256
|
+
docsUrl: PI_SETTINGS_DOCS,
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
id: 'pi.project.settings',
|
|
260
|
+
runners: ['pi'],
|
|
261
|
+
kind: 'settings',
|
|
262
|
+
scope: 'project',
|
|
263
|
+
resolve: (repo) => join(repo, '.pi', 'settings.json'),
|
|
264
|
+
label: '.pi/settings.json',
|
|
265
|
+
format: 'json',
|
|
266
|
+
tracked: 'tracked',
|
|
267
|
+
precedence: 'Project (current directory), overriding the global file key by key. Read ONLY in a folder pi has trusted, and trust grants more than reading: “Trusting a project allows pi to load .pi/settings.json and .pi resources, install missing project packages, and execute project extensions.” Non-interactive runs (-p, --mode json, --mode rpc) never prompt, but they are not a blanket refusal: “Without an applicable saved trust decision, they use defaultProjectTrust from global settings: ask (default) and never ignore those project resources, while always trusts them.” So this file DOES apply in such a run when a saved decision in ~/.pi/agent/trust.json covers the folder or a parent, when defaultProjectTrust is “always”, or when the run passes --approve/-a (“Pass --approve/-a or --no-approve/-na to override project trust for one run.”). Runs read the committed copy.',
|
|
268
|
+
docsUrl: PI_SETTINGS_DOCS,
|
|
269
|
+
},
|
|
270
|
+
{
|
|
271
|
+
id: 'pi.user.mcp',
|
|
272
|
+
runners: ['pi'],
|
|
273
|
+
kind: 'mcp',
|
|
274
|
+
scope: 'user',
|
|
275
|
+
resolve: (_repo, home) => join(home.pi, 'mcp.json'),
|
|
276
|
+
label: '~/.pi/agent/mcp.json',
|
|
277
|
+
format: 'json',
|
|
278
|
+
tracked: 'outside-repo',
|
|
279
|
+
holdsMcp: true,
|
|
280
|
+
precedence: `Pi global override — 4th of six sources, so both project files beat it. ${PI_MCP_PRECEDENCE} Read by the pi-mcp-adapter extension, not by pi itself: with the extension not installed pi reads no MCP config at all.`,
|
|
281
|
+
docsUrl: PI_MCP_DOCS,
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
id: 'pi.project.mcp',
|
|
285
|
+
runners: ['pi'],
|
|
286
|
+
kind: 'mcp',
|
|
287
|
+
scope: 'project',
|
|
288
|
+
resolve: (repo) => join(repo, '.pi', 'mcp.json'),
|
|
289
|
+
label: '.pi/mcp.json',
|
|
290
|
+
format: 'json',
|
|
291
|
+
tracked: 'tracked',
|
|
292
|
+
holdsMcp: true,
|
|
293
|
+
precedence: `Pi project override — the HIGHEST of the six sources. ${PI_MCP_PRECEDENCE} Read by the pi-mcp-adapter extension, not by pi itself. Runs read the committed copy.`,
|
|
294
|
+
docsUrl: PI_MCP_DOCS,
|
|
295
|
+
},
|
|
296
|
+
{
|
|
297
|
+
id: 'pi.user.memory',
|
|
298
|
+
runners: ['pi'],
|
|
299
|
+
kind: 'memory',
|
|
300
|
+
scope: 'user',
|
|
301
|
+
resolve: (_repo, home) => join(home.pi, 'AGENTS.md'),
|
|
302
|
+
label: '~/.pi/agent/AGENTS.md',
|
|
303
|
+
format: 'markdown',
|
|
304
|
+
tracked: 'outside-repo',
|
|
305
|
+
precedence: 'Global instructions, loaded first and not replaced by a project file. pi’s docs give the sources as a list, so they are quoted as one — “Pi loads AGENTS.md or CLAUDE.md at startup from:” (1) “~/.pi/agent/AGENTS.md for global instructions”, (2) “parent directories, walking up from the current working directory”, (3) “the current directory”. Two qualifiers from the same page: a per-directory override — “If a directory contains AGENTS.override.md, Pi loads it instead of AGENTS.md or CLAUDE.md from that directory. Context files from other directories still layer normally.”, which is why a project’s override does not displace THIS file (an AGENTS.override.md in pi’s own home would) — and an off switch, “Disable loading with --no-context-files or -nc”, which skips every source including this one. xezar catalogs no AGENTS.override.md at any scope. pi therefore also reads this repo’s AGENTS.md and CLAUDE.md; those entries stay listed under the vendors whose precedence rules they carry.',
|
|
306
|
+
docsUrl: PI_USAGE_DOCS,
|
|
307
|
+
},
|
|
201
308
|
// ---- Shared: <repo>/AGENTS.md is read by BOTH Codex and OpenCode ----
|
|
202
309
|
{
|
|
203
310
|
id: 'project.agents',
|