@qodeca/xezar 0.10.1

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 (481) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +810 -0
  3. package/dist/agent-config/account-identity.d.ts +44 -0
  4. package/dist/agent-config/account-identity.js +128 -0
  5. package/dist/agent-config/account-identity.js.map +1 -0
  6. package/dist/agent-config/catalog.d.ts +71 -0
  7. package/dist/agent-config/catalog.js +223 -0
  8. package/dist/agent-config/catalog.js.map +1 -0
  9. package/dist/agent-config/files.d.ts +46 -0
  10. package/dist/agent-config/files.js +119 -0
  11. package/dist/agent-config/files.js.map +1 -0
  12. package/dist/agent-config/model-settings/claude.d.ts +2 -0
  13. package/dist/agent-config/model-settings/claude.js +11 -0
  14. package/dist/agent-config/model-settings/claude.js.map +1 -0
  15. package/dist/agent-config/model-settings/codex.d.ts +2 -0
  16. package/dist/agent-config/model-settings/codex.js +16 -0
  17. package/dist/agent-config/model-settings/codex.js.map +1 -0
  18. package/dist/agent-config/model-settings/opencode.d.ts +2 -0
  19. package/dist/agent-config/model-settings/opencode.js +8 -0
  20. package/dist/agent-config/model-settings/opencode.js.map +1 -0
  21. package/dist/agent-config/model-settings/pi.d.ts +12 -0
  22. package/dist/agent-config/model-settings/pi.js +18 -0
  23. package/dist/agent-config/model-settings/pi.js.map +1 -0
  24. package/dist/agent-config/model-settings/shared.d.ts +9 -0
  25. package/dist/agent-config/model-settings/shared.js +93 -0
  26. package/dist/agent-config/model-settings/shared.js.map +1 -0
  27. package/dist/agent-config/model-settings/types.d.ts +9 -0
  28. package/dist/agent-config/model-settings/types.js +2 -0
  29. package/dist/agent-config/model-settings/types.js.map +1 -0
  30. package/dist/agent-config/models.d.ts +9 -0
  31. package/dist/agent-config/models.js +32 -0
  32. package/dist/agent-config/models.js.map +1 -0
  33. package/dist/agent-config/seed.d.ts +7 -0
  34. package/dist/agent-config/seed.js +90 -0
  35. package/dist/agent-config/seed.js.map +1 -0
  36. package/dist/agent-config/service.d.ts +44 -0
  37. package/dist/agent-config/service.js +71 -0
  38. package/dist/agent-config/service.js.map +1 -0
  39. package/dist/agent-config/validate.d.ts +21 -0
  40. package/dist/agent-config/validate.js +76 -0
  41. package/dist/agent-config/validate.js.map +1 -0
  42. package/dist/automations/coordinator.d.ts +26 -0
  43. package/dist/automations/coordinator.js +66 -0
  44. package/dist/automations/coordinator.js.map +1 -0
  45. package/dist/automations/github-poller.d.ts +74 -0
  46. package/dist/automations/github-poller.js +234 -0
  47. package/dist/automations/github-poller.js.map +1 -0
  48. package/dist/automations/scheduler.d.ts +42 -0
  49. package/dist/automations/scheduler.js +192 -0
  50. package/dist/automations/scheduler.js.map +1 -0
  51. package/dist/automations/store.d.ts +65 -0
  52. package/dist/automations/store.js +298 -0
  53. package/dist/automations/store.js.map +1 -0
  54. package/dist/automations/task-template.d.ts +18 -0
  55. package/dist/automations/task-template.js +95 -0
  56. package/dist/automations/task-template.js.map +1 -0
  57. package/dist/automations/types.d.ts +255 -0
  58. package/dist/automations/types.js +159 -0
  59. package/dist/automations/types.js.map +1 -0
  60. package/dist/config.d.ts +77 -0
  61. package/dist/config.js +242 -0
  62. package/dist/config.js.map +1 -0
  63. package/dist/contract/agent-config.d.ts +153 -0
  64. package/dist/contract/agent-profiles.d.ts +347 -0
  65. package/dist/contract/automations.d.ts +935 -0
  66. package/dist/contract/events.d.ts +104 -0
  67. package/dist/contract/github.d.ts +597 -0
  68. package/dist/contract/health.d.ts +102 -0
  69. package/dist/contract/index.d.ts +16 -0
  70. package/dist/contract/index.js +1953 -0
  71. package/dist/contract/projects.d.ts +210 -0
  72. package/dist/contract/repo.d.ts +234 -0
  73. package/dist/contract/runs.d.ts +1527 -0
  74. package/dist/contract/skills.d.ts +234 -0
  75. package/dist/contract/workflows.d.ts +218 -0
  76. package/dist/contract/workspace.d.ts +579 -0
  77. package/dist/core/agent-env.d.ts +31 -0
  78. package/dist/core/agent-env.js +371 -0
  79. package/dist/core/agent-env.js.map +1 -0
  80. package/dist/core/agent-model-policy.d.ts +10 -0
  81. package/dist/core/agent-model-policy.js +36 -0
  82. package/dist/core/agent-model-policy.js.map +1 -0
  83. package/dist/core/agent-profiles.d.ts +62 -0
  84. package/dist/core/agent-profiles.js +90 -0
  85. package/dist/core/agent-profiles.js.map +1 -0
  86. package/dist/core/agent-runner.d.ts +211 -0
  87. package/dist/core/agent-runner.js +68 -0
  88. package/dist/core/agent-runner.js.map +1 -0
  89. package/dist/core/ask.d.ts +115 -0
  90. package/dist/core/ask.js +256 -0
  91. package/dist/core/ask.js.map +1 -0
  92. package/dist/core/backend-detect.d.ts +16 -0
  93. package/dist/core/backend-detect.js +155 -0
  94. package/dist/core/backend-detect.js.map +1 -0
  95. package/dist/core/claude-cli-runner.d.ts +65 -0
  96. package/dist/core/claude-cli-runner.js +479 -0
  97. package/dist/core/claude-cli-runner.js.map +1 -0
  98. package/dist/core/claude-model-catalog.d.ts +24 -0
  99. package/dist/core/claude-model-catalog.js +208 -0
  100. package/dist/core/claude-model-catalog.js.map +1 -0
  101. package/dist/core/claude-ui-mapper.d.ts +79 -0
  102. package/dist/core/claude-ui-mapper.js +597 -0
  103. package/dist/core/claude-ui-mapper.js.map +1 -0
  104. package/dist/core/codex-app-server-runner.d.ts +41 -0
  105. package/dist/core/codex-app-server-runner.js +584 -0
  106. package/dist/core/codex-app-server-runner.js.map +1 -0
  107. package/dist/core/codex-app-server-transport.d.ts +35 -0
  108. package/dist/core/codex-app-server-transport.js +150 -0
  109. package/dist/core/codex-app-server-transport.js.map +1 -0
  110. package/dist/core/codex-model-catalog.d.ts +10 -0
  111. package/dist/core/codex-model-catalog.js +110 -0
  112. package/dist/core/codex-model-catalog.js.map +1 -0
  113. package/dist/core/codex-ui-mapper.d.ts +109 -0
  114. package/dist/core/codex-ui-mapper.js +764 -0
  115. package/dist/core/codex-ui-mapper.js.map +1 -0
  116. package/dist/core/model-identity.d.ts +125 -0
  117. package/dist/core/model-identity.js +132 -0
  118. package/dist/core/model-identity.js.map +1 -0
  119. package/dist/core/model-presets.d.ts +21 -0
  120. package/dist/core/model-presets.js +91 -0
  121. package/dist/core/model-presets.js.map +1 -0
  122. package/dist/core/ndjson.d.ts +6 -0
  123. package/dist/core/ndjson.js +23 -0
  124. package/dist/core/ndjson.js.map +1 -0
  125. package/dist/core/opencode-model-catalog.d.ts +32 -0
  126. package/dist/core/opencode-model-catalog.js +153 -0
  127. package/dist/core/opencode-model-catalog.js.map +1 -0
  128. package/dist/core/opencode-server-runner.d.ts +32 -0
  129. package/dist/core/opencode-server-runner.js +535 -0
  130. package/dist/core/opencode-server-runner.js.map +1 -0
  131. package/dist/core/opencode-ui-mapper.d.ts +111 -0
  132. package/dist/core/opencode-ui-mapper.js +668 -0
  133. package/dist/core/opencode-ui-mapper.js.map +1 -0
  134. package/dist/core/pi-runner.d.ts +24 -0
  135. package/dist/core/pi-runner.js +349 -0
  136. package/dist/core/pi-runner.js.map +1 -0
  137. package/dist/core/pi-ui-mapper.d.ts +34 -0
  138. package/dist/core/pi-ui-mapper.js +270 -0
  139. package/dist/core/pi-ui-mapper.js.map +1 -0
  140. package/dist/core/process-usage.d.ts +66 -0
  141. package/dist/core/process-usage.js +193 -0
  142. package/dist/core/process-usage.js.map +1 -0
  143. package/dist/core/provider-auth.d.ts +154 -0
  144. package/dist/core/provider-auth.js +509 -0
  145. package/dist/core/provider-auth.js.map +1 -0
  146. package/dist/core/provider-availability.d.ts +3 -0
  147. package/dist/core/provider-availability.js +14 -0
  148. package/dist/core/provider-availability.js.map +1 -0
  149. package/dist/core/runner-factory.d.ts +8 -0
  150. package/dist/core/runner-factory.js +25 -0
  151. package/dist/core/runner-factory.js.map +1 -0
  152. package/dist/core/runner-model-catalog.d.ts +28 -0
  153. package/dist/core/runner-model-catalog.js +62 -0
  154. package/dist/core/runner-model-catalog.js.map +1 -0
  155. package/dist/core/secret-redaction.d.ts +37 -0
  156. package/dist/core/secret-redaction.js +115 -0
  157. package/dist/core/secret-redaction.js.map +1 -0
  158. package/dist/core/shell-env.d.ts +28 -0
  159. package/dist/core/shell-env.js +56 -0
  160. package/dist/core/shell-env.js.map +1 -0
  161. package/dist/core/tool-display.d.ts +31 -0
  162. package/dist/core/tool-display.js +179 -0
  163. package/dist/core/tool-display.js.map +1 -0
  164. package/dist/core/ui-events.d.ts +332 -0
  165. package/dist/core/ui-events.js +22 -0
  166. package/dist/core/ui-events.js.map +1 -0
  167. package/dist/core/usage-limit.d.ts +42 -0
  168. package/dist/core/usage-limit.js +209 -0
  169. package/dist/core/usage-limit.js.map +1 -0
  170. package/dist/core/usage.d.ts +11 -0
  171. package/dist/core/usage.js +15 -0
  172. package/dist/core/usage.js.map +1 -0
  173. package/dist/core/v1-text-coalescer.d.ts +36 -0
  174. package/dist/core/v1-text-coalescer.js +72 -0
  175. package/dist/core/v1-text-coalescer.js.map +1 -0
  176. package/dist/git-diff-base.d.ts +85 -0
  177. package/dist/git-diff-base.js +180 -0
  178. package/dist/git-diff-base.js.map +1 -0
  179. package/dist/git-refs.d.ts +11 -0
  180. package/dist/git-refs.js +14 -0
  181. package/dist/git-refs.js.map +1 -0
  182. package/dist/git-worktree.d.ts +161 -0
  183. package/dist/git-worktree.js +508 -0
  184. package/dist/git-worktree.js.map +1 -0
  185. package/dist/handoff.d.ts +62 -0
  186. package/dist/handoff.js +154 -0
  187. package/dist/handoff.js.map +1 -0
  188. package/dist/index.d.ts +2 -0
  189. package/dist/index.js +684 -0
  190. package/dist/index.js.map +1 -0
  191. package/dist/install-as-command.d.ts +40 -0
  192. package/dist/install-as-command.js +52 -0
  193. package/dist/install-as-command.js.map +1 -0
  194. package/dist/pack-check.d.ts +17 -0
  195. package/dist/pack-check.js +27 -0
  196. package/dist/pack-check.js.map +1 -0
  197. package/dist/paths.d.ts +140 -0
  198. package/dist/paths.js +192 -0
  199. package/dist/paths.js.map +1 -0
  200. package/dist/planner.d.ts +27 -0
  201. package/dist/planner.js +268 -0
  202. package/dist/planner.js.map +1 -0
  203. package/dist/release/manifests.d.ts +78 -0
  204. package/dist/release/manifests.js +57 -0
  205. package/dist/release/manifests.js.map +1 -0
  206. package/dist/release/snapshot.d.ts +67 -0
  207. package/dist/release/snapshot.js +97 -0
  208. package/dist/release/snapshot.js.map +1 -0
  209. package/dist/release/stable.d.ts +33 -0
  210. package/dist/release/stable.js +50 -0
  211. package/dist/release/stable.js.map +1 -0
  212. package/dist/runs/agent-tmpdir.d.ts +41 -0
  213. package/dist/runs/agent-tmpdir.js +183 -0
  214. package/dist/runs/agent-tmpdir.js.map +1 -0
  215. package/dist/runs/arm-repo-handle.d.ts +17 -0
  216. package/dist/runs/arm-repo-handle.js +24 -0
  217. package/dist/runs/arm-repo-handle.js.map +1 -0
  218. package/dist/runs/auto-name.d.ts +75 -0
  219. package/dist/runs/auto-name.js +179 -0
  220. package/dist/runs/auto-name.js.map +1 -0
  221. package/dist/runs/event-history.d.ts +50 -0
  222. package/dist/runs/event-history.js +613 -0
  223. package/dist/runs/event-history.js.map +1 -0
  224. package/dist/runs/retention.d.ts +60 -0
  225. package/dist/runs/retention.js +86 -0
  226. package/dist/runs/retention.js.map +1 -0
  227. package/dist/runs/review-gate.d.ts +18 -0
  228. package/dist/runs/review-gate.js +21 -0
  229. package/dist/runs/review-gate.js.map +1 -0
  230. package/dist/runs/run-index.d.ts +19 -0
  231. package/dist/runs/run-index.js +43 -0
  232. package/dist/runs/run-index.js.map +1 -0
  233. package/dist/runs/store.d.ts +490 -0
  234. package/dist/runs/store.js +1283 -0
  235. package/dist/runs/store.js.map +1 -0
  236. package/dist/runs/task-markers.d.ts +28 -0
  237. package/dist/runs/task-markers.js +74 -0
  238. package/dist/runs/task-markers.js.map +1 -0
  239. package/dist/runs/task-refs.d.ts +25 -0
  240. package/dist/runs/task-refs.js +74 -0
  241. package/dist/runs/task-refs.js.map +1 -0
  242. package/dist/runs/ui-event-sink.d.ts +80 -0
  243. package/dist/runs/ui-event-sink.js +209 -0
  244. package/dist/runs/ui-event-sink.js.map +1 -0
  245. package/dist/server/app-type.d.ts +21 -0
  246. package/dist/server/app-type.js +2 -0
  247. package/dist/server/app-type.js.map +1 -0
  248. package/dist/server/capabilities.d.ts +70 -0
  249. package/dist/server/capabilities.js +152 -0
  250. package/dist/server/capabilities.js.map +1 -0
  251. package/dist/server/checkout.d.ts +128 -0
  252. package/dist/server/checkout.js +296 -0
  253. package/dist/server/checkout.js.map +1 -0
  254. package/dist/server/forge/github.d.ts +535 -0
  255. package/dist/server/forge/github.js +2544 -0
  256. package/dist/server/forge/github.js.map +1 -0
  257. package/dist/server/forge/index.d.ts +40 -0
  258. package/dist/server/forge/index.js +72 -0
  259. package/dist/server/forge/index.js.map +1 -0
  260. package/dist/server/forge/types.d.ts +267 -0
  261. package/dist/server/forge/types.js +2 -0
  262. package/dist/server/forge/types.js.map +1 -0
  263. package/dist/server/fs-browse.d.ts +105 -0
  264. package/dist/server/fs-browse.js +182 -0
  265. package/dist/server/fs-browse.js.map +1 -0
  266. package/dist/server/git-changes.d.ts +213 -0
  267. package/dist/server/git-changes.js +555 -0
  268. package/dist/server/git-changes.js.map +1 -0
  269. package/dist/server/git.d.ts +28 -0
  270. package/dist/server/git.js +112 -0
  271. package/dist/server/git.js.map +1 -0
  272. package/dist/server/github.d.ts +9 -0
  273. package/dist/server/github.js +8 -0
  274. package/dist/server/github.js.map +1 -0
  275. package/dist/server/launch-key.d.ts +7 -0
  276. package/dist/server/launch-key.js +33 -0
  277. package/dist/server/launch-key.js.map +1 -0
  278. package/dist/server/open-in-app.d.ts +66 -0
  279. package/dist/server/open-in-app.js +211 -0
  280. package/dist/server/open-in-app.js.map +1 -0
  281. package/dist/server/open-in-terminal.d.ts +70 -0
  282. package/dist/server/open-in-terminal.js +179 -0
  283. package/dist/server/open-in-terminal.js.map +1 -0
  284. package/dist/server/pr.d.ts +7 -0
  285. package/dist/server/pr.js +7 -0
  286. package/dist/server/pr.js.map +1 -0
  287. package/dist/server/project-context.d.ts +120 -0
  288. package/dist/server/project-context.js +192 -0
  289. package/dist/server/project-context.js.map +1 -0
  290. package/dist/server/provider-action-gate.d.ts +8 -0
  291. package/dist/server/provider-action-gate.js +56 -0
  292. package/dist/server/provider-action-gate.js.map +1 -0
  293. package/dist/server/provider-auth-runtime.d.ts +21 -0
  294. package/dist/server/provider-auth-runtime.js +66 -0
  295. package/dist/server/provider-auth-runtime.js.map +1 -0
  296. package/dist/server/server.d.ts +13578 -0
  297. package/dist/server/server.js +5284 -0
  298. package/dist/server/server.js.map +1 -0
  299. package/dist/server/static-ui.d.ts +49 -0
  300. package/dist/server/static-ui.js +92 -0
  301. package/dist/server/static-ui.js.map +1 -0
  302. package/dist/server/validators.d.ts +97 -0
  303. package/dist/server/validators.js +86 -0
  304. package/dist/server/validators.js.map +1 -0
  305. package/dist/server/ws.d.ts +83 -0
  306. package/dist/server/ws.js +216 -0
  307. package/dist/server/ws.js.map +1 -0
  308. package/dist/server/wsl.d.ts +25 -0
  309. package/dist/server/wsl.js +92 -0
  310. package/dist/server/wsl.js.map +1 -0
  311. package/dist/server-install/engine.d.ts +50 -0
  312. package/dist/server-install/engine.js +324 -0
  313. package/dist/server-install/engine.js.map +1 -0
  314. package/dist/server-install/platforms/macosx-ngrok.d.ts +6 -0
  315. package/dist/server-install/platforms/macosx-ngrok.js +348 -0
  316. package/dist/server-install/platforms/macosx-ngrok.js.map +1 -0
  317. package/dist/server-install/platforms/ubuntu-vps.d.ts +63 -0
  318. package/dist/server-install/platforms/ubuntu-vps.js +997 -0
  319. package/dist/server-install/platforms/ubuntu-vps.js.map +1 -0
  320. package/dist/server-install/state.d.ts +52 -0
  321. package/dist/server-install/state.js +182 -0
  322. package/dist/server-install/state.js.map +1 -0
  323. package/dist/server-install/steps.d.ts +109 -0
  324. package/dist/server-install/steps.js +334 -0
  325. package/dist/server-install/steps.js.map +1 -0
  326. package/dist/server-install/strategies.d.ts +4 -0
  327. package/dist/server-install/strategies.js +20 -0
  328. package/dist/server-install/strategies.js.map +1 -0
  329. package/dist/server-install/types.d.ts +287 -0
  330. package/dist/server-install/types.js +121 -0
  331. package/dist/server-install/types.js.map +1 -0
  332. package/dist/server-install/ui.d.ts +42 -0
  333. package/dist/server-install/ui.js +130 -0
  334. package/dist/server-install/ui.js.map +1 -0
  335. package/dist/skills-banner.d.ts +22 -0
  336. package/dist/skills-banner.js +41 -0
  337. package/dist/skills-banner.js.map +1 -0
  338. package/dist/skills-remote.d.ts +84 -0
  339. package/dist/skills-remote.js +468 -0
  340. package/dist/skills-remote.js.map +1 -0
  341. package/dist/skills-update.d.ts +88 -0
  342. package/dist/skills-update.js +392 -0
  343. package/dist/skills-update.js.map +1 -0
  344. package/dist/skills.d.ts +82 -0
  345. package/dist/skills.js +251 -0
  346. package/dist/skills.js.map +1 -0
  347. package/dist/todos.d.ts +48 -0
  348. package/dist/todos.js +201 -0
  349. package/dist/todos.js.map +1 -0
  350. package/dist/ui-state.d.ts +26 -0
  351. package/dist/ui-state.js +38 -0
  352. package/dist/ui-state.js.map +1 -0
  353. package/dist/update-check.d.ts +12 -0
  354. package/dist/update-check.js +41 -0
  355. package/dist/update-check.js.map +1 -0
  356. package/dist/workflows/load.d.ts +15 -0
  357. package/dist/workflows/load.js +56 -0
  358. package/dist/workflows/load.js.map +1 -0
  359. package/dist/workflows/run.d.ts +803 -0
  360. package/dist/workflows/run.js +3483 -0
  361. package/dist/workflows/run.js.map +1 -0
  362. package/dist/workflows/types.d.ts +145 -0
  363. package/dist/workflows/types.js +194 -0
  364. package/dist/workflows/types.js.map +1 -0
  365. package/dist/workspace/agent-accounts.d.ts +153 -0
  366. package/dist/workspace/agent-accounts.js +304 -0
  367. package/dist/workspace/agent-accounts.js.map +1 -0
  368. package/dist/workspace/agent-profiles.d.ts +78 -0
  369. package/dist/workspace/agent-profiles.js +115 -0
  370. package/dist/workspace/agent-profiles.js.map +1 -0
  371. package/dist/workspace/config.d.ts +169 -0
  372. package/dist/workspace/config.js +379 -0
  373. package/dist/workspace/config.js.map +1 -0
  374. package/dist/workspace/migrations.d.ts +45 -0
  375. package/dist/workspace/migrations.js +147 -0
  376. package/dist/workspace/migrations.js.map +1 -0
  377. package/dist/workspace/projects-cli.d.ts +25 -0
  378. package/dist/workspace/projects-cli.js +172 -0
  379. package/dist/workspace/projects-cli.js.map +1 -0
  380. package/dist/workspace/projects.d.ts +109 -0
  381. package/dist/workspace/projects.js +250 -0
  382. package/dist/workspace/projects.js.map +1 -0
  383. package/dist/workspace/semaphore.d.ts +179 -0
  384. package/dist/workspace/semaphore.js +195 -0
  385. package/dist/workspace/semaphore.js.map +1 -0
  386. package/dist/workspace/ui-state.d.ts +34 -0
  387. package/dist/workspace/ui-state.js +53 -0
  388. package/dist/workspace/ui-state.js.map +1 -0
  389. package/package.json +85 -0
  390. package/scripts/check-pack.mjs +46 -0
  391. package/scripts/inline-contract.mjs +112 -0
  392. package/scripts/install-as-command.mjs +120 -0
  393. package/scripts/mock-claude.mjs +524 -0
  394. package/scripts/mock-pi-rpc.mjs +83 -0
  395. package/scripts/sync-readme.mjs +20 -0
  396. package/scripts/test-process-usage.mjs +47 -0
  397. package/web/dist/assets/alert-dialog-CGskMvgc.js +1 -0
  398. package/web/dist/assets/arrow-down-G8adPhbu.js +1 -0
  399. package/web/dist/assets/arrow-left-BJsIW6A0.js +1 -0
  400. package/web/dist/assets/bundle-mjs-BT31bpU6.js +1 -0
  401. package/web/dist/assets/centered-state-B_V_Ai2h.js +43 -0
  402. package/web/dist/assets/chevron-right-CFzn-von.js +1 -0
  403. package/web/dist/assets/chunk-BO2N2NFS-DE6qKn3r.js +131 -0
  404. package/web/dist/assets/collapsible-B_8uYwHb.js +1 -0
  405. package/web/dist/assets/commit-list-C4Dv6vUL.js +1 -0
  406. package/web/dist/assets/compare-variants-SR2zZfZq.js +1 -0
  407. package/web/dist/assets/core-BCsw8oQw.js +12 -0
  408. package/web/dist/assets/css-BsVw1vtW.js +1 -0
  409. package/web/dist/assets/diff-CbozNUJq.js +3 -0
  410. package/web/dist/assets/diff-stat-btAmKFJr.js +1 -0
  411. package/web/dist/assets/diff-view-BpFTcG3R.js +6 -0
  412. package/web/dist/assets/diff-woXpYk--.js +1 -0
  413. package/web/dist/assets/dropdown-menu-Z80KMInL.js +1 -0
  414. package/web/dist/assets/editable-title-wS5NWwob.js +1 -0
  415. package/web/dist/assets/ellipsis-vertical-Bmi2u2TG.js +1 -0
  416. package/web/dist/assets/engine-javascript-FQvzRocB.js +141 -0
  417. package/web/dist/assets/file-DKoYWRsv.js +1 -0
  418. package/web/dist/assets/folder-u01HScRT.js +1 -0
  419. package/web/dist/assets/git-toolbar-DZlZjTGz.js +1 -0
  420. package/web/dist/assets/github-CFURo9kf.js +1 -0
  421. package/web/dist/assets/go-rLFTqkRN.js +1 -0
  422. package/web/dist/assets/highlighted-body-OFNGDK62-BL-MfFgl.js +1 -0
  423. package/web/dist/assets/highlighter-C8DK1_sG.js +3 -0
  424. package/web/dist/assets/html-BY76lXLH.js +1 -0
  425. package/web/dist/assets/image-preview-BR3iIIhf.js +1 -0
  426. package/web/dist/assets/index-BcI5hug3.css +2 -0
  427. package/web/dist/assets/index-DlC81_GI.js +7 -0
  428. package/web/dist/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  429. package/web/dist/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  430. package/web/dist/assets/javascript-BgS3c2Ky.js +1 -0
  431. package/web/dist/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
  432. package/web/dist/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
  433. package/web/dist/assets/json-qhed-kSA.js +1 -0
  434. package/web/dist/assets/jsonc-CYpm1nAK.js +1 -0
  435. package/web/dist/assets/jsx-Bz0zcwM4.js +1 -0
  436. package/web/dist/assets/lib-BQXq3kEf.js +1 -0
  437. package/web/dist/assets/lib-BxQXEXDF.js +1 -0
  438. package/web/dist/assets/markdown-5FuCZDA4.js +2 -0
  439. package/web/dist/assets/markdown-BYOwaDjH.js +1 -0
  440. package/web/dist/assets/mermaid-GHXKKRXX-C4jxqUUb.js +1 -0
  441. package/web/dist/assets/new-task-form-BydHBbef.js +1 -0
  442. package/web/dist/assets/pill-vNzaaYxj.js +1 -0
  443. package/web/dist/assets/project-router-BbCzrHKs.js +1 -0
  444. package/web/dist/assets/prompt-templates-B7Fs2b1S.js +15 -0
  445. package/web/dist/assets/python-gzcpVVnB.js +1 -0
  446. package/web/dist/assets/react-runtime-CCIEwYL0.js +9 -0
  447. package/web/dist/assets/refresh-cw-DGliez3E.js +1 -0
  448. package/web/dist/assets/repo-git-CJFDMauC.js +1 -0
  449. package/web/dist/assets/rolldown-runtime-QTnfLwEv.js +1 -0
  450. package/web/dist/assets/run-diff-Bq9vkSNK.js +3 -0
  451. package/web/dist/assets/run-header-Cd8mSKBG.js +1 -0
  452. package/web/dist/assets/rust-Cfkwpbl8.js +1 -0
  453. package/web/dist/assets/search-x-69n_672Y.js +1 -0
  454. package/web/dist/assets/shellscript-CLZ0U2zV.js +1 -0
  455. package/web/dist/assets/skill-empty-hint-DTu0LzaJ.js +1 -0
  456. package/web/dist/assets/skills-Cs-auniL.js +1 -0
  457. package/web/dist/assets/skills-D4P-Hgey.js +1 -0
  458. package/web/dist/assets/sparkles-B8agSxBZ.js +1 -0
  459. package/web/dist/assets/sql-BsFa4tDR.js +1 -0
  460. package/web/dist/assets/square-terminal-Cf4Og6ct.js +1 -0
  461. package/web/dist/assets/tab-link-Cp2-CJS8.js +1 -0
  462. package/web/dist/assets/task-changes-DYgNXOyY.js +1 -0
  463. package/web/dist/assets/task-commits-BRpZSz1G.js +1 -0
  464. package/web/dist/assets/task-files-pKOwSyLh.js +2 -0
  465. package/web/dist/assets/task-thread-Bfyqqy-t.js +9 -0
  466. package/web/dist/assets/textarea--cpYshee.js +1 -0
  467. package/web/dist/assets/thread-loading-GyH2Atwo.js +1 -0
  468. package/web/dist/assets/toml-CcmNWLt0.js +1 -0
  469. package/web/dist/assets/trash-2--ZtrzUx3.js +1 -0
  470. package/web/dist/assets/triangle-alert-D5tJwRD2.js +1 -0
  471. package/web/dist/assets/tsx-udAQXfEw.js +1 -0
  472. package/web/dist/assets/typescript-bsJCZSQ-.js +1 -0
  473. package/web/dist/assets/upload-SnwVxKOA.js +1 -0
  474. package/web/dist/assets/use-desktop-C31lOFUD.js +1 -0
  475. package/web/dist/assets/use-submit-shortcut-JY8M_MPL.js +1 -0
  476. package/web/dist/assets/utils-Bb8ohcr3.js +64 -0
  477. package/web/dist/assets/workflows-BmOehP-A.js +11 -0
  478. package/web/dist/assets/yaml-rwi0_p6S.js +1 -0
  479. package/web/dist/assets/zoomable-image-0G3IBXWC.js +1 -0
  480. package/web/dist/index.html +80 -0
  481. package/web/dist/xezar.svg +14 -0
