@qodeca/xezar 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (481) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +810 -0
  3. package/dist/agent-config/account-identity.d.ts +44 -0
  4. package/dist/agent-config/account-identity.js +128 -0
  5. package/dist/agent-config/account-identity.js.map +1 -0
  6. package/dist/agent-config/catalog.d.ts +71 -0
  7. package/dist/agent-config/catalog.js +223 -0
  8. package/dist/agent-config/catalog.js.map +1 -0
  9. package/dist/agent-config/files.d.ts +46 -0
  10. package/dist/agent-config/files.js +119 -0
  11. package/dist/agent-config/files.js.map +1 -0
  12. package/dist/agent-config/model-settings/claude.d.ts +2 -0
  13. package/dist/agent-config/model-settings/claude.js +11 -0
  14. package/dist/agent-config/model-settings/claude.js.map +1 -0
  15. package/dist/agent-config/model-settings/codex.d.ts +2 -0
  16. package/dist/agent-config/model-settings/codex.js +16 -0
  17. package/dist/agent-config/model-settings/codex.js.map +1 -0
  18. package/dist/agent-config/model-settings/opencode.d.ts +2 -0
  19. package/dist/agent-config/model-settings/opencode.js +8 -0
  20. package/dist/agent-config/model-settings/opencode.js.map +1 -0
  21. package/dist/agent-config/model-settings/pi.d.ts +12 -0
  22. package/dist/agent-config/model-settings/pi.js +18 -0
  23. package/dist/agent-config/model-settings/pi.js.map +1 -0
  24. package/dist/agent-config/model-settings/shared.d.ts +9 -0
  25. package/dist/agent-config/model-settings/shared.js +93 -0
  26. package/dist/agent-config/model-settings/shared.js.map +1 -0
  27. package/dist/agent-config/model-settings/types.d.ts +9 -0
  28. package/dist/agent-config/model-settings/types.js +2 -0
  29. package/dist/agent-config/model-settings/types.js.map +1 -0
  30. package/dist/agent-config/models.d.ts +9 -0
  31. package/dist/agent-config/models.js +32 -0
  32. package/dist/agent-config/models.js.map +1 -0
  33. package/dist/agent-config/seed.d.ts +7 -0
  34. package/dist/agent-config/seed.js +90 -0
  35. package/dist/agent-config/seed.js.map +1 -0
  36. package/dist/agent-config/service.d.ts +44 -0
  37. package/dist/agent-config/service.js +71 -0
  38. package/dist/agent-config/service.js.map +1 -0
  39. package/dist/agent-config/validate.d.ts +21 -0
  40. package/dist/agent-config/validate.js +76 -0
  41. package/dist/agent-config/validate.js.map +1 -0
  42. package/dist/automations/coordinator.d.ts +26 -0
  43. package/dist/automations/coordinator.js +66 -0
  44. package/dist/automations/coordinator.js.map +1 -0
  45. package/dist/automations/github-poller.d.ts +74 -0
  46. package/dist/automations/github-poller.js +234 -0
  47. package/dist/automations/github-poller.js.map +1 -0
  48. package/dist/automations/scheduler.d.ts +42 -0
  49. package/dist/automations/scheduler.js +192 -0
  50. package/dist/automations/scheduler.js.map +1 -0
  51. package/dist/automations/store.d.ts +65 -0
  52. package/dist/automations/store.js +298 -0
  53. package/dist/automations/store.js.map +1 -0
  54. package/dist/automations/task-template.d.ts +18 -0
  55. package/dist/automations/task-template.js +95 -0
  56. package/dist/automations/task-template.js.map +1 -0
  57. package/dist/automations/types.d.ts +255 -0
  58. package/dist/automations/types.js +159 -0
  59. package/dist/automations/types.js.map +1 -0
  60. package/dist/config.d.ts +77 -0
  61. package/dist/config.js +242 -0
  62. package/dist/config.js.map +1 -0
  63. package/dist/contract/agent-config.d.ts +153 -0
  64. package/dist/contract/agent-profiles.d.ts +347 -0
  65. package/dist/contract/automations.d.ts +935 -0
  66. package/dist/contract/events.d.ts +104 -0
  67. package/dist/contract/github.d.ts +597 -0
  68. package/dist/contract/health.d.ts +102 -0
  69. package/dist/contract/index.d.ts +16 -0
  70. package/dist/contract/index.js +1953 -0
  71. package/dist/contract/projects.d.ts +210 -0
  72. package/dist/contract/repo.d.ts +234 -0
  73. package/dist/contract/runs.d.ts +1527 -0
  74. package/dist/contract/skills.d.ts +234 -0
  75. package/dist/contract/workflows.d.ts +218 -0
  76. package/dist/contract/workspace.d.ts +579 -0
  77. package/dist/core/agent-env.d.ts +31 -0
  78. package/dist/core/agent-env.js +371 -0
  79. package/dist/core/agent-env.js.map +1 -0
  80. package/dist/core/agent-model-policy.d.ts +10 -0
  81. package/dist/core/agent-model-policy.js +36 -0
  82. package/dist/core/agent-model-policy.js.map +1 -0
  83. package/dist/core/agent-profiles.d.ts +62 -0
  84. package/dist/core/agent-profiles.js +90 -0
  85. package/dist/core/agent-profiles.js.map +1 -0
  86. package/dist/core/agent-runner.d.ts +211 -0
  87. package/dist/core/agent-runner.js +68 -0
  88. package/dist/core/agent-runner.js.map +1 -0
  89. package/dist/core/ask.d.ts +115 -0
  90. package/dist/core/ask.js +256 -0
  91. package/dist/core/ask.js.map +1 -0
  92. package/dist/core/backend-detect.d.ts +16 -0
  93. package/dist/core/backend-detect.js +155 -0
  94. package/dist/core/backend-detect.js.map +1 -0
  95. package/dist/core/claude-cli-runner.d.ts +65 -0
  96. package/dist/core/claude-cli-runner.js +479 -0
  97. package/dist/core/claude-cli-runner.js.map +1 -0
  98. package/dist/core/claude-model-catalog.d.ts +24 -0
  99. package/dist/core/claude-model-catalog.js +208 -0
  100. package/dist/core/claude-model-catalog.js.map +1 -0
  101. package/dist/core/claude-ui-mapper.d.ts +79 -0
  102. package/dist/core/claude-ui-mapper.js +597 -0
  103. package/dist/core/claude-ui-mapper.js.map +1 -0
  104. package/dist/core/codex-app-server-runner.d.ts +41 -0
  105. package/dist/core/codex-app-server-runner.js +584 -0
  106. package/dist/core/codex-app-server-runner.js.map +1 -0
  107. package/dist/core/codex-app-server-transport.d.ts +35 -0
  108. package/dist/core/codex-app-server-transport.js +150 -0
  109. package/dist/core/codex-app-server-transport.js.map +1 -0
  110. package/dist/core/codex-model-catalog.d.ts +10 -0
  111. package/dist/core/codex-model-catalog.js +110 -0
  112. package/dist/core/codex-model-catalog.js.map +1 -0
  113. package/dist/core/codex-ui-mapper.d.ts +109 -0
  114. package/dist/core/codex-ui-mapper.js +764 -0
  115. package/dist/core/codex-ui-mapper.js.map +1 -0
  116. package/dist/core/model-identity.d.ts +125 -0
  117. package/dist/core/model-identity.js +132 -0
  118. package/dist/core/model-identity.js.map +1 -0
  119. package/dist/core/model-presets.d.ts +21 -0
  120. package/dist/core/model-presets.js +91 -0
  121. package/dist/core/model-presets.js.map +1 -0
  122. package/dist/core/ndjson.d.ts +6 -0
  123. package/dist/core/ndjson.js +23 -0
  124. package/dist/core/ndjson.js.map +1 -0
  125. package/dist/core/opencode-model-catalog.d.ts +32 -0
  126. package/dist/core/opencode-model-catalog.js +153 -0
  127. package/dist/core/opencode-model-catalog.js.map +1 -0
  128. package/dist/core/opencode-server-runner.d.ts +32 -0
  129. package/dist/core/opencode-server-runner.js +535 -0
  130. package/dist/core/opencode-server-runner.js.map +1 -0
  131. package/dist/core/opencode-ui-mapper.d.ts +111 -0
  132. package/dist/core/opencode-ui-mapper.js +668 -0
  133. package/dist/core/opencode-ui-mapper.js.map +1 -0
  134. package/dist/core/pi-runner.d.ts +24 -0
  135. package/dist/core/pi-runner.js +349 -0
  136. package/dist/core/pi-runner.js.map +1 -0
  137. package/dist/core/pi-ui-mapper.d.ts +34 -0
  138. package/dist/core/pi-ui-mapper.js +270 -0
  139. package/dist/core/pi-ui-mapper.js.map +1 -0
  140. package/dist/core/process-usage.d.ts +66 -0
  141. package/dist/core/process-usage.js +193 -0
  142. package/dist/core/process-usage.js.map +1 -0
  143. package/dist/core/provider-auth.d.ts +154 -0
  144. package/dist/core/provider-auth.js +509 -0
  145. package/dist/core/provider-auth.js.map +1 -0
  146. package/dist/core/provider-availability.d.ts +3 -0
  147. package/dist/core/provider-availability.js +14 -0
  148. package/dist/core/provider-availability.js.map +1 -0
  149. package/dist/core/runner-factory.d.ts +8 -0
  150. package/dist/core/runner-factory.js +25 -0
  151. package/dist/core/runner-factory.js.map +1 -0
  152. package/dist/core/runner-model-catalog.d.ts +28 -0
  153. package/dist/core/runner-model-catalog.js +62 -0
  154. package/dist/core/runner-model-catalog.js.map +1 -0
  155. package/dist/core/secret-redaction.d.ts +37 -0
  156. package/dist/core/secret-redaction.js +115 -0
  157. package/dist/core/secret-redaction.js.map +1 -0
  158. package/dist/core/shell-env.d.ts +28 -0
  159. package/dist/core/shell-env.js +56 -0
  160. package/dist/core/shell-env.js.map +1 -0
  161. package/dist/core/tool-display.d.ts +31 -0
  162. package/dist/core/tool-display.js +179 -0
  163. package/dist/core/tool-display.js.map +1 -0
  164. package/dist/core/ui-events.d.ts +332 -0
  165. package/dist/core/ui-events.js +22 -0
  166. package/dist/core/ui-events.js.map +1 -0
  167. package/dist/core/usage-limit.d.ts +42 -0
  168. package/dist/core/usage-limit.js +209 -0
  169. package/dist/core/usage-limit.js.map +1 -0
  170. package/dist/core/usage.d.ts +11 -0
  171. package/dist/core/usage.js +15 -0
  172. package/dist/core/usage.js.map +1 -0
  173. package/dist/core/v1-text-coalescer.d.ts +36 -0
  174. package/dist/core/v1-text-coalescer.js +72 -0
  175. package/dist/core/v1-text-coalescer.js.map +1 -0
  176. package/dist/git-diff-base.d.ts +85 -0
  177. package/dist/git-diff-base.js +180 -0
  178. package/dist/git-diff-base.js.map +1 -0
  179. package/dist/git-refs.d.ts +11 -0
  180. package/dist/git-refs.js +14 -0
  181. package/dist/git-refs.js.map +1 -0
  182. package/dist/git-worktree.d.ts +161 -0
  183. package/dist/git-worktree.js +508 -0
  184. package/dist/git-worktree.js.map +1 -0
  185. package/dist/handoff.d.ts +62 -0
  186. package/dist/handoff.js +154 -0
  187. package/dist/handoff.js.map +1 -0
  188. package/dist/index.d.ts +2 -0
  189. package/dist/index.js +684 -0
  190. package/dist/index.js.map +1 -0
  191. package/dist/install-as-command.d.ts +40 -0
  192. package/dist/install-as-command.js +52 -0
  193. package/dist/install-as-command.js.map +1 -0
  194. package/dist/pack-check.d.ts +17 -0
  195. package/dist/pack-check.js +27 -0
  196. package/dist/pack-check.js.map +1 -0
  197. package/dist/paths.d.ts +140 -0
  198. package/dist/paths.js +192 -0
  199. package/dist/paths.js.map +1 -0
  200. package/dist/planner.d.ts +27 -0
  201. package/dist/planner.js +268 -0
  202. package/dist/planner.js.map +1 -0
  203. package/dist/release/manifests.d.ts +78 -0
  204. package/dist/release/manifests.js +57 -0
  205. package/dist/release/manifests.js.map +1 -0
  206. package/dist/release/snapshot.d.ts +67 -0
  207. package/dist/release/snapshot.js +97 -0
  208. package/dist/release/snapshot.js.map +1 -0
  209. package/dist/release/stable.d.ts +33 -0
  210. package/dist/release/stable.js +50 -0
  211. package/dist/release/stable.js.map +1 -0
  212. package/dist/runs/agent-tmpdir.d.ts +41 -0
  213. package/dist/runs/agent-tmpdir.js +183 -0
  214. package/dist/runs/agent-tmpdir.js.map +1 -0
  215. package/dist/runs/arm-repo-handle.d.ts +17 -0
  216. package/dist/runs/arm-repo-handle.js +24 -0
  217. package/dist/runs/arm-repo-handle.js.map +1 -0
  218. package/dist/runs/auto-name.d.ts +75 -0
  219. package/dist/runs/auto-name.js +179 -0
  220. package/dist/runs/auto-name.js.map +1 -0
  221. package/dist/runs/event-history.d.ts +50 -0
  222. package/dist/runs/event-history.js +613 -0
  223. package/dist/runs/event-history.js.map +1 -0
  224. package/dist/runs/retention.d.ts +60 -0
  225. package/dist/runs/retention.js +86 -0
  226. package/dist/runs/retention.js.map +1 -0
  227. package/dist/runs/review-gate.d.ts +18 -0
  228. package/dist/runs/review-gate.js +21 -0
  229. package/dist/runs/review-gate.js.map +1 -0
  230. package/dist/runs/run-index.d.ts +19 -0
  231. package/dist/runs/run-index.js +43 -0
  232. package/dist/runs/run-index.js.map +1 -0
  233. package/dist/runs/store.d.ts +490 -0
  234. package/dist/runs/store.js +1283 -0
  235. package/dist/runs/store.js.map +1 -0
  236. package/dist/runs/task-markers.d.ts +28 -0
  237. package/dist/runs/task-markers.js +74 -0
  238. package/dist/runs/task-markers.js.map +1 -0
  239. package/dist/runs/task-refs.d.ts +25 -0
  240. package/dist/runs/task-refs.js +74 -0
  241. package/dist/runs/task-refs.js.map +1 -0
  242. package/dist/runs/ui-event-sink.d.ts +80 -0
  243. package/dist/runs/ui-event-sink.js +209 -0
  244. package/dist/runs/ui-event-sink.js.map +1 -0
  245. package/dist/server/app-type.d.ts +21 -0
  246. package/dist/server/app-type.js +2 -0
  247. package/dist/server/app-type.js.map +1 -0
  248. package/dist/server/capabilities.d.ts +70 -0
  249. package/dist/server/capabilities.js +152 -0
  250. package/dist/server/capabilities.js.map +1 -0
  251. package/dist/server/checkout.d.ts +128 -0
  252. package/dist/server/checkout.js +296 -0
  253. package/dist/server/checkout.js.map +1 -0
  254. package/dist/server/forge/github.d.ts +535 -0
  255. package/dist/server/forge/github.js +2544 -0
  256. package/dist/server/forge/github.js.map +1 -0
  257. package/dist/server/forge/index.d.ts +40 -0
  258. package/dist/server/forge/index.js +72 -0
  259. package/dist/server/forge/index.js.map +1 -0
  260. package/dist/server/forge/types.d.ts +267 -0
  261. package/dist/server/forge/types.js +2 -0
  262. package/dist/server/forge/types.js.map +1 -0
  263. package/dist/server/fs-browse.d.ts +105 -0
  264. package/dist/server/fs-browse.js +182 -0
  265. package/dist/server/fs-browse.js.map +1 -0
  266. package/dist/server/git-changes.d.ts +213 -0
  267. package/dist/server/git-changes.js +555 -0
  268. package/dist/server/git-changes.js.map +1 -0
  269. package/dist/server/git.d.ts +28 -0
  270. package/dist/server/git.js +112 -0
  271. package/dist/server/git.js.map +1 -0
  272. package/dist/server/github.d.ts +9 -0
  273. package/dist/server/github.js +8 -0
  274. package/dist/server/github.js.map +1 -0
  275. package/dist/server/launch-key.d.ts +7 -0
  276. package/dist/server/launch-key.js +33 -0
  277. package/dist/server/launch-key.js.map +1 -0
  278. package/dist/server/open-in-app.d.ts +66 -0
  279. package/dist/server/open-in-app.js +211 -0
  280. package/dist/server/open-in-app.js.map +1 -0
  281. package/dist/server/open-in-terminal.d.ts +70 -0
  282. package/dist/server/open-in-terminal.js +179 -0
  283. package/dist/server/open-in-terminal.js.map +1 -0
  284. package/dist/server/pr.d.ts +7 -0
  285. package/dist/server/pr.js +7 -0
  286. package/dist/server/pr.js.map +1 -0
  287. package/dist/server/project-context.d.ts +120 -0
  288. package/dist/server/project-context.js +192 -0
  289. package/dist/server/project-context.js.map +1 -0
  290. package/dist/server/provider-action-gate.d.ts +8 -0
  291. package/dist/server/provider-action-gate.js +56 -0
  292. package/dist/server/provider-action-gate.js.map +1 -0
  293. package/dist/server/provider-auth-runtime.d.ts +21 -0
  294. package/dist/server/provider-auth-runtime.js +66 -0
  295. package/dist/server/provider-auth-runtime.js.map +1 -0
  296. package/dist/server/server.d.ts +13578 -0
  297. package/dist/server/server.js +5284 -0
  298. package/dist/server/server.js.map +1 -0
  299. package/dist/server/static-ui.d.ts +49 -0
  300. package/dist/server/static-ui.js +92 -0
  301. package/dist/server/static-ui.js.map +1 -0
  302. package/dist/server/validators.d.ts +97 -0
  303. package/dist/server/validators.js +86 -0
  304. package/dist/server/validators.js.map +1 -0
  305. package/dist/server/ws.d.ts +83 -0
  306. package/dist/server/ws.js +216 -0
  307. package/dist/server/ws.js.map +1 -0
  308. package/dist/server/wsl.d.ts +25 -0
  309. package/dist/server/wsl.js +92 -0
  310. package/dist/server/wsl.js.map +1 -0
  311. package/dist/server-install/engine.d.ts +50 -0
  312. package/dist/server-install/engine.js +324 -0
  313. package/dist/server-install/engine.js.map +1 -0
  314. package/dist/server-install/platforms/macosx-ngrok.d.ts +6 -0
  315. package/dist/server-install/platforms/macosx-ngrok.js +348 -0
  316. package/dist/server-install/platforms/macosx-ngrok.js.map +1 -0
  317. package/dist/server-install/platforms/ubuntu-vps.d.ts +63 -0
  318. package/dist/server-install/platforms/ubuntu-vps.js +997 -0
  319. package/dist/server-install/platforms/ubuntu-vps.js.map +1 -0
  320. package/dist/server-install/state.d.ts +52 -0
  321. package/dist/server-install/state.js +182 -0
  322. package/dist/server-install/state.js.map +1 -0
  323. package/dist/server-install/steps.d.ts +109 -0
  324. package/dist/server-install/steps.js +334 -0
  325. package/dist/server-install/steps.js.map +1 -0
  326. package/dist/server-install/strategies.d.ts +4 -0
  327. package/dist/server-install/strategies.js +20 -0
  328. package/dist/server-install/strategies.js.map +1 -0
  329. package/dist/server-install/types.d.ts +287 -0
  330. package/dist/server-install/types.js +121 -0
  331. package/dist/server-install/types.js.map +1 -0
  332. package/dist/server-install/ui.d.ts +42 -0
  333. package/dist/server-install/ui.js +130 -0
  334. package/dist/server-install/ui.js.map +1 -0
  335. package/dist/skills-banner.d.ts +22 -0
  336. package/dist/skills-banner.js +41 -0
  337. package/dist/skills-banner.js.map +1 -0
  338. package/dist/skills-remote.d.ts +84 -0
  339. package/dist/skills-remote.js +468 -0
  340. package/dist/skills-remote.js.map +1 -0
  341. package/dist/skills-update.d.ts +88 -0
  342. package/dist/skills-update.js +392 -0
  343. package/dist/skills-update.js.map +1 -0
  344. package/dist/skills.d.ts +82 -0
  345. package/dist/skills.js +251 -0
  346. package/dist/skills.js.map +1 -0
  347. package/dist/todos.d.ts +48 -0
  348. package/dist/todos.js +201 -0
  349. package/dist/todos.js.map +1 -0
  350. package/dist/ui-state.d.ts +26 -0
  351. package/dist/ui-state.js +38 -0
  352. package/dist/ui-state.js.map +1 -0
  353. package/dist/update-check.d.ts +12 -0
  354. package/dist/update-check.js +41 -0
  355. package/dist/update-check.js.map +1 -0
  356. package/dist/workflows/load.d.ts +15 -0
  357. package/dist/workflows/load.js +56 -0
  358. package/dist/workflows/load.js.map +1 -0
  359. package/dist/workflows/run.d.ts +803 -0
  360. package/dist/workflows/run.js +3483 -0
  361. package/dist/workflows/run.js.map +1 -0
  362. package/dist/workflows/types.d.ts +145 -0
  363. package/dist/workflows/types.js +194 -0
  364. package/dist/workflows/types.js.map +1 -0
  365. package/dist/workspace/agent-accounts.d.ts +153 -0
  366. package/dist/workspace/agent-accounts.js +304 -0
  367. package/dist/workspace/agent-accounts.js.map +1 -0
  368. package/dist/workspace/agent-profiles.d.ts +78 -0
  369. package/dist/workspace/agent-profiles.js +115 -0
  370. package/dist/workspace/agent-profiles.js.map +1 -0
  371. package/dist/workspace/config.d.ts +169 -0
  372. package/dist/workspace/config.js +379 -0
  373. package/dist/workspace/config.js.map +1 -0
  374. package/dist/workspace/migrations.d.ts +45 -0
  375. package/dist/workspace/migrations.js +147 -0
  376. package/dist/workspace/migrations.js.map +1 -0
  377. package/dist/workspace/projects-cli.d.ts +25 -0
  378. package/dist/workspace/projects-cli.js +172 -0
  379. package/dist/workspace/projects-cli.js.map +1 -0
  380. package/dist/workspace/projects.d.ts +109 -0
  381. package/dist/workspace/projects.js +250 -0
  382. package/dist/workspace/projects.js.map +1 -0
  383. package/dist/workspace/semaphore.d.ts +179 -0
  384. package/dist/workspace/semaphore.js +195 -0
  385. package/dist/workspace/semaphore.js.map +1 -0
  386. package/dist/workspace/ui-state.d.ts +34 -0
  387. package/dist/workspace/ui-state.js +53 -0
  388. package/dist/workspace/ui-state.js.map +1 -0
  389. package/package.json +85 -0
  390. package/scripts/check-pack.mjs +46 -0
  391. package/scripts/inline-contract.mjs +112 -0
  392. package/scripts/install-as-command.mjs +120 -0
  393. package/scripts/mock-claude.mjs +524 -0
  394. package/scripts/mock-pi-rpc.mjs +83 -0
  395. package/scripts/sync-readme.mjs +20 -0
  396. package/scripts/test-process-usage.mjs +47 -0
  397. package/web/dist/assets/alert-dialog-CGskMvgc.js +1 -0
  398. package/web/dist/assets/arrow-down-G8adPhbu.js +1 -0
  399. package/web/dist/assets/arrow-left-BJsIW6A0.js +1 -0
  400. package/web/dist/assets/bundle-mjs-BT31bpU6.js +1 -0
  401. package/web/dist/assets/centered-state-B_V_Ai2h.js +43 -0
  402. package/web/dist/assets/chevron-right-CFzn-von.js +1 -0
  403. package/web/dist/assets/chunk-BO2N2NFS-DE6qKn3r.js +131 -0
  404. package/web/dist/assets/collapsible-B_8uYwHb.js +1 -0
  405. package/web/dist/assets/commit-list-C4Dv6vUL.js +1 -0
  406. package/web/dist/assets/compare-variants-SR2zZfZq.js +1 -0
  407. package/web/dist/assets/core-BCsw8oQw.js +12 -0
  408. package/web/dist/assets/css-BsVw1vtW.js +1 -0
  409. package/web/dist/assets/diff-CbozNUJq.js +3 -0
  410. package/web/dist/assets/diff-stat-btAmKFJr.js +1 -0
  411. package/web/dist/assets/diff-view-BpFTcG3R.js +6 -0
  412. package/web/dist/assets/diff-woXpYk--.js +1 -0
  413. package/web/dist/assets/dropdown-menu-Z80KMInL.js +1 -0
  414. package/web/dist/assets/editable-title-wS5NWwob.js +1 -0
  415. package/web/dist/assets/ellipsis-vertical-Bmi2u2TG.js +1 -0
  416. package/web/dist/assets/engine-javascript-FQvzRocB.js +141 -0
  417. package/web/dist/assets/file-DKoYWRsv.js +1 -0
  418. package/web/dist/assets/folder-u01HScRT.js +1 -0
  419. package/web/dist/assets/git-toolbar-DZlZjTGz.js +1 -0
  420. package/web/dist/assets/github-CFURo9kf.js +1 -0
  421. package/web/dist/assets/go-rLFTqkRN.js +1 -0
  422. package/web/dist/assets/highlighted-body-OFNGDK62-BL-MfFgl.js +1 -0
  423. package/web/dist/assets/highlighter-C8DK1_sG.js +3 -0
  424. package/web/dist/assets/html-BY76lXLH.js +1 -0
  425. package/web/dist/assets/image-preview-BR3iIIhf.js +1 -0
  426. package/web/dist/assets/index-BcI5hug3.css +2 -0
  427. package/web/dist/assets/index-DlC81_GI.js +7 -0
  428. package/web/dist/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  429. package/web/dist/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  430. package/web/dist/assets/javascript-BgS3c2Ky.js +1 -0
  431. package/web/dist/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
  432. package/web/dist/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
  433. package/web/dist/assets/json-qhed-kSA.js +1 -0
  434. package/web/dist/assets/jsonc-CYpm1nAK.js +1 -0
  435. package/web/dist/assets/jsx-Bz0zcwM4.js +1 -0
  436. package/web/dist/assets/lib-BQXq3kEf.js +1 -0
  437. package/web/dist/assets/lib-BxQXEXDF.js +1 -0
  438. package/web/dist/assets/markdown-5FuCZDA4.js +2 -0
  439. package/web/dist/assets/markdown-BYOwaDjH.js +1 -0
  440. package/web/dist/assets/mermaid-GHXKKRXX-C4jxqUUb.js +1 -0
  441. package/web/dist/assets/new-task-form-BydHBbef.js +1 -0
  442. package/web/dist/assets/pill-vNzaaYxj.js +1 -0
  443. package/web/dist/assets/project-router-BbCzrHKs.js +1 -0
  444. package/web/dist/assets/prompt-templates-B7Fs2b1S.js +15 -0
  445. package/web/dist/assets/python-gzcpVVnB.js +1 -0
  446. package/web/dist/assets/react-runtime-CCIEwYL0.js +9 -0
  447. package/web/dist/assets/refresh-cw-DGliez3E.js +1 -0
  448. package/web/dist/assets/repo-git-CJFDMauC.js +1 -0
  449. package/web/dist/assets/rolldown-runtime-QTnfLwEv.js +1 -0
  450. package/web/dist/assets/run-diff-Bq9vkSNK.js +3 -0
  451. package/web/dist/assets/run-header-Cd8mSKBG.js +1 -0
  452. package/web/dist/assets/rust-Cfkwpbl8.js +1 -0
  453. package/web/dist/assets/search-x-69n_672Y.js +1 -0
  454. package/web/dist/assets/shellscript-CLZ0U2zV.js +1 -0
  455. package/web/dist/assets/skill-empty-hint-DTu0LzaJ.js +1 -0
  456. package/web/dist/assets/skills-Cs-auniL.js +1 -0
  457. package/web/dist/assets/skills-D4P-Hgey.js +1 -0
  458. package/web/dist/assets/sparkles-B8agSxBZ.js +1 -0
  459. package/web/dist/assets/sql-BsFa4tDR.js +1 -0
  460. package/web/dist/assets/square-terminal-Cf4Og6ct.js +1 -0
  461. package/web/dist/assets/tab-link-Cp2-CJS8.js +1 -0
  462. package/web/dist/assets/task-changes-DYgNXOyY.js +1 -0
  463. package/web/dist/assets/task-commits-BRpZSz1G.js +1 -0
  464. package/web/dist/assets/task-files-pKOwSyLh.js +2 -0
  465. package/web/dist/assets/task-thread-Bfyqqy-t.js +9 -0
  466. package/web/dist/assets/textarea--cpYshee.js +1 -0
  467. package/web/dist/assets/thread-loading-GyH2Atwo.js +1 -0
  468. package/web/dist/assets/toml-CcmNWLt0.js +1 -0
  469. package/web/dist/assets/trash-2--ZtrzUx3.js +1 -0
  470. package/web/dist/assets/triangle-alert-D5tJwRD2.js +1 -0
  471. package/web/dist/assets/tsx-udAQXfEw.js +1 -0
  472. package/web/dist/assets/typescript-bsJCZSQ-.js +1 -0
  473. package/web/dist/assets/upload-SnwVxKOA.js +1 -0
  474. package/web/dist/assets/use-desktop-C31lOFUD.js +1 -0
  475. package/web/dist/assets/use-submit-shortcut-JY8M_MPL.js +1 -0
  476. package/web/dist/assets/utils-Bb8ohcr3.js +64 -0
  477. package/web/dist/assets/workflows-BmOehP-A.js +11 -0
  478. package/web/dist/assets/yaml-rwi0_p6S.js +1 -0
  479. package/web/dist/assets/zoomable-image-0G3IBXWC.js +1 -0
  480. package/web/dist/index.html +80 -0
  481. package/web/dist/xezar.svg +14 -0
