@qodeca/xezar 0.13.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (250) hide show
  1. package/README.md +72 -39
  2. package/dist/agent-config/account-identity.d.ts +2 -8
  3. package/dist/agent-config/account-identity.js +54 -10
  4. package/dist/agent-config/account-identity.js.map +1 -1
  5. package/dist/agent-config/catalog.d.ts +49 -7
  6. package/dist/agent-config/catalog.js +107 -0
  7. package/dist/agent-config/catalog.js.map +1 -1
  8. package/dist/agent-config/model-settings/pi.d.ts +12 -6
  9. package/dist/agent-config/model-settings/pi.js +12 -6
  10. package/dist/agent-config/model-settings/pi.js.map +1 -1
  11. package/dist/agent-config/seed.js +10 -0
  12. package/dist/agent-config/seed.js.map +1 -1
  13. package/dist/contract/github.d.ts +15 -0
  14. package/dist/contract/index.d.ts +9 -0
  15. package/dist/contract/index.js +1527 -895
  16. package/dist/contract/mcp-api-reference.d.ts +174 -0
  17. package/dist/contract/mcp-audit.d.ts +103 -0
  18. package/dist/contract/mcp-discovery.d.ts +257 -0
  19. package/dist/contract/mcp-event-catalog.d.ts +121 -0
  20. package/dist/contract/mcp-event-catalog.test.d.ts +1 -0
  21. package/dist/contract/mcp-idempotency.d.ts +200 -0
  22. package/dist/contract/mcp-journal.d.ts +268 -0
  23. package/dist/contract/mcp-leader.d.ts +88 -0
  24. package/dist/contract/mcp-ownership.d.ts +78 -0
  25. package/dist/contract/mcp-versioning.d.ts +139 -0
  26. package/dist/contract/runs.d.ts +81 -0
  27. package/dist/core/agent-profiles.d.ts +15 -4
  28. package/dist/core/agent-profiles.js +22 -8
  29. package/dist/core/agent-profiles.js.map +1 -1
  30. package/dist/core/opencode-server-runner.js +71 -11
  31. package/dist/core/opencode-server-runner.js.map +1 -1
  32. package/dist/core/secret-redaction.d.ts +7 -1
  33. package/dist/core/secret-redaction.js +44 -10
  34. package/dist/core/secret-redaction.js.map +1 -1
  35. package/dist/index.js +138 -27
  36. package/dist/index.js.map +1 -1
  37. package/dist/machine-identity.d.ts +66 -0
  38. package/dist/machine-identity.js +96 -0
  39. package/dist/machine-identity.js.map +1 -0
  40. package/dist/mcp/adapters/claude-code.d.ts +41 -0
  41. package/dist/mcp/adapters/claude-code.js +40 -0
  42. package/dist/mcp/adapters/claude-code.js.map +1 -0
  43. package/dist/mcp/adapters/codex.d.ts +140 -0
  44. package/dist/mcp/adapters/codex.js +323 -0
  45. package/dist/mcp/adapters/codex.js.map +1 -0
  46. package/dist/mcp/adapters/opencode.d.ts +148 -0
  47. package/dist/mcp/adapters/opencode.js +528 -0
  48. package/dist/mcp/adapters/opencode.js.map +1 -0
  49. package/dist/mcp/adapters/pi-link.d.ts +102 -0
  50. package/dist/mcp/adapters/pi-link.js +235 -0
  51. package/dist/mcp/adapters/pi-link.js.map +1 -0
  52. package/dist/mcp/adapters/pi.d.ts +188 -0
  53. package/dist/mcp/adapters/pi.js +418 -0
  54. package/dist/mcp/adapters/pi.js.map +1 -0
  55. package/dist/mcp/api-reference.d.ts +26 -0
  56. package/dist/mcp/api-reference.js +133 -0
  57. package/dist/mcp/api-reference.js.map +1 -0
  58. package/dist/mcp/audit-trail.d.ts +162 -0
  59. package/dist/mcp/audit-trail.js +306 -0
  60. package/dist/mcp/audit-trail.js.map +1 -0
  61. package/dist/mcp/bridge.d.ts +81 -0
  62. package/dist/mcp/bridge.js +407 -0
  63. package/dist/mcp/bridge.js.map +1 -0
  64. package/dist/mcp/connection-file.d.ts +49 -0
  65. package/dist/mcp/connection-file.js +63 -0
  66. package/dist/mcp/connection-file.js.map +1 -0
  67. package/dist/mcp/echo-guard.d.ts +94 -0
  68. package/dist/mcp/echo-guard.js +160 -0
  69. package/dist/mcp/echo-guard.js.map +1 -0
  70. package/dist/mcp/event-catalog.d.ts +120 -0
  71. package/dist/mcp/event-catalog.js +306 -0
  72. package/dist/mcp/event-catalog.js.map +1 -0
  73. package/dist/mcp/event-controller.d.ts +230 -0
  74. package/dist/mcp/event-controller.js +596 -0
  75. package/dist/mcp/event-controller.js.map +1 -0
  76. package/dist/mcp/event-journal.d.ts +57 -0
  77. package/dist/mcp/event-journal.js +423 -0
  78. package/dist/mcp/event-journal.js.map +1 -0
  79. package/dist/mcp/index.d.ts +63 -0
  80. package/dist/mcp/index.js +386 -0
  81. package/dist/mcp/index.js.map +1 -0
  82. package/dist/mcp/ipc.d.ts +202 -0
  83. package/dist/mcp/ipc.js +206 -0
  84. package/dist/mcp/ipc.js.map +1 -0
  85. package/dist/mcp/leader-delivery.d.ts +119 -0
  86. package/dist/mcp/leader-delivery.js +450 -0
  87. package/dist/mcp/leader-delivery.js.map +1 -0
  88. package/dist/mcp/operation-receipts.d.ts +210 -0
  89. package/dist/mcp/operation-receipts.js +723 -0
  90. package/dist/mcp/operation-receipts.js.map +1 -0
  91. package/dist/mcp/project-catalogs.d.ts +23 -0
  92. package/dist/mcp/project-catalogs.js +25 -0
  93. package/dist/mcp/project-catalogs.js.map +1 -0
  94. package/dist/mcp/project-leaders.d.ts +26 -0
  95. package/dist/mcp/project-leaders.js +17 -0
  96. package/dist/mcp/project-leaders.js.map +1 -0
  97. package/dist/mcp/protocol.d.ts +50 -0
  98. package/dist/mcp/protocol.js +47 -0
  99. package/dist/mcp/protocol.js.map +1 -0
  100. package/dist/mcp/reconnect.d.ts +297 -0
  101. package/dist/mcp/reconnect.js +465 -0
  102. package/dist/mcp/reconnect.js.map +1 -0
  103. package/dist/mcp/resource-ownership.d.ts +228 -0
  104. package/dist/mcp/resource-ownership.js +390 -0
  105. package/dist/mcp/resource-ownership.js.map +1 -0
  106. package/dist/mcp/service-adapter.d.ts +16488 -0
  107. package/dist/mcp/service-adapter.js +148 -0
  108. package/dist/mcp/service-adapter.js.map +1 -0
  109. package/dist/mcp/service.d.ts +83 -0
  110. package/dist/mcp/service.js +233 -0
  111. package/dist/mcp/service.js.map +1 -0
  112. package/dist/mcp/session-binding.d.ts +105 -0
  113. package/dist/mcp/session-binding.js +163 -0
  114. package/dist/mcp/session-binding.js.map +1 -0
  115. package/dist/mcp/stale-write.d.ts +145 -0
  116. package/dist/mcp/stale-write.js +219 -0
  117. package/dist/mcp/stale-write.js.map +1 -0
  118. package/dist/mcp/tool.d.ts +48 -0
  119. package/dist/mcp/tool.js +24 -0
  120. package/dist/mcp/tool.js.map +1 -0
  121. package/dist/mcp/tools/discovery.d.ts +40 -0
  122. package/dist/mcp/tools/discovery.js +232 -0
  123. package/dist/mcp/tools/discovery.js.map +1 -0
  124. package/dist/mcp/tools/execution-control.d.ts +171 -0
  125. package/dist/mcp/tools/execution-control.js +513 -0
  126. package/dist/mcp/tools/execution-control.js.map +1 -0
  127. package/dist/mcp/tools/handoff-git.d.ts +26 -0
  128. package/dist/mcp/tools/handoff-git.js +544 -0
  129. package/dist/mcp/tools/handoff-git.js.map +1 -0
  130. package/dist/mcp/tools/index.d.ts +2 -0
  131. package/dist/mcp/tools/index.js +23 -0
  132. package/dist/mcp/tools/index.js.map +1 -0
  133. package/dist/mcp/tools/leader-events.d.ts +46 -0
  134. package/dist/mcp/tools/leader-events.js +126 -0
  135. package/dist/mcp/tools/leader-events.js.map +1 -0
  136. package/dist/mcp/tools/local-handoff.d.ts +102 -0
  137. package/dist/mcp/tools/local-handoff.js +306 -0
  138. package/dist/mcp/tools/local-handoff.js.map +1 -0
  139. package/dist/mcp/tools/project-config.d.ts +340 -0
  140. package/dist/mcp/tools/project-config.js +1075 -0
  141. package/dist/mcp/tools/project-config.js.map +1 -0
  142. package/dist/mcp/tools/results-evidence.d.ts +112 -0
  143. package/dist/mcp/tools/results-evidence.js +1045 -0
  144. package/dist/mcp/tools/results-evidence.js.map +1 -0
  145. package/dist/mcp/tools/task-create.d.ts +70 -0
  146. package/dist/mcp/tools/task-create.js +473 -0
  147. package/dist/mcp/tools/task-create.js.map +1 -0
  148. package/dist/mcp/tools/task-reads.d.ts +102 -0
  149. package/dist/mcp/tools/task-reads.js +689 -0
  150. package/dist/mcp/tools/task-reads.js.map +1 -0
  151. package/dist/mcp/tools/work-organisation.d.ts +2 -0
  152. package/dist/mcp/tools/work-organisation.js +502 -0
  153. package/dist/mcp/tools/work-organisation.js.map +1 -0
  154. package/dist/paths.d.ts +17 -7
  155. package/dist/paths.js +18 -8
  156. package/dist/paths.js.map +1 -1
  157. package/dist/runs/project-writer.js +76 -11
  158. package/dist/runs/project-writer.js.map +1 -1
  159. package/dist/runs/retention.d.ts +25 -2
  160. package/dist/runs/retention.js +63 -2
  161. package/dist/runs/retention.js.map +1 -1
  162. package/dist/server/forge/github.js +44 -0
  163. package/dist/server/forge/github.js.map +1 -1
  164. package/dist/server/forge/types.d.ts +16 -0
  165. package/dist/server/project-context.d.ts +81 -8
  166. package/dist/server/project-context.js +143 -35
  167. package/dist/server/project-context.js.map +1 -1
  168. package/dist/server/server.d.ts +1050 -53
  169. package/dist/server/server.js +326 -120
  170. package/dist/server/server.js.map +1 -1
  171. package/dist/server/validators.d.ts +26 -6
  172. package/dist/server/validators.js +17 -0
  173. package/dist/server/validators.js.map +1 -1
  174. package/dist/skills-remote.js +64 -6
  175. package/dist/skills-remote.js.map +1 -1
  176. package/dist/workflows/run.d.ts +277 -12
  177. package/dist/workflows/run.js +599 -79
  178. package/dist/workflows/run.js.map +1 -1
  179. package/dist/workspace/agent-profiles.d.ts +30 -3
  180. package/dist/workspace/agent-profiles.js +39 -4
  181. package/dist/workspace/agent-profiles.js.map +1 -1
  182. package/dist/workspace/config.js +25 -4
  183. package/dist/workspace/config.js.map +1 -1
  184. package/dist/workspace/project-owner.d.ts +210 -0
  185. package/dist/workspace/project-owner.js +518 -0
  186. package/dist/workspace/project-owner.js.map +1 -0
  187. package/package.json +5 -3
  188. package/scripts/pi-leader-extension.ts +420 -0
  189. package/scripts/sync-readme.mjs +83 -2
  190. package/web/dist/assets/{alert-dialog-BVsVcbFy.js → alert-dialog-D6rP6d39.js} +1 -1
  191. package/web/dist/assets/arrow-down-DMOfFIzW.js +1 -0
  192. package/web/dist/assets/arrow-left-C4Ec2BUg.js +1 -0
  193. package/web/dist/assets/{centered-state-Djgly6Ni.js → centered-state-B0ZqrPaa.js} +12 -12
  194. package/web/dist/assets/chevron-right-mHJ-crvn.js +1 -0
  195. package/web/dist/assets/{collapsible-DZ4D-DHG.js → collapsible-DchEHgUM.js} +1 -1
  196. package/web/dist/assets/{commit-list-B-z1JL9G.js → commit-list-BpMim1Rv.js} +1 -1
  197. package/web/dist/assets/{compare-variants-CdS8r8E2.js → compare-variants-D5ItQbAq.js} +1 -1
  198. package/web/dist/assets/{diff-BKew9rQX.js → diff-HqqZ_WDR.js} +2 -2
  199. package/web/dist/assets/{diff-stat-D0mc5V6Z.js → diff-stat-NsU-3ecr.js} +1 -1
  200. package/web/dist/assets/{diff-view-xpIcuLIC.js → diff-view-B7c11Xux.js} +1 -1
  201. package/web/dist/assets/{dropdown-menu-CEQziH7X.js → dropdown-menu-CtTpnyod.js} +1 -1
  202. package/web/dist/assets/{editable-title-BCX3T2BY.js → editable-title-BXtuGQry.js} +1 -1
  203. package/web/dist/assets/{ellipsis-vertical-ByVdDc4z.js → ellipsis-vertical-MHtGZSH6.js} +1 -1
  204. package/web/dist/assets/{file-xBSB5hXO.js → file-DKLw5SOb.js} +1 -1
  205. package/web/dist/assets/{folder-CldgbZ5A.js → folder-Drw6-ufH.js} +1 -1
  206. package/web/dist/assets/{git-toolbar-BYlnf4qf.js → git-toolbar-BQH8bORV.js} +1 -1
  207. package/web/dist/assets/github-ynnpKFCJ.js +1 -0
  208. package/web/dist/assets/{image-preview-Cv5mZr0n.js → image-preview-DLhMN_R9.js} +1 -1
  209. package/web/dist/assets/index-BEsrNdXt.js +29 -0
  210. package/web/dist/assets/index-Da8DOBau.css +2 -0
  211. package/web/dist/assets/{markdown-CgEEE2ND.js → markdown-q365eN6Y.js} +1 -1
  212. package/web/dist/assets/{new-task-form-1r2bgsdD.js → new-task-form-CW-hNIWQ.js} +1 -1
  213. package/web/dist/assets/{pill-q-x22_ej.js → pill-B_TFulXa.js} +1 -1
  214. package/web/dist/assets/{project-router-VDN4jQM8.js → project-router-CLPc-ImZ.js} +1 -1
  215. package/web/dist/assets/{prompt-templates-BmZtCe-L.js → prompt-templates-CLc4RxyO.js} +1 -1
  216. package/web/dist/assets/{repo-git-C2On8SlI.js → repo-git-Is7R6-Tj.js} +1 -1
  217. package/web/dist/assets/{run-diff-vguEMJzh.js → run-diff-DHMvDlVo.js} +2 -2
  218. package/web/dist/assets/run-header-DvZJbQ8I.js +1 -0
  219. package/web/dist/assets/{search-x-QmhaAbg5.js → search-x-Ce2MMetu.js} +1 -1
  220. package/web/dist/assets/{skill-empty-hint-BrzUwByZ.js → skill-empty-hint-C_xCSvzB.js} +1 -1
  221. package/web/dist/assets/skills-CivqD4si.js +1 -0
  222. package/web/dist/assets/{sparkles-CP8QDOgX.js → sparkles-BCqPoj5g.js} +1 -1
  223. package/web/dist/assets/{square-terminal-CGypshSD.js → square-terminal-ikj5g-oK.js} +1 -1
  224. package/web/dist/assets/{tab-link-D4lFzzI1.js → tab-link-VsEjFV1Y.js} +1 -1
  225. package/web/dist/assets/{task-changes-6aopqAmV.js → task-changes-CH-E81-_.js} +1 -1
  226. package/web/dist/assets/{task-commits-u-dwaCyw.js → task-commits-DqfkMFxp.js} +1 -1
  227. package/web/dist/assets/{task-files-IMOZnIUK.js → task-files-D_nkHZ_a.js} +2 -2
  228. package/web/dist/assets/task-thread-bxQompxJ.js +9 -0
  229. package/web/dist/assets/{textarea-CyBCyKIk.js → textarea-xajuW1L_.js} +1 -1
  230. package/web/dist/assets/{thread-loading-Cuq2jchC.js → thread-loading-C3JQZbIE.js} +1 -1
  231. package/web/dist/assets/{trash-2-B6Dp3ZNs.js → trash-2-hJrBhpUD.js} +1 -1
  232. package/web/dist/assets/{triangle-alert-xBya8FUp.js → triangle-alert-D1u82y1a.js} +1 -1
  233. package/web/dist/assets/{upload-D6MXEB9p.js → upload-Bn6FBZ59.js} +1 -1
  234. package/web/dist/assets/{use-desktop-fLDKEJoB.js → use-desktop-DOIMfHfY.js} +1 -1
  235. package/web/dist/assets/{use-submit-shortcut-JTpNzU-u.js → use-submit-shortcut-Dj4DHTdE.js} +1 -1
  236. package/web/dist/assets/utils-YwBpOoRN.js +64 -0
  237. package/web/dist/assets/{workflows-BY3KTkFw.js → workflows-CTaAKz2m.js} +3 -3
  238. package/web/dist/assets/{zoomable-image-GTYwLtkS.js → zoomable-image-C1-6P3tg.js} +1 -1
  239. package/web/dist/index.html +23 -23
  240. package/web/dist/assets/arrow-down-CYgAlZtW.js +0 -1
  241. package/web/dist/assets/arrow-left-BOqE0a3k.js +0 -1
  242. package/web/dist/assets/chevron-right-Cc9BWnbN.js +0 -1
  243. package/web/dist/assets/github-CqGK62Lw.js +0 -1
  244. package/web/dist/assets/index-3nxVmdn5.css +0 -2
  245. package/web/dist/assets/index-qX7n11FX.js +0 -9
  246. package/web/dist/assets/refresh-cw-DcNCj2nu.js +0 -1
  247. package/web/dist/assets/run-header-DM7MiKj9.js +0 -1
  248. package/web/dist/assets/skills-Bj-uG_Hz.js +0 -1
  249. package/web/dist/assets/task-thread-CbMPmrWq.js +0 -9
  250. package/web/dist/assets/utils--z9hRtl3.js +0 -64
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
+ [![CI](https://github.com/qodeca/xezar/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/qodeca/xezar/actions/workflows/ci.yml)
22
23
  [![npm](https://img.shields.io/npm/v/@qodeca/xezar?color=cb3837&logo=npm)](https://www.npmjs.com/package/@qodeca/xezar)
23
- [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
24
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/qodeca/xezar/blob/main/LICENSE)
24
25
  ![Node 20+](https://img.shields.io/badge/Node-20%2B-339933)
25
26
  ![TypeScript 7.x](https://img.shields.io/badge/TypeScript-7.x-3178c6)
26
27
  ![Zero config](https://img.shields.io/badge/config-zero-success)
@@ -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
- | [![The Tasks view — parallel runs, a queue with positions, per-run cost and peak memory, and a variants compare card](docs/screenshots/task-view.png)](docs/screenshots/task-view.png) | [![A running task streaming agent text, tool calls and screenshots live](docs/screenshots/live-run.png)](docs/screenshots/live-run.png) | [![Two competing variants of the same task compared side by side — pick the winner](docs/screenshots/variants-compare.png)](docs/screenshots/variants-compare.png) |
54
+ | [![The Tasks view — parallel runs, a queue with positions, per-run cost and peak memory, and a variants compare card](https://raw.githubusercontent.com/qodeca/xezar/main/docs/screenshots/task-view.png)](https://raw.githubusercontent.com/qodeca/xezar/main/docs/screenshots/task-view.png) | [![A running task streaming agent text, tool calls and screenshots live](https://raw.githubusercontent.com/qodeca/xezar/main/docs/screenshots/live-run.png)](https://raw.githubusercontent.com/qodeca/xezar/main/docs/screenshots/live-run.png) | [![Two competing variants of the same task compared side by side — pick the winner](https://raw.githubusercontent.com/qodeca/xezar/main/docs/screenshots/variants-compare.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
- | [![The workflow builder — drag skills into an ordered chain of agent steps and shell checks](docs/screenshots/workflow-builder.png)](docs/screenshots/workflow-builder.png) | [![The GitHub tab — hand an open issue to the agent with a workflow and skills](docs/screenshots/github-issues.png)](docs/screenshots/github-issues.png) | [![The task composer — pick a skill playbook and flip the Autonomous flag to run unattended](docs/screenshots/skills-autonomous.png)](docs/screenshots/skills-autonomous.png) |
57
+ | [![The workflow builder — drag skills into an ordered chain of agent steps and shell checks](https://raw.githubusercontent.com/qodeca/xezar/main/docs/screenshots/workflow-builder.png)](https://raw.githubusercontent.com/qodeca/xezar/main/docs/screenshots/workflow-builder.png) | [![The GitHub tab — hand an open issue to the agent with a workflow and skills](https://raw.githubusercontent.com/qodeca/xezar/main/docs/screenshots/github-issues.png)](https://raw.githubusercontent.com/qodeca/xezar/main/docs/screenshots/github-issues.png) | [![The task composer — pick a skill playbook and flip the Autonomous flag to run unattended](https://raw.githubusercontent.com/qodeca/xezar/main/docs/screenshots/skills-autonomous.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 OpenCode (experimental)** through one runner seam — set a
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), or
151
- [OpenCode](https://opencode.ai) — and, optionally, `git` and the `gh` CLI.
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 OpenCode are drop-in alternatives, per task
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
- Five moves that make the cockpit worth the browser tab:
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 the skills catalog. |
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
- **Worktrees**, **Bookmarklets**, **Prompt templates** and **MCP** describe one
378
- repo and live under `/p/<projectId>/settings`; **Appearance**,
379
- **Notifications**, **Resources**, **Projects** and **Keyboard** are yours or the
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 Claude, Codex and
627
- OpenCode xezar asks the CLI on your host what *it* currently offers (Claude
628
- Code's `list_models` control request; the Codex app-server's `model/list`;
629
- `opencode models`) and shows exactly that, in that order — so a model your
630
- account gained yesterday is selectable today with no xezar release, and one your
631
- provider retired stops being offered. Discovery is read-only, costs no tokens,
632
- and is cached briefly in memory. If the CLI is missing, logged out, too old or
633
- slow, the picker quietly falls back to that runner's built-in entries (`auto`
634
- plus Claude's tier aliases) and says so in a status row; `pi`, which has no
635
- host-local catalog yet, always shows its built-in entries. `auto` — send no
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. Other CLIs pi, aider, whatever ships next
692
- can slot in the same way.
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 OpenCode read for settings,
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 api-client and the server (`tsc → packages/xezar/dist/`) and the cockpit
827
- (`vite build → packages/xezar/web/dist/`), then runs the pack gate:
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 before changing them.
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. OpenCode answers "unsupported": its credentials live in a SQLite DB outside the
114
- * config dir (see `core/agent-profiles.ts`), so there is nothing in a config folder to read and
115
- * guessing from the default login would attribute one account's identity to another.
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
- export async function readAccountIdentity(provider, configDir) {
118
- if (provider === 'claude')
119
- return readClaudeIdentity(configDir);
120
- if (provider === 'codex')
121
- return readCodexIdentity(configDir);
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":"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"}
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`, `settings.json`, and the
33
- * `auth.json` xezar never reads). No vendor variable relocates it (verified against pi 0.85.1,
34
- * 2026-09-10), which is why this slot carries no `env.` alternative the way the three above do.
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` lists no pi entry yet, so nothing in the raw config editor resolves through
37
- * this slot today; model discovery (#152) does, and it lives here so pi's home is derived in
38
- * the one place every other agent's is.
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',