package/README.md ADDED
@@ -0,0 +1,810 @@
1
+ <div align="center">
2
+
3
+ # xezar ⚡
4
+
5
+ **Parallel coding agents orchestrator** — a local cockpit for running and
6
+ tracking AI coding-agent tasks in your repo.
7
+
8
+ Type a task, pick a workflow and an agent — **Claude Code, Codex, OpenCode or pi
9
+ (the latter two experimental), or a mix of them per step** — and watch it work live: steps, tool calls,
10
+ tokens, diffs, in a browser cockpit that runs entirely on your machine.
11
+ Your CLI logins, your `gh`, your files. No accounts, no database, no cloud.
12
+
13
+ 🔥 **Fire and forget.** Queue a stack of autonomous coding and maintenance
14
+ tasks and let them run — xezar orchestrates them across isolated worktrees,
15
+ in parallel. Flip the **Autonomous** flag
16
+ and a run never stops to ask; it just finishes. Leave it on a VPS and you get
17
+ a dev team that's *always on* — a mobile-friendly cockpit you can check from
18
+ your phone, working your backlog while you're away.
19
+
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
+
22
+ [![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
+ ![Node 20+](https://img.shields.io/badge/Node-20%2B-339933)
25
+ ![TypeScript 7.x](https://img.shields.io/badge/TypeScript-7.x-3178c6)
26
+ ![Zero config](https://img.shields.io/badge/config-zero-success)
27
+ ![No database](https://img.shields.io/badge/database-none-success)
28
+
29
+ </div>
30
+
31
+ ---
32
+
33
+ ```bash
34
+ npm install -g @qodeca/xezar
35
+ cd your-repo
36
+ xezar # → cockpit at http://localhost:4321
37
+ ```
38
+
39
+ That is the whole setup. If your `claude` CLI is logged in (Pro/Max) and
40
+ `gh` is authenticated, there is nothing else to configure. State lives in `.ai/xezar/`
41
+ inside your repo — plain JSON, NDJSON and Markdown you can `cat` and fix by hand.
42
+
43
+ ## A look inside
44
+
45
+ Click any thumbnail for the full-size screenshot.
46
+
47
+ | Orchestrate parallel agents | Watch a run live | Parallel variants |
48
+ |:--:|:--:|:--:|
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) |
50
+ | *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
+ | **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) |
53
+ | *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
+
55
+ ---
56
+
57
+ ## What xezar does best 🏆
58
+
59
+ Plenty of tools wrap a single coding agent in a nicer window — a "Codex GUI", a
60
+ conductor-style app, one-agent front-ends. xezar's bet is different. Three things
61
+ it does better than any of them:
62
+
63
+ - 🪶 **Genuinely zero config.** Run `xezar` in your repo and you're going —
64
+ no wizard, no API keys, no env vars, no schema, no database. It rides the
65
+ `claude` / `codex` / `opencode` / `pi` logins and the `gh` you already have, and every
66
+ missing piece degrades gracefully instead of blocking you.
67
+ - 🖥️ **Built for a server (VPS mode).** xezar is made to live on a **VPS, cloud,
68
+ or dedicated box** as an always-on janitor for your repo — headless-first, with
69
+ a mobile-friendly cockpit you drive from anywhere. It's a coding server you can
70
+ actually watch, not a desktop app bolted onto one machine.
71
+ - 🔀 **Parallel + autonomous orchestration.** The real edge: xezar runs **many
72
+ agents at once** in isolated worktrees, **queues** the overflow, and pushes each
73
+ one **autonomously** through skill playbooks — fire-and-forget. This is exactly
74
+ what single-agent GUIs don't do well: they babysit one agent, while xezar
75
+ orchestrates a whole team and drains your backlog while you're away.
76
+
77
+ ---
78
+
79
+ ## What it solves
80
+
81
+ Most "AI coding agent" tooling makes you choose between a **terminal** you can't
82
+ see into once it's running, and a **cloud product** that wants your API key, your
83
+ code on their servers, and an account. xezar is the third option: the agents run
84
+ locally under *your* subscription, a cockpit shows you exactly what they're doing,
85
+ and an orchestrator keeps a whole queue of them moving.
86
+
87
+ - 👀 **No visibility into a running agent.** A headless `claude` run is a black box
88
+ until it finishes. xezar streams every step — agent text, each tool call and
89
+ its result, tokens and cost per step — live, and keeps the full replay.
90
+ - 🧩 **One agent, one working tree, one thing at a time.** Kick off a second task and
91
+ it fights the first over your files. xezar runs each task in its **own git
92
+ worktree**, so two (or three) agents work in parallel without stepping on
93
+ each other — or on the branch you're editing.
94
+ - 🗂️ **A backlog that needs babysitting.** Queue a stack of tasks and xezar
95
+ **orchestrates** them: it runs up to your parallel limit and holds the rest in
96
+ an ordered queue. Point it at a GitHub issue and it runs straight on that, so
97
+ working the tracker down stops being a manual chore. Turn on the opt-in
98
+ **Inbox** (`XEZ_FOLLOWUPS=1`) and an agent's leftover follow-ups become the
99
+ next tasks too — one click each.
100
+ - 🤖 **"Autonomous" means you still have to sit there.** Flip the **Autonomous**
101
+ flag and a run never parks to ask — it keeps going until the task is done. Pair
102
+ it with a **skill** (a Markdown playbook) and you've got fire-and-forget
103
+ automation: hand off "fix this", "upgrade that", "triage these" and walk away.
104
+ - ✅ **The agent finishes and you have to trust it.** xezar ends non-trivial runs at
105
+ a **review gate**: inspect the diff, send notes back into the same session, or
106
+ push a **draft PR** — never an auto-merge.
107
+ - ♻️ **Losing a session when it fails.** Every run records its `claude` session id.
108
+ Take it over interactively in one click (`claude --resume <id>`), or continue it
109
+ in-process from the cockpit.
110
+ - 🔀 **Locked into one agent vendor.** Most tools wed you to a single CLI. xezar
111
+ drives **Claude Code, Codex and OpenCode (experimental)** through one runner seam — set a
112
+ default, pick a backend per task, or mix them inside one workflow (implement
113
+ with one agent, review with another) — and through **OpenCode** you can point
114
+ a run at **open-source or local models**, not just the big vendors. See
115
+ [Agent backends](#coding-agent-backends).
116
+ - 🖥️ **Close the laptop and the work stops.** A local agent only runs while your
117
+ machine is on and awake. Put xezar on a **VPS, cloud box, or dedicated server**
118
+ and the cockpit becomes the GUI for an **always-on AI coding team** — kick off,
119
+ watch and steer tasks from your laptop or **phone**, on the train or between
120
+ meetings, while the agents keep grinding through the backlog back on the server.
121
+ - ⚡ **Setup tax.** No wizard, no env vars, no schema. Skills are Markdown, workflows
122
+ are short YAML, and everything degrades: no `gh` → works without PRs, no network
123
+ → local skills still load, no `.ai/skills` → the bare prompt still runs.
124
+
125
+ ---
126
+
127
+ ## Who it's for
128
+
129
+ - **Solo devs and small teams** who want the leverage of coding agents without
130
+ handing their code and keys to a SaaS — the agent runs on your subscription,
131
+ on your machine.
132
+ - **`claude` CLI power users** who love headless runs but want to *see* them,
133
+ compare a few attempts side by side, and review a diff before it lands.
134
+ - **Anyone with a backlog** who'd rather queue three tasks into isolated worktrees
135
+ and pick the winners than babysit one terminal.
136
+ - **Teams with shared conventions** who want their playbooks (skills) pulled from
137
+ a git repo, applied consistently, with zero per-project setup.
138
+
139
+ ---
140
+
141
+ ## Quick start
142
+
143
+ **Prerequisites:** Node 20+, at least one logged-in agent CLI — the
144
+ [`claude` CLI](https://github.com/anthropics/claude-code) (Pro/Max subscription),
145
+ the [`codex` CLI](https://github.com/openai/codex), or
146
+ [OpenCode](https://opencode.ai) — and, optionally, `git` and the `gh` CLI.
147
+
148
+ Install it once, then run it in any repo:
149
+
150
+ ```bash
151
+ npm install -g @qodeca/xezar # installs the `xezar` and `xez` commands
152
+ cd your-repo
153
+ xezar # start the cockpit for the current repo
154
+ ```
155
+
156
+ Prefer not to install anything?
157
+
158
+ ```bash
159
+ npx @qodeca/xezar # same thing, fetched on demand
160
+ ```
161
+
162
+ The cockpit opens at `http://localhost:4321` (auto-picks the next free port if
163
+ busy). Type a task, pick a workflow, hit **Start**. That's it.
164
+
165
+ ```bash
166
+ xezar run "add a --json flag to the export command" # headless, CI-friendly
167
+ xezar init # scaffold .ai/xezar/
168
+ ```
169
+
170
+ Both the `xezar` and `xez` commands are installed, so once it's on your PATH you
171
+ can run either. No API key is ever used — xezar shells out to whichever agent
172
+ CLIs you are already logged into, `claude` by default.
173
+
174
+ To upgrade later: `npm install -g @qodeca/xezar@latest`.
175
+
176
+ > **Working on xezar itself?** [Local development](#local-development) shows how
177
+ > to get a global `xezar` command straight off your checkout
178
+ > (`npm run install-as-command`) — no publish needed.
179
+
180
+ > **Just kicking the tires?** Set `XEZ_DRY_RUN=1` to run against a bundled mock
181
+ > instead of the real CLI — the whole cockpit works with no `claude` login, so
182
+ > you can explore runs, diffs, variants and the review gate offline.
183
+
184
+ ---
185
+
186
+ ## How it works
187
+
188
+ You describe a task. xezar runs it as a **workflow** — an ordered list of agent
189
+ steps and shell checks — shelling out to your locally installed agent CLI
190
+ (Claude Code by default; Codex and OpenCode are drop-in alternatives, per task
191
+ or per step). Each task gets its own git worktree; the cockpit streams every
192
+ event live and parks the run at a review gate when there's a diff to inspect.
193
+
194
+ ```
195
+ you type a task
196
+
197
+
198
+ ┌─────────────┐ optional: Plan → AI drafts a chain of steps you approve
199
+ │ workflow │ (agent steps + shell checks, with bounded onFail retries)
200
+ └─────────────┘
201
+
202
+
203
+ ┌──────────────────────────────┐ ┌───────────────────────────────┐
204
+ │ git worktree per task │ │ agent CLI (your login) │
205
+ │ (isolated branch, parallel) │◄───►│ claude · codex · opencode · pi│
206
+ └──────────────────────────────┘ │ Bash open · no prompts │
207
+ │ └───────────────────────────────┘
208
+ │ agent text · tool calls · tool results · tokens · cost
209
+
210
+ ┌─────────────┐ SSE (replay + live) ┌──────────────────────────┐
211
+ │ .ai/xezar/ │ ──────────────────────► │ cockpit localhost:4321 │
212
+ │ JSON·NDJSON │ │ Tasks · Git · GitHub · │
213
+ │ ·Markdown │ │ Skills · Workflows │
214
+ └─────────────┘ └──────────────────────────┘
215
+
216
+ review gate: read the diff →
217
+ send notes back · draft PR · finish
218
+ ```
219
+
220
+ When a check fails, the workflow can loop back to an earlier step (bounded by
221
+ `max`) with the failing output appended to the retried agent's prompt. Nothing
222
+ auto-merges: a run with changes rests in `review` until you act on it.
223
+
224
+ ---
225
+
226
+ ## Core concepts
227
+
228
+ Three words, no jargon — **task**, **skill**, **chain**:
229
+
230
+ - 📋 **Tasks** are the unit of work. Every task is a **run**: `queued → running →
231
+ review / done / failed / cancelled`, with a live event log, per-step token and
232
+ cost usage, cancel/delete, and — for anything with a diff — a review gate. Attach
233
+ screenshots, PDFs, `.txt` or `.md` files to the task (paperclip, ⌘V or drag-drop;
234
+ the agent gets each one as a real file on disk), or send follow-up messages into
235
+ the live session while it works.
236
+ - 📖 **Skills** are Markdown playbooks. Drop them in `.ai/skills/` or
237
+ `.ai/xezar/skills/`, or pull them from a shared **team skills repo** (a bare
238
+ git clone cached globally in `~/.cache/xez/`). A workflow step references one by
239
+ `skill: <name>` and its body becomes the agent's extra system prompt — so you
240
+ shape *how* the agent reasons without touching code.
241
+ - 🔗 **Chains (workflows)** stitch steps into a pipeline: agent steps plus shell
242
+ checks, with bounded `onFail` retry loops. Write the YAML yourself, build one by
243
+ drag-ordering skills in the **Workflows** tab, or press **Plan first** and let the
244
+ AI draft a chain for your task that you review, trim and start. The built-in
245
+ `quick-task` (one agent step) works with zero setup.
246
+
247
+ Five moves that make the cockpit worth the browser tab:
248
+
249
+ - 🗃️ **Queue + orchestration.** Start as many tasks as you like: xezar runs up to
250
+ `maxParallel` at once across every project (default **2**; a non-git directory
251
+ always runs one) and
252
+ holds the rest in a FIFO queue with visible positions (`#1`, `#2`, …). Cancel a
253
+ queued task before it starts; the queue even survives a cockpit restart —
254
+ everything still `queued` is re-enqueued in order. It's the orchestration layer
255
+ that turns "one agent at a time" into a backlog that drains itself.
256
+ - 🧠 **Memory-aware runs.** Each run's whole process tree is sampled (~2 s) for CPU
257
+ and RSS, and its **peak memory** is recorded and shown in the task table. Set an
258
+ optional per-task **memory ceiling** (`memoryLimitMb`) and a run that crosses it
259
+ is *paused* — freeing its tree so the queue keeps advancing — and resumes on
260
+ demand. Event logs are append-only NDJSON and streamed rather than re-serialized,
261
+ and live UI deltas are coalesced so they never hit disk.
262
+ - 🪞 **Parallel variants (×2 / ×3).** Run the same task as competing agents in
263
+ separate worktrees, then compare their diffs side by side and **pick** one —
264
+ the losers are archived and their worktrees cleaned up.
265
+ - 🧹 **Bounded worktree disk.** Each task runs in its own full checkout, so a busy
266
+ cockpit would otherwise grow without limit. xezar keeps only the last
267
+ `worktreeRetention` **finished** worktrees on disk (default **10**; `0` =
268
+ unlimited) and reclaims the rest — directory only, the `xez/<id8>` branch is
269
+ always kept, so the work stays recoverable. Settings → Resources shows every
270
+ worktree's disk use with per-row delete and a **Reclaim now** button.
271
+ - 🛡️ **Review gate.** A finished run with changes waits in `review`. Read the diff,
272
+ type notes that go straight back into the agent's session, or push a
273
+ `gh pr create --draft`. You stay the merge button.
274
+ - 📱 **Runs on your coding server, drives from your pocket.** The cockpit is a
275
+ responsive web app streaming over SSE, so the box running xezar can be a
276
+ **VPS, cloud, or dedicated server** you never sit in front of. Point a browser
277
+ — laptop or **phone** — at it and run an **always-on coding team** on the move:
278
+ start tasks, watch them live, and hit the review gate from anywhere.
279
+
280
+ ---
281
+
282
+ ## Cockpit tour
283
+
284
+ Eight views, one browser window, all live over Server-Sent Events (seven until you opt into the Inbox):
285
+
286
+ | View | What's in it |
287
+ |---|---|
288
+ | **Tasks** | Every task with its status, live event stream (agent text · tool calls · tool results · pasted/generated screenshots and file attachments), tokens and cost. Continue, cancel, open in terminal (`claude --resume`), review the diff, or push a draft PR. |
289
+ | **All tasks** | Every *registered project's* tasks in one table, filtered and grouped by tag, project, status or workflow — see [Grouping connected repositories](#grouping-connected-repositories-tags-and-the-all-tasks-page). Appears once a second project is registered. |
290
+ | **Inbox** | **Opt-in** (`XEZ_FOLLOWUPS=1`; hidden by default). Follow-ups an agent left behind (`todos.json`) — one click turns a suggestion into the next task, pre-wired to its suggested skill. Off, agents are never asked to leave follow-ups; each task's own **Notes** handoff journal is unaffected. |
291
+ | **Git** | Branch, working-tree status, diff vs HEAD, recent commits (click one for its inline patch + GitHub link), and the configurable base branch that worktrees fork from and PRs target. |
292
+ | **GitHub** | Open issues and PRs of the repo's origin, read through your logged-in `gh`. Hand an issue straight to the agent — pick a workflow and skills, one click runs it. |
293
+ | **Skills** | Local skills plus the team skills repo, with a rendered body + prompt preview. Refresh pulls the latest from the remote. |
294
+ | **Workflows** | Build a chain by drag-ordering skills, save it as portable YAML, import/export, or delete. Built-ins always come back. |
295
+ | **Settings** | Appearance (dark/light theme, accent, density), agent backends, notifications, and the skills catalog. |
296
+
297
+ The cockpit is a React app served pre-built from the package — running `xezar`
298
+ needs no dev server on your machine — with a dark/light
299
+ theme, a ⌘K command palette, and bookmarklets that launch a task straight from
300
+ a GitHub page.
301
+
302
+ ---
303
+
304
+ ## Multiple projects, one cockpit
305
+
306
+ One `xezar serve` hosts **every repo you work in**, not just the one you started
307
+ it in. Each repo xezar boots in registers itself in a per-user registry at
308
+ `~/.xezar/config.json` — the workspace file that also holds the global knobs
309
+ (the parallel cap, the memory ceiling, the browse root, and the checkout root). Nothing is added to
310
+ the repo: per-project state stays exactly where it was, in that repo's
311
+ `.ai/xezar/`.
312
+
313
+ Every view is project-scoped:
314
+
315
+ ```
316
+ /p/<projectId>/ tasks · git · github · skills · workflows · settings
317
+ ```
318
+
319
+ `<projectId>` is a slug derived from the folder name (`my-app`, then `my-app-2`
320
+ on a collision), and `/p/default/…` always means the project xezar was started
321
+ in. The sidebar shows one collapsible group per project — each with its own nav
322
+ and task list — and the new-task composer names the project it will run in.
323
+
324
+ **Adding a project** — the **+** button beside *New task*:
325
+
326
+ - 📂 **Open local folder…** browses from the configured browse root
327
+ (**Settings → Projects**, default `~/`) in a folder picker and
328
+ registers the folder you pick.
329
+ - ⬇️ **Clone from GitHub…** clones with your logged-in `gh` into the checkout
330
+ root (**Settings → Projects**, default `~/xezar/projects`) with live progress,
331
+ then registers the clone. Close the dialog and the clone is killed and its
332
+ partial directory removed.
333
+
334
+ Removing a project (**Settings → Projects**) drops the registry entry only — the
335
+ repo and its `.ai/xezar/` are never touched, so re-adding it later finds all its
336
+ tasks intact. The project xezar is currently serving can't be removed: it
337
+ re-registers itself at the next start.
338
+
339
+ **From the terminal** — the same registry, no cockpit required (handy over ssh):
340
+
341
+ ```bash
342
+ xezar projects # list: id, branch or status, path, tags
343
+ xezar projects add ~/code/api # register a folder (defaults to the current repo)
344
+ xezar projects remove api # drop the registry entry; the repo is untouched
345
+ xezar projects tag api storefront backend # set the grouping tags (no tags clears them)
346
+ ```
347
+
348
+ These read and write `~/.xezar/config.json` directly, so they work with the
349
+ server stopped, and `XEZ_HOME` selects which workspace they operate on.
350
+
351
+ Settings split along the same line: **General** (the project's folder, its
352
+ registry facts, its parallel-task ceiling, and Remove), **Agents**,
353
+ **Worktrees**, **Bookmarklets**, **Prompt templates** and **MCP** describe one
354
+ repo and live under `/p/<projectId>/settings`; **Appearance**,
355
+ **Notifications**, **Resources**, **Projects** and **Keyboard** are yours or the
356
+ machine's and live at `/settings/global`.
357
+
358
+ ### Grouping connected repositories: tags and the All tasks page
359
+
360
+ Work rarely stops at a repo boundary. A storefront is an API, a web app and a
361
+ design system; a platform is a handful of services plus the infra that runs
362
+ them. **Tags** are how you say so, and **All tasks** is where saying so pays off.
363
+
364
+ **Tag a repo** in **Settings → Projects**: type into the *Tags* cell on its row
365
+ and press Enter (comma works too; the × on a chip, or Backspace in an empty
366
+ field, removes one). The field **autocompletes from the tags already used in the
367
+ workspace** — click the field to see them all, arrow keys and Enter to pick —
368
+ which is what keeps the second repo landing on the first one's spelling instead
369
+ of inventing `store-front` next to `storefront`. Anything not on the list is
370
+ just typed. A tag is a free-form label — `storefront`, `infra`, `client-acme` —
371
+ and a project can carry several, because a repo can belong to more than one
372
+ piece of work. Tags are trimmed, deduplicated case-insensitively (`API` and
373
+ `api` are one tag) and stored in `~/.xezar/config.json` beside the rest of the
374
+ registry, so they are yours and this machine's, never something added to the
375
+ repo.
376
+
377
+ **All tasks** — the top item in the sidebar, `/tasks`, or `⌘K → All tasks` —
378
+ then shows every registered project's work in one table:
379
+
380
+ - **Filter** by tag, status and workflow. Tags are one-click chips; status and
381
+ workflow are searchable multi-selects. Every facet ORs inside itself and ANDs
382
+ across, so *"anything running or waiting in storefront or infra"* is one set
383
+ of clicks. Each option carries how many tasks it would leave, so a filter that
384
+ would empty the table says so before you click it. The search box matches
385
+ title, project, workflow, branch and tags.
386
+ - **Group by** tag, project, status or workflow — click the pressed one again to
387
+ ungroup. Grouping by tag is the reason tags exist: three repos tagged
388
+ `storefront` become one section, and a repo tagged twice appears under both —
389
+ it genuinely belongs to both.
390
+
391
+ The filters, the grouping and the Active/Archived tab live in the **URL**, so a
392
+ filtered view survives a refresh, pastes into a chat, and sits in a bookmark —
393
+ `/tasks?tag=storefront&status=running&group=tag` is a link to exactly what you
394
+ were looking at. Only what you changed shows up: Active is the default, so the
395
+ Archived view is `?archived=1` and a normal link carries no key for it.
396
+
397
+ Each row shows **every** PR and issue it references — a task opened on an issue
398
+ that landed a PR shows both — plus its cost and live CPU/memory, and can be
399
+ marked **read/unread** (the eye) or **archived** (or restored) right there. Every task title, project name and project group heading links into that
400
+ project, so the thread, its diff and its worktree are one click away and stay
401
+ exactly where they were.
402
+
403
+ There is deliberately **no project filter**: narrowing this page to one project
404
+ is that project's own Tasks page, which is a better version of the same answer
405
+ (live updates, the full column set, the composer). So picking a project *leaves*
406
+ for it rather than turning the global view into a worse local one.
407
+
408
+ Nothing else in xezar reads tags, on purpose: a tag is a lens, not a permission,
409
+ a queue or a routing rule. Removing one changes what you see and nothing else.
410
+
411
+ > The page reads a workspace-wide index capped at the newest 200 tasks per
412
+ > project — it says so, and names the projects it capped, rather than showing a
413
+ > short list as if it were complete. Older tasks are always in that project's own
414
+ > Tasks page.
415
+
416
+ **Old page URLs keep working.** Every unprefixed page path — `/`, `/tasks/<id>`,
417
+ `/settings` — still answers, bound to the project xezar was started in; the
418
+ cockpit redirects flat paths to their `/p/<boot>/…` twin, so existing bookmarks
419
+ and bookmarklets need no change. The HTTP API is the exception: it moved to
420
+ `/api/v1/…` (see the CHANGELOG), so a script that calls it needs the extra
421
+ segment.
422
+
423
+ > **Hosted cockpit?** The folder picker is confined to the independent browse
424
+ > root. Set `XEZ_BROWSE_ROOT` narrowly before first boot (or save it in
425
+ > **Settings → Projects**) when a remote viewer should not enumerate the host's
426
+ > whole home. Clones continue to use the separate checkout root.
427
+
428
+ ---
429
+
430
+ ## Workflow format
431
+
432
+ A workflow is a small YAML file in `.ai/xezar/workflows/`:
433
+
434
+ ```yaml
435
+ name: fix-and-verify
436
+ description: Implement the task, then verify; retry with failing output on red.
437
+ steps:
438
+ - id: implement
439
+ name: Implement
440
+ prompt: "{{task}}"
441
+ skill: project-conventions # optional — from .ai/skills or .ai/xezar/skills
442
+ # model: opus # optional per-step model override
443
+ # runner: codex # optional per-step backend: claude · codex · opencode · pi
444
+ # allowedTools: [Read, Edit, Write, Grep, Glob, Bash]
445
+ - id: verify
446
+ name: Verify
447
+ command: "npm test" # a check step: exit 0 passes
448
+ onFail:
449
+ retry: implement # loop back to an earlier step…
450
+ max: 2 # …at most twice
451
+ ```
452
+
453
+ `{{task}}` is replaced with the task text you typed. When a check fails and loops
454
+ back, its failing output is appended to the retried agent's prompt so the next
455
+ attempt can see what broke.
456
+
457
+ Prefer skills over steps? A workflow can also be written in the portable
458
+ shorthand — an ordered list of skill names, each becoming one agent step:
459
+
460
+ ```yaml
461
+ name: triage-and-fix
462
+ skills: [reproduce, root-cause, implement, self-review]
463
+ ```
464
+
465
+ ---
466
+
467
+ ## How it runs agents
468
+
469
+ xezar shells out to your locally installed, logged-in agent CLI —
470
+ **your subscription, no API key**. With the default Claude Code backend that
471
+ means headless `stream-json` mode, tool access via `--allowedTools`, with
472
+ unapproved tools denied without prompting (`--permission-mode dontAsk`) inside
473
+ the task's worktree — but note the zero-config default list (`Read`, `Edit`,
474
+ `Write`, `Grep`, `Glob`, `Bash`) grants unrestricted `Bash` unless a step sets
475
+ `bashAllowlist`, so treat a run as having full shell access in its worktree,
476
+ not a sandboxed allowlist. Set `XEZ_APPROVAL_GATE=1` to opt into Claude's
477
+ interactive approval UI. Codex and OpenCode are driven through their own
478
+ native protocols and don't honor `allowedTools` at all — see
479
+ [Coding agent backends](#coding-agent-backends) for what each one actually
480
+ locks down. Nothing runs on a server you don't own.
481
+
482
+ Useful environment variables:
483
+
484
+ | Var | Effect |
485
+ |---|---|
486
+ | `XEZ_DRY_RUN=1` | Use the bundled mock instead of the real `claude` CLI — the entire cockpit works offline, for demos and development. |
487
+ | `XEZ_AGENT_MODELS_LOCKED=1` | Globally lock each runner to the model configured in its native Claude/Codex/OpenCode settings while keeping runner selection available. Exact `1` also delegates authentication and provider enablement to those native agents, so Xezar skips its credential probes and provider-disable preferences. Existing Xezar presets are preserved but ignored, and an environment change requires a restart. The config-file equivalent is `"modelsLocked": true` in global `~/.xezar/config.json` or one repository's `.ai/xezar/config.json`; config-file locks do not disable provider checks. |
488
+ | `XEZ_APPROVAL_GATE=1` | Opt into Claude's interactive approval UI; by default, unapproved tools are denied without interrupting the run. |
489
+ | `XEZ_FOLLOWUPS=1` | Turn on the global follow-up **Inbox**: agents are asked to leave follow-ups in `todos.json` when they finish, and the Inbox view appears. Off by default — each task's own **Notes** handoff journal runs either way. |
490
+ | `XEZ_AUTOMATIONS=1` | Turn on **GitHub automations**: the Automations view appears and xezar polls GitHub on each enabled automation's interval, launching tasks from what it finds. Off by default, and only the exact value `1` enables it — without it nothing polls GitHub, the automations endpoints answer `409`, and the nav item is absent. Read at boot, so restart after changing it; definitions, receipts and high-watermarks are retained, so unsetting it and restarting restores the feature without migration or data loss. |
491
+ | `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. |
492
+ | `XEZ_CLAUDE_BIN=/path/to/claude` | Override which `claude` binary is used. |
493
+ | `XEZ_CODEX_BIN=/path/to/codex` | Override which `codex` binary is used. |
494
+ | `XEZ_OPENCODE_BIN=/path/to/opencode` | Override which `opencode` binary is used. |
495
+ | `XEZ_PI_BIN=/path/to/pi` | Override which `pi` binary is used. |
496
+ | `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. 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. |
497
+ | `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. |
498
+ | `XEZ_PROJECTS_DIR=~/xezar/projects` | Default destination for **Clone from GitHub**. Saved workspace settings override it, and missing directories are created recursively. |
499
+ | `XEZ_SKILLS_AUTO_UPDATE=0` | Disable automatic checks and updates for upstream-CLI-tracked Open Mercato skill installations. On by default; a saved global Skills setting overrides this environment default. Checks are delayed, bounded, cached, and non-blocking. |
500
+ | `XEZ_AUTONOMOUS_DEFAULT=0` | Seed the New Task Autonomous default (`0` or `1`). Without a seed, skills default on and workflows off; a saved global Resources setting overrides it. |
501
+ | `XEZ_WORKTREE_DEFAULT=1` | Seed the New Task Worktree default (`0` or `1`). Without a seed, eligible runs default on; a saved global Resources setting overrides it. |
502
+ | `XEZ_DISABLE_REPO_LOCK=1` | **Dangerous escape hatch:** allow any run executing in the repository root — an explicit `worktree=false` run, non-Git degradation, or a continuation whose worktree cannot be restored — to proceed without Xezar’s repository-root lease. Agents can overwrite each other’s files or Git state; isolated worktree runs are unaffected. Off by default; only the exact value `1` enables it. |
503
+ | `XEZ_SINGLE_PROJECT=1` | Opt into a launch-project-only cockpit: only the exact value `1` enables it. Project add, edit, checkout, folder browsing, and removal are refused and only the launch project is shown. Off by default; stored registry rows are retained, so unsetting it and restarting restores the full multi-project workspace without migration or data loss. |
504
+ | `XEZ_HIDE_TOKEN_USAGE=1` | Hide raw input/output token counts throughout the browser cockpit while leaving backend-reported cost visible. Only the exact value `1` enables it; telemetry and API payloads are unchanged, and a restart is required after changing it. |
505
+ | `XEZ_HIDE_COST=1` | Hide backend-reported monetary cost throughout the browser cockpit while leaving raw input/output token counts visible. Only the exact value `1` enables it; telemetry and API payloads are unchanged, and a restart is required after changing it. |
506
+ | `XEZ_HIDE_TOKEN_METRICS=1` | Legacy master switch that hides both token usage and cost. It takes precedence over the two independent flags; only the exact value `1` enables it, payloads are unchanged, and a restart is required. |
507
+ | `GITHUB_TOKEN` | Fallback for GitHub reads/PRs when `gh` isn't authenticated. |
508
+ | `XEZ_ENV_PASSTHROUGH=A,B` | Forward these extra host env vars to spawned agents. By default agents get a least-privilege env (safe shell/toolchain vars + the backend's own auth + `GITHUB_TOKEN` + `XEZ_*`), not your full environment — use this to add a var an agent needs. |
509
+ | `XEZ_AGENT_ENV_FULL=1` | Escape hatch: give spawned agents the full host environment (pre-hardening behavior). Off by default; only set it if you understand that this hands every host secret to the agent process. |
510
+ | `XEZ_AGENT_TMPDIR=0` | Stop giving each task its own temp directory and hand agents the host `TMPDIR` again (pre-#785 behavior). On by default: every run gets `TMPDIR`/`TEMP`/`TMP` pointing at `.ai/xezar/tmp/<task-id>`, created and write-probed before the agent spawns and reaped when the run ends, so concurrent tasks stop sharing one directory and a task refuses to start rather than run against a temp directory that silently swallows its shell output (see Troubleshooting below). Only an exact `0` disables it, and it disables the whole thing — the pre-spawn check included, so this stays an escape hatch you can actually take. |
511
+ | `XEZ_REDACT_SECRETS=0` | Disable scrubbing of credential values/token shapes from the on-disk state (the NDJSON transcript and the free-text fields of `runs.json`). On by default; leave it on. Best-effort defense-in-depth, not a guarantee: it catches known token shapes and the values of your own secret-named env vars, so a credential in neither category can still get through. |
512
+ | `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. |
513
+ | `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`. |
514
+ | `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. |
515
+ | `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.) |
516
+ | `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. |
517
+
518
+ ### Troubleshooting: the agent's shell returns nothing
519
+
520
+ **Symptom.** A task on the Claude backend keeps working, but every shell command
521
+ comes back with no output and a spurious non-zero exit status — `echo hello`
522
+ included. Redirecting into a file inside the worktree still produces the right
523
+ content, so the commands genuinely run; only the *capture* is lost. Codex tasks
524
+ on the same machine are unaffected, because that backend streams over stdio
525
+ pipes instead of round-tripping a command's output through a temp file.
526
+
527
+ **Diagnosis.** The temp directory the agent was given is out of space or out of
528
+ quota. One line tells you:
529
+
530
+ ```bash
531
+ echo probe > "${TMPDIR:-/tmp}/probe" # "Disk quota exceeded" / "No space left on device"
532
+ df -i "${TMPDIR:-/tmp}" # a tmpfs can exhaust inodes long before bytes
533
+ ```
534
+
535
+ Under quota the file is *created* and the write then fails, so the backend reads
536
+ back a zero-byte capture file and hands the agent an empty result.
537
+
538
+ **Fix.** Since #785 xezar gives each task its own `TMPDIR` under
539
+ `.ai/xezar/tmp/<task-id>` and write-probes it before spawning, so a broken temp
540
+ directory fails the task with `agent temp directory is not writable: …` on the
541
+ task thread instead of corrupting its work. If you see that error, free space on
542
+ the disk holding the repo. `XEZ_AGENT_TMPDIR=0` turns the whole mechanism off —
543
+ per-task directory and pre-spawn check alike — and hands agents the host
544
+ `TMPDIR` again, which is the way out if the check itself is wrong on your
545
+ platform.
546
+
547
+ ---
548
+
549
+ ## Coding agent backends
550
+
551
+ xezar is not married to one vendor. Every agent step runs through a single
552
+ `AgentRunner` seam with four built-in backends:
553
+
554
+ | Backend | CLI | How xezar drives it | Tool access |
555
+ |---|---|---|---|
556
+ | **Claude Code** (default) | [`claude`](https://github.com/anthropics/claude-code) | Headless `stream-json` mode. | Per-tool `--allowedTools` (`bashAllowlist` scopes `Bash`); `dontAsk` denies unapproved tools without prompting (`XEZ_APPROVAL_GATE=1` → `acceptEdits` + approval UI). |
557
+ | **Codex** | [`codex`](https://github.com/openai/codex) | `codex app-server` — JSON-RPC over stdio, the same transport the Codex IDE extensions use. | Ignores `allowedTools`; the default auto mode uses `danger-full-access` with `approvalPolicy: never` (`XEZ_CODEX_NETWORK=0` opts into the network-blocked `workspace-write` sandbox). |
558
+ | **OpenCode** _(experimental)_ | [`opencode`](https://opencode.ai) | `opencode serve` — a local HTTP server with an SSE event stream. | Ignores `allowedTools` entirely; every permission is auto-approved. |
559
+ | **pi** _(experimental)_ | [`pi`](https://github.com/badlogic/pi-mono) | Persistent `--mode rpc` over JSONL; models are picked with the `provider/model` convention. | Maps `allowedTools` onto pi's `--tools` allowlist; a configured `bashAllowlist` disables Bash because pi cannot express command-prefix rules. |
560
+
561
+ > ⚠️ **OpenCode and pi support are experimental.** Both runners work but are less
562
+ > battle-tested than the Claude Code and Codex backends, and OpenCode auto-approves
563
+ > every permission (it ignores `allowedTools`). Treat them as previews and expect
564
+ > rough edges.
565
+
566
+ On startup xezar probes which CLIs are installed and the cockpit only offers
567
+ the backends it found — install any one of the four and you're operational.
568
+
569
+ **Models come from your own machine.** The model picker does not ship a list of
570
+ vendor releases that goes stale between xezar versions. For Claude, Codex and
571
+ OpenCode xezar asks the CLI on your host what *it* currently offers (Claude
572
+ Code's `list_models` control request; the Codex app-server's `model/list`;
573
+ `opencode models`) and shows exactly that, in that order — so a model your
574
+ account gained yesterday is selectable today with no xezar release, and one your
575
+ provider retired stops being offered. Discovery is read-only, costs no tokens,
576
+ and is cached briefly in memory. If the CLI is missing, logged out, too old or
577
+ slow, the picker quietly falls back to that runner's built-in entries (`auto`
578
+ plus Claude's tier aliases) and says so in a status row; `pi`, which has no
579
+ host-local catalog yet, always shows its built-in entries. `auto` — send no
580
+ model at all and let the CLI decide — is always available, and a model you
581
+ pinned by hand stays selectable even when it is no longer advertised.
582
+
583
+ **Pick a backend at three levels** (most specific wins):
584
+
585
+ 1. **Config default** — `"defaultRunner": "codex"` in `.ai/xezar/config.json`.
586
+ 2. **Per task** — the backend picker next to the task box in the cockpit.
587
+ 3. **Per workflow step** — `runner:` on any step in the YAML.
588
+
589
+ Per-step overrides are what make **mixed-agent strategies** a one-liner:
590
+ implement with one agent, review with another, and let a shell check referee:
591
+
592
+ ```yaml
593
+ name: implement-and-cross-review
594
+ steps:
595
+ - id: implement
596
+ name: Implement
597
+ prompt: "{{task}}"
598
+ runner: codex # one vendor writes the code…
599
+ - id: review
600
+ name: Cross-review
601
+ prompt: "Review the diff produced for: {{task}}. Fix real issues only."
602
+ runner: claude # …another one reviews it
603
+ - id: verify
604
+ name: Verify
605
+ command: "npm test"
606
+ onFail: { retry: implement, max: 2 }
607
+ ```
608
+
609
+ Parallel variants (×2/×3) of one task share that task's backend — mixing
610
+ happens per task and per step, not inside a variant group.
611
+
612
+ The seam is deliberately small: a backend is one class implementing the
613
+ `AgentRunner` interface (`packages/xezar/src/core/agent-runner.ts`) that turns a prompt into
614
+ a stream of normalized events. Other CLIs — pi, aider, whatever ships next —
615
+ can slot in the same way.
616
+
617
+ ---
618
+
619
+ ## Remote access (host xezar on a server)
620
+
621
+ xezar runs on `localhost` by default. To reach the cockpit from another machine —
622
+ a shared team box, a VPS, your phone — put an **authenticated public front** in
623
+ front of it. The built-in installer does this interactively, per **platform
624
+ strategy**, and never escalates silently: every privileged command is printed
625
+ and verified, and it ends with a real authenticated end-to-end check.
626
+
627
+ ```bash
628
+ xezar server-install --platform ubuntu-vps # stand it up
629
+ xezar server-deploy --platform ubuntu-vps # roll out a new version (reload the service)
630
+ xezar server-uninstall --platform ubuntu-vps # reverse it
631
+
632
+ # host a SECOND cockpit for another domain on the same box (ubuntu-vps):
633
+ xezar server-install --platform ubuntu-vps --domain shop.example.com
634
+ ```
635
+
636
+ On `ubuntu-vps` a single host can run several independent cockpits — add
637
+ `--domain <host>` and each gets its own port, nginx site, login and service; a
638
+ new domain never resumes or clobbers the first install.
639
+
640
+ **Already running a reverse proxy?** If Dokploy, Coolify, Caddy or your own
641
+ nginx already owns `:80/:443`, xezar's would fight it for the ports. Install the
642
+ service only and let your proxy front it:
643
+
644
+ ```bash
645
+ xezar server-install --platform ubuntu-vps \
646
+ --external-proxy --domain xezar.example.com --bind-host 172.17.0.1
647
+ ```
648
+
649
+ `--bind-host` is only needed when the proxy runs in a **container** (Traefik
650
+ can't reach the host's loopback); a host-installed proxy uses the `127.0.0.1`
651
+ default. In this mode **your proxy must enforce authentication** — xezar has
652
+ none of its own. [Details →](docs/server-install/ubuntu-vps.md#the-box-already-has-a-reverse-proxy-dokploy-coolify-caddy)
653
+
654
+ | Provider | `--platform` | Public front | Guide |
655
+ |----------|--------------|--------------|-------|
656
+ | Ubuntu / Debian VPS | `ubuntu-vps` | nginx + Let's Encrypt HTTPS, htpasswd login, systemd | [Step-by-step →](docs/server-install/ubuntu-vps.md) |
657
+ | 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) |
658
+ | macOS + ngrok | `macosx-ngrok` | ngrok tunnel + `--basic-auth`, launchd | [Step-by-step →](docs/server-install/macosx-ngrok.md) |
659
+
660
+ See the **[Remote access overview](docs/server-install/README.md)** for how it
661
+ works and how to redeploy new versions.
662
+
663
+ ---
664
+
665
+ ## Configuration (optional)
666
+
667
+ Zero config is the default — everything below is opt-in via
668
+ `.ai/xezar/config.json` (a missing or invalid file simply uses the defaults, and
669
+ never blocks startup):
670
+
671
+ ```jsonc
672
+ {
673
+ "skillsRepos": [{ "repo": "open-mercato/skills", "ref": "main" }], // team skills; [] disables
674
+ // Team-skill repos are code-trusted: a skill body becomes an agent system prompt.
675
+ // Only owner/name, https/ssh URLs, or local paths (`/abs`, `./rel`, `~/dir`,
676
+ // `C:\dir`) are accepted — no ext::/fd:: transport helpers. Write a relative
677
+ // path as `./name`, not a bare `name`. Pin `ref` to a full commit SHA to freeze
678
+ // the source against a moving branch head — xezar verifies it resolves to
679
+ // exactly that commit, and reports it as `team.commit`.
680
+ "worktreeRetention": 10, // keep the last N finished worktrees on disk; 0 = unlimited (branch always kept)
681
+ "defaultRunner": "claude", // agent backend: "claude" (default) · "codex" · "opencode" · "pi"
682
+ "modelsLocked": true, // optional: native per-runner model is fixed/read-only; runner stays selectable
683
+ "plannerModel": "sonnet", // model the "Plan first" button uses to draft chains
684
+ "baseBranch": "develop" // branch worktrees fork from + PRs target (also settable in the Git tab)
685
+ }
686
+ ```
687
+
688
+ Put the same `"modelsLocked": true` key in `~/.xezar/config.json` to apply it
689
+ to every registered project. When the key is absent or `false` in both config
690
+ files (and `XEZ_AGENT_MODELS_LOCKED` is not `1`), each runner's normal model
691
+ selector uses that runner's discovered model list. While locked, the model is
692
+ shown read-only and follows the selected runner's native settings; the runner
693
+ itself remains selectable.
694
+
695
+ Run data (`runs.json`, NDJSON event logs, worktrees, `todos.json`) is
696
+ git-ignored automatically; your workflows and skills stay committable.
697
+
698
+ Settings that belong to *you* rather than to a repo — the parallel cap
699
+ (`maxParallel`, default **2**), the per-task memory ceiling and the checkout
700
+ root — live once in `~/.xezar/config.json`, alongside the
701
+ [project registry](#multiple-projects-one-cockpit), and are edited from
702
+ **Settings → Resources** and **Settings → Projects**. A `maxParallel` left over
703
+ in a repo's `.ai/xezar/config.json` is imported into the workspace file the
704
+ first time xezar boots there, and ignored afterwards.
705
+
706
+ ### Editing the agents' own config (Settings → Agent config)
707
+
708
+ xezar picks *which* agent runs; **Settings → Agent config** lets you edit *how* it
709
+ behaves — the raw config files Claude, Codex and OpenCode read for settings,
710
+ MCP, and memory. In the multi-project cockpit the section is project-scoped:
711
+ repo-relative files resolve from the selected project's root, while user-scope
712
+ files continue to resolve from the agent's home.
713
+
714
+ Each file keeps its native format and vendor-documented precedence. Tracked
715
+ files reach task worktrees after commit; Claude's gitignored personal layer is
716
+ seeded into each run's worktree. Editing is a local-machine capability, so a
717
+ hosted cockpit (`XEZ_REMOTE=1`) is read-only and never serves home-file contents.
718
+
719
+ ---
720
+
721
+ ## Local development
722
+
723
+ End-to-end, from a fresh clone to a global `xezar` command you can run in **any**
724
+ repo on your machine — no npm publish required.
725
+
726
+ **1. Prerequisites** — Node 20+ and `git` (plus at least one logged-in agent CLI,
727
+ as in [Quick start](#quick-start)).
728
+
729
+ **2. Clone & install**
730
+
731
+ ```bash
732
+ git clone https://github.com/qodeca/xezar.git
733
+ cd xezar
734
+ npm install
735
+ ```
736
+
737
+ **3. Build** — compiles the api-client and the server (`tsc → packages/xezar/dist/`) and the cockpit
738
+ (`vite build → packages/xezar/web/dist/`), then runs the pack gate:
739
+
740
+ ```bash
741
+ npm run build
742
+ ```
743
+
744
+ **4. Install as a global command** — build + put `xezar` / `xez` on
745
+ your PATH pointing at *this checkout*:
746
+
747
+ ```bash
748
+ npm run install-as-command # live link (default) — see the change loop below
749
+ # or: npm run install-as-command:global # self-contained snapshot copy
750
+ ```
751
+
752
+ Now `cd` into any other repo and run it:
753
+
754
+ ```bash
755
+ cd ~/some-other-project
756
+ xezar # cockpit for that repo, straight off your checkout
757
+ xez --help # same binary under its short name
758
+ ```
759
+
760
+ **5. The change loop**
761
+
762
+ - **Link mode** (default): edit source → `npm run build` → the global command
763
+ reflects it immediately. No relink needed. (It is a live symlink into this
764
+ checkout — don't move or delete the checkout while it's linked.)
765
+ - **Snapshot mode** (`:global`): re-run `npm run install-as-command:global` to
766
+ refresh the installed copy. It survives moving/deleting the checkout.
767
+
768
+ **6. Uninstall**
769
+
770
+ ```bash
771
+ npm run uninstall-as-command # removes xezar / xez (either flavor)
772
+ ```
773
+
774
+ **7. Troubleshooting**
775
+
776
+ - **`xezar: command not found`** after install → your npm global bin dir isn't on
777
+ PATH. The script prints the exact dir; add it to your shell profile
778
+ (`export PATH="$(npm prefix -g)/bin:$PATH"`).
779
+ - **`EACCES` / permission denied** → your global prefix is root-owned. Point npm
780
+ at a user-writable one and retry — **never** sudo:
781
+ `npm config set prefix ~/.npm-global`.
782
+ - **Already installed the published `@qodeca/xezar` globally?** The
783
+ link/snapshot install replaces it; `uninstall-as-command` removes ours, and
784
+ `npm i -g @qodeca/xezar` brings the published one back.
785
+
786
+ ### In-checkout scripts
787
+
788
+ ```bash
789
+ npm run dev # server (API :4321) + Vite dev server, opens the cockpit in the browser
790
+ npm run dev:server # tsx packages/xezar/src/index.ts — the API server alone
791
+ npm run dev:web # Vite dev server alone (proxies /api to :4321)
792
+ npm run build # tsc → packages/xezar/dist/, vite build → packages/xezar/web/dist/, then the pack gate
793
+ npm run typecheck # contract + api-client + server + web (tsc --noEmit)
794
+ npm test # vitest — server + cockpit unit suites
795
+ npm run test:unit # node:test — fast core-module tests
796
+ npm run test:package # pack/install and exercise the built CLI
797
+ npm run test:e2e # real-browser cockpit suite (agent-browser)
798
+ ```
799
+
800
+ The stack is deliberately small: **TypeScript** (strict, ESM), **Hono** + SSE for
801
+ the server, **Zod** at every boundary, **YAML** for workflows, and a **React 19 +
802
+ Vite + Tailwind v4 + shadcn/ui** cockpit shipped pre-built in `packages/xezar/web/dist/` — the
803
+ published package carries the built app, so `npx` users never run a bundler.
804
+ Every module is meant to be read in one sitting.
805
+
806
+ ---
807
+
808
+ ## License
809
+
810
+ **MIT** © Patryk Lewczuk — full text in [LICENSE](LICENSE).