@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,668 @@
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 { toolDisplay } from './tool-display.js';
32
+ export function createOpencodeUiState() {
33
+ return {
34
+ sessionId: null,
35
+ sessionStarted: false,
36
+ turnSeq: 0,
37
+ currentTurnId: null,
38
+ currentTurnMessageIds: new Set(),
39
+ turnErrored: false,
40
+ msgRoles: new Map(),
41
+ cursors: new Map(),
42
+ startedItems: new Set(),
43
+ endedItems: new Set(),
44
+ tools: new Map(),
45
+ lastPlanJson: null,
46
+ subtasks: new Map(),
47
+ unboundSubtasks: [],
48
+ usageByMessage: new Map(),
49
+ lastUsage: null,
50
+ };
51
+ }
52
+ /**
53
+ * Opencode has no wire-level session-start event — the session is created by
54
+ * the runner's `POST /session`, so the runner calls this once the response
55
+ * carries the id (like codex's out-of-band thread/start result).
56
+ */
57
+ export function opencodeSessionStarted(sessionId, state) {
58
+ if (state.sessionStarted || sessionId === '')
59
+ return { events: [], state };
60
+ return {
61
+ events: [{ type: 'session.started', sessionId, backend: 'opencode' }],
62
+ state: { ...state, sessionId, sessionStarted: true },
63
+ };
64
+ }
65
+ /**
66
+ * Opencode has no wire-level turn-start either — the runner POSTing a prompt
67
+ * IS the turn boundary, so the runner calls this on each prompt POST. The
68
+ * matching `turn.completed` comes from the wire `session.idle` (never from
69
+ * the HTTP prompt response — that is v1's known fidelity gap).
70
+ */
71
+ export function opencodeTurnStarted(state) {
72
+ const turnId = `turn_${state.turnSeq + 1}`;
73
+ return {
74
+ events: [{ type: 'turn.started', turnId }],
75
+ state: {
76
+ ...state,
77
+ turnSeq: state.turnSeq + 1,
78
+ currentTurnId: turnId,
79
+ currentTurnMessageIds: new Set(),
80
+ turnErrored: false,
81
+ },
82
+ };
83
+ }
84
+ /** Fold one parsed SSE bus event into v2 events. Never throws. */
85
+ export function mapOpencodeEvent(evt, state) {
86
+ if (!isRecord(evt) || typeof evt.type !== 'string')
87
+ return { events: [], state };
88
+ const props = isRecord(evt.properties) ? evt.properties : {};
89
+ switch (evt.type) {
90
+ case 'message.updated':
91
+ case 'message.created':
92
+ case 'message.completed':
93
+ return mapMessageInfo(props, state);
94
+ case 'message.part.updated':
95
+ case 'message.part.created':
96
+ return mapPart(props, state);
97
+ case 'session.idle':
98
+ return mapIdle(props, state);
99
+ case 'session.error':
100
+ return mapSessionError(props, state);
101
+ default:
102
+ // server.connected, session.updated, message.part.removed,
103
+ // permission.* (reserved for the permission.* events later), …
104
+ return { events: [], state };
105
+ }
106
+ }
107
+ // ---- message info → roles + usage.updated -----------------------------------
108
+ function mapMessageInfo(props, state) {
109
+ const info = isRecord(props.info) ? props.info : props;
110
+ const id = str(info.id);
111
+ const role = str(info.role);
112
+ let next = state;
113
+ const messageSession = str(info.sessionID);
114
+ const foreign = messageSession !== undefined && state.sessionId !== null && messageSession !== state.sessionId;
115
+ if (foreign && messageSession !== undefined) {
116
+ next = resolveSubtask(messageSession, next).state;
117
+ }
118
+ if (id !== undefined && role !== undefined && state.msgRoles.get(id) !== role) {
119
+ const msgRoles = new Map(state.msgRoles);
120
+ msgRoles.set(id, role);
121
+ next = { ...next, msgRoles };
122
+ }
123
+ if (id !== undefined && role === 'assistant' && next.currentTurnId !== null && !next.currentTurnMessageIds.has(id)) {
124
+ next = { ...next, currentTurnMessageIds: new Set(next.currentTurnMessageIds).add(id) };
125
+ }
126
+ // Telemetry rides only on assistant messages (cumulative per message).
127
+ if (id !== undefined && role === 'assistant') {
128
+ const usage = tokensToUsage(info.tokens);
129
+ const cost = num(info.cost);
130
+ if (usage || cost !== undefined) {
131
+ const prev = next.usageByMessage.get(id) ?? EMPTY_MESSAGE_USAGE;
132
+ const merged = {
133
+ // Monotonic guard: a stale/zero snapshot never shrinks the record.
134
+ info: usage && (prev.info === null || usage.total >= prev.info.total) ? usage : prev.info,
135
+ infoCost: maxCost(prev.infoCost, cost),
136
+ steps: prev.steps,
137
+ stepsCost: prev.stepsCost,
138
+ };
139
+ const usageByMessage = new Map(next.usageByMessage);
140
+ usageByMessage.set(id, merged);
141
+ return emitUsage({ ...next, usageByMessage });
142
+ }
143
+ }
144
+ return { events: [], state: next };
145
+ }
146
+ // ---- parts -------------------------------------------------------------------
147
+ function mapPart(props, state) {
148
+ const part = isRecord(props.part) ? props.part : props;
149
+ const type = str(part.type);
150
+ const messageID = str(part.messageID);
151
+ const id = str(part.id) ?? messageID;
152
+ if (type === undefined || id === undefined)
153
+ return { events: [], state };
154
+ // Foreign-session parts nest only under the subtask bound to that child
155
+ // session. A newly seen child can claim the sole unbound subtask; with two
156
+ // candidates attribution is ambiguous, so the event is dropped.
157
+ const partSession = str(part.sessionID);
158
+ const foreign = partSession !== undefined && state.sessionId !== null && partSession !== state.sessionId;
159
+ const resolved = foreign && partSession !== undefined ? resolveSubtask(partSession, state) : undefined;
160
+ if (foreign && resolved?.subtask === undefined)
161
+ return { events: [], state };
162
+ state = resolved?.state ?? state;
163
+ const parentItemId = resolved?.subtask?.id;
164
+ // Only assistant parts surface — the user's own prompt streams as parts
165
+ // over the same feed. Role is known early (message.updated precedes its
166
+ // parts); an unknown role means "not assistant yet" → skip.
167
+ if (messageID !== undefined && state.msgRoles.get(messageID) !== 'assistant') {
168
+ return { events: [], state };
169
+ }
170
+ switch (type) {
171
+ case 'text':
172
+ return mapTextLike(part, id, 'text', props.delta, parentItemId, state);
173
+ case 'reasoning':
174
+ return mapTextLike(part, id, 'reasoning', props.delta, parentItemId, state);
175
+ case 'tool':
176
+ return mapTool(part, id, parentItemId, state);
177
+ case 'patch':
178
+ return mapPatch(part, id, parentItemId, state);
179
+ case 'subtask':
180
+ return mapSubtask(part, id, state);
181
+ case 'step-finish':
182
+ return mapStepFinish(part, messageID, state);
183
+ default:
184
+ // file, snapshot, step-start, agent, retry, compaction, … — nothing to
185
+ // render yet.
186
+ return { events: [], state };
187
+ }
188
+ }
189
+ /** Text/reasoning parts carry the FULL accumulated text each update — the
190
+ * cursor diffs it into true deltas; a server-sent `delta` wins when present.
191
+ * `time.end` marks the part finished → `item.completed` (once). */
192
+ function mapTextLike(part, id, field, serverDelta, parentItemId, state) {
193
+ const full = typeof part.text === 'string' ? part.text : '';
194
+ const events = [];
195
+ let startedItems = state.startedItems;
196
+ let cursors = state.cursors;
197
+ let endedItems = state.endedItems;
198
+ const makeItem = (text) => {
199
+ const item = field === 'text'
200
+ ? { kind: 'message', id, role: 'assistant', text }
201
+ : { kind: 'reasoning', id, text };
202
+ if (parentItemId !== undefined)
203
+ item.parentItemId = parentItemId;
204
+ return item;
205
+ };
206
+ if (!startedItems.has(id)) {
207
+ events.push({ type: 'item.started', item: makeItem('') });
208
+ startedItems = new Set(startedItems).add(id);
209
+ }
210
+ const cursor = cursors.get(id) ?? 0;
211
+ const winning = str(serverDelta);
212
+ let delta;
213
+ let nextCursor = cursor;
214
+ if (winning !== undefined) {
215
+ delta = winning;
216
+ // Keep the cursor consistent with the accumulated text so a later
217
+ // full-text-only update doesn't re-emit what the server delta covered.
218
+ nextCursor = Math.max(cursor + winning.length, full.length);
219
+ }
220
+ else if (full.length > cursor) {
221
+ delta = full.slice(cursor);
222
+ nextCursor = full.length;
223
+ }
224
+ if (delta !== undefined) {
225
+ events.push({ type: 'item.delta', itemId: id, field, delta });
226
+ const nextCursors = new Map(cursors);
227
+ nextCursors.set(id, nextCursor);
228
+ cursors = nextCursors;
229
+ }
230
+ const time = isRecord(part.time) ? part.time : undefined;
231
+ if (time && num(time.end) !== undefined && !endedItems.has(id)) {
232
+ events.push({ type: 'item.completed', item: makeItem(full) });
233
+ endedItems = new Set(endedItems).add(id);
234
+ }
235
+ if (events.length === 0)
236
+ return { events, state };
237
+ return { events, state: { ...state, startedItems, cursors, endedItems } };
238
+ }
239
+ /** The §7.1 direct status map — opencode is the only backend with a real
240
+ * pending phase, and its `error` state is v2's `failed`. */
241
+ const STATUS_MAP = {
242
+ pending: 'pending',
243
+ running: 'running',
244
+ completed: 'completed',
245
+ error: 'failed',
246
+ };
247
+ function mapTool(part, id, parentItemId, state) {
248
+ const name = str(part.tool) ?? str(part.name) ?? 'tool';
249
+ const toolState = isRecord(part.state) ? part.state : {};
250
+ const prev = state.tools.get(id);
251
+ const mapped = typeof toolState.status === 'string' ? STATUS_MAP[toolState.status] : undefined;
252
+ const status = mapped ?? prev?.status ?? 'pending';
253
+ const display = toolDisplay(name, toolState.input);
254
+ // The running/completed states carry a live human title ("npm test") — the
255
+ // wire word wins over the derived one (§7.1). The error state has no title
256
+ // field (§4.2), so the last live title carries over instead of regressing.
257
+ const title = str(toolState.title) ?? prev?.title ?? display.title;
258
+ const item = { kind: 'tool', id, name, toolKind: display.toolKind, title, status };
259
+ if (toolState.input !== undefined)
260
+ item.input = toolState.input;
261
+ if (status === 'completed') {
262
+ const output = str(toolState.output);
263
+ if (output !== undefined)
264
+ item.output = output;
265
+ }
266
+ if (status === 'failed') {
267
+ const error = errorText(toolState.error);
268
+ if (error !== undefined)
269
+ item.error = error;
270
+ }
271
+ const metadata = isRecord(toolState.metadata) ? toolState.metadata : undefined;
272
+ const exitCode = metadata ? num(metadata.exit) : undefined;
273
+ if (exitCode !== undefined)
274
+ item.exitCode = exitCode;
275
+ if (parentItemId !== undefined)
276
+ item.parentItemId = parentItemId;
277
+ const events = [];
278
+ const settled = status === 'completed' || status === 'failed';
279
+ if (prev === undefined) {
280
+ // First sight — a part already settled is a lone final snapshot
281
+ // (consumers upsert by id, so it renders fine).
282
+ events.push({ type: settled ? 'item.completed' : 'item.started', item });
283
+ }
284
+ else if (prev.status !== status) {
285
+ events.push({ type: settled ? 'item.completed' : 'item.updated', item });
286
+ }
287
+ else if (prev.title !== title && !settled) {
288
+ // Same state, new live title (running-state metadata updates).
289
+ events.push({ type: 'item.updated', item });
290
+ }
291
+ let next = state;
292
+ if (events.length > 0) {
293
+ const tools = new Map(state.tools);
294
+ tools.set(id, { status, title });
295
+ next = { ...next, tools };
296
+ }
297
+ // todowrite IS the plan (full-replacement semantics, deduplicated).
298
+ if (name.toLowerCase() === 'todowrite') {
299
+ const entries = planEntriesOf(toolState.input);
300
+ if (entries) {
301
+ const json = JSON.stringify(entries);
302
+ if (json !== next.lastPlanJson) {
303
+ events.push({ type: 'plan.updated', entries });
304
+ next = { ...next, lastPlanJson: json };
305
+ }
306
+ }
307
+ }
308
+ if (events.length === 0 && next === state)
309
+ return { events, state };
310
+ return { events, state: next };
311
+ }
312
+ /**
313
+ * todowrite input `{todos:[{content,status,priority}]}` → plan entries
314
+ * (an empty list is a valid plan; malformed rows are filtered).
315
+ *
316
+ * `status` is a free-form string upstream (`Schema.String`, not an enum) — its
317
+ * documented vocabulary is pending|in_progress|completed|cancelled. Rows with
318
+ * an unrecognized status fall back to `pending` rather than being dropped: a
319
+ * todo the agent wrote must stay on screen, and dropping it silently shrinks
320
+ * the plan mid-run for no visible reason.
321
+ *
322
+ * A `pending` tool part carries `input: {}` (opencode publishes the part before
323
+ * the arguments finish parsing), which lands on the `!Array.isArray` guard and
324
+ * maps to zero events — so a streaming part cannot clobber a good plan.
325
+ */
326
+ function planEntriesOf(input) {
327
+ if (!isRecord(input) || !Array.isArray(input.todos))
328
+ return undefined;
329
+ const entries = [];
330
+ for (const todo of input.todos) {
331
+ if (!isRecord(todo) || typeof todo.content !== 'string')
332
+ continue;
333
+ const status = PLAN_STATUSES.find((s) => s === todo.status) ?? 'pending';
334
+ const entry = { content: todo.content, status };
335
+ if (todo.priority === 'high' || todo.priority === 'medium' || todo.priority === 'low') {
336
+ entry.priority = todo.priority;
337
+ }
338
+ entries.push(entry);
339
+ }
340
+ return entries;
341
+ }
342
+ const PLAN_STATUSES = ['pending', 'in_progress', 'completed', 'cancelled'];
343
+ /** `patch` parts snapshot applied file changes → a completed edit-tool item
344
+ * carrying `diffs` (unified when the wire includes content; the older
345
+ * paths-only shape still yields per-file entries + locations). */
346
+ function mapPatch(part, id, parentItemId, state) {
347
+ if (state.endedItems.has(id))
348
+ return { events: [], state };
349
+ const artifacts = patchArtifacts(part.files);
350
+ if (!artifacts)
351
+ return { events: [], state };
352
+ const { diffs, locations } = artifacts;
353
+ const label = locations.length === 1 ? locations[0]?.path : locations.length > 1 ? `${locations.length} files` : undefined;
354
+ const item = {
355
+ kind: 'tool',
356
+ id,
357
+ name: 'patch',
358
+ toolKind: 'edit',
359
+ title: label !== undefined ? `Edit ${label}` : 'Edit',
360
+ status: 'completed',
361
+ diffs,
362
+ locations,
363
+ };
364
+ if (parentItemId !== undefined)
365
+ item.parentItemId = parentItemId;
366
+ return {
367
+ events: [{ type: 'item.completed', item }],
368
+ state: { ...state, endedItems: new Set(state.endedItems).add(id) },
369
+ };
370
+ }
371
+ /** `files` as `{path: unifiedDiff}` record (or `[{path, diff}]`) carries the
372
+ * content; the paths-only `string[]` shape still yields diff entries.
373
+ * Opencode sends unified diffs only — old text is unknown, never "empty". */
374
+ function patchArtifacts(files) {
375
+ const diffs = [];
376
+ const push = (path, unified) => {
377
+ const diff = { path, oldText: null };
378
+ if (unified !== undefined)
379
+ diff.unified = unified;
380
+ diffs.push(diff);
381
+ };
382
+ if (Array.isArray(files)) {
383
+ for (const entry of files) {
384
+ if (typeof entry === 'string' && entry !== '')
385
+ push(entry);
386
+ else if (isRecord(entry)) {
387
+ const path = str(entry.path) ?? str(entry.file) ?? str(entry.filename);
388
+ if (path !== undefined)
389
+ push(path, str(entry.diff) ?? str(entry.patch));
390
+ }
391
+ }
392
+ }
393
+ else if (isRecord(files)) {
394
+ for (const [path, value] of Object.entries(files)) {
395
+ if (path === '')
396
+ continue;
397
+ if (typeof value === 'string')
398
+ push(path, str(value));
399
+ else if (isRecord(value))
400
+ push(path, str(value.diff) ?? str(value.patch));
401
+ else
402
+ push(path);
403
+ }
404
+ }
405
+ if (diffs.length === 0)
406
+ return undefined;
407
+ return { diffs, locations: diffs.map((d) => ({ path: d.path })) };
408
+ }
409
+ /** `subtask` parts spawn a child session → a task-kind tool item whose id
410
+ * scopes subsequent foreign-session items via `parentItemId` (§7.1); the
411
+ * child's `session.idle` completes it. */
412
+ function mapSubtask(part, id, state) {
413
+ if (state.startedItems.has(id))
414
+ return { events: [], state };
415
+ const description = str(part.description);
416
+ const display = toolDisplay('task', { description });
417
+ const item = {
418
+ kind: 'tool',
419
+ id,
420
+ name: 'subtask',
421
+ toolKind: display.toolKind,
422
+ title: display.title,
423
+ status: 'running',
424
+ };
425
+ const input = {};
426
+ if (str(part.prompt) !== undefined)
427
+ input.prompt = part.prompt;
428
+ if (description !== undefined)
429
+ input.description = description;
430
+ if (str(part.agent) !== undefined)
431
+ input.agent = part.agent;
432
+ if (Object.keys(input).length > 0)
433
+ item.input = input;
434
+ return {
435
+ events: [{ type: 'item.started', item }],
436
+ state: {
437
+ ...state,
438
+ startedItems: new Set(state.startedItems).add(id),
439
+ unboundSubtasks: [...state.unboundSubtasks, { id, title: item.title, input: item.input }],
440
+ },
441
+ };
442
+ }
443
+ /** `step-finish` parts carry per-LLM-round-trip cost + tokens → summed as
444
+ * usage increments (the larger of this sum and the `message.updated`
445
+ * snapshot wins per message — see `MessageUsage`). */
446
+ function mapStepFinish(part, messageID, state) {
447
+ if (messageID === undefined)
448
+ return { events: [], state };
449
+ const tokens = tokensToUsage(part.tokens);
450
+ const cost = num(part.cost);
451
+ if (!tokens && cost === undefined)
452
+ return { events: [], state };
453
+ const prev = state.usageByMessage.get(messageID) ?? EMPTY_MESSAGE_USAGE;
454
+ const merged = {
455
+ info: prev.info,
456
+ infoCost: prev.infoCost,
457
+ steps: tokens ? addUsage(prev.steps, tokens) : prev.steps,
458
+ stepsCost: cost !== undefined ? (prev.stepsCost ?? 0) + cost : prev.stepsCost,
459
+ };
460
+ const usageByMessage = new Map(state.usageByMessage);
461
+ usageByMessage.set(messageID, merged);
462
+ const currentTurnMessageIds = state.currentTurnId !== null
463
+ ? new Set(state.currentTurnMessageIds).add(messageID)
464
+ : state.currentTurnMessageIds;
465
+ return emitUsage({ ...state, usageByMessage, currentTurnMessageIds });
466
+ }
467
+ // ---- session lifecycle -------------------------------------------------------
468
+ /** `session.idle` is THE turn-end signal (§4.1). The main session's idle
469
+ * closes the current turn; a foreign idle is the subtask's child session
470
+ * going quiet → the subtask item completes. */
471
+ function mapIdle(props, state) {
472
+ const sid = str(props.sessionID);
473
+ const isMain = sid === undefined || state.sessionId === null || sid === state.sessionId;
474
+ if (!isMain) {
475
+ if (sid === undefined)
476
+ return { events: [], state };
477
+ const resolved = resolveSubtask(sid, state);
478
+ if (resolved.subtask === undefined)
479
+ return { events: [], state };
480
+ const subtasks = new Map(resolved.state.subtasks);
481
+ subtasks.delete(sid);
482
+ return {
483
+ events: [{ type: 'item.completed', item: completedSubtask(resolved.subtask) }],
484
+ state: { ...resolved.state, subtasks },
485
+ };
486
+ }
487
+ // Idle with no turn in flight (or a repeated idle) closes nothing.
488
+ if (state.currentTurnId === null)
489
+ return { events: [], state };
490
+ const openSubtasks = [...state.subtasks.values(), ...state.unboundSubtasks];
491
+ const completed = {
492
+ type: 'turn.completed',
493
+ turnId: state.currentTurnId,
494
+ stopReason: state.turnErrored ? 'error' : 'end_turn',
495
+ };
496
+ const turnUsage = usageForMessages(state.currentTurnMessageIds, state.usageByMessage);
497
+ if (turnUsage.usage !== null)
498
+ completed.usage = turnUsage.usage;
499
+ if (turnUsage.cost !== null)
500
+ completed.costUsd = turnUsage.cost;
501
+ return {
502
+ events: [
503
+ ...openSubtasks.map((subtask) => ({ type: 'item.completed', item: completedSubtask(subtask) })),
504
+ completed,
505
+ ],
506
+ state: {
507
+ ...state,
508
+ currentTurnId: null,
509
+ currentTurnMessageIds: new Set(),
510
+ turnErrored: false,
511
+ subtasks: new Map(),
512
+ unboundSubtasks: [],
513
+ },
514
+ };
515
+ }
516
+ /** `session.error` → non-fatal `session.error` (the mapper can't know the
517
+ * session died — the runner owns fatality) + the turn closes as 'error'. */
518
+ function mapSessionError(props, state) {
519
+ const sid = str(props.sessionID);
520
+ const foreign = sid !== undefined && state.sessionId !== null && sid !== state.sessionId;
521
+ const resolved = foreign && sid !== undefined ? resolveSubtask(sid, state) : undefined;
522
+ if (foreign && resolved?.subtask === undefined)
523
+ return { events: [], state };
524
+ state = resolved?.state ?? state;
525
+ const message = errorText(props.error) ?? 'opencode session error';
526
+ return {
527
+ events: [{ type: 'session.error', message, fatal: false }],
528
+ state: { ...state, turnErrored: state.currentTurnId !== null ? true : state.turnErrored },
529
+ };
530
+ }
531
+ function resolveSubtask(sessionId, state) {
532
+ const existing = state.subtasks.get(sessionId);
533
+ if (existing !== undefined)
534
+ return { state, subtask: existing };
535
+ if (state.unboundSubtasks.length !== 1)
536
+ return { state };
537
+ const subtask = state.unboundSubtasks[0];
538
+ if (subtask === undefined)
539
+ return { state };
540
+ const subtasks = new Map(state.subtasks);
541
+ subtasks.set(sessionId, subtask);
542
+ return { state: { ...state, subtasks, unboundSubtasks: [] }, subtask };
543
+ }
544
+ function completedSubtask(subtask) {
545
+ const item = {
546
+ kind: 'tool',
547
+ id: subtask.id,
548
+ name: 'subtask',
549
+ toolKind: 'task',
550
+ title: subtask.title,
551
+ status: 'completed',
552
+ };
553
+ if (subtask.input !== undefined)
554
+ item.input = subtask.input;
555
+ return item;
556
+ }
557
+ // ---- telemetry ----------------------------------------------------------------
558
+ const EMPTY_MESSAGE_USAGE = { info: null, infoCost: null, steps: null, stepsCost: null };
559
+ /** `{input, output, reasoning, cache:{read,write}}` → raw TokenUsage
560
+ * (opencode reports no total — the sum of the parts is the total). */
561
+ function tokensToUsage(tokens) {
562
+ if (!isRecord(tokens))
563
+ return undefined;
564
+ const input = num(tokens.input) ?? 0;
565
+ const output = num(tokens.output) ?? 0;
566
+ const reasoning = num(tokens.reasoning);
567
+ const cache = isRecord(tokens.cache) ? tokens.cache : undefined;
568
+ const cacheRead = cache ? num(cache.read) : undefined;
569
+ const cacheWrite = cache ? num(cache.write) : undefined;
570
+ const usage = {
571
+ input,
572
+ output,
573
+ total: input + output + (reasoning ?? 0) + (cacheRead ?? 0) + (cacheWrite ?? 0),
574
+ };
575
+ if (cacheRead !== undefined)
576
+ usage.cacheRead = cacheRead;
577
+ if (cacheWrite !== undefined)
578
+ usage.cacheWrite = cacheWrite;
579
+ if (reasoning !== undefined)
580
+ usage.reasoning = reasoning;
581
+ return usage;
582
+ }
583
+ function addUsage(a, b) {
584
+ if (a === null)
585
+ return b;
586
+ const sum = { input: a.input + b.input, output: a.output + b.output, total: a.total + b.total };
587
+ const cacheRead = optSum(a.cacheRead, b.cacheRead);
588
+ if (cacheRead !== undefined)
589
+ sum.cacheRead = cacheRead;
590
+ const cacheWrite = optSum(a.cacheWrite, b.cacheWrite);
591
+ if (cacheWrite !== undefined)
592
+ sum.cacheWrite = cacheWrite;
593
+ const reasoning = optSum(a.reasoning, b.reasoning);
594
+ if (reasoning !== undefined)
595
+ sum.reasoning = reasoning;
596
+ return sum;
597
+ }
598
+ function optSum(a, b) {
599
+ if (a === undefined && b === undefined)
600
+ return undefined;
601
+ return (a ?? 0) + (b ?? 0);
602
+ }
603
+ function maxCost(a, b) {
604
+ if (b === undefined)
605
+ return a;
606
+ return a === null ? b : Math.max(a, b);
607
+ }
608
+ /** Session totals = per-message effective usage summed across messages;
609
+ * emitted only when the snapshot actually changed and is non-zero. */
610
+ function emitUsage(state) {
611
+ let usage = { input: 0, output: 0, total: 0 };
612
+ let cost = null;
613
+ for (const mu of state.usageByMessage.values()) {
614
+ const effective = mu.info !== null && (mu.steps === null || mu.info.total >= mu.steps.total) ? mu.info : mu.steps;
615
+ if (effective !== null)
616
+ usage = addUsage(usage, effective);
617
+ const effCost = maxCost(mu.infoCost, mu.stepsCost ?? undefined);
618
+ if (effCost !== null)
619
+ cost = (cost ?? 0) + effCost;
620
+ }
621
+ if (usage.total === 0 && (cost === null || cost === 0))
622
+ return { events: [], state };
623
+ if (state.lastUsage !== null && state.lastUsage.total === usage.total && state.lastUsage.cost === cost) {
624
+ return { events: [], state };
625
+ }
626
+ const event = { type: 'usage.updated', usage };
627
+ if (cost !== null)
628
+ event.costUsd = cost;
629
+ return { events: [event], state: { ...state, lastUsage: { total: usage.total, cost } } };
630
+ }
631
+ function usageForMessages(messageIds, usageByMessage) {
632
+ let usage = null;
633
+ let cost = null;
634
+ for (const id of messageIds) {
635
+ const message = usageByMessage.get(id);
636
+ if (message === undefined)
637
+ continue;
638
+ const effective = message.info !== null && (message.steps === null || message.info.total >= message.steps.total)
639
+ ? message.info
640
+ : message.steps;
641
+ if (effective !== null && (effective.input > 0 || effective.output > 0))
642
+ usage = addUsage(usage, effective);
643
+ const effectiveCost = maxCost(message.infoCost, message.stepsCost ?? undefined);
644
+ if (effectiveCost !== null && effectiveCost > 0)
645
+ cost = (cost ?? 0) + effectiveCost;
646
+ }
647
+ return { usage, cost };
648
+ }
649
+ // ---- tiny guards ---------------------------------------------------------------
650
+ function isRecord(value) {
651
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
652
+ }
653
+ function str(value) {
654
+ return typeof value === 'string' && value !== '' ? value : undefined;
655
+ }
656
+ function num(value) {
657
+ return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
658
+ }
659
+ /** Opencode error objects are `{name, data:{message}}` (or plain strings). */
660
+ function errorText(error) {
661
+ if (typeof error === 'string')
662
+ return str(error);
663
+ if (!isRecord(error))
664
+ return undefined;
665
+ const data = isRecord(error.data) ? error.data : undefined;
666
+ return str(error.message) ?? (data && str(data.message)) ?? str(error.name);
667
+ }
668
+ //# sourceMappingURL=opencode-ui-mapper.js.map