@@ -0,0 +1,535 @@
1
+ import { spawn as nodeSpawn } from 'node:child_process';
2
+ import { prependSystemPrompt, trackChildExit } from './agent-runner.js';
3
+ import { buildChildEnv } from './agent-env.js';
4
+ import { AUTO_END_DELAY_MS, DEFAULT_RUN_TIMEOUT_MS } from './claude-cli-runner.js';
5
+ import { parseModelIdentity } from './model-identity.js';
6
+ import { V1TextCoalescer } from './v1-text-coalescer.js';
7
+ import { createOpencodeUiState, mapOpencodeEvent, opencodeSessionStarted, opencodeTurnStarted, } from './opencode-ui-mapper.js';
8
+ const SERVER_START_TIMEOUT_MS = 30_000;
9
+ /** Grace between the teardown SIGTERM and the SIGKILL that follows it. */
10
+ export const KILL_GRACE_MS = 4_000;
11
+ /**
12
+ * `AgentRunner` over `opencode serve` — a headless HTTP server (the same one
13
+ * the opencode TUI talks to) with an SSE event stream. One server per session,
14
+ * bound to the run's `cwd` (worktree), gives OpenCode the same multi-turn shape
15
+ * as the Claude runner: each `sendMessage` posts another prompt to the same
16
+ * session (history is kept server-side), `session/abort` cancels, and reusing
17
+ * the session id resumes for "Continue".
18
+ *
19
+ * Auth = the host's opencode config/logins. The agent runs autonomously
20
+ * (auto-approved permissions); OpenCode has no per-tool allowlist, so
21
+ * `spec.allowedTools` is ignored. `spec.model` is `provider/model`.
22
+ */
23
+ export class OpencodeServerRunner {
24
+ backend = 'opencode';
25
+ bin;
26
+ timeoutMs;
27
+ lastSession = null;
28
+ constructor(opts = {}) {
29
+ this.bin = opts.bin ?? process.env.XEZ_OPENCODE_BIN ?? 'opencode';
30
+ this.timeoutMs = opts.timeoutMs ?? DEFAULT_RUN_TIMEOUT_MS;
31
+ }
32
+ run(spec, onEvent) {
33
+ return this.startSession(spec, onEvent, { autoEndAfterFirstTurn: true }).result;
34
+ }
35
+ async interrupt() {
36
+ this.lastSession?.interrupt();
37
+ }
38
+ startSession(spec, onEvent, opts = {}) {
39
+ const session = new OpencodeSession(this.bin, this.timeoutMs, spec, onEvent, opts);
40
+ this.lastSession = session;
41
+ return session;
42
+ }
43
+ }
44
+ /** One live `opencode serve` process driving a single session. */
45
+ class OpencodeSession {
46
+ bin;
47
+ spec;
48
+ onEvent;
49
+ opts;
50
+ result;
51
+ child;
52
+ /** "Has the server actually terminated?" — never `child.killed`, which only
53
+ * reports delivery and would disarm the escalation (#844/#858). */
54
+ hasExited;
55
+ serverOpen = true;
56
+ baseUrl;
57
+ sessionId;
58
+ ready;
59
+ resolveExit;
60
+ exited;
61
+ sse = new AbortController();
62
+ toolCalls = [];
63
+ textChunks = [];
64
+ /** Per text-part cursor so only newly-appended text is buffered (deltas). */
65
+ textSeen = new Map();
66
+ /** Streamed part deltas buffered per part — v1 `text` is emitted once per
67
+ * finished part (claude parity: one event per complete block), never per
68
+ * delta, so the persisted transcript and the headless CLI get whole
69
+ * paragraphs. Streaming display rides protocol v2's `item.delta`. */
70
+ textCoalescer = new V1TextCoalescer((text) => {
71
+ this.textChunks.push(text);
72
+ this.emit({ type: 'text', text });
73
+ });
74
+ toolsSeen = new Set();
75
+ /** messageID → role. Parts carry no role; only assistant parts are surfaced
76
+ * (the user's own message also streams as parts over the same SSE feed). */
77
+ msgRole = new Map();
78
+ tokensUsed = 0;
79
+ lastCost = 0;
80
+ turnInFlight = false;
81
+ /** Protocol v2 emission — additive alongside v1 (`onEvent` keeps flowing
82
+ * byte-identical); the channel is `opts.onUiEvent` (RunManager wiring
83
+ * lands in R2 step 2.1). Unlike v1's HTTP-response-synthesized turn-end,
84
+ * v2 takes its `turn.completed` from the wire `session.idle`. */
85
+ uiState = createOpencodeUiState();
86
+ autoEndTimer;
87
+ spawnFailed = null;
88
+ timedOut = false;
89
+ /** One teardown per session — see `terminate()`. */
90
+ signalled = false;
91
+ constructor(bin, timeoutMs, spec, onEvent, opts) {
92
+ this.bin = bin;
93
+ this.spec = spec;
94
+ this.onEvent = onEvent;
95
+ this.opts = opts;
96
+ // Random high port; the actual bound URL is read back from stdout.
97
+ const port = 40000 + Math.floor(Math.random() * 20000);
98
+ try {
99
+ this.child = nodeSpawn(bin, ['serve', '--hostname', '127.0.0.1', '--port', String(port)], {
100
+ cwd: spec.cwd,
101
+ env: buildChildEnv({ backend: 'opencode', extraEnv: spec.env }),
102
+ });
103
+ }
104
+ catch (err) {
105
+ throw wrapSpawnError(err, bin);
106
+ }
107
+ this.hasExited = trackChildExit(this.child);
108
+ this.child.on('error', (err) => {
109
+ this.spawnFailed = wrapSpawnError(err, bin);
110
+ });
111
+ this.exited = new Promise((resolve) => {
112
+ this.resolveExit = resolve;
113
+ });
114
+ this.child.once('exit', () => this.resolveExit());
115
+ this.child.once('close', () => this.resolveExit());
116
+ const stderrChunks = [];
117
+ this.child.stderr.setEncoding('utf8');
118
+ this.child.stderr.on('data', (chunk) => stderrChunks.push(chunk));
119
+ // The server prints its URL on stdout once listening.
120
+ const urlReady = this.waitForServerUrl(port);
121
+ const limitMs = spec.timeoutMs ?? timeoutMs;
122
+ let deadline;
123
+ if (limitMs > 0) {
124
+ deadline = setTimeout(() => {
125
+ this.timedOut = true;
126
+ this.interrupt();
127
+ }, limitMs);
128
+ deadline.unref?.();
129
+ }
130
+ this.ready = (async () => {
131
+ this.baseUrl = await urlReady;
132
+ await this.bootstrap();
133
+ })();
134
+ this.result = (async () => {
135
+ try {
136
+ await this.ready;
137
+ // Live for the whole session; the SSE loop runs until end()/interrupt.
138
+ await this.exited;
139
+ }
140
+ catch (err) {
141
+ if (!this.timedOut) {
142
+ const message = err instanceof Error ? err.message : String(err);
143
+ this.emit({ type: 'error', message: `opencode: ${message}` });
144
+ }
145
+ }
146
+ finally {
147
+ if (deadline)
148
+ clearTimeout(deadline);
149
+ if (this.autoEndTimer)
150
+ clearTimeout(this.autoEndTimer);
151
+ this.sse.abort();
152
+ this.serverOpen = false;
153
+ this.terminate();
154
+ }
155
+ await this.exited;
156
+ if (this.spawnFailed)
157
+ throw this.spawnFailed;
158
+ // Timeout/interrupt can cut the SSE feed mid-part — recover buffered prose.
159
+ this.textCoalescer.flush();
160
+ // Chunks are whole blocks now (one per finished part), so newline-join
161
+ // like the other runners, not the old delta concatenation.
162
+ const text = this.textChunks.join('\n').trim();
163
+ const base = {
164
+ text,
165
+ toolCalls: this.toolCalls,
166
+ tokensUsed: this.tokensUsed,
167
+ sessionId: this.sessionId ?? spec.sessionId,
168
+ };
169
+ if (this.timedOut) {
170
+ const mins = Math.round((limitMs / 60_000) * 10) / 10;
171
+ this.emit({ type: 'error', message: `opencode timed out after ${mins}m and was killed` });
172
+ }
173
+ this.emit({ type: 'done' });
174
+ return base;
175
+ })();
176
+ }
177
+ get open() {
178
+ return this.serverOpen;
179
+ }
180
+ get pid() {
181
+ return this.child.pid;
182
+ }
183
+ sendMessage(content) {
184
+ if (!this.serverOpen)
185
+ return false;
186
+ if (this.autoEndTimer) {
187
+ clearTimeout(this.autoEndTimer);
188
+ this.autoEndTimer = undefined;
189
+ }
190
+ const text = textOf(content);
191
+ if (!text)
192
+ return true;
193
+ void this.ready
194
+ .then(() => this.prompt(text))
195
+ .catch((err) => {
196
+ const message = err instanceof Error ? err.message : String(err);
197
+ this.emit({ type: 'note', message: `opencode: prompt failed: ${message}` });
198
+ });
199
+ return true;
200
+ }
201
+ end() {
202
+ if (!this.serverOpen)
203
+ return;
204
+ this.serverOpen = false;
205
+ this.sse.abort();
206
+ this.terminate();
207
+ }
208
+ interrupt() {
209
+ this.serverOpen = false;
210
+ if (this.baseUrl && this.sessionId) {
211
+ void this.http('POST', `/session/${this.sessionId}/abort`, undefined).catch(() => undefined);
212
+ }
213
+ this.sse.abort();
214
+ this.terminate();
215
+ }
216
+ /**
217
+ * The one place either signal is sent: SIGTERM now, SIGKILL once the grace
218
+ * window elapses.
219
+ *
220
+ * Both steps gate on `hasExited()`, never on `child.killed` — the latter
221
+ * flips the moment SIGTERM is *delivered*, so the old nested
222
+ * `exitCode == null && !killed` guard disarmed the escalation for exactly the
223
+ * server it was written for: one that installs its own SIGTERM handler stayed
224
+ * alive with `killed = true` and `exitCode === null`, outliving the whole
225
+ * window (#858, the same defect #844 fixed for the other two backends). Every
226
+ * caller here is followed by `await this.exited`, so a server that survived
227
+ * SIGTERM did not just leak — it hung the session's result forever.
228
+ *
229
+ * One teardown per session: all three call sites can run for the same session
230
+ * (`interrupt()` on the deadline, then the result promise's `finally`), and
231
+ * once SIGTERM is out with SIGKILL armed there is nothing a second pass adds.
232
+ * The old `!child.killed` test deduplicated this as a side effect of being
233
+ * wrong; `signalled` keeps that property on purpose.
234
+ */
235
+ terminate() {
236
+ if (this.signalled || this.hasExited())
237
+ return;
238
+ this.signalled = true;
239
+ this.child.kill('SIGTERM');
240
+ setTimeout(() => {
241
+ if (this.hasExited())
242
+ return;
243
+ this.child.kill('SIGKILL');
244
+ }, KILL_GRACE_MS).unref?.();
245
+ }
246
+ // ---- server lifecycle ---------------------------------------------------
247
+ waitForServerUrl(fallbackPort) {
248
+ return new Promise((resolve, reject) => {
249
+ let buffer = '';
250
+ const timer = setTimeout(() => {
251
+ cleanup();
252
+ // Nothing parsed — try the port we asked for.
253
+ resolve(`http://127.0.0.1:${fallbackPort}`);
254
+ }, SERVER_START_TIMEOUT_MS);
255
+ timer.unref?.();
256
+ const onData = (chunk) => {
257
+ buffer += chunk;
258
+ const m = /https?:\/\/[\d.]+:\d+/.exec(buffer);
259
+ if (m) {
260
+ cleanup();
261
+ resolve(m[0]);
262
+ }
263
+ };
264
+ const onExit = () => {
265
+ cleanup();
266
+ reject(new Error('opencode serve exited before it started listening'));
267
+ };
268
+ const cleanup = () => {
269
+ clearTimeout(timer);
270
+ this.child.stdout.off('data', onData);
271
+ this.child.off('exit', onExit);
272
+ };
273
+ this.child.stdout.setEncoding('utf8');
274
+ this.child.stdout.on('data', onData);
275
+ this.child.once('exit', onExit);
276
+ });
277
+ }
278
+ async bootstrap() {
279
+ const created = await this.http('POST', '/session', { title: 'xezar task' });
280
+ this.sessionId = stringField(created, 'id');
281
+ if (!this.sessionId)
282
+ throw new Error('opencode did not return a session id');
283
+ this.emit({ type: 'session', sessionId: this.sessionId });
284
+ const sessionId = this.sessionId;
285
+ this.emitUi((state) => opencodeSessionStarted(sessionId, state));
286
+ // The SSE subscription must be LIVE before the first prompt posts —
287
+ // events the server emits while the POST is in flight would otherwise be
288
+ // lost (a race this await closes; the bundled mock made it visible).
289
+ await this.consumeEvents();
290
+ const first = prependSystemPrompt(this.spec.systemPrompt, this.spec.userPrompt);
291
+ await this.prompt(first);
292
+ }
293
+ async prompt(text) {
294
+ if (!this.sessionId)
295
+ return;
296
+ this.turnInFlight = true;
297
+ // v2 turn boundary — the prompt POST is the turn start (§7.1); the end
298
+ // comes from the SSE `session.idle`, never from the HTTP response below.
299
+ this.emitUi(opencodeTurnStarted);
300
+ const body = { parts: [{ type: 'text', text }] };
301
+ // `spec.model` arrives already normalised to canonical `provider/model`
302
+ // (the run wiring's fail-loud gate). Split it with the shared parser — the
303
+ // one every runner uses — into opencode's `{ providerID, modelID }`.
304
+ const id = parseModelIdentity(this.spec.model);
305
+ if (id)
306
+ body.model = { providerID: id.provider, modelID: id.model };
307
+ try {
308
+ const res = await this.http('POST', `/session/${this.sessionId}/message`, body);
309
+ this.absorbUsage(res);
310
+ }
311
+ finally {
312
+ this.turnInFlight = false;
313
+ // A part that never saw `time.end` (abort, server quirk) still surfaces
314
+ // its prose before the turn boundary (run.ts reads markers there).
315
+ this.textCoalescer.flush();
316
+ this.emit({ type: 'turn-end' });
317
+ if (this.opts.autoEndAfterFirstTurn && this.serverOpen && !this.autoEndTimer) {
318
+ this.autoEndTimer = setTimeout(() => this.end(), AUTO_END_DELAY_MS);
319
+ this.autoEndTimer.unref?.();
320
+ }
321
+ }
322
+ }
323
+ // ---- SSE stream ---------------------------------------------------------
324
+ /** Resolves once the SSE stream is CONNECTED (headers in) — the frames are
325
+ * then drained in the background. Callers await the connection so no
326
+ * event emitted after this resolves can be missed. */
327
+ async consumeEvents() {
328
+ if (!this.baseUrl)
329
+ return;
330
+ let res;
331
+ try {
332
+ res = await fetch(`${this.baseUrl}/event`, {
333
+ headers: { accept: 'text/event-stream' },
334
+ signal: this.sse.signal,
335
+ });
336
+ }
337
+ catch {
338
+ return; // aborted or server gone — the turn response still carries results
339
+ }
340
+ if (!res.body)
341
+ return;
342
+ void this.readEvents(res.body.getReader());
343
+ }
344
+ async readEvents(reader) {
345
+ const decoder = new TextDecoder();
346
+ let buffer = '';
347
+ try {
348
+ for (;;) {
349
+ const { done, value } = await reader.read();
350
+ if (done)
351
+ break;
352
+ buffer += decoder.decode(value, { stream: true });
353
+ let sep;
354
+ while ((sep = buffer.indexOf('\n\n')) >= 0) {
355
+ const frame = buffer.slice(0, sep);
356
+ buffer = buffer.slice(sep + 2);
357
+ this.handleFrame(frame);
358
+ }
359
+ }
360
+ }
361
+ catch {
362
+ // aborted — normal on end()/interrupt
363
+ }
364
+ }
365
+ handleFrame(frame) {
366
+ const dataLines = frame
367
+ .split('\n')
368
+ .filter((l) => l.startsWith('data:'))
369
+ .map((l) => l.slice(5).trim());
370
+ if (dataLines.length === 0)
371
+ return;
372
+ let evt;
373
+ try {
374
+ evt = JSON.parse(dataLines.join('\n'));
375
+ }
376
+ catch {
377
+ return;
378
+ }
379
+ this.emitUi((state) => mapOpencodeEvent(evt, state));
380
+ this.handleEvent(evt);
381
+ }
382
+ handleEvent(evt) {
383
+ const type = evt.type ?? '';
384
+ const props = evt.properties ?? {};
385
+ if (type === 'message.updated' || type === 'message.created' || type === 'message.completed') {
386
+ const info = props.info ?? props;
387
+ const mid = stringField(info, 'id');
388
+ const role = stringField(info, 'role');
389
+ if (mid && role)
390
+ this.msgRole.set(mid, role);
391
+ this.absorbUsage(info);
392
+ }
393
+ else if (type === 'message.part.updated' || type === 'message.part.created') {
394
+ this.handlePart(props.part ?? props);
395
+ }
396
+ }
397
+ handlePart(part) {
398
+ // Only surface parts of assistant messages — the user's own message streams
399
+ // over the same feed. Role is known early (the message.updated event
400
+ // precedes its parts); an unknown role means "not assistant yet" → skip.
401
+ const messageID = stringField(part, 'messageID');
402
+ if (messageID && this.msgRole.get(messageID) !== 'assistant')
403
+ return;
404
+ const kind = stringField(part, 'type');
405
+ const id = stringField(part, 'id') ?? messageID ?? '';
406
+ if (kind === 'text') {
407
+ const full = stringField(part, 'text') ?? '';
408
+ const seen = this.textSeen.get(id) ?? 0;
409
+ if (full.length > seen) {
410
+ this.textSeen.set(id, full.length);
411
+ this.textCoalescer.append(id, full.slice(seen));
412
+ }
413
+ // `time.end` marks the part finished (same signal the v2 mapper uses) —
414
+ // emit the whole block once, preferring the snapshot's full text.
415
+ const time = part.time;
416
+ if (time && typeof time === 'object' && typeof time.end === 'number') {
417
+ this.textCoalescer.complete(id, full);
418
+ }
419
+ }
420
+ else if (kind === 'tool') {
421
+ const state = part.state ?? {};
422
+ const status = stringField(state, 'status');
423
+ const name = stringField(part, 'tool') ?? stringField(part, 'name') ?? 'tool';
424
+ const callId = id || `${name}-${this.toolsSeen.size}`;
425
+ if (!this.toolsSeen.has(callId)) {
426
+ this.toolsSeen.add(callId);
427
+ this.toolCalls.push({ id: callId, name, input: state.input ?? state });
428
+ this.emit({ type: 'tool-call', id: callId, tool: name, input: state.input ?? state });
429
+ }
430
+ if (status === 'completed' || status === 'error') {
431
+ this.emit({
432
+ type: 'tool-result',
433
+ toolCallId: callId,
434
+ result: safeStringify(state.output ?? state.result ?? state),
435
+ isError: status === 'error',
436
+ });
437
+ }
438
+ }
439
+ }
440
+ /** Pull cumulative tokens/cost out of an assistant message info object. */
441
+ absorbUsage(info) {
442
+ if (!info)
443
+ return;
444
+ const tokens = info.tokens;
445
+ if (tokens) {
446
+ const input = numField(tokens, 'input');
447
+ const output = numField(tokens, 'output');
448
+ const reasoning = numField(tokens, 'reasoning');
449
+ const total = input + output + reasoning;
450
+ if (total > this.tokensUsed) {
451
+ this.tokensUsed = total;
452
+ this.emit({ type: 'token-usage', tokensUsed: this.tokensUsed });
453
+ }
454
+ }
455
+ const cost = numField(info, 'cost');
456
+ if (cost > this.lastCost) {
457
+ this.emit({ type: 'cost', usd: cost - this.lastCost });
458
+ this.lastCost = cost;
459
+ }
460
+ }
461
+ // ---- http ---------------------------------------------------------------
462
+ async http(method, path, body) {
463
+ if (!this.baseUrl)
464
+ throw new Error('opencode server not ready');
465
+ const res = await fetch(`${this.baseUrl}${path}`, {
466
+ method,
467
+ headers: body !== undefined ? { 'content-type': 'application/json' } : {},
468
+ body: body !== undefined ? JSON.stringify(body) : undefined,
469
+ });
470
+ if (!res.ok) {
471
+ const detail = await res.text().catch(() => '');
472
+ throw new Error(`${method} ${path} → ${res.status} ${detail.slice(0, 200)}`);
473
+ }
474
+ const text = await res.text();
475
+ if (!text)
476
+ return {};
477
+ try {
478
+ return JSON.parse(text);
479
+ }
480
+ catch {
481
+ return {};
482
+ }
483
+ }
484
+ emit(event) {
485
+ this.onEvent?.(event);
486
+ }
487
+ /** The mapper never throws, but a defect in it must still never disturb
488
+ * the v1 stream — hence the belt-and-braces try. */
489
+ emitUi(map) {
490
+ try {
491
+ const mapped = map(this.uiState);
492
+ this.uiState = mapped.state;
493
+ if (this.opts.onUiEvent) {
494
+ for (const event of mapped.events)
495
+ this.opts.onUiEvent(event);
496
+ }
497
+ }
498
+ catch {
499
+ // v2 mapping is best-effort; v1 consumers stay unaffected.
500
+ }
501
+ }
502
+ }
503
+ function textOf(content) {
504
+ return content
505
+ .filter((b) => b.type === 'text')
506
+ .map((b) => b.text)
507
+ .join('\n')
508
+ .trim();
509
+ }
510
+ function stringField(obj, key) {
511
+ const v = obj[key];
512
+ return typeof v === 'string' ? v : undefined;
513
+ }
514
+ function numField(obj, key) {
515
+ const v = obj[key];
516
+ return typeof v === 'number' ? v : 0;
517
+ }
518
+ function safeStringify(value) {
519
+ if (typeof value === 'string')
520
+ return value;
521
+ try {
522
+ return JSON.stringify(value);
523
+ }
524
+ catch {
525
+ return String(value);
526
+ }
527
+ }
528
+ function wrapSpawnError(err, bin) {
529
+ const code = err?.code;
530
+ if (code === 'ENOENT') {
531
+ return new Error(`\`${bin}\` not found on PATH — install OpenCode (https://opencode.ai) and run \`opencode\` once to configure a provider`);
532
+ }
533
+ return err instanceof Error ? err : new Error(String(err));
534
+ }
535
+ //# sourceMappingURL=opencode-server-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opencode-server-runner.js","sourceRoot":"","sources":["../../src/core/opencode-server-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Pure opencode SSE-bus → protocol-v2 mapper. `mapOpencodeEvent` folds one
3
+ * parsed `{type, properties}` bus event into `UiEvent`s plus the next mapper
4
+ * state; the runner calls it ALONGSIDE the v1 path (v1 events keep flowing
5
+ * unchanged — including v1's HTTP-response-synthesized `turn-end`; only the
6
+ * v2 stream uses the correct `session.idle` signal, fixing gap §5.9).
7
+ *
8
+ * Contract: `AGENT_PROTOCOL.md` §4 (per-backend mapping: Message/Part model,
9
+ * ToolState lifecycle). Golden fixtures replaying wire-faithful
10
+ * bus-event sequences live in `__fixtures__/opencode/`.
11
+ *
12
+ * Robustness rule: input is untrusted wire data — the mapper never throws;
13
+ * unknown event/part types map to zero events.
14
+ *
15
+ * State is explicit and treated as immutable: callers thread the returned
16
+ * `state` into the next call. Ids are deterministic — items reuse the wire
17
+ * part ids, turns get `turn_<n>` minted at each prompt POST — so replaying
18
+ * a stored transcript reproduces the exact event sequence.
19
+ *
20
+ * Opencode-specific mechanics baked in:
21
+ * - text/reasoning parts carry the FULL accumulated text on every update;
22
+ * a per-part cursor diffs it into true `item.delta`s (a server-provided
23
+ * `delta` field wins when present — newer servers send it);
24
+ * - tool parts have the ONLY real `pending` phase of the three backends
25
+ * (`pending→pending`, `running→running`, `completed→completed`,
26
+ * `error→failed`);
27
+ * - the SSE bus is server-wide: parts from a foreign session id are the
28
+ * active subtask's child session and nest via `parentItemId` (§7.1);
29
+ * anything foreign outside a subtask scope is dropped.
30
+ */
31
+ import type { TokenUsage, ToolStatus, UiEvent } from './ui-events.ts';
32
+ /** Per-message telemetry: `message.updated` snapshots (cumulative per
33
+ * message) and summed `step-finish` increments are tracked separately —
34
+ * they describe the same accumulation, so the larger total wins and
35
+ * nothing is double-counted. */
36
+ interface MessageUsage {
37
+ readonly info: TokenUsage | null;
38
+ readonly infoCost: number | null;
39
+ readonly steps: TokenUsage | null;
40
+ readonly stepsCost: number | null;
41
+ }
42
+ interface SubtaskScope {
43
+ readonly id: string;
44
+ readonly title: string;
45
+ readonly input?: unknown;
46
+ }
47
+ export interface OpencodeUiMapperState {
48
+ /** The main session id (from POST /session) — the SSE bus is server-wide,
49
+ * so this is what separates our events from a subtask's child session. */
50
+ readonly sessionId: string | null;
51
+ /** True once `opencodeSessionStarted` emitted `session.started`. */
52
+ readonly sessionStarted: boolean;
53
+ readonly turnSeq: number;
54
+ readonly currentTurnId: string | null;
55
+ /** Message ids observed during the active turn. Their latest snapshots are
56
+ * summed once when the matching `session.idle` closes the turn. */
57
+ readonly currentTurnMessageIds: ReadonlySet<string>;
58
+ /** A `session.error` arrived since the turn started → `session.idle`
59
+ * closes the turn with stopReason 'error' (§7.1). */
60
+ readonly turnErrored: boolean;
61
+ /** messageID → role. Parts carry no role; only assistant parts surface
62
+ * (the user's own prompt streams as parts over the same feed). */
63
+ readonly msgRoles: ReadonlyMap<string, string>;
64
+ /** Text/reasoning part id → chars already emitted as deltas. */
65
+ readonly cursors: ReadonlyMap<string, number>;
66
+ /** Part ids whose `item.started` was emitted. */
67
+ readonly startedItems: ReadonlySet<string>;
68
+ /** Text/reasoning/patch part ids whose `item.completed` was emitted. */
69
+ readonly endedItems: ReadonlySet<string>;
70
+ /** Tool part id → last emitted status/title (flip + live-title detection). */
71
+ readonly tools: ReadonlyMap<string, {
72
+ status: ToolStatus;
73
+ title: string;
74
+ }>;
75
+ /** Serialized last plan — todowrite snapshots are idempotent, so identical
76
+ * replacements emit no duplicate `plan.updated`. */
77
+ readonly lastPlanJson: string | null;
78
+ /** Child session id → subtask scope. Foreign parts are attributed only to
79
+ * their own child session; that session's idle completes the scope. */
80
+ readonly subtasks: ReadonlyMap<string, SubtaskScope>;
81
+ /** Subtask parts do not carry the child session id. Bind one on the first
82
+ * foreign event only while attribution is unambiguous. */
83
+ readonly unboundSubtasks: readonly SubtaskScope[];
84
+ readonly usageByMessage: ReadonlyMap<string, MessageUsage>;
85
+ /** Last emitted session totals — usage.updated fires only on change. */
86
+ readonly lastUsage: {
87
+ total: number;
88
+ cost: number | null;
89
+ } | null;
90
+ }
91
+ export interface OpencodeUiMapping {
92
+ events: UiEvent[];
93
+ state: OpencodeUiMapperState;
94
+ }
95
+ export declare function createOpencodeUiState(): OpencodeUiMapperState;
96
+ /**
97
+ * Opencode has no wire-level session-start event — the session is created by
98
+ * the runner's `POST /session`, so the runner calls this once the response
99
+ * carries the id (like codex's out-of-band thread/start result).
100
+ */
101
+ export declare function opencodeSessionStarted(sessionId: string, state: OpencodeUiMapperState): OpencodeUiMapping;
102
+ /**
103
+ * Opencode has no wire-level turn-start either — the runner POSTing a prompt
104
+ * IS the turn boundary, so the runner calls this on each prompt POST. The
105
+ * matching `turn.completed` comes from the wire `session.idle` (never from
106
+ * the HTTP prompt response — that is v1's known fidelity gap).
107
+ */
108
+ export declare function opencodeTurnStarted(state: OpencodeUiMapperState): OpencodeUiMapping;
109
+ /** Fold one parsed SSE bus event into v2 events. Never throws. */
110
+ export declare function mapOpencodeEvent(evt: unknown, state: OpencodeUiMapperState): OpencodeUiMapping;
111
+ export {};