@wjarka/cezarion 0.10.0-pr30.54

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 (478) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +838 -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 +72 -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 +556 -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 +1895 -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 +1473 -0
  74. package/dist/contract/skills.d.ts +232 -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 +105 -0
  90. package/dist/core/ask.js +187 -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 +59 -0
  96. package/dist/core/claude-cli-runner.js +483 -0
  97. package/dist/core/claude-cli-runner.js.map +1 -0
  98. package/dist/core/claude-ui-mapper.d.ts +80 -0
  99. package/dist/core/claude-ui-mapper.js +598 -0
  100. package/dist/core/claude-ui-mapper.js.map +1 -0
  101. package/dist/core/codex-app-server-runner.d.ts +41 -0
  102. package/dist/core/codex-app-server-runner.js +584 -0
  103. package/dist/core/codex-app-server-runner.js.map +1 -0
  104. package/dist/core/codex-app-server-transport.d.ts +35 -0
  105. package/dist/core/codex-app-server-transport.js +150 -0
  106. package/dist/core/codex-app-server-transport.js.map +1 -0
  107. package/dist/core/codex-model-catalog.d.ts +10 -0
  108. package/dist/core/codex-model-catalog.js +110 -0
  109. package/dist/core/codex-model-catalog.js.map +1 -0
  110. package/dist/core/codex-ui-mapper.d.ts +112 -0
  111. package/dist/core/codex-ui-mapper.js +766 -0
  112. package/dist/core/codex-ui-mapper.js.map +1 -0
  113. package/dist/core/model-identity.d.ts +125 -0
  114. package/dist/core/model-identity.js +132 -0
  115. package/dist/core/model-identity.js.map +1 -0
  116. package/dist/core/model-presets.d.ts +21 -0
  117. package/dist/core/model-presets.js +81 -0
  118. package/dist/core/model-presets.js.map +1 -0
  119. package/dist/core/ndjson.d.ts +6 -0
  120. package/dist/core/ndjson.js +23 -0
  121. package/dist/core/ndjson.js.map +1 -0
  122. package/dist/core/opencode-model-catalog.d.ts +32 -0
  123. package/dist/core/opencode-model-catalog.js +153 -0
  124. package/dist/core/opencode-model-catalog.js.map +1 -0
  125. package/dist/core/opencode-server-runner.d.ts +32 -0
  126. package/dist/core/opencode-server-runner.js +882 -0
  127. package/dist/core/opencode-server-runner.js.map +1 -0
  128. package/dist/core/opencode-ui-mapper.d.ts +137 -0
  129. package/dist/core/opencode-ui-mapper.js +800 -0
  130. package/dist/core/opencode-ui-mapper.js.map +1 -0
  131. package/dist/core/pi-model-catalog.d.ts +31 -0
  132. package/dist/core/pi-model-catalog.js +152 -0
  133. package/dist/core/pi-model-catalog.js.map +1 -0
  134. package/dist/core/pi-runner.d.ts +24 -0
  135. package/dist/core/pi-runner.js +403 -0
  136. package/dist/core/pi-runner.js.map +1 -0
  137. package/dist/core/pi-ui-mapper.d.ts +36 -0
  138. package/dist/core/pi-ui-mapper.js +304 -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 +29 -0
  153. package/dist/core/runner-model-catalog.js +78 -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 +335 -0
  165. package/dist/core/ui-events.js +25 -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 +680 -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 +81 -0
  204. package/dist/release/manifests.js +74 -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 +38 -0
  210. package/dist/release/stable.js +55 -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/auto-name.d.ts +75 -0
  216. package/dist/runs/auto-name.js +179 -0
  217. package/dist/runs/auto-name.js.map +1 -0
  218. package/dist/runs/event-history.d.ts +50 -0
  219. package/dist/runs/event-history.js +613 -0
  220. package/dist/runs/event-history.js.map +1 -0
  221. package/dist/runs/retention.d.ts +60 -0
  222. package/dist/runs/retention.js +86 -0
  223. package/dist/runs/retention.js.map +1 -0
  224. package/dist/runs/review-gate.d.ts +18 -0
  225. package/dist/runs/review-gate.js +21 -0
  226. package/dist/runs/review-gate.js.map +1 -0
  227. package/dist/runs/run-index.d.ts +19 -0
  228. package/dist/runs/run-index.js +43 -0
  229. package/dist/runs/run-index.js.map +1 -0
  230. package/dist/runs/store.d.ts +446 -0
  231. package/dist/runs/store.js +1118 -0
  232. package/dist/runs/store.js.map +1 -0
  233. package/dist/runs/task-markers.d.ts +28 -0
  234. package/dist/runs/task-markers.js +74 -0
  235. package/dist/runs/task-markers.js.map +1 -0
  236. package/dist/runs/task-refs.d.ts +25 -0
  237. package/dist/runs/task-refs.js +74 -0
  238. package/dist/runs/task-refs.js.map +1 -0
  239. package/dist/runs/ui-event-sink.d.ts +81 -0
  240. package/dist/runs/ui-event-sink.js +210 -0
  241. package/dist/runs/ui-event-sink.js.map +1 -0
  242. package/dist/server/app-type.d.ts +21 -0
  243. package/dist/server/app-type.js +2 -0
  244. package/dist/server/app-type.js.map +1 -0
  245. package/dist/server/capabilities.d.ts +70 -0
  246. package/dist/server/capabilities.js +152 -0
  247. package/dist/server/capabilities.js.map +1 -0
  248. package/dist/server/checkout.d.ts +128 -0
  249. package/dist/server/checkout.js +296 -0
  250. package/dist/server/checkout.js.map +1 -0
  251. package/dist/server/forge/github.d.ts +513 -0
  252. package/dist/server/forge/github.js +2364 -0
  253. package/dist/server/forge/github.js.map +1 -0
  254. package/dist/server/forge/index.d.ts +40 -0
  255. package/dist/server/forge/index.js +72 -0
  256. package/dist/server/forge/index.js.map +1 -0
  257. package/dist/server/forge/types.d.ts +242 -0
  258. package/dist/server/forge/types.js +2 -0
  259. package/dist/server/forge/types.js.map +1 -0
  260. package/dist/server/fs-browse.d.ts +105 -0
  261. package/dist/server/fs-browse.js +182 -0
  262. package/dist/server/fs-browse.js.map +1 -0
  263. package/dist/server/git-changes.d.ts +213 -0
  264. package/dist/server/git-changes.js +555 -0
  265. package/dist/server/git-changes.js.map +1 -0
  266. package/dist/server/git.d.ts +28 -0
  267. package/dist/server/git.js +112 -0
  268. package/dist/server/git.js.map +1 -0
  269. package/dist/server/github.d.ts +9 -0
  270. package/dist/server/github.js +8 -0
  271. package/dist/server/github.js.map +1 -0
  272. package/dist/server/launch-key.d.ts +7 -0
  273. package/dist/server/launch-key.js +33 -0
  274. package/dist/server/launch-key.js.map +1 -0
  275. package/dist/server/open-in-app.d.ts +66 -0
  276. package/dist/server/open-in-app.js +211 -0
  277. package/dist/server/open-in-app.js.map +1 -0
  278. package/dist/server/open-in-terminal.d.ts +70 -0
  279. package/dist/server/open-in-terminal.js +179 -0
  280. package/dist/server/open-in-terminal.js.map +1 -0
  281. package/dist/server/pr.d.ts +7 -0
  282. package/dist/server/pr.js +7 -0
  283. package/dist/server/pr.js.map +1 -0
  284. package/dist/server/project-context.d.ts +120 -0
  285. package/dist/server/project-context.js +182 -0
  286. package/dist/server/project-context.js.map +1 -0
  287. package/dist/server/provider-action-gate.d.ts +8 -0
  288. package/dist/server/provider-action-gate.js +56 -0
  289. package/dist/server/provider-action-gate.js.map +1 -0
  290. package/dist/server/provider-auth-runtime.d.ts +21 -0
  291. package/dist/server/provider-auth-runtime.js +66 -0
  292. package/dist/server/provider-auth-runtime.js.map +1 -0
  293. package/dist/server/server.d.ts +13138 -0
  294. package/dist/server/server.js +5263 -0
  295. package/dist/server/server.js.map +1 -0
  296. package/dist/server/static-ui.d.ts +49 -0
  297. package/dist/server/static-ui.js +92 -0
  298. package/dist/server/static-ui.js.map +1 -0
  299. package/dist/server/validators.d.ts +97 -0
  300. package/dist/server/validators.js +86 -0
  301. package/dist/server/validators.js.map +1 -0
  302. package/dist/server/ws.d.ts +85 -0
  303. package/dist/server/ws.js +218 -0
  304. package/dist/server/ws.js.map +1 -0
  305. package/dist/server/wsl.d.ts +25 -0
  306. package/dist/server/wsl.js +92 -0
  307. package/dist/server/wsl.js.map +1 -0
  308. package/dist/server-install/engine.d.ts +50 -0
  309. package/dist/server-install/engine.js +324 -0
  310. package/dist/server-install/engine.js.map +1 -0
  311. package/dist/server-install/platforms/macosx-ngrok.d.ts +6 -0
  312. package/dist/server-install/platforms/macosx-ngrok.js +345 -0
  313. package/dist/server-install/platforms/macosx-ngrok.js.map +1 -0
  314. package/dist/server-install/platforms/ubuntu-vps.d.ts +78 -0
  315. package/dist/server-install/platforms/ubuntu-vps.js +1016 -0
  316. package/dist/server-install/platforms/ubuntu-vps.js.map +1 -0
  317. package/dist/server-install/state.d.ts +52 -0
  318. package/dist/server-install/state.js +182 -0
  319. package/dist/server-install/state.js.map +1 -0
  320. package/dist/server-install/steps.d.ts +109 -0
  321. package/dist/server-install/steps.js +334 -0
  322. package/dist/server-install/steps.js.map +1 -0
  323. package/dist/server-install/strategies.d.ts +4 -0
  324. package/dist/server-install/strategies.js +20 -0
  325. package/dist/server-install/strategies.js.map +1 -0
  326. package/dist/server-install/types.d.ts +287 -0
  327. package/dist/server-install/types.js +121 -0
  328. package/dist/server-install/types.js.map +1 -0
  329. package/dist/server-install/ui.d.ts +42 -0
  330. package/dist/server-install/ui.js +130 -0
  331. package/dist/server-install/ui.js.map +1 -0
  332. package/dist/skills-banner.d.ts +22 -0
  333. package/dist/skills-banner.js +41 -0
  334. package/dist/skills-banner.js.map +1 -0
  335. package/dist/skills-remote.d.ts +84 -0
  336. package/dist/skills-remote.js +468 -0
  337. package/dist/skills-remote.js.map +1 -0
  338. package/dist/skills-update.d.ts +88 -0
  339. package/dist/skills-update.js +392 -0
  340. package/dist/skills-update.js.map +1 -0
  341. package/dist/skills.d.ts +82 -0
  342. package/dist/skills.js +251 -0
  343. package/dist/skills.js.map +1 -0
  344. package/dist/todos.d.ts +48 -0
  345. package/dist/todos.js +201 -0
  346. package/dist/todos.js.map +1 -0
  347. package/dist/ui-state.d.ts +26 -0
  348. package/dist/ui-state.js +38 -0
  349. package/dist/ui-state.js.map +1 -0
  350. package/dist/update-check.d.ts +12 -0
  351. package/dist/update-check.js +41 -0
  352. package/dist/update-check.js.map +1 -0
  353. package/dist/workflows/load.d.ts +15 -0
  354. package/dist/workflows/load.js +56 -0
  355. package/dist/workflows/load.js.map +1 -0
  356. package/dist/workflows/run.d.ts +758 -0
  357. package/dist/workflows/run.js +3389 -0
  358. package/dist/workflows/run.js.map +1 -0
  359. package/dist/workflows/types.d.ts +153 -0
  360. package/dist/workflows/types.js +212 -0
  361. package/dist/workflows/types.js.map +1 -0
  362. package/dist/workspace/agent-accounts.d.ts +153 -0
  363. package/dist/workspace/agent-accounts.js +304 -0
  364. package/dist/workspace/agent-accounts.js.map +1 -0
  365. package/dist/workspace/agent-profiles.d.ts +78 -0
  366. package/dist/workspace/agent-profiles.js +115 -0
  367. package/dist/workspace/agent-profiles.js.map +1 -0
  368. package/dist/workspace/config.d.ts +169 -0
  369. package/dist/workspace/config.js +379 -0
  370. package/dist/workspace/config.js.map +1 -0
  371. package/dist/workspace/migrations.d.ts +45 -0
  372. package/dist/workspace/migrations.js +147 -0
  373. package/dist/workspace/migrations.js.map +1 -0
  374. package/dist/workspace/projects-cli.d.ts +25 -0
  375. package/dist/workspace/projects-cli.js +172 -0
  376. package/dist/workspace/projects-cli.js.map +1 -0
  377. package/dist/workspace/projects.d.ts +109 -0
  378. package/dist/workspace/projects.js +250 -0
  379. package/dist/workspace/projects.js.map +1 -0
  380. package/dist/workspace/semaphore.d.ts +179 -0
  381. package/dist/workspace/semaphore.js +195 -0
  382. package/dist/workspace/semaphore.js.map +1 -0
  383. package/dist/workspace/ui-state.d.ts +34 -0
  384. package/dist/workspace/ui-state.js +53 -0
  385. package/dist/workspace/ui-state.js.map +1 -0
  386. package/package.json +70 -0
  387. package/scripts/check-pack.mjs +46 -0
  388. package/scripts/inline-contract.mjs +112 -0
  389. package/scripts/install-as-command.mjs +120 -0
  390. package/scripts/mock-claude.mjs +520 -0
  391. package/scripts/mock-pi-rpc.mjs +83 -0
  392. package/scripts/sync-readme.mjs +20 -0
  393. package/scripts/test-process-usage.mjs +47 -0
  394. package/web/dist/assets/alert-dialog-B4Ofsgv7.js +1 -0
  395. package/web/dist/assets/arrow-down-Dy8dup7j.js +1 -0
  396. package/web/dist/assets/arrow-left-BJaucbhn.js +1 -0
  397. package/web/dist/assets/bundle-mjs-BT31bpU6.js +1 -0
  398. package/web/dist/assets/centered-state-duPW0phQ.js +43 -0
  399. package/web/dist/assets/chevron-right-Be4A5TCS.js +1 -0
  400. package/web/dist/assets/chunk-BO2N2NFS-DE6qKn3r.js +131 -0
  401. package/web/dist/assets/collapsible-DdcNBdSk.js +1 -0
  402. package/web/dist/assets/commit-list-CgvN9vec.js +1 -0
  403. package/web/dist/assets/compare-variants-CQA2nd65.js +1 -0
  404. package/web/dist/assets/core-BCsw8oQw.js +12 -0
  405. package/web/dist/assets/css-BsVw1vtW.js +1 -0
  406. package/web/dist/assets/diff-B6Agp5Hl.js +3 -0
  407. package/web/dist/assets/diff-stat-BoXuGkgq.js +1 -0
  408. package/web/dist/assets/diff-view-CD8XI-fj.js +6 -0
  409. package/web/dist/assets/diff-woXpYk--.js +1 -0
  410. package/web/dist/assets/dropdown-menu-B3SYw-k5.js +1 -0
  411. package/web/dist/assets/editable-title-B-hjp5wl.js +1 -0
  412. package/web/dist/assets/ellipsis-vertical-BYwzw0xl.js +1 -0
  413. package/web/dist/assets/engine-javascript-FQvzRocB.js +141 -0
  414. package/web/dist/assets/file-BRj5eISx.js +1 -0
  415. package/web/dist/assets/folder-z4oT5981.js +1 -0
  416. package/web/dist/assets/git-toolbar-owSEkYld.js +1 -0
  417. package/web/dist/assets/github-Bz2VgRX3.js +1 -0
  418. package/web/dist/assets/go-rLFTqkRN.js +1 -0
  419. package/web/dist/assets/highlighted-body-OFNGDK62-BL-MfFgl.js +1 -0
  420. package/web/dist/assets/highlighter-CdHqIwFr.js +3 -0
  421. package/web/dist/assets/html-BY76lXLH.js +1 -0
  422. package/web/dist/assets/image-preview-h3WFluuy.js +1 -0
  423. package/web/dist/assets/index-BbcQNT92.css +2 -0
  424. package/web/dist/assets/index-EtQQQ6Kj.js +7 -0
  425. package/web/dist/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  426. package/web/dist/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  427. package/web/dist/assets/javascript-BgS3c2Ky.js +1 -0
  428. package/web/dist/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
  429. package/web/dist/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
  430. package/web/dist/assets/json-qhed-kSA.js +1 -0
  431. package/web/dist/assets/jsonc-CYpm1nAK.js +1 -0
  432. package/web/dist/assets/jsx-Bz0zcwM4.js +1 -0
  433. package/web/dist/assets/lib-BQXq3kEf.js +1 -0
  434. package/web/dist/assets/lib-BxQXEXDF.js +1 -0
  435. package/web/dist/assets/markdown-BYOwaDjH.js +1 -0
  436. package/web/dist/assets/markdown-DqBKYPiB.js +2 -0
  437. package/web/dist/assets/mermaid-GHXKKRXX-C4jxqUUb.js +1 -0
  438. package/web/dist/assets/new-task-form-BdJKRBJX.js +1 -0
  439. package/web/dist/assets/pill-BQfmfpYp.js +1 -0
  440. package/web/dist/assets/project-router-DxgFZY1l.js +1 -0
  441. package/web/dist/assets/prompt-templates-B6m16gq-.js +15 -0
  442. package/web/dist/assets/python-gzcpVVnB.js +1 -0
  443. package/web/dist/assets/react-runtime-CCIEwYL0.js +9 -0
  444. package/web/dist/assets/refresh-cw-mhSpxf2a.js +1 -0
  445. package/web/dist/assets/repo-git-CUNRxR3_.js +1 -0
  446. package/web/dist/assets/rolldown-runtime-QTnfLwEv.js +1 -0
  447. package/web/dist/assets/run-diff-DsmmDVfx.js +3 -0
  448. package/web/dist/assets/run-header-BkhrseLJ.js +1 -0
  449. package/web/dist/assets/rust-Cfkwpbl8.js +1 -0
  450. package/web/dist/assets/search-x-BqDMB2g8.js +1 -0
  451. package/web/dist/assets/shellscript-CLZ0U2zV.js +1 -0
  452. package/web/dist/assets/skill-empty-hint-BWEvTggc.js +1 -0
  453. package/web/dist/assets/skills-9oR_oHse.js +1 -0
  454. package/web/dist/assets/skills-DwIxnnWO.js +1 -0
  455. package/web/dist/assets/sparkles-DIoTQpyx.js +1 -0
  456. package/web/dist/assets/sql-BsFa4tDR.js +1 -0
  457. package/web/dist/assets/square-terminal-Cc7CuQxc.js +1 -0
  458. package/web/dist/assets/tab-link-D1fQgpmO.js +1 -0
  459. package/web/dist/assets/task-changes-BKeLlDpK.js +1 -0
  460. package/web/dist/assets/task-commits-gcEFZIa5.js +1 -0
  461. package/web/dist/assets/task-files-BGAqoXTW.js +2 -0
  462. package/web/dist/assets/task-thread-DT8aUYTS.js +9 -0
  463. package/web/dist/assets/textarea-BOVbfy5C.js +1 -0
  464. package/web/dist/assets/thread-loading-CypW73KD.js +1 -0
  465. package/web/dist/assets/toml-CcmNWLt0.js +1 -0
  466. package/web/dist/assets/trash-2-CJq6LHWn.js +1 -0
  467. package/web/dist/assets/triangle-alert-CjDFvU27.js +1 -0
  468. package/web/dist/assets/tsx-udAQXfEw.js +1 -0
  469. package/web/dist/assets/typescript-bsJCZSQ-.js +1 -0
  470. package/web/dist/assets/upload-CPDZlJeK.js +1 -0
  471. package/web/dist/assets/use-desktop-5JsLmi0a.js +1 -0
  472. package/web/dist/assets/use-submit-shortcut-CHVFevty.js +1 -0
  473. package/web/dist/assets/utils-DiO6zyJd.js +64 -0
  474. package/web/dist/assets/workflows-rQDFzWRt.js +11 -0
  475. package/web/dist/assets/yaml-rwi0_p6S.js +1 -0
  476. package/web/dist/assets/zoomable-image-COWqb11v.js +1 -0
  477. package/web/dist/index.html +80 -0
  478. package/web/dist/open-mercato.svg +11 -0
