@open-mercato/cezar 0.9.1 → 0.9.2-pr710.1256

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 (393) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +157 -32
  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 +9 -1
  7. package/dist/agent-config/catalog.js +18 -0
  8. package/dist/agent-config/catalog.js.map +1 -1
  9. package/dist/agent-config/files.d.ts +1 -1
  10. package/dist/agent-config/model-settings/claude.d.ts +2 -0
  11. package/dist/agent-config/model-settings/claude.js +11 -0
  12. package/dist/agent-config/model-settings/claude.js.map +1 -0
  13. package/dist/agent-config/model-settings/codex.d.ts +2 -0
  14. package/dist/agent-config/model-settings/codex.js +16 -0
  15. package/dist/agent-config/model-settings/codex.js.map +1 -0
  16. package/dist/agent-config/model-settings/opencode.d.ts +2 -0
  17. package/dist/agent-config/model-settings/opencode.js +8 -0
  18. package/dist/agent-config/model-settings/opencode.js.map +1 -0
  19. package/dist/agent-config/model-settings/pi.d.ts +12 -0
  20. package/dist/agent-config/model-settings/pi.js +18 -0
  21. package/dist/agent-config/model-settings/pi.js.map +1 -0
  22. package/dist/agent-config/model-settings/shared.d.ts +9 -0
  23. package/dist/agent-config/model-settings/shared.js +93 -0
  24. package/dist/agent-config/model-settings/shared.js.map +1 -0
  25. package/dist/agent-config/model-settings/types.d.ts +9 -0
  26. package/dist/agent-config/model-settings/types.js +2 -0
  27. package/dist/agent-config/model-settings/types.js.map +1 -0
  28. package/dist/agent-config/models.d.ts +9 -0
  29. package/dist/agent-config/models.js +32 -0
  30. package/dist/agent-config/models.js.map +1 -0
  31. package/dist/agent-config/service.d.ts +1 -1
  32. package/dist/agent-config/service.js +4 -4
  33. package/dist/agent-config/service.js.map +1 -1
  34. package/dist/agent-config/validate.d.ts +1 -1
  35. package/dist/automations/coordinator.d.ts +26 -0
  36. package/dist/automations/coordinator.js +66 -0
  37. package/dist/automations/coordinator.js.map +1 -0
  38. package/dist/automations/github-poller.d.ts +74 -0
  39. package/dist/automations/github-poller.js +234 -0
  40. package/dist/automations/github-poller.js.map +1 -0
  41. package/dist/automations/scheduler.d.ts +42 -0
  42. package/dist/automations/scheduler.js +192 -0
  43. package/dist/automations/scheduler.js.map +1 -0
  44. package/dist/automations/store.d.ts +65 -0
  45. package/dist/automations/store.js +298 -0
  46. package/dist/automations/store.js.map +1 -0
  47. package/dist/automations/task-template.d.ts +18 -0
  48. package/dist/automations/task-template.js +95 -0
  49. package/dist/automations/task-template.js.map +1 -0
  50. package/dist/automations/types.d.ts +255 -0
  51. package/dist/automations/types.js +159 -0
  52. package/dist/automations/types.js.map +1 -0
  53. package/dist/config.d.ts +19 -112
  54. package/dist/config.js +48 -5
  55. package/dist/config.js.map +1 -1
  56. package/dist/contract/agent-config.d.ts +153 -0
  57. package/dist/contract/agent-profiles.d.ts +347 -0
  58. package/dist/contract/automations.d.ts +935 -0
  59. package/dist/contract/events.d.ts +104 -0
  60. package/dist/contract/github.d.ts +467 -0
  61. package/dist/contract/health.d.ts +102 -0
  62. package/dist/contract/index.d.ts +16 -0
  63. package/dist/contract/index.js +1830 -0
  64. package/dist/contract/projects.d.ts +210 -0
  65. package/dist/contract/repo.d.ts +234 -0
  66. package/dist/contract/runs.d.ts +1407 -0
  67. package/dist/contract/skills.d.ts +232 -0
  68. package/dist/contract/workflows.d.ts +218 -0
  69. package/dist/contract/workspace.d.ts +577 -0
  70. package/dist/core/agent-env.d.ts +1 -1
  71. package/dist/core/agent-env.js +41 -16
  72. package/dist/core/agent-env.js.map +1 -1
  73. package/dist/core/agent-model-policy.d.ts +10 -0
  74. package/dist/core/agent-model-policy.js +36 -0
  75. package/dist/core/agent-model-policy.js.map +1 -0
  76. package/dist/core/agent-profiles.d.ts +62 -0
  77. package/dist/core/agent-profiles.js +90 -0
  78. package/dist/core/agent-profiles.js.map +1 -0
  79. package/dist/core/agent-runner.d.ts +49 -7
  80. package/dist/core/agent-runner.js +48 -3
  81. package/dist/core/agent-runner.js.map +1 -1
  82. package/dist/core/ask.d.ts +45 -124
  83. package/dist/core/ask.js +103 -13
  84. package/dist/core/ask.js.map +1 -1
  85. package/dist/core/backend-detect.d.ts +5 -5
  86. package/dist/core/backend-detect.js +44 -7
  87. package/dist/core/backend-detect.js.map +1 -1
  88. package/dist/core/claude-cli-runner.d.ts +2 -2
  89. package/dist/core/claude-cli-runner.js +61 -13
  90. package/dist/core/claude-cli-runner.js.map +1 -1
  91. package/dist/core/claude-ui-mapper.d.ts +1 -1
  92. package/dist/core/codex-app-server-runner.d.ts +1 -1
  93. package/dist/core/codex-app-server-runner.js +65 -3
  94. package/dist/core/codex-app-server-runner.js.map +1 -1
  95. package/dist/core/codex-app-server-transport.d.ts +6 -1
  96. package/dist/core/codex-app-server-transport.js +17 -3
  97. package/dist/core/codex-app-server-transport.js.map +1 -1
  98. package/dist/core/codex-model-catalog.d.ts +1 -1
  99. package/dist/core/codex-ui-mapper.d.ts +5 -1
  100. package/dist/core/codex-ui-mapper.js +74 -17
  101. package/dist/core/codex-ui-mapper.js.map +1 -1
  102. package/dist/core/model-identity.d.ts +24 -12
  103. package/dist/core/model-identity.js +41 -24
  104. package/dist/core/model-identity.js.map +1 -1
  105. package/dist/core/model-presets.d.ts +10 -4
  106. package/dist/core/model-presets.js +52 -9
  107. package/dist/core/model-presets.js.map +1 -1
  108. package/dist/core/opencode-model-catalog.d.ts +30 -0
  109. package/dist/core/opencode-model-catalog.js +126 -0
  110. package/dist/core/opencode-model-catalog.js.map +1 -0
  111. package/dist/core/opencode-server-runner.d.ts +2 -2
  112. package/dist/core/opencode-ui-mapper.d.ts +4 -1
  113. package/dist/core/opencode-ui-mapper.js +45 -7
  114. package/dist/core/opencode-ui-mapper.js.map +1 -1
  115. package/dist/core/pi-runner.d.ts +24 -0
  116. package/dist/core/pi-runner.js +349 -0
  117. package/dist/core/pi-runner.js.map +1 -0
  118. package/dist/core/pi-ui-mapper.d.ts +34 -0
  119. package/dist/core/pi-ui-mapper.js +270 -0
  120. package/dist/core/pi-ui-mapper.js.map +1 -0
  121. package/dist/core/provider-auth.d.ts +154 -0
  122. package/dist/core/provider-auth.js +509 -0
  123. package/dist/core/provider-auth.js.map +1 -0
  124. package/dist/core/provider-availability.d.ts +3 -0
  125. package/dist/core/provider-availability.js +14 -0
  126. package/dist/core/provider-availability.js.map +1 -0
  127. package/dist/core/runner-factory.d.ts +1 -1
  128. package/dist/core/runner-factory.js +3 -0
  129. package/dist/core/runner-factory.js.map +1 -1
  130. package/dist/core/runner-model-catalog.d.ts +1 -1
  131. package/dist/core/shell-env.d.ts +28 -0
  132. package/dist/core/shell-env.js +56 -0
  133. package/dist/core/shell-env.js.map +1 -0
  134. package/dist/core/tool-display.d.ts +1 -1
  135. package/dist/core/ui-events.d.ts +2 -2
  136. package/dist/core/ui-events.js +1 -1
  137. package/dist/core/usage-limit.d.ts +42 -0
  138. package/dist/core/usage-limit.js +209 -0
  139. package/dist/core/usage-limit.js.map +1 -0
  140. package/dist/git-diff-base.d.ts +85 -0
  141. package/dist/git-diff-base.js +180 -0
  142. package/dist/git-diff-base.js.map +1 -0
  143. package/dist/git-worktree.d.ts +46 -6
  144. package/dist/git-worktree.js +46 -9
  145. package/dist/git-worktree.js.map +1 -1
  146. package/dist/handoff.d.ts +2 -2
  147. package/dist/handoff.js +1 -1
  148. package/dist/index.js +66 -8
  149. package/dist/index.js.map +1 -1
  150. package/dist/paths.d.ts +69 -6
  151. package/dist/paths.js +86 -9
  152. package/dist/paths.js.map +1 -1
  153. package/dist/planner.d.ts +2 -2
  154. package/dist/planner.js +7 -1
  155. package/dist/planner.js.map +1 -1
  156. package/dist/release/manifests.d.ts +81 -0
  157. package/dist/release/manifests.js +74 -0
  158. package/dist/release/manifests.js.map +1 -0
  159. package/dist/release/snapshot.d.ts +9 -23
  160. package/dist/release/snapshot.js +9 -22
  161. package/dist/release/snapshot.js.map +1 -1
  162. package/dist/release/stable.d.ts +15 -29
  163. package/dist/release/stable.js +14 -27
  164. package/dist/release/stable.js.map +1 -1
  165. package/dist/runs/agent-tmpdir.d.ts +41 -0
  166. package/dist/runs/agent-tmpdir.js +183 -0
  167. package/dist/runs/agent-tmpdir.js.map +1 -0
  168. package/dist/runs/auto-name.d.ts +1 -1
  169. package/dist/runs/auto-name.js +6 -1
  170. package/dist/runs/auto-name.js.map +1 -1
  171. package/dist/runs/event-history.d.ts +50 -0
  172. package/dist/runs/event-history.js +613 -0
  173. package/dist/runs/event-history.js.map +1 -0
  174. package/dist/runs/retention.d.ts +1 -1
  175. package/dist/runs/run-index.d.ts +19 -0
  176. package/dist/runs/run-index.js +43 -0
  177. package/dist/runs/run-index.js.map +1 -0
  178. package/dist/runs/store.d.ts +209 -344
  179. package/dist/runs/store.js +298 -39
  180. package/dist/runs/store.js.map +1 -1
  181. package/dist/runs/ui-event-sink.d.ts +1 -1
  182. package/dist/server/app-type.d.ts +21 -0
  183. package/dist/server/app-type.js +2 -0
  184. package/dist/server/app-type.js.map +1 -0
  185. package/dist/server/capabilities.d.ts +21 -6
  186. package/dist/server/capabilities.js +27 -1
  187. package/dist/server/capabilities.js.map +1 -1
  188. package/dist/server/forge/github.d.ts +58 -151
  189. package/dist/server/forge/github.js +530 -6
  190. package/dist/server/forge/github.js.map +1 -1
  191. package/dist/server/forge/index.d.ts +19 -3
  192. package/dist/server/forge/index.js +28 -1
  193. package/dist/server/forge/index.js.map +1 -1
  194. package/dist/server/forge/types.d.ts +86 -1
  195. package/dist/server/git-changes.d.ts +10 -8
  196. package/dist/server/git-changes.js +19 -17
  197. package/dist/server/git-changes.js.map +1 -1
  198. package/dist/server/git.d.ts +2 -0
  199. package/dist/server/git.js +9 -0
  200. package/dist/server/git.js.map +1 -1
  201. package/dist/server/github.d.ts +3 -3
  202. package/dist/server/github.js +1 -1
  203. package/dist/server/github.js.map +1 -1
  204. package/dist/server/open-in-app.d.ts +2 -1
  205. package/dist/server/open-in-app.js +3 -1
  206. package/dist/server/open-in-app.js.map +1 -1
  207. package/dist/server/open-in-terminal.d.ts +46 -1
  208. package/dist/server/open-in-terminal.js +72 -13
  209. package/dist/server/open-in-terminal.js.map +1 -1
  210. package/dist/server/pr.d.ts +2 -2
  211. package/dist/server/project-context.d.ts +20 -3
  212. package/dist/server/project-context.js +30 -1
  213. package/dist/server/project-context.js.map +1 -1
  214. package/dist/server/provider-action-gate.d.ts +8 -0
  215. package/dist/server/provider-action-gate.js +56 -0
  216. package/dist/server/provider-action-gate.js.map +1 -0
  217. package/dist/server/provider-auth-runtime.d.ts +21 -0
  218. package/dist/server/provider-auth-runtime.js +66 -0
  219. package/dist/server/provider-auth-runtime.js.map +1 -0
  220. package/dist/server/server.d.ts +12802 -47
  221. package/dist/server/server.js +2857 -949
  222. package/dist/server/server.js.map +1 -1
  223. package/dist/server/validators.d.ts +97 -0
  224. package/dist/server/validators.js +86 -0
  225. package/dist/server/validators.js.map +1 -0
  226. package/dist/server/ws.d.ts +2 -2
  227. package/dist/server/ws.js +2 -2
  228. package/dist/server/ws.js.map +1 -1
  229. package/dist/server-install/engine.d.ts +1 -1
  230. package/dist/server-install/engine.js +5 -18
  231. package/dist/server-install/engine.js.map +1 -1
  232. package/dist/server-install/platforms/macosx-ngrok.d.ts +1 -1
  233. package/dist/server-install/platforms/ubuntu-vps.d.ts +16 -1
  234. package/dist/server-install/platforms/ubuntu-vps.js +83 -1
  235. package/dist/server-install/platforms/ubuntu-vps.js.map +1 -1
  236. package/dist/server-install/state.d.ts +1 -1
  237. package/dist/server-install/steps.d.ts +2 -2
  238. package/dist/server-install/steps.js +6 -2
  239. package/dist/server-install/steps.js.map +1 -1
  240. package/dist/server-install/strategies.d.ts +1 -1
  241. package/dist/server-install/types.d.ts +38 -424
  242. package/dist/server-install/ui.d.ts +1 -1
  243. package/dist/skills-banner.d.ts +7 -6
  244. package/dist/skills-banner.js +7 -6
  245. package/dist/skills-banner.js.map +1 -1
  246. package/dist/skills-remote.d.ts +2 -2
  247. package/dist/skills-update.d.ts +88 -0
  248. package/dist/skills-update.js +392 -0
  249. package/dist/skills-update.js.map +1 -0
  250. package/dist/skills.d.ts +2 -0
  251. package/dist/skills.js +7 -2
  252. package/dist/skills.js.map +1 -1
  253. package/dist/todos.d.ts +2 -28
  254. package/dist/todos.js +1 -1
  255. package/dist/ui-state.d.ts +16 -2
  256. package/dist/ui-state.js +14 -1
  257. package/dist/ui-state.js.map +1 -1
  258. package/dist/workflows/load.d.ts +1 -1
  259. package/dist/workflows/run.d.ts +276 -15
  260. package/dist/workflows/run.js +1261 -159
  261. package/dist/workflows/run.js.map +1 -1
  262. package/dist/workflows/types.d.ts +62 -224
  263. package/dist/workflows/types.js +25 -2
  264. package/dist/workflows/types.js.map +1 -1
  265. package/dist/workspace/agent-accounts.d.ts +153 -0
  266. package/dist/workspace/agent-accounts.js +304 -0
  267. package/dist/workspace/agent-accounts.js.map +1 -0
  268. package/dist/workspace/agent-profiles.d.ts +78 -0
  269. package/dist/workspace/agent-profiles.js +115 -0
  270. package/dist/workspace/agent-profiles.js.map +1 -0
  271. package/dist/workspace/config.d.ts +94 -206
  272. package/dist/workspace/config.js +226 -14
  273. package/dist/workspace/config.js.map +1 -1
  274. package/dist/workspace/migrations.d.ts +1 -1
  275. package/dist/workspace/migrations.js +19 -4
  276. package/dist/workspace/migrations.js.map +1 -1
  277. package/dist/workspace/projects-cli.js +54 -4
  278. package/dist/workspace/projects-cli.js.map +1 -1
  279. package/dist/workspace/projects.d.ts +26 -2
  280. package/dist/workspace/projects.js +42 -3
  281. package/dist/workspace/projects.js.map +1 -1
  282. package/dist/workspace/semaphore.d.ts +51 -0
  283. package/dist/workspace/semaphore.js +53 -3
  284. package/dist/workspace/semaphore.js.map +1 -1
  285. package/dist/workspace/ui-state.d.ts +16 -5
  286. package/dist/workspace/ui-state.js +18 -7
  287. package/dist/workspace/ui-state.js.map +1 -1
  288. package/package.json +17 -39
  289. package/scripts/inline-contract.mjs +112 -0
  290. package/scripts/mock-claude.mjs +59 -1
  291. package/scripts/mock-pi-rpc.mjs +83 -0
  292. package/scripts/sync-readme.mjs +20 -0
  293. package/web/dist/assets/alert-dialog-BVs3QSmP.js +1 -0
  294. package/web/dist/assets/arrow-down-D7T7XuF6.js +1 -0
  295. package/web/dist/assets/arrow-left-B1dRFd8y.js +1 -0
  296. package/web/dist/assets/bundle-mjs-BT31bpU6.js +1 -0
  297. package/web/dist/assets/centered-state-DdRLYi9u.js +43 -0
  298. package/web/dist/assets/chevron-right-Dh0t3AL8.js +1 -0
  299. package/web/dist/assets/{chunk-BO2N2NFS-DtrdTCWa.js → chunk-BO2N2NFS-DE6qKn3r.js} +8 -8
  300. package/web/dist/assets/circle-check-4FDOlh9u.js +1 -0
  301. package/web/dist/assets/circle-x-CgTVbqX5.js +1 -0
  302. package/web/dist/assets/collapsible-BoADzTok.js +1 -0
  303. package/web/dist/assets/commit-list-BCcCkRbU.js +1 -0
  304. package/web/dist/assets/compare-variants-B7gTgGqR.js +1 -0
  305. package/web/dist/assets/{core-DePtBHcl.js → core-BCsw8oQw.js} +1 -1
  306. package/web/dist/assets/diff-ecfV3-op.js +3 -0
  307. package/web/dist/assets/diff-stat-C2KGLVnZ.js +1 -0
  308. package/web/dist/assets/{diff-view-DCeSegKk.js → diff-view-CQtonQ4L.js} +4 -4
  309. package/web/dist/assets/dropdown-menu-WcGoirf2.js +1 -0
  310. package/web/dist/assets/editable-title-SqNK-wuI.js +1 -0
  311. package/web/dist/assets/{ellipsis-vertical-CNnSLn5a.js → ellipsis-vertical-ClTFrwit.js} +1 -1
  312. package/web/dist/assets/{file-D4GBh1ao.js → file-BU0mWida.js} +1 -1
  313. package/web/dist/assets/folder-rsgCF0aw.js +1 -0
  314. package/web/dist/assets/{git-pull-request-DnR8Xh4_.js → git-pull-request-BFhIKb83.js} +1 -1
  315. package/web/dist/assets/git-toolbar-CF1_tzqz.js +1 -0
  316. package/web/dist/assets/github-CyjPz-Ks.js +1 -0
  317. package/web/dist/assets/highlighted-body-OFNGDK62-BL-MfFgl.js +1 -0
  318. package/web/dist/assets/highlighter-CdHqIwFr.js +3 -0
  319. package/web/dist/assets/image-preview-iEzCyEmz.js +1 -0
  320. package/web/dist/assets/index-BN09RpYY.css +2 -0
  321. package/web/dist/assets/index-CyG7aE1W.js +7 -0
  322. package/web/dist/assets/lib-BQXq3kEf.js +1 -0
  323. package/web/dist/assets/lib-BxQXEXDF.js +1 -0
  324. package/web/dist/assets/markdown-CNAa22LB.js +2 -0
  325. package/web/dist/assets/mermaid-GHXKKRXX-C4jxqUUb.js +1 -0
  326. package/web/dist/assets/new-task-form-CWhQZbsX.js +1 -0
  327. package/web/dist/assets/pill-BO5s2x3N.js +1 -0
  328. package/web/dist/assets/project-router-Dm4OhAPE.js +1 -0
  329. package/web/dist/assets/prompt-templates-CP__OCDQ.js +15 -0
  330. package/web/dist/assets/react-runtime-CCIEwYL0.js +9 -0
  331. package/web/dist/assets/{refresh-cw-BT8E96Tm.js → refresh-cw-DyiysCoP.js} +1 -1
  332. package/web/dist/assets/repo-git-B1WM6N8T.js +1 -0
  333. package/web/dist/assets/rolldown-runtime-QTnfLwEv.js +1 -0
  334. package/web/dist/assets/run-diff-CKx4d9Oo.js +3 -0
  335. package/web/dist/assets/run-header-DpbfOtNi.js +1 -0
  336. package/web/dist/assets/{search-x-BDjaMrzG.js → search-x-DRvk-6x4.js} +1 -1
  337. package/web/dist/assets/skill-empty-hint-D5vsHfMr.js +1 -0
  338. package/web/dist/assets/skills-BiWfHmCR.js +1 -0
  339. package/web/dist/assets/skills-XGltyIJ_.js +1 -0
  340. package/web/dist/assets/sparkles-BugkDxWO.js +1 -0
  341. package/web/dist/assets/{square-terminal-Ckjjn0vb.js → square-terminal-Drp2h-o8.js} +1 -1
  342. package/web/dist/assets/tab-link-CiRLRlnY.js +1 -0
  343. package/web/dist/assets/task-changes-C2hKkEtc.js +1 -0
  344. package/web/dist/assets/task-commits-CwGs_Opa.js +1 -0
  345. package/web/dist/assets/task-files-5KUgFzX3.js +2 -0
  346. package/web/dist/assets/task-thread-B3AFO3SS.js +9 -0
  347. package/web/dist/assets/textarea-Dn90Eun6.js +1 -0
  348. package/web/dist/assets/thread-loading-_1hPuk76.js +1 -0
  349. package/web/dist/assets/{trash-2-DAyZ0VSi.js → trash-2-BKEc5Sp2.js} +1 -1
  350. package/web/dist/assets/{triangle-alert-Uy8rokUh.js → triangle-alert-BGGPY2C2.js} +1 -1
  351. package/web/dist/assets/{upload-CDdyPPo_.js → upload-B0AQw-mO.js} +1 -1
  352. package/web/dist/assets/use-desktop-CegyTp3X.js +1 -0
  353. package/web/dist/assets/use-submit-shortcut-Mle-9uJp.js +1 -0
  354. package/web/dist/assets/utils-D9GHDNza.js +64 -0
  355. package/web/dist/assets/workflows-3PCz57Z6.js +11 -0
  356. package/web/dist/assets/zoomable-image-DTq7s8CZ.js +1 -0
  357. package/web/dist/index.html +33 -13
  358. package/scripts/dev.mjs +0 -74
  359. package/scripts/release-snapshot.mjs +0 -130
  360. package/scripts/release.mjs +0 -119
  361. package/web/dist/assets/arrow-left-CnSdp92h.js +0 -1
  362. package/web/dist/assets/bundle-mjs-BegPhL5c.js +0 -1
  363. package/web/dist/assets/centered-state-DOsTcJZF.js +0 -43
  364. package/web/dist/assets/commit-list-BrxBEzRK.js +0 -1
  365. package/web/dist/assets/compare-variants-Bv2c9ORF.js +0 -1
  366. package/web/dist/assets/dist-B6XQOhgM.js +0 -1
  367. package/web/dist/assets/git-toolbar-pIC1ubPM.js +0 -1
  368. package/web/dist/assets/github-DTTSG0ht.js +0 -1
  369. package/web/dist/assets/highlighted-body-OFNGDK62-BuFJwunK.js +0 -1
  370. package/web/dist/assets/image-preview-DEhW0TFz.js +0 -1
  371. package/web/dist/assets/index-Cijmlz7q.js +0 -30
  372. package/web/dist/assets/index-DzroxqBG.css +0 -2
  373. package/web/dist/assets/lib-DPEZDBUN.js +0 -1
  374. package/web/dist/assets/lib-uHpeUPzK.js +0 -1
  375. package/web/dist/assets/mermaid-GHXKKRXX-CN2zQue0.js +0 -1
  376. package/web/dist/assets/open-mercato-toBr6SOa.svg +0 -11
  377. package/web/dist/assets/project-router-BMx4e8m-.js +0 -1
  378. package/web/dist/assets/repo-git-BusYfa3t.js +0 -1
  379. package/web/dist/assets/run-diff-wOJ3odA-.js +0 -3
  380. package/web/dist/assets/run-header-Cg5incil.js +0 -1
  381. package/web/dist/assets/skill-empty-hint-DTUSp6Vl.js +0 -1
  382. package/web/dist/assets/skills-PpP2owbM.js +0 -1
  383. package/web/dist/assets/tab-link-F3uQrdm2.js +0 -1
  384. package/web/dist/assets/task-changes-iD9kS79I.js +0 -1
  385. package/web/dist/assets/task-commits-COkLaUri.js +0 -1
  386. package/web/dist/assets/task-files-Ckttz7XH.js +0 -2
  387. package/web/dist/assets/task-thread-CQD91VPt.js +0 -9
  388. package/web/dist/assets/textarea-Bj_LCreg.js +0 -1
  389. package/web/dist/assets/use-desktop-DUh0STzq.js +0 -3
  390. package/web/dist/assets/utils-B8s5qIcK.js +0 -1
  391. package/web/dist/assets/workflows-BFk8C0co.js +0 -11
  392. package/web/dist/assets/zoomable-image-PEDOqyLQ.js +0 -1
  393. /package/web/{open-mercato.svg → dist/open-mercato.svg} +0 -0
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Rendering environment assignments into a shell command line — the CLI-handoff half of agent
3
+ * profiles (spec 2026-07-29-agent-profiles).
4
+ *
5
+ * A run executed under a second account only resumes under that same account: `claude --resume
6
+ * <id>` reads `<CLAUDE_CONFIG_DIR>/sessions`, so a handoff without the variable does not fail
7
+ * loudly — it silently starts a fresh conversation. The variable therefore has to travel with
8
+ * every command cezar hands to a terminal, and it has to SURVIVE the command, because the window
9
+ * stays open and the user types the next `claude` in it themselves. Hence `export` / `set` rather
10
+ * than a one-shot `VAR=v cmd` prefix.
11
+ *
12
+ * There is no portable spelling: `VAR=v cmd` is meaningless to `cmd.exe`, and `set "VAR=v"` is
13
+ * meaningless to a POSIX shell. So this renders per platform, and — the load-bearing part —
14
+ * refuses rather than guesses. `null` means "this value cannot be embedded safely here", and
15
+ * every caller must then fail closed: opening a terminal on the WRONG account is worse than not
16
+ * opening one, because the user cannot see which account a shell is pointed at.
17
+ */
18
+ /** Values that cannot be embedded safely, per platform. Control characters are rejected
19
+ * everywhere (they would break the line-based launch script and are never a real path). */
20
+ const CONTROL_CHARS_RE = /[\u0000-\u001f\u007f]/;
21
+ /** `cmd.exe` has no escape inside a quoted `set` argument: `"` ends the quote and `%`/`!` expand.
22
+ * A path containing one is pathological, so refusing is honest rather than limiting. */
23
+ const WIN32_UNSAFE_RE = /["%!]/;
24
+ /** POSIX single-quoting — the `'\''` dance, so any character but a control one is inert. */
25
+ export function shellQuote(value) {
26
+ return `'${value.replaceAll("'", `'\\''`)}'`;
27
+ }
28
+ /**
29
+ * Assignments that persist for the rest of the shell session, or `null` when any value cannot be
30
+ * embedded safely on `platform`. An empty `env` renders `''` — the zero-config path adds nothing.
31
+ *
32
+ * The result is a PREFIX ready to concatenate: it already ends with its own separator.
33
+ */
34
+ export function renderEnvPrefix(env, platform) {
35
+ const entries = Object.entries(env);
36
+ if (entries.length === 0)
37
+ return '';
38
+ for (const [name, value] of entries) {
39
+ if (CONTROL_CHARS_RE.test(name) || CONTROL_CHARS_RE.test(value))
40
+ return null;
41
+ if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(name))
42
+ return null;
43
+ if (platform === 'win32' && (WIN32_UNSAFE_RE.test(name) || WIN32_UNSAFE_RE.test(value)))
44
+ return null;
45
+ }
46
+ if (platform === 'win32') {
47
+ return entries.map(([name, value]) => `set "${name}=${value}" && `).join('');
48
+ }
49
+ return entries.map(([name, value]) => `export ${name}=${shellQuote(value)}; `).join('');
50
+ }
51
+ /** `renderEnvPrefix` applied to a command, or `null` when the env cannot be rendered safely. */
52
+ export function withEnvPrefix(command, env, platform) {
53
+ const prefix = renderEnvPrefix(env, platform);
54
+ return prefix === null ? null : `${prefix}${command}`;
55
+ }
56
+ //# sourceMappingURL=shell-env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell-env.js","sourceRoot":"","sources":["../../src/core/shell-env.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH;4FAC4F;AAC5F,MAAM,gBAAgB,GAAG,uBAAuB,CAAC;AACjD;yFACyF;AACzF,MAAM,eAAe,GAAG,OAAO,CAAC;AAEhC,4FAA4F;AAC5F,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,OAAO,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC;AAC/C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC7B,GAA2B,EAC3B,QAAyB;IAEzB,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACpC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,OAAO,EAAE,CAAC;QACpC,IAAI,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAC7E,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QACxD,IAAI,QAAQ,KAAK,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;IACvG,CAAC;IACD,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzB,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,QAAQ,IAAI,IAAI,KAAK,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC/E,CAAC;IACD,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,UAAU,IAAI,IAAI,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC1F,CAAC;AAED,gGAAgG;AAChG,MAAM,UAAU,aAAa,CAC3B,OAAe,EACf,GAA2B,EAC3B,QAAyB;IAEzB,MAAM,MAAM,GAAG,eAAe,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC9C,OAAO,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,OAAO,EAAE,CAAC;AACxD,CAAC"}
@@ -20,7 +20,7 @@
20
20
  * as tolerance for its non-app-server transports)
21
21
  * - opencode: bash, edit, write, read, grep, glob, webfetch, task, todowrite
22
22
  */
23
- import type { ToolKind } from './ui-events.js';
23
+ import type { ToolKind } from './ui-events.ts';
24
24
  export interface ToolDisplay {
25
25
  toolKind: ToolKind;
26
26
  /** Human line for the card trigger, e.g. "Ran npm test". */
@@ -19,12 +19,12 @@
19
19
  * can migrate one panel at a time.
20
20
  *
21
21
  * This module is pure vocabulary: no runtime imports, no runner coupling.
22
- * Step 2.4 mirrors it into `web/app/src/protocol/`.
22
+ * Mirrored into `packages/api-client/src/protocol/`.
23
23
  */
24
24
  /** The backend that produced a session — mirrors `RunnerId` in
25
25
  * `agent-runner.ts` (kept structurally identical; a type-level test
26
26
  * guards against drift so this module stays dependency-free). */
27
- export type UiBackend = 'claude' | 'codex' | 'opencode';
27
+ export type UiBackend = 'claude' | 'codex' | 'opencode' | 'pi';
28
28
  /**
29
29
  * Tool lifecycle status (ACP: pending/in_progress/completed/failed).
30
30
  * `running` ≡ ACP `in_progress` (opencode's word — reads better in code);
@@ -19,7 +19,7 @@
19
19
  * can migrate one panel at a time.
20
20
  *
21
21
  * This module is pure vocabulary: no runtime imports, no runner coupling.
22
- * Step 2.4 mirrors it into `web/app/src/protocol/`.
22
+ * Mirrored into `packages/api-client/src/protocol/`.
23
23
  */
24
24
  export {};
25
25
  //# sourceMappingURL=ui-events.js.map
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Provider usage-limit detection (spec 2026-08-03-auto-resume-after-usage-limit).
3
+ *
4
+ * A subscription that runs out of its window does not fail like an agent bug does: the work is
5
+ * fine, the account is simply closed until a KNOWN instant. That instant is the whole feature —
6
+ * without it there is nothing to schedule, so this module answers exactly one question about a
7
+ * terminal error string: "is this a usage limit, and when does it lift?".
8
+ *
9
+ * The evidence differs per backend, so the shapes are recognized in order of how exact they are:
10
+ *
11
+ * 1. Claude Code's machine-readable envelope, `Claude AI usage limit reached|<epoch>` — the CLI
12
+ * puts it in an `is_error` result frame, which reaches cezar verbatim as the run's `error`.
13
+ * Exact, no locale, no parsing of prose. This is the one that matters in practice.
14
+ * 2. An explicit reset instant in the prose (`try again at 2026-08-03T18:00:00Z`) — how Codex and
15
+ * OpenCode phrase the same thing when they carry a timestamp at all.
16
+ * 3. A clock-only reset in prose (`resets 8:10pm (Europe/Warsaw)`) — how Claude Code phrases
17
+ * session windows in some interactive output.
18
+ * 4. A relative delay (`try again in 42 minutes`, `retry-after: 3600`).
19
+ *
20
+ * Nothing else counts. A limit message with no recoverable reset instant returns `null` on
21
+ * purpose: guessing a window would turn one interruption into a retry loop against a provider
22
+ * that is still refusing, and "we don't know when" is an honest answer the caller can surface.
23
+ */
24
+ export interface UsageLimitHit {
25
+ /** When the provider says the limit lifts. Never in the past — a stale instant clamps to now. */
26
+ resetAt: Date;
27
+ /** Which shape carried it — the lifecycle note quotes this so the schedule is auditable. */
28
+ evidence: 'claude-marker' | 'timestamp' | 'clock' | 'delay';
29
+ }
30
+ /**
31
+ * The furthest ahead a reset may sit and still be believed. Claude's weekly window is the real
32
+ * ceiling; anything beyond a week is a corrupt or unit-confused number, and parking a task on it
33
+ * would be indistinguishable from losing the task.
34
+ */
35
+ export declare const MAX_USAGE_LIMIT_WAIT_MS: number;
36
+ /**
37
+ * Read a usage limit out of a terminal error message, or `null` when it is not one (or carries no
38
+ * usable reset instant). `now` is injected so callers and tests share one clock.
39
+ *
40
+ * Never throws: this runs on the failure path of every run, where a second failure helps nobody.
41
+ */
42
+ export declare function parseUsageLimit(message: string | undefined, now?: number): UsageLimitHit | null;
@@ -0,0 +1,209 @@
1
+ /**
2
+ * Provider usage-limit detection (spec 2026-08-03-auto-resume-after-usage-limit).
3
+ *
4
+ * A subscription that runs out of its window does not fail like an agent bug does: the work is
5
+ * fine, the account is simply closed until a KNOWN instant. That instant is the whole feature —
6
+ * without it there is nothing to schedule, so this module answers exactly one question about a
7
+ * terminal error string: "is this a usage limit, and when does it lift?".
8
+ *
9
+ * The evidence differs per backend, so the shapes are recognized in order of how exact they are:
10
+ *
11
+ * 1. Claude Code's machine-readable envelope, `Claude AI usage limit reached|<epoch>` — the CLI
12
+ * puts it in an `is_error` result frame, which reaches cezar verbatim as the run's `error`.
13
+ * Exact, no locale, no parsing of prose. This is the one that matters in practice.
14
+ * 2. An explicit reset instant in the prose (`try again at 2026-08-03T18:00:00Z`) — how Codex and
15
+ * OpenCode phrase the same thing when they carry a timestamp at all.
16
+ * 3. A clock-only reset in prose (`resets 8:10pm (Europe/Warsaw)`) — how Claude Code phrases
17
+ * session windows in some interactive output.
18
+ * 4. A relative delay (`try again in 42 minutes`, `retry-after: 3600`).
19
+ *
20
+ * Nothing else counts. A limit message with no recoverable reset instant returns `null` on
21
+ * purpose: guessing a window would turn one interruption into a retry loop against a provider
22
+ * that is still refusing, and "we don't know when" is an honest answer the caller can surface.
23
+ */
24
+ /**
25
+ * The furthest ahead a reset may sit and still be believed. Claude's weekly window is the real
26
+ * ceiling; anything beyond a week is a corrupt or unit-confused number, and parking a task on it
27
+ * would be indistinguishable from losing the task.
28
+ */
29
+ export const MAX_USAGE_LIMIT_WAIT_MS = 7 * 24 * 60 * 60_000;
30
+ /** Claude Code's own envelope. The suffix is Unix EPOCH SECONDS (ms tolerated — see below). */
31
+ const CLAUDE_MARKER_RE = /claude(?:\s+ai)?\s+usage\s+limit\s+reached\s*\|\s*(\d{9,16})/i;
32
+ /**
33
+ * "This is a limit, not a crash." Deliberately narrow: it gates the two prose shapes below, and a
34
+ * false positive there would schedule a resume on a timestamp that means something else entirely.
35
+ */
36
+ const LIMIT_PHRASE_RE = /\b(?:usage|rate|session|weekly|hourly)[\s-]?limit\b|\brate[_-]?limit(?:_error|ed)?\b|\bquota\s+(?:exceeded|reached)\b|\bout\s+of\s+(?:credits|quota)\b/i;
37
+ /** `…try again at 2026-08-03T18:00:00Z`, `…resets at 2026-08-03 18:00`. */
38
+ const RESET_AT_RE = /(?:resets?|reset[s]?\s+at|try\s+again|retry|available\s+again|unlocks?)\b[^\n]{0,24}?\b(\d{4}-\d{2}-\d{2}(?:[T ]\d{2}:\d{2}(?::\d{2})?(?:\.\d+)?(?:Z|[+-]\d{2}:?\d{2})?)?)/i;
39
+ /** `...resets 8:10pm (Europe/Warsaw)`, `...try again at 20:10`. */
40
+ const RESET_CLOCK_RE = /(?:resets?|reset[s]?\s+at|try\s+again|retry|available\s+again|unlocks?)\b[^\n]{0,24}?\b(?:at\s*)?(\d{1,2})(?:(?::(\d{2}))\s*([ap]\.?m\.?)?|\s*([ap]\.?m\.?))(?:\s*\(([^)]+)\))?/i;
41
+ /** `…try again in 42 minutes`, `…retry after 3600 seconds`, `retry-after: 3600`. */
42
+ const RESET_IN_RE = /(?:try\s+again|retry|resets?|available\s+again)\b[^\n]{0,16}?\b(?:in|after)\s+(\d{1,7})\s*(seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h)\b/i;
43
+ const RETRY_AFTER_HEADER_RE = /\bretry[-_\s]?after\b\s*[:=]?\s*(\d{1,7})\b/i;
44
+ const UNIT_MS = {
45
+ s: 1_000, sec: 1_000, secs: 1_000, second: 1_000, seconds: 1_000,
46
+ m: 60_000, min: 60_000, mins: 60_000, minute: 60_000, minutes: 60_000,
47
+ h: 3_600_000, hr: 3_600_000, hrs: 3_600_000, hour: 3_600_000, hours: 3_600_000,
48
+ };
49
+ /**
50
+ * Read a usage limit out of a terminal error message, or `null` when it is not one (or carries no
51
+ * usable reset instant). `now` is injected so callers and tests share one clock.
52
+ *
53
+ * Never throws: this runs on the failure path of every run, where a second failure helps nobody.
54
+ */
55
+ export function parseUsageLimit(message, now = Date.now()) {
56
+ if (!message)
57
+ return null;
58
+ const marker = CLAUDE_MARKER_RE.exec(message);
59
+ if (marker) {
60
+ const raw = Number(marker[1]);
61
+ // Epoch seconds is the documented unit; a value large enough to only make sense as
62
+ // milliseconds is accepted rather than parked ~50,000 years out.
63
+ const epochMs = raw >= 1e12 ? raw : raw * 1_000;
64
+ return settle(epochMs, now, 'claude-marker');
65
+ }
66
+ if (!LIMIT_PHRASE_RE.test(message))
67
+ return null;
68
+ const at = RESET_AT_RE.exec(message);
69
+ if (at) {
70
+ // A bare date, or `YYYY-MM-DD HH:MM` without a zone, is read in the host's local time — the
71
+ // provider is talking to the person at this machine, and `Date.parse` would otherwise read the
72
+ // space-separated form as UTC on some runtimes and local on others. A date with no time at all
73
+ // needs the midnight spelled out for the same reason: the ECMAScript date-ONLY form is defined
74
+ // as UTC, so `2026-08-03` alone would land up to a day away from the day the provider named.
75
+ const stamp = at[1].includes('T') ? at[1] : at[1].replace(' ', 'T');
76
+ const parsed = Date.parse(stamp.includes('T') ? stamp : `${stamp}T00:00`);
77
+ if (Number.isFinite(parsed))
78
+ return settle(parsed, now, 'timestamp');
79
+ }
80
+ const clock = RESET_CLOCK_RE.exec(message);
81
+ if (clock) {
82
+ const parsed = parseClockReset(clock, now);
83
+ if (parsed !== null)
84
+ return settle(parsed, now, 'clock');
85
+ }
86
+ const relative = RESET_IN_RE.exec(message);
87
+ if (relative) {
88
+ const unit = UNIT_MS[relative[2].toLowerCase()];
89
+ if (unit !== undefined)
90
+ return settle(now + Number(relative[1]) * unit, now, 'delay');
91
+ }
92
+ const header = RETRY_AFTER_HEADER_RE.exec(message);
93
+ if (header)
94
+ return settle(now + Number(header[1]) * 1_000, now, 'delay');
95
+ return null;
96
+ }
97
+ function parseClockReset(match, now) {
98
+ const hourRaw = Number(match[1]);
99
+ const minute = match[2] === undefined ? 0 : Number(match[2]);
100
+ const meridiem = (match[3] ?? match[4])?.toLowerCase().replaceAll('.', '');
101
+ if (!Number.isInteger(hourRaw) || !Number.isInteger(minute) || minute < 0 || minute > 59) {
102
+ return null;
103
+ }
104
+ let hour = hourRaw;
105
+ if (meridiem) {
106
+ if (hour < 1 || hour > 12)
107
+ return null;
108
+ if (meridiem === 'am')
109
+ hour = hour === 12 ? 0 : hour;
110
+ else if (meridiem === 'pm')
111
+ hour = hour === 12 ? 12 : hour + 12;
112
+ else
113
+ return null;
114
+ }
115
+ else if (hour < 0 || hour > 23) {
116
+ return null;
117
+ }
118
+ const timeZone = validTimeZone(match[5]?.trim());
119
+ if (timeZone)
120
+ return nextClockInTimeZone(hour, minute, timeZone, now);
121
+ return nextLocalClock(hour, minute, now);
122
+ }
123
+ function nextLocalClock(hour, minute, now) {
124
+ const candidate = new Date(now);
125
+ candidate.setHours(hour, minute, 0, 0);
126
+ if (candidate.getTime() < now)
127
+ candidate.setDate(candidate.getDate() + 1);
128
+ return candidate.getTime();
129
+ }
130
+ function nextClockInTimeZone(hour, minute, timeZone, now) {
131
+ const today = zonedParts(now, timeZone);
132
+ if (!today)
133
+ return null;
134
+ let candidate = zonedWallTimeToUtc(today.year, today.month, today.day, hour, minute, timeZone);
135
+ if (candidate === null)
136
+ return null;
137
+ if (candidate < now) {
138
+ const tomorrow = new Date(Date.UTC(today.year, today.month - 1, today.day + 1));
139
+ candidate = zonedWallTimeToUtc(tomorrow.getUTCFullYear(), tomorrow.getUTCMonth() + 1, tomorrow.getUTCDate(), hour, minute, timeZone);
140
+ }
141
+ return candidate;
142
+ }
143
+ function validTimeZone(candidate) {
144
+ if (!candidate)
145
+ return null;
146
+ try {
147
+ new Intl.DateTimeFormat('en-US', { timeZone: candidate }).format(new Date(0));
148
+ return candidate;
149
+ }
150
+ catch {
151
+ return null;
152
+ }
153
+ }
154
+ function zonedWallTimeToUtc(year, month, day, hour, minute, timeZone) {
155
+ const wallAsUtc = Date.UTC(year, month - 1, day, hour, minute, 0, 0);
156
+ let candidate = wallAsUtc;
157
+ for (let i = 0; i < 3; i += 1) {
158
+ const offset = timeZoneOffsetMs(timeZone, candidate);
159
+ if (offset === null)
160
+ return null;
161
+ const next = wallAsUtc - offset;
162
+ if (Math.abs(next - candidate) < 1_000)
163
+ return next;
164
+ candidate = next;
165
+ }
166
+ return candidate;
167
+ }
168
+ function timeZoneOffsetMs(timeZone, utcMs) {
169
+ const parts = zonedParts(utcMs, timeZone);
170
+ if (!parts)
171
+ return null;
172
+ const asUtc = Date.UTC(parts.year, parts.month - 1, parts.day, parts.hour, parts.minute, parts.second);
173
+ return asUtc - utcMs;
174
+ }
175
+ function zonedParts(utcMs, timeZone) {
176
+ try {
177
+ const parts = new Intl.DateTimeFormat('en-CA', {
178
+ timeZone,
179
+ year: 'numeric',
180
+ month: '2-digit',
181
+ day: '2-digit',
182
+ hour: '2-digit',
183
+ minute: '2-digit',
184
+ second: '2-digit',
185
+ hourCycle: 'h23',
186
+ }).formatToParts(new Date(utcMs));
187
+ const value = (type) => Number(parts.find((part) => part.type === type)?.value);
188
+ return {
189
+ year: value('year'),
190
+ month: value('month'),
191
+ day: value('day'),
192
+ hour: value('hour'),
193
+ minute: value('minute'),
194
+ second: value('second'),
195
+ };
196
+ }
197
+ catch {
198
+ return null;
199
+ }
200
+ }
201
+ /** Bound a candidate instant: past → now (the limit already lifted), absurd → not believed. */
202
+ function settle(epochMs, now, evidence) {
203
+ if (!Number.isFinite(epochMs))
204
+ return null;
205
+ if (epochMs - now > MAX_USAGE_LIMIT_WAIT_MS)
206
+ return null;
207
+ return { resetAt: new Date(Math.max(epochMs, now)), evidence };
208
+ }
209
+ //# sourceMappingURL=usage-limit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-limit.js","sourceRoot":"","sources":["../../src/core/usage-limit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * "Which ref anchors *this task's* diff" — the single rule every task-diff
3
+ * surface resolves through (#751).
4
+ *
5
+ * The normal answer is `merge-base(baseBranch, HEAD)`: it keeps a task's diff
6
+ * to the task's own commits even after the base branch moves on, and even
7
+ * after the task merges the base back in.
8
+ *
9
+ * Two things break that answer, and both are fixed here:
10
+ *
11
+ * **A stale local base ref.** `RunRecord.baseBranch` is a NAME (`main`),
12
+ * resolved to a ref once, when the worktree was created. Nothing ever
13
+ * fast-forwards the user's local `main` — cezar's agents only ever `git fetch`,
14
+ * which moves `origin/main` — so on a repo the user does not pull, the local
15
+ * ref drifts arbitrarily far behind. The merge-base then collapses onto that
16
+ * stale tip and every upstream commit the task forked from or merged in counts
17
+ * as the task's own work: an eight-line fix measured `+59514 −12160` against a
18
+ * `main` that was 98 commits and one monorepo restructure behind origin. So the
19
+ * base is re-resolved to the freshest ref it names at every call
20
+ * (`freshestBaseRef`) — the read-time twin of `resolveBaseRef`, which does the
21
+ * same thing at worktree-creation time and cannot know what happens later.
22
+ *
23
+ * **A repointed HEAD.** cezar hands the agent a worktree on the task's own
24
+ * branch, but nothing stops the agent from checking out another branch in it —
25
+ * every `review/pr-NNN` and QA run does exactly that, and so does every skill
26
+ * that opens its work on a named `feat/…` branch. The merge-base then silently
27
+ * redefines "this task's diff" as *the whole checked-out branch*, which is how
28
+ * a task that committed nothing came to report `+22505 −2628`. #591 and #751
29
+ * answered that with `HEAD` — uncommitted work only — which is right for a
30
+ * pure review and badly wrong for the far more common case of an agent that
31
+ * committed real work on a branch it created itself: those runs reported
32
+ * `+0 −0` for changes that were genuinely theirs.
33
+ *
34
+ * The honest anchor for a repointed HEAD is the branch as it stood **when this
35
+ * run first saw it** — its `<branch>@{<run start>}` reflog state. Diffing
36
+ * against that attributes exactly what the run did to the tree and nothing
37
+ * that was already there: a review run gets its `+0`, and a run that branched
38
+ * off the base and committed gets its real numbers. Where that baseline is
39
+ * itself stale — the run merged the base branch in afterwards, dragging the
40
+ * whole upstream delta behind it — the ordinary merge-base is the tighter
41
+ * answer, so the two candidates compete and the one that attributes FEWER
42
+ * CHANGED LINES to the task wins. The reported number is then never more than
43
+ * the least either measure can defend.
44
+ *
45
+ * It lives here so a third surface cannot get it wrong again — callers hand in
46
+ * their own `git` runner (`git-worktree.ts` and `server/git-changes.ts` each
47
+ * own a private one, and `git-changes` needs its scratch-`GIT_INDEX_FILE`
48
+ * variant), so this module stays a pure decision with no process-spawning of
49
+ * its own.
50
+ */
51
+ /** What a caller's `git` runner must answer with. Both existing runners are wider than this. */
52
+ export interface GitRunResult {
53
+ ok: boolean;
54
+ stdout: string;
55
+ }
56
+ /** A caller-supplied `git` invocation, already bound to a working directory (and env). */
57
+ export type GitRunner = (args: string[]) => Promise<GitRunResult>;
58
+ /** The task branch cezar created vs. the branch HEAD actually sits on. */
59
+ export interface RepointedHead {
60
+ headBranch: string;
61
+ taskBranch: string;
62
+ }
63
+ export interface TaskDiffBase {
64
+ /** The ref to diff against. */
65
+ base: string;
66
+ /** Present only when HEAD left the task's branch — the reason `base` is what it is. */
67
+ repointedHead?: RepointedHead;
68
+ }
69
+ /**
70
+ * Resolve the diff anchor for a task worktree. Never throws: a failing git call
71
+ * degrades to the base branch name, which is what the un-guarded callers did
72
+ * before this helper existed.
73
+ *
74
+ * `taskBranch` is optional because not every caller has one (the main working
75
+ * tree has no task branch at all). Without it there is nothing to compare HEAD
76
+ * against, so the merge-base anchor is used unchanged.
77
+ *
78
+ * `runStartedAt` is what makes the repointed-HEAD answer a measurement instead
79
+ * of a guess; without it the anchor stays `HEAD` (uncommitted work only), the
80
+ * conservative #751 answer that can never claim someone else's commits.
81
+ */
82
+ export declare function resolveTaskDiffBase(runGit: GitRunner, baseBranch: string, opts?: {
83
+ taskBranch?: string;
84
+ runStartedAt?: string;
85
+ }): Promise<TaskDiffBase>;
@@ -0,0 +1,180 @@
1
+ /**
2
+ * "Which ref anchors *this task's* diff" — the single rule every task-diff
3
+ * surface resolves through (#751).
4
+ *
5
+ * The normal answer is `merge-base(baseBranch, HEAD)`: it keeps a task's diff
6
+ * to the task's own commits even after the base branch moves on, and even
7
+ * after the task merges the base back in.
8
+ *
9
+ * Two things break that answer, and both are fixed here:
10
+ *
11
+ * **A stale local base ref.** `RunRecord.baseBranch` is a NAME (`main`),
12
+ * resolved to a ref once, when the worktree was created. Nothing ever
13
+ * fast-forwards the user's local `main` — cezar's agents only ever `git fetch`,
14
+ * which moves `origin/main` — so on a repo the user does not pull, the local
15
+ * ref drifts arbitrarily far behind. The merge-base then collapses onto that
16
+ * stale tip and every upstream commit the task forked from or merged in counts
17
+ * as the task's own work: an eight-line fix measured `+59514 −12160` against a
18
+ * `main` that was 98 commits and one monorepo restructure behind origin. So the
19
+ * base is re-resolved to the freshest ref it names at every call
20
+ * (`freshestBaseRef`) — the read-time twin of `resolveBaseRef`, which does the
21
+ * same thing at worktree-creation time and cannot know what happens later.
22
+ *
23
+ * **A repointed HEAD.** cezar hands the agent a worktree on the task's own
24
+ * branch, but nothing stops the agent from checking out another branch in it —
25
+ * every `review/pr-NNN` and QA run does exactly that, and so does every skill
26
+ * that opens its work on a named `feat/…` branch. The merge-base then silently
27
+ * redefines "this task's diff" as *the whole checked-out branch*, which is how
28
+ * a task that committed nothing came to report `+22505 −2628`. #591 and #751
29
+ * answered that with `HEAD` — uncommitted work only — which is right for a
30
+ * pure review and badly wrong for the far more common case of an agent that
31
+ * committed real work on a branch it created itself: those runs reported
32
+ * `+0 −0` for changes that were genuinely theirs.
33
+ *
34
+ * The honest anchor for a repointed HEAD is the branch as it stood **when this
35
+ * run first saw it** — its `<branch>@{<run start>}` reflog state. Diffing
36
+ * against that attributes exactly what the run did to the tree and nothing
37
+ * that was already there: a review run gets its `+0`, and a run that branched
38
+ * off the base and committed gets its real numbers. Where that baseline is
39
+ * itself stale — the run merged the base branch in afterwards, dragging the
40
+ * whole upstream delta behind it — the ordinary merge-base is the tighter
41
+ * answer, so the two candidates compete and the one that attributes FEWER
42
+ * CHANGED LINES to the task wins. The reported number is then never more than
43
+ * the least either measure can defend.
44
+ *
45
+ * It lives here so a third surface cannot get it wrong again — callers hand in
46
+ * their own `git` runner (`git-worktree.ts` and `server/git-changes.ts` each
47
+ * own a private one, and `git-changes` needs its scratch-`GIT_INDEX_FILE`
48
+ * variant), so this module stays a pure decision with no process-spawning of
49
+ * its own.
50
+ */
51
+ import { isSafeGitRef } from './git-refs.js';
52
+ /**
53
+ * ISO-8601 instants only, for the `<branch>@{<date>}` revision below. The
54
+ * timestamp comes from a stored run record, and a git revision expression is
55
+ * the one place a stray value would be interpreted rather than compared —
56
+ * `@{-1}` is "the previously checked-out branch", not a date. Anything that is
57
+ * not plainly a timestamp simply disables the baseline anchor.
58
+ */
59
+ const ISO_INSTANT = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/;
60
+ /**
61
+ * The freshest ref the configured base branch names: `origin/<base>` when the
62
+ * local branch is behind it (or missing entirely), the local branch otherwise.
63
+ *
64
+ * Same rule as `resolveBaseRef` (`git-worktree.ts`), which picks the fork point
65
+ * when the worktree is created; this one re-applies it every time a diff is
66
+ * measured, because that is when the local ref's staleness actually shows up.
67
+ * A base that is already remote-tracking, a commit sha pinned from a detached
68
+ * HEAD, or a repo with no `origin` all fall through unchanged.
69
+ */
70
+ async function freshestBaseRef(runGit, base) {
71
+ if (!isSafeGitRef(base) || base === 'HEAD' || base.startsWith('origin/'))
72
+ return base;
73
+ const remote = `origin/${base}`;
74
+ const hasRemote = await runGit(['rev-parse', '--verify', '--quiet', `${remote}^{commit}`]);
75
+ if (!hasRemote.ok)
76
+ return base;
77
+ // Exits 0 iff local is equal to or ahead of origin — the case where the local
78
+ // ref carries unpushed base commits and is the better answer.
79
+ const localCurrent = await runGit(['merge-base', '--is-ancestor', remote, base]);
80
+ return localCurrent.ok ? base : remote;
81
+ }
82
+ /**
83
+ * Where the repointed branch stood when this run started — `git rev-parse
84
+ * <branch>@{<runStartedAt>}`, i.e. its own reflog, read at a point in time.
85
+ *
86
+ * Git answers this generously by design: a timestamp older than the whole
87
+ * reflog resolves to the branch's OLDEST recorded state, which for a branch the
88
+ * agent created during the run is its creation commit — exactly the fork point
89
+ * we want. A branch that already existed resolves to the tip it had before the
90
+ * run touched it, so the previous author's commits stay theirs.
91
+ *
92
+ * Null (→ the caller keeps the conservative `HEAD` anchor) when there is no run
93
+ * start to read at, when HEAD is detached (no branch reflog to consult), or
94
+ * when reflogs are unavailable — a guess is worse than the narrow answer.
95
+ */
96
+ async function checkoutBaseline(runGit, headBranch, runStartedAt) {
97
+ if (!runStartedAt || !ISO_INSTANT.test(runStartedAt))
98
+ return null;
99
+ if (headBranch === 'HEAD' || !isSafeGitRef(headBranch))
100
+ return null;
101
+ const at = await runGit([
102
+ 'rev-parse',
103
+ '--verify',
104
+ '--quiet',
105
+ `${headBranch}@{${runStartedAt}}^{commit}`,
106
+ ]);
107
+ const sha = at.ok ? at.stdout.trim() : '';
108
+ return sha || null;
109
+ }
110
+ /**
111
+ * How many changed lines an anchor attributes to the task — the comparison that
112
+ * picks between two candidates, never a number anyone sees (the callers do their
113
+ * own parsing for that, `parseShortstat`). Both candidates cover the same
114
+ * uncommitted work, so the comparison is fair whatever the index holds.
115
+ *
116
+ * This is the one part of the decision that reads the index rather than just
117
+ * refs, and `git diff` rewrites the index it reads (a stat refresh). Callers
118
+ * that keep their diffs off an index they do not own — `collectChanges` and its
119
+ * scratch `GIT_INDEX_FILE` — must therefore hand this module a runner carrying
120
+ * that same environment, and the two probes below run one after the other so
121
+ * they never refresh one index file concurrently.
122
+ */
123
+ async function changedLines(runGit, ref) {
124
+ const res = await runGit(['diff', '--shortstat', ref]);
125
+ if (!res.ok)
126
+ return null;
127
+ let total = 0;
128
+ for (const m of res.stdout.matchAll(/(\d+) (?:insertions?\(\+\)|deletions?\(-\))/g)) {
129
+ total += Number(m[1]);
130
+ }
131
+ return total;
132
+ }
133
+ /**
134
+ * Resolve the diff anchor for a task worktree. Never throws: a failing git call
135
+ * degrades to the base branch name, which is what the un-guarded callers did
136
+ * before this helper existed.
137
+ *
138
+ * `taskBranch` is optional because not every caller has one (the main working
139
+ * tree has no task branch at all). Without it there is nothing to compare HEAD
140
+ * against, so the merge-base anchor is used unchanged.
141
+ *
142
+ * `runStartedAt` is what makes the repointed-HEAD answer a measurement instead
143
+ * of a guess; without it the anchor stays `HEAD` (uncommitted work only), the
144
+ * conservative #751 answer that can never claim someone else's commits.
145
+ */
146
+ export async function resolveTaskDiffBase(runGit, baseBranch, opts = {}) {
147
+ const base = await freshestBaseRef(runGit, baseBranch);
148
+ const mergeBase = async () => {
149
+ const res = await runGit(['merge-base', base, 'HEAD']);
150
+ return res.ok && res.stdout.trim() ? res.stdout.trim() : base;
151
+ };
152
+ if (!opts.taskBranch)
153
+ return { base: await mergeBase() };
154
+ const headBranchResult = await runGit(['rev-parse', '--abbrev-ref', 'HEAD']);
155
+ const headBranch = headBranchResult.ok ? headBranchResult.stdout.trim() : '';
156
+ // An unreadable HEAD (no commits yet, broken worktree) is NOT evidence of a
157
+ // repoint — fall through to the merge-base anchor rather than narrowing on a
158
+ // guess. A detached HEAD, on the other hand, is by definition not the task's
159
+ // branch and takes the repointed path below.
160
+ if (!headBranch || headBranch === opts.taskBranch)
161
+ return { base: await mergeBase() };
162
+ const repointedHead = { headBranch, taskBranch: opts.taskBranch };
163
+ const baseline = await checkoutBaseline(runGit, headBranch, opts.runStartedAt);
164
+ if (!baseline)
165
+ return { base: 'HEAD', repointedHead };
166
+ // Two defensible anchors, so report the tighter one: the number must never
167
+ // claim more than the least either measure attributes to this task. The
168
+ // baseline is usually it — but not when the run merged the base branch in
169
+ // afterwards, which drags the whole upstream delta past a pre-merge baseline
170
+ // and leaves the merge-base as the only anchor that still measures the task.
171
+ const anchor = await mergeBase();
172
+ const viaBaseline = await changedLines(runGit, baseline);
173
+ if (viaBaseline === null)
174
+ return { base: anchor, repointedHead };
175
+ const viaMergeBase = await changedLines(runGit, anchor);
176
+ if (viaMergeBase === null || viaBaseline <= viaMergeBase)
177
+ return { base: baseline, repointedHead };
178
+ return { base: anchor, repointedHead };
179
+ }
180
+ //# sourceMappingURL=git-diff-base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-diff-base.js","sourceRoot":"","sources":["../src/git-diff-base.ts"],"names":[],"mappings":"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"}