@@ -0,0 +1,153 @@
1
+ import { z } from 'zod';
2
+ import { DEFAULT_AGENT_ACCOUNT_ID } from '../contract/index.js';
3
+ import { type ProviderId } from '../core/provider-auth.ts';
4
+ /**
5
+ * `~/.cezar/agent-accounts.json` — the agent-accounts store (spec `2026-07-29-agent-profiles.md`).
6
+ *
7
+ * ## Why its own file
8
+ *
9
+ * These keys started life in `config.json`, where their survival across a cezar downgrade rested
10
+ * on a `.passthrough()` modifier in the OTHER version's schema. That held for the versions in
11
+ * this repo's history — measured, not assumed — but it is not a guarantee this repo can make on
12
+ * behalf of a build someone switches to, and it fails completely in the one case that matters
13
+ * most: any version that cannot parse `config.json` degrades to in-memory defaults, and its next
14
+ * merge-write rewrites the file without whatever it did not understand.
15
+ *
16
+ * A version that has never heard of accounts does not open THIS file, so it cannot lose them.
17
+ * That is the entire argument, and it is why the selections live here too rather than on the
18
+ * project registry.
19
+ *
20
+ * ## House rules (the same ones `config.json` follows, for the same reasons)
21
+ *
22
+ * - every field optional/defaulted with `.catch`, so a bad value degrades per key;
23
+ * - `.passthrough()` at every object level, so a NEWER cezar's keys survive an older one;
24
+ * - per-entry salvage for `accounts` — one hand-edited row never evicts the rest;
25
+ * - atomic tmp+rename at `0600` through the shared writer;
26
+ * - a corrupt or unreadable file degrades to empty with ONE warning, never a boot failure.
27
+ *
28
+ * ## Identity
29
+ *
30
+ * Selections are keyed by the project's REALPATH'D ROOT, not its registry slug. The root is what
31
+ * every consumer already has in hand (`resolveProfileEnvForRoot` takes it), it survives the
32
+ * registry being rebuilt, and it means this file needs no cross-reference into `config.json` at
33
+ * all. An orphaned entry — a project the user deregistered — resolves to nothing and is inert.
34
+ */
35
+ /** `id` slug rule — the project rule, for the same URL/segment-safety reason. */
36
+ export declare const AGENT_ACCOUNT_ID_RE: RegExp;
37
+ /**
38
+ * Reserved id meaning "the dir cezar discovers" (`agentHomePaths()`).
39
+ *
40
+ * NEVER stored and never allocated: the default account is the zero-config answer, so an absent
41
+ * file behaves exactly as cezar always has. Materializing it would turn a discovered fact into
42
+ * state a user has to maintain.
43
+ *
44
+ * Re-exported from the contract rather than spelled again here: the cockpit sends this exact string
45
+ * to mean "the discovered account, whatever the repo is set to", so a second definition is a place
46
+ * for the two sides to drift apart silently.
47
+ */
48
+ export { DEFAULT_AGENT_ACCOUNT_ID };
49
+ /**
50
+ * Is `configDir` absolute on `platform`? The account routes' only path rule, and the reason it is a
51
+ * named function rather than a test written inline.
52
+ *
53
+ * A relative dir would resolve against whatever cwd the agent happens to be spawned in — for a task
54
+ * that is a throwaway worktree — so it has to be refused. But the obvious spelling of that refusal,
55
+ * a leading-`/` test, refuses every real Windows path too: `C:\Users\me\.claude-work` starts with
56
+ * neither `/` nor `~`. That is not a corner case: `core/shell-env.ts` renders `set "VAR=v"` for
57
+ * `cmd.exe` precisely so an account survives a Windows terminal handoff, and the Add-account dialog
58
+ * delegates ALL path validation to the server, so a string test would leave the whole feature
59
+ * unreachable on the one platform the rest of this work went out of its way to support.
60
+ *
61
+ * `platform` is a parameter so both answers stay testable from either OS.
62
+ */
63
+ export declare function isAbsoluteConfigDir(configDir: string, platform?: NodeJS.Platform): boolean;
64
+ /** C0 controls + DEL. A path containing one is never legitimate and would be interpolated into a
65
+ * shell command by the CLI handoff, so it is refused at the schema, not just at the route. */
66
+ export declare const CONTROL_CHARS_RE: RegExp;
67
+ /**
68
+ * One extra config dir for a provider — a second login of the same CLI
69
+ * (`CLAUDE_CONFIG_DIR=~/.claude-klaudiusz claude`), see `src/core/agent-profiles.ts`.
70
+ *
71
+ * `id`, `provider` and `configDir` are load-bearing and carry no `.catch`: a row missing any of
72
+ * them names no account, so the per-entry salvage below drops it. Display fields degrade per key.
73
+ *
74
+ * `configDir` is stored AS WRITTEN — a literal `~` survives — and every consumer expands it
75
+ * through `expandTilde`.
76
+ */
77
+ declare const agentAccountSchema: z.ZodObject<{
78
+ id: z.ZodString;
79
+ provider: z.ZodEnum<{
80
+ claude: "claude";
81
+ codex: "codex";
82
+ opencode: "opencode";
83
+ pi: "pi";
84
+ }>;
85
+ configDir: z.ZodString;
86
+ label: z.ZodCatch<z.ZodString>;
87
+ addedAt: z.ZodCatch<z.ZodString>;
88
+ }, z.core.$loose>;
89
+ export type AgentAccount = z.infer<typeof agentAccountSchema>;
90
+ /** One project's choice, per provider. Explicit keys so `PROVIDER_IDS` stays the one source of
91
+ * truth and the value is bounded. An absent key means the discovered default. */
92
+ declare const selectionSchema: z.ZodObject<{
93
+ claude: z.ZodCatch<z.ZodOptional<z.ZodString>>;
94
+ codex: z.ZodCatch<z.ZodOptional<z.ZodString>>;
95
+ opencode: z.ZodCatch<z.ZodOptional<z.ZodString>>;
96
+ pi: z.ZodCatch<z.ZodOptional<z.ZodString>>;
97
+ }, z.core.$loose>;
98
+ export type AgentAccountSelection = z.infer<typeof selectionSchema>;
99
+ declare const storeSchema: z.ZodObject<{
100
+ version: z.ZodCatch<z.ZodDefault<z.ZodNumber>>;
101
+ accounts: z.ZodPipe<z.ZodCatch<z.ZodDefault<z.ZodArray<z.ZodUnknown>>>, z.ZodTransform<{
102
+ [x: string]: unknown;
103
+ id: string;
104
+ provider: "claude" | "codex" | "opencode" | "pi";
105
+ configDir: string;
106
+ label: string;
107
+ addedAt: string;
108
+ }[], unknown[]>>;
109
+ defaults: z.ZodCatch<z.ZodDefault<z.ZodObject<{
110
+ claude: z.ZodCatch<z.ZodOptional<z.ZodString>>;
111
+ codex: z.ZodCatch<z.ZodOptional<z.ZodString>>;
112
+ opencode: z.ZodCatch<z.ZodOptional<z.ZodString>>;
113
+ pi: z.ZodCatch<z.ZodOptional<z.ZodString>>;
114
+ }, z.core.$loose>>>;
115
+ selections: z.ZodPipe<z.ZodCatch<z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodUnknown>>>, z.ZodTransform<Record<string, {
116
+ [x: string]: unknown;
117
+ claude?: string | undefined;
118
+ codex?: string | undefined;
119
+ opencode?: string | undefined;
120
+ pi?: string | undefined;
121
+ }>, Record<string, unknown>>>;
122
+ }, z.core.$loose>;
123
+ export type AgentAccountStore = z.infer<typeof storeSchema>;
124
+ /** The in-memory default — what a missing file behaves like, and the zero-config state. */
125
+ export declare function defaultAgentAccountStore(): AgentAccountStore;
126
+ /**
127
+ * Read the store on demand — never cached, never throws.
128
+ *
129
+ * Not cached because `~/.cezar/` is shared by every cezar process on the machine, so a snapshot is
130
+ * a staleness bug; one small JSON read is free next to spawning a CLI.
131
+ *
132
+ * A missing file is the zero-config default (silent). A corrupt one degrades to the default with a
133
+ * one-line warning and is left on disk untouched, so the user can repair it by hand — the next
134
+ * successful merge-write is what replaces it.
135
+ */
136
+ export declare function loadAgentAccounts(): Promise<AgentAccountStore>;
137
+ /**
138
+ * Read-modify-write merge: re-read, apply `mutator`, atomic-rename write.
139
+ *
140
+ * Because every writer re-reads immediately before writing, two cezar processes editing different
141
+ * accounts converge instead of dropping each other's — last-writer-wins only inside the tiny
142
+ * read→rename window, which is the same bargain `config.json` makes. Throws on write failure (a
143
+ * read-only home); degrading is the caller's policy.
144
+ */
145
+ export declare function mergeWriteAgentAccounts(mutator: (store: AgentAccountStore) => AgentAccountStore | void): Promise<AgentAccountStore>;
146
+ /**
147
+ * The account `provider` uses for `repoRoot`, or undefined when nothing has an opinion.
148
+ *
149
+ * Repo first, then the machine-wide default. The order is the whole feature: a repo that chose is
150
+ * never overruled by a later change to the default, and a repo that never chose follows it — so
151
+ * adding a second login is a one-time act rather than one per checkout.
152
+ */
153
+ export declare function selectionFor(store: Pick<AgentAccountStore, 'selections' | 'defaults'>, repoRoot: string | undefined, provider: ProviderId): string | undefined;
@@ -0,0 +1,304 @@
1
+ import { realpathSync } from 'node:fs';
2
+ import { readFile } from 'node:fs/promises';
3
+ import { posix, resolve, win32 } from 'node:path';
4
+ import { z } from 'zod';
5
+ import { DEFAULT_AGENT_ACCOUNT_ID } from '../contract/index.js';
6
+ import { PROVIDER_IDS } from '../core/provider-auth.js';
7
+ import { supportsProfiles } from '../core/agent-profiles.js';
8
+ import { agentAccountsPath, workspaceConfigPath } from '../paths.js';
9
+ import { atomicWriteJsonSync } from './config.js';
10
+ /**
11
+ * `~/.cezar/agent-accounts.json` — the agent-accounts store (spec `2026-07-29-agent-profiles.md`).
12
+ *
13
+ * ## Why its own file
14
+ *
15
+ * These keys started life in `config.json`, where their survival across a cezar downgrade rested
16
+ * on a `.passthrough()` modifier in the OTHER version's schema. That held for the versions in
17
+ * this repo's history — measured, not assumed — but it is not a guarantee this repo can make on
18
+ * behalf of a build someone switches to, and it fails completely in the one case that matters
19
+ * most: any version that cannot parse `config.json` degrades to in-memory defaults, and its next
20
+ * merge-write rewrites the file without whatever it did not understand.
21
+ *
22
+ * A version that has never heard of accounts does not open THIS file, so it cannot lose them.
23
+ * That is the entire argument, and it is why the selections live here too rather than on the
24
+ * project registry.
25
+ *
26
+ * ## House rules (the same ones `config.json` follows, for the same reasons)
27
+ *
28
+ * - every field optional/defaulted with `.catch`, so a bad value degrades per key;
29
+ * - `.passthrough()` at every object level, so a NEWER cezar's keys survive an older one;
30
+ * - per-entry salvage for `accounts` — one hand-edited row never evicts the rest;
31
+ * - atomic tmp+rename at `0600` through the shared writer;
32
+ * - a corrupt or unreadable file degrades to empty with ONE warning, never a boot failure.
33
+ *
34
+ * ## Identity
35
+ *
36
+ * Selections are keyed by the project's REALPATH'D ROOT, not its registry slug. The root is what
37
+ * every consumer already has in hand (`resolveProfileEnvForRoot` takes it), it survives the
38
+ * registry being rebuilt, and it means this file needs no cross-reference into `config.json` at
39
+ * all. An orphaned entry — a project the user deregistered — resolves to nothing and is inert.
40
+ */
41
+ /** `id` slug rule — the project rule, for the same URL/segment-safety reason. */
42
+ export const AGENT_ACCOUNT_ID_RE = /^[a-z0-9][a-z0-9-]{0,63}$/;
43
+ /**
44
+ * Reserved id meaning "the dir cezar discovers" (`agentHomePaths()`).
45
+ *
46
+ * NEVER stored and never allocated: the default account is the zero-config answer, so an absent
47
+ * file behaves exactly as cezar always has. Materializing it would turn a discovered fact into
48
+ * state a user has to maintain.
49
+ *
50
+ * Re-exported from the contract rather than spelled again here: the cockpit sends this exact string
51
+ * to mean "the discovered account, whatever the repo is set to", so a second definition is a place
52
+ * for the two sides to drift apart silently.
53
+ */
54
+ export { DEFAULT_AGENT_ACCOUNT_ID };
55
+ /**
56
+ * Is `configDir` absolute on `platform`? The account routes' only path rule, and the reason it is a
57
+ * named function rather than a test written inline.
58
+ *
59
+ * A relative dir would resolve against whatever cwd the agent happens to be spawned in — for a task
60
+ * that is a throwaway worktree — so it has to be refused. But the obvious spelling of that refusal,
61
+ * a leading-`/` test, refuses every real Windows path too: `C:\Users\me\.claude-work` starts with
62
+ * neither `/` nor `~`. That is not a corner case: `core/shell-env.ts` renders `set "VAR=v"` for
63
+ * `cmd.exe` precisely so an account survives a Windows terminal handoff, and the Add-account dialog
64
+ * delegates ALL path validation to the server, so a string test would leave the whole feature
65
+ * unreachable on the one platform the rest of this work went out of its way to support.
66
+ *
67
+ * `platform` is a parameter so both answers stay testable from either OS.
68
+ */
69
+ export function isAbsoluteConfigDir(configDir, platform = process.platform) {
70
+ return (platform === 'win32' ? win32 : posix).isAbsolute(configDir);
71
+ }
72
+ /** C0 controls + DEL. A path containing one is never legitimate and would be interpolated into a
73
+ * shell command by the CLI handoff, so it is refused at the schema, not just at the route. */
74
+ export const CONTROL_CHARS_RE = /[\u0000-\u001f\u007f]/;
75
+ /**
76
+ * One extra config dir for a provider — a second login of the same CLI
77
+ * (`CLAUDE_CONFIG_DIR=~/.claude-klaudiusz claude`), see `src/core/agent-profiles.ts`.
78
+ *
79
+ * `id`, `provider` and `configDir` are load-bearing and carry no `.catch`: a row missing any of
80
+ * them names no account, so the per-entry salvage below drops it. Display fields degrade per key.
81
+ *
82
+ * `configDir` is stored AS WRITTEN — a literal `~` survives — and every consumer expands it
83
+ * through `expandTilde`.
84
+ */
85
+ const agentAccountSchema = z
86
+ .object({
87
+ id: z.string().regex(AGENT_ACCOUNT_ID_RE).refine((v) => v !== DEFAULT_AGENT_ACCOUNT_ID, {
88
+ message: `"${DEFAULT_AGENT_ACCOUNT_ID}" is reserved for the discovered account`,
89
+ }),
90
+ // Refused at the SCHEMA, not just at the route, for the same reason the reserved `default` id
91
+ // is: this file is designed to survive hand edits, foreign writers and the legacy import, and a
92
+ // provider whose credentials do not follow its config dir resolves to a LIE — `profileEnv`
93
+ // returns `{}` for it, so the step records the account, the UI names it, and the CLI runs on
94
+ // the default login anyway. Dropped by the per-entry salvage instead, which is the one
95
+ // degradation that cannot mislead.
96
+ provider: z.enum(PROVIDER_IDS).refine(supportsProfiles, {
97
+ message: 'this agent cannot carry more than one account (its credentials do not follow its config dir)',
98
+ }),
99
+ configDir: z
100
+ .string()
101
+ .min(1)
102
+ .max(4096)
103
+ .refine((v) => !CONTROL_CHARS_RE.test(v), 'configDir must not contain control characters'),
104
+ label: z.string().max(200).catch(''),
105
+ addedAt: z.string().max(64).catch(''),
106
+ })
107
+ .passthrough();
108
+ /** One project's choice, per provider. Explicit keys so `PROVIDER_IDS` stays the one source of
109
+ * truth and the value is bounded. An absent key means the discovered default. */
110
+ const selectionSchema = z
111
+ .object({
112
+ claude: z.string().max(64).optional().catch(undefined),
113
+ codex: z.string().max(64).optional().catch(undefined),
114
+ opencode: z.string().max(64).optional().catch(undefined),
115
+ pi: z.string().max(64).optional().catch(undefined),
116
+ })
117
+ .passthrough();
118
+ const storeSchema = z
119
+ .object({
120
+ /** Format cursor for THIS file, independent of `config.json`'s `schemaVersion`. Nothing reads
121
+ * it yet; it exists so a future shape change has somewhere to say so. */
122
+ version: z.number().int().min(0).default(1).catch(1),
123
+ accounts: z
124
+ .array(z.unknown())
125
+ .default(() => [])
126
+ .catch(() => [])
127
+ .transform((entries) => {
128
+ const seen = new Set();
129
+ return entries.flatMap((entry) => {
130
+ const parsed = agentAccountSchema.safeParse(entry);
131
+ // First-wins on a duplicated id, so two consumers never resolve the same id differently.
132
+ if (!parsed.success || seen.has(parsed.data.id))
133
+ return [];
134
+ seen.add(parsed.data.id);
135
+ return [parsed.data];
136
+ });
137
+ }),
138
+ /**
139
+ * The per-provider account a repo with no selection of its own uses.
140
+ *
141
+ * A machine-wide answer to "which login do I work under", so a second account does not have to
142
+ * be re-chosen for every checkout. Consulted only where `selections` is silent for that repo
143
+ * and provider — a repo that HAS chosen keeps its choice, which is what makes this a default
144
+ * rather than an override.
145
+ */
146
+ defaults: selectionSchema.default(() => ({})).catch(() => ({})),
147
+ /** Repo root → per-provider choice. Per-entry salvage: a bad row is dropped, the rest stay. */
148
+ selections: z
149
+ .record(z.string(), z.unknown())
150
+ .default(() => ({}))
151
+ .catch(() => ({}))
152
+ .transform((raw) => {
153
+ const out = {};
154
+ for (const [root, value] of Object.entries(raw)) {
155
+ const parsed = selectionSchema.safeParse(value);
156
+ if (parsed.success)
157
+ out[root] = parsed.data;
158
+ }
159
+ return out;
160
+ }),
161
+ })
162
+ .passthrough();
163
+ /** The in-memory default — what a missing file behaves like, and the zero-config state. */
164
+ export function defaultAgentAccountStore() {
165
+ return storeSchema.parse({});
166
+ }
167
+ /**
168
+ * Read the store on demand — never cached, never throws.
169
+ *
170
+ * Not cached because `~/.cezar/` is shared by every cezar process on the machine, so a snapshot is
171
+ * a staleness bug; one small JSON read is free next to spawning a CLI.
172
+ *
173
+ * A missing file is the zero-config default (silent). A corrupt one degrades to the default with a
174
+ * one-line warning and is left on disk untouched, so the user can repair it by hand — the next
175
+ * successful merge-write is what replaces it.
176
+ */
177
+ export async function loadAgentAccounts() {
178
+ const path = agentAccountsPath();
179
+ let raw;
180
+ try {
181
+ raw = await readFile(path, 'utf8');
182
+ }
183
+ catch {
184
+ // Absent — but accounts may predate this file (they lived in config.json on the branch that
185
+ // introduced them), so give those one chance to come across.
186
+ return importLegacyAccounts();
187
+ }
188
+ try {
189
+ const parsed = storeSchema.safeParse(JSON.parse(raw));
190
+ if (parsed.success)
191
+ return parsed.data;
192
+ }
193
+ catch {
194
+ // malformed JSON — fall through to the warning + defaults
195
+ }
196
+ console.warn(`[cez] agent accounts ${path} is corrupt — ignoring it (every project falls back to its default account)`);
197
+ return defaultAgentAccountStore();
198
+ }
199
+ /**
200
+ * Read-modify-write merge: re-read, apply `mutator`, atomic-rename write.
201
+ *
202
+ * Because every writer re-reads immediately before writing, two cezar processes editing different
203
+ * accounts converge instead of dropping each other's — last-writer-wins only inside the tiny
204
+ * read→rename window, which is the same bargain `config.json` makes. Throws on write failure (a
205
+ * read-only home); degrading is the caller's policy.
206
+ */
207
+ export async function mergeWriteAgentAccounts(mutator) {
208
+ const current = await loadAgentAccounts();
209
+ const next = mutator(current) ?? current;
210
+ atomicWriteJsonSync(agentAccountsPath(), next);
211
+ return next;
212
+ }
213
+ /**
214
+ * One-time, non-destructive import of accounts that were written into `config.json` by the branch
215
+ * that first introduced them (before they got their own file).
216
+ *
217
+ * Reads the RAW object rather than going through the workspace schema, because that schema no
218
+ * longer names these keys — they only survive there as passthrough. Nothing is deleted from
219
+ * `config.json`: an older cezar sharing this home keeps reading what it has always read, and this
220
+ * import is idempotent because it only runs while `agent-accounts.json` is absent.
221
+ */
222
+ async function importLegacyAccounts() {
223
+ let parsed;
224
+ try {
225
+ parsed = JSON.parse(await readFile(workspaceConfigPath(), 'utf8'));
226
+ }
227
+ catch {
228
+ return defaultAgentAccountStore();
229
+ }
230
+ if (!parsed || typeof parsed !== 'object')
231
+ return defaultAgentAccountStore();
232
+ const legacy = parsed;
233
+ const selections = {};
234
+ if (Array.isArray(legacy.projects)) {
235
+ for (const entry of legacy.projects) {
236
+ if (!entry || typeof entry !== 'object')
237
+ continue;
238
+ const { root, agentProfile } = entry;
239
+ if (typeof root === 'string' && agentProfile && typeof agentProfile === 'object') {
240
+ selections[root] = agentProfile;
241
+ }
242
+ }
243
+ }
244
+ const imported = storeSchema.safeParse({ accounts: legacy.agentProfiles, selections });
245
+ if (!imported.success)
246
+ return defaultAgentAccountStore();
247
+ // Only worth persisting when there was something to carry over; an empty import must not create
248
+ // a file, or the zero-config promise ("delete any of them and cezar rebuilds") gains a file that
249
+ // exists for no reason.
250
+ if (imported.data.accounts.length === 0)
251
+ return imported.data;
252
+ try {
253
+ atomicWriteJsonSync(agentAccountsPath(), imported.data);
254
+ }
255
+ catch {
256
+ // read-only home: the import stays in memory for this process, which is still correct
257
+ }
258
+ return imported.data;
259
+ }
260
+ /**
261
+ * The account `provider` uses for `repoRoot`, or undefined when nothing has an opinion.
262
+ *
263
+ * Repo first, then the machine-wide default. The order is the whole feature: a repo that chose is
264
+ * never overruled by a later change to the default, and a repo that never chose follows it — so
265
+ * adding a second login is a one-time act rather than one per checkout.
266
+ */
267
+ export function selectionFor(store, repoRoot, provider) {
268
+ const chosen = repoRoot === undefined ? undefined : selectionForRoot(store, repoRoot)?.[provider];
269
+ return chosen ?? store.defaults[provider];
270
+ }
271
+ /**
272
+ * The selection stored for `repoRoot`, matched on the literal spelling first and the realpath'd
273
+ * one second.
274
+ *
275
+ * The keys come from the REGISTRY, which realpath-normalizes every root it stores
276
+ * (`workspace/projects.ts` `normalizeRoot`); the readers hold whatever spelling their caller had —
277
+ * `RunManager` is constructed with `repoInfo?.root ?? cwd` for the boot project, not with the
278
+ * registry entry. `workspace/semaphore.ts` already normalizes at lookup for the per-project
279
+ * concurrency map for exactly this reason. Doing it here too matters more, not less: a missed
280
+ * concurrency override runs the task with the wrong ceiling, a missed account selection runs it on
281
+ * the wrong subscription and says nothing.
282
+ *
283
+ * The literal probe comes first because it is free and answers the overwhelmingly common case; the
284
+ * normalized one only pays a `realpathSync` when the literal key is absent.
285
+ */
286
+ function selectionForRoot(store, repoRoot) {
287
+ const literal = store.selections[repoRoot];
288
+ if (literal !== undefined)
289
+ return literal;
290
+ const normalized = normalizeRootSync(repoRoot);
291
+ return normalized === repoRoot ? undefined : store.selections[normalized];
292
+ }
293
+ /** Realpath-normalize a root the way the registry does, but synchronously — this answers a run's
294
+ * per-step lookup and must not `await`. A path that cannot be realpath'd (gone, unreadable)
295
+ * degrades to `resolve()`, matching the registry's own fallback and `semaphore.ts`'s. */
296
+ function normalizeRootSync(root) {
297
+ try {
298
+ return realpathSync(root);
299
+ }
300
+ catch {
301
+ return resolve(root);
302
+ }
303
+ }
304
+ //# sourceMappingURL=agent-accounts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-accounts.js","sourceRoot":"","sources":["../../src/workspace/agent-accounts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ import type { ProviderId } from '../core/provider-auth.ts';
2
+ import { type AgentAccount, type AgentAccountStore } from './agent-accounts.ts';
3
+ /**
4
+ * Resolving an agent account against `~/.cezar/agent-accounts.json` — the I/O half of
5
+ * `src/core/agent-profiles.ts` (which stays pure and owns the vendor knowledge).
6
+ *
7
+ * Nothing here is cached. `~/.cezar/` is shared by every cezar process on the machine (a `serve`
8
+ * per repo, headless `cezar run`s, a settings PUT), so a snapshot is a staleness bug waiting to
9
+ * happen — and one small JSON read is free next to spawning an agent CLI.
10
+ */
11
+ /** An account as the rest of the codebase consumes it: id, provider, and the dir to point at. */
12
+ export interface ResolvedAgentProfile {
13
+ id: string;
14
+ provider: ProviderId;
15
+ label: string;
16
+ /** As stored (`~` kept) — what the user typed, or the discovered default's path. */
17
+ configDir: string;
18
+ /** Expanded absolute path — what actually gets handed to the CLI. */
19
+ path: string;
20
+ /** True for the discovered account, which is never stored and cannot be edited or deleted. */
21
+ isDefault: boolean;
22
+ }
23
+ /**
24
+ * The implicit account for a provider: whatever `agentHomePaths()` discovers, which already
25
+ * honours the vendors' own `CLAUDE_CONFIG_DIR` / `CODEX_HOME` / `XDG_CONFIG_HOME`. Setting one of
26
+ * those on the cezar process therefore moves the DEFAULT account rather than being ignored.
27
+ */
28
+ export declare function defaultAgentProfile(provider: ProviderId, env?: NodeJS.ProcessEnv): ResolvedAgentProfile;
29
+ /** Expand a stored account into its resolved form. Pure; the caller supplies the row. */
30
+ export declare function resolveStoredProfile(account: AgentAccount): ResolvedAgentProfile;
31
+ /** Every account for `provider`, discovered default first, then the stored extras in file order. */
32
+ export declare function profilesForProvider(store: Pick<AgentAccountStore, 'accounts'>, provider: ProviderId, env?: NodeJS.ProcessEnv): ResolvedAgentProfile[];
33
+ /** Every account across every provider — the listing route's source. */
34
+ export declare function listAgentProfiles(store: Pick<AgentAccountStore, 'accounts'>, providers: readonly ProviderId[], env?: NodeJS.ProcessEnv): ResolvedAgentProfile[];
35
+ /**
36
+ * The account a given `(project, provider)` pair resolves to.
37
+ *
38
+ * `profileId` is the caller's explicit choice — a run's recorded account, or a composer override.
39
+ * When it is absent the project's stored selection decides, and when THAT is absent (or names an
40
+ * account that no longer exists) the answer is the discovered default.
41
+ *
42
+ * Note the deliberate asymmetry with a missing DIRECTORY: an UNKNOWN id degrades silently to the
43
+ * default, because a dangling reference names no account and the default is the only safe answer.
44
+ * A KNOWN id whose directory has vanished does NOT degrade — see `profileDirState`. Falling back
45
+ * there would run the task on the personal subscription while the UI still said "Work", and a
46
+ * billing boundary is not a preference to degrade quietly across.
47
+ */
48
+ export declare function selectProfile(store: AgentAccountStore, options: {
49
+ provider: ProviderId;
50
+ repoRoot?: string;
51
+ profileId?: string;
52
+ env?: NodeJS.ProcessEnv;
53
+ }): ResolvedAgentProfile;
54
+ /**
55
+ * The env a spawned `provider` process needs for the account selected by `repoRoot`/`profileId`.
56
+ *
57
+ * `{}` for the default account, which is the whole point: the zero-config path adds nothing to the
58
+ * child environment. Reads the store per call (see the module note) and never throws — an
59
+ * unreadable home degrades to the default account, which is the behaviour cezar had before
60
+ * accounts existed.
61
+ */
62
+ export declare function resolveProfileEnvForRoot(repoRoot: string | undefined, provider: ProviderId, profileId?: string, env?: NodeJS.ProcessEnv): Promise<{
63
+ profile: ResolvedAgentProfile;
64
+ env: Record<string, string>;
65
+ }>;
66
+ /** Whether an account's directory exists and looks like the agent wrote it. Never throws. */
67
+ export declare function profileDirState(provider: ProviderId, path: string): Promise<{
68
+ exists: boolean;
69
+ looksValid: boolean;
70
+ }>;
71
+ /**
72
+ * Is `path` the same directory as an existing account's (or the default's)?
73
+ *
74
+ * Compared through `realpath` so two spellings of one dir — a symlink, a trailing slash — cannot
75
+ * become two accounts that silently share a session store. A path that does not exist yet cannot
76
+ * collide with anything, which is correct: the CLI has not created it, so it is nobody's home.
77
+ */
78
+ export declare function sameProfileDir(a: string, b: string): Promise<boolean>;
@@ -0,0 +1,115 @@
1
+ import { readdir, realpath } from 'node:fs/promises';
2
+ import { profileEnv, looksLikeProfileDir } from '../core/agent-profiles.js';
3
+ import { agentHomePaths, expandTilde } from '../paths.js';
4
+ import { DEFAULT_AGENT_ACCOUNT_ID, loadAgentAccounts, selectionFor, } from './agent-accounts.js';
5
+ /**
6
+ * The implicit account for a provider: whatever `agentHomePaths()` discovers, which already
7
+ * honours the vendors' own `CLAUDE_CONFIG_DIR` / `CODEX_HOME` / `XDG_CONFIG_HOME`. Setting one of
8
+ * those on the cezar process therefore moves the DEFAULT account rather than being ignored.
9
+ */
10
+ export function defaultAgentProfile(provider, env = process.env) {
11
+ const home = agentHomePaths(env);
12
+ const path = provider === 'codex' ? home.codex : provider === 'opencode' ? home.opencodeConfig : home.claude;
13
+ return {
14
+ id: DEFAULT_AGENT_ACCOUNT_ID,
15
+ provider,
16
+ label: 'Default',
17
+ configDir: path,
18
+ path,
19
+ isDefault: true,
20
+ };
21
+ }
22
+ /** Expand a stored account into its resolved form. Pure; the caller supplies the row. */
23
+ export function resolveStoredProfile(account) {
24
+ return {
25
+ id: account.id,
26
+ provider: account.provider,
27
+ label: account.label || account.id,
28
+ configDir: account.configDir,
29
+ path: expandTilde(account.configDir),
30
+ isDefault: false,
31
+ };
32
+ }
33
+ /** Every account for `provider`, discovered default first, then the stored extras in file order. */
34
+ export function profilesForProvider(store, provider, env = process.env) {
35
+ return [
36
+ defaultAgentProfile(provider, env),
37
+ ...store.accounts.filter((a) => a.provider === provider).map(resolveStoredProfile),
38
+ ];
39
+ }
40
+ /** Every account across every provider — the listing route's source. */
41
+ export function listAgentProfiles(store, providers, env = process.env) {
42
+ return providers.flatMap((provider) => profilesForProvider(store, provider, env));
43
+ }
44
+ /**
45
+ * The account a given `(project, provider)` pair resolves to.
46
+ *
47
+ * `profileId` is the caller's explicit choice — a run's recorded account, or a composer override.
48
+ * When it is absent the project's stored selection decides, and when THAT is absent (or names an
49
+ * account that no longer exists) the answer is the discovered default.
50
+ *
51
+ * Note the deliberate asymmetry with a missing DIRECTORY: an UNKNOWN id degrades silently to the
52
+ * default, because a dangling reference names no account and the default is the only safe answer.
53
+ * A KNOWN id whose directory has vanished does NOT degrade — see `profileDirState`. Falling back
54
+ * there would run the task on the personal subscription while the UI still said "Work", and a
55
+ * billing boundary is not a preference to degrade quietly across.
56
+ */
57
+ export function selectProfile(store, options) {
58
+ const { provider, repoRoot, profileId } = options;
59
+ const env = options.env ?? process.env;
60
+ const chosen = profileId ?? selectionFor(store, repoRoot, provider);
61
+ if (chosen === undefined || chosen === DEFAULT_AGENT_ACCOUNT_ID)
62
+ return defaultAgentProfile(provider, env);
63
+ const stored = store.accounts.find((a) => a.id === chosen && a.provider === provider);
64
+ return stored ? resolveStoredProfile(stored) : defaultAgentProfile(provider, env);
65
+ }
66
+ /**
67
+ * The env a spawned `provider` process needs for the account selected by `repoRoot`/`profileId`.
68
+ *
69
+ * `{}` for the default account, which is the whole point: the zero-config path adds nothing to the
70
+ * child environment. Reads the store per call (see the module note) and never throws — an
71
+ * unreadable home degrades to the default account, which is the behaviour cezar had before
72
+ * accounts existed.
73
+ */
74
+ export async function resolveProfileEnvForRoot(repoRoot, provider, profileId, env = process.env) {
75
+ let store;
76
+ try {
77
+ store = await loadAgentAccounts();
78
+ }
79
+ catch {
80
+ return { profile: defaultAgentProfile(provider, env), env: {} };
81
+ }
82
+ const profile = selectProfile(store, { provider, repoRoot, profileId, env });
83
+ // The default account contributes nothing: `agentHomePaths()` already reflects whatever the host
84
+ // env says, so re-exporting it would be a no-op at best and a surprise at worst.
85
+ return { profile, env: profile.isDefault ? {} : profileEnv(provider, profile.path) };
86
+ }
87
+ /** Whether an account's directory exists and looks like the agent wrote it. Never throws. */
88
+ export async function profileDirState(provider, path) {
89
+ let entries;
90
+ try {
91
+ entries = await readdir(path);
92
+ }
93
+ catch {
94
+ return { exists: false, looksValid: false };
95
+ }
96
+ return { exists: true, looksValid: looksLikeProfileDir(provider, entries) };
97
+ }
98
+ /**
99
+ * Is `path` the same directory as an existing account's (or the default's)?
100
+ *
101
+ * Compared through `realpath` so two spellings of one dir — a symlink, a trailing slash — cannot
102
+ * become two accounts that silently share a session store. A path that does not exist yet cannot
103
+ * collide with anything, which is correct: the CLI has not created it, so it is nobody's home.
104
+ */
105
+ export async function sameProfileDir(a, b) {
106
+ if (a === b)
107
+ return true;
108
+ try {
109
+ return (await realpath(a)) === (await realpath(b));
110
+ }
111
+ catch {
112
+ return false;
113
+ }
114
+ }
115
+ //# sourceMappingURL=agent-profiles.js.map