@wjarka/cezarion 0.10.0-pr30.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (478) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +838 -0
  3. package/dist/agent-config/account-identity.d.ts +44 -0
  4. package/dist/agent-config/account-identity.js +128 -0
  5. package/dist/agent-config/account-identity.js.map +1 -0
  6. package/dist/agent-config/catalog.d.ts +72 -0
  7. package/dist/agent-config/catalog.js +223 -0
  8. package/dist/agent-config/catalog.js.map +1 -0
  9. package/dist/agent-config/files.d.ts +46 -0
  10. package/dist/agent-config/files.js +119 -0
  11. package/dist/agent-config/files.js.map +1 -0
  12. package/dist/agent-config/model-settings/claude.d.ts +2 -0
  13. package/dist/agent-config/model-settings/claude.js +11 -0
  14. package/dist/agent-config/model-settings/claude.js.map +1 -0
  15. package/dist/agent-config/model-settings/codex.d.ts +2 -0
  16. package/dist/agent-config/model-settings/codex.js +16 -0
  17. package/dist/agent-config/model-settings/codex.js.map +1 -0
  18. package/dist/agent-config/model-settings/opencode.d.ts +2 -0
  19. package/dist/agent-config/model-settings/opencode.js +8 -0
  20. package/dist/agent-config/model-settings/opencode.js.map +1 -0
  21. package/dist/agent-config/model-settings/pi.d.ts +12 -0
  22. package/dist/agent-config/model-settings/pi.js +18 -0
  23. package/dist/agent-config/model-settings/pi.js.map +1 -0
  24. package/dist/agent-config/model-settings/shared.d.ts +9 -0
  25. package/dist/agent-config/model-settings/shared.js +93 -0
  26. package/dist/agent-config/model-settings/shared.js.map +1 -0
  27. package/dist/agent-config/model-settings/types.d.ts +9 -0
  28. package/dist/agent-config/model-settings/types.js +2 -0
  29. package/dist/agent-config/model-settings/types.js.map +1 -0
  30. package/dist/agent-config/models.d.ts +9 -0
  31. package/dist/agent-config/models.js +32 -0
  32. package/dist/agent-config/models.js.map +1 -0
  33. package/dist/agent-config/seed.d.ts +7 -0
  34. package/dist/agent-config/seed.js +90 -0
  35. package/dist/agent-config/seed.js.map +1 -0
  36. package/dist/agent-config/service.d.ts +44 -0
  37. package/dist/agent-config/service.js +71 -0
  38. package/dist/agent-config/service.js.map +1 -0
  39. package/dist/agent-config/validate.d.ts +21 -0
  40. package/dist/agent-config/validate.js +76 -0
  41. package/dist/agent-config/validate.js.map +1 -0
  42. package/dist/automations/coordinator.d.ts +26 -0
  43. package/dist/automations/coordinator.js +66 -0
  44. package/dist/automations/coordinator.js.map +1 -0
  45. package/dist/automations/github-poller.d.ts +74 -0
  46. package/dist/automations/github-poller.js +234 -0
  47. package/dist/automations/github-poller.js.map +1 -0
  48. package/dist/automations/scheduler.d.ts +42 -0
  49. package/dist/automations/scheduler.js +192 -0
  50. package/dist/automations/scheduler.js.map +1 -0
  51. package/dist/automations/store.d.ts +65 -0
  52. package/dist/automations/store.js +298 -0
  53. package/dist/automations/store.js.map +1 -0
  54. package/dist/automations/task-template.d.ts +18 -0
  55. package/dist/automations/task-template.js +95 -0
  56. package/dist/automations/task-template.js.map +1 -0
  57. package/dist/automations/types.d.ts +255 -0
  58. package/dist/automations/types.js +159 -0
  59. package/dist/automations/types.js.map +1 -0
  60. package/dist/config.d.ts +77 -0
  61. package/dist/config.js +242 -0
  62. package/dist/config.js.map +1 -0
  63. package/dist/contract/agent-config.d.ts +153 -0
  64. package/dist/contract/agent-profiles.d.ts +347 -0
  65. package/dist/contract/automations.d.ts +935 -0
  66. package/dist/contract/events.d.ts +104 -0
  67. package/dist/contract/github.d.ts +556 -0
  68. package/dist/contract/health.d.ts +102 -0
  69. package/dist/contract/index.d.ts +16 -0
  70. package/dist/contract/index.js +1895 -0
  71. package/dist/contract/projects.d.ts +210 -0
  72. package/dist/contract/repo.d.ts +234 -0
  73. package/dist/contract/runs.d.ts +1473 -0
  74. package/dist/contract/skills.d.ts +232 -0
  75. package/dist/contract/workflows.d.ts +218 -0
  76. package/dist/contract/workspace.d.ts +579 -0
  77. package/dist/core/agent-env.d.ts +31 -0
  78. package/dist/core/agent-env.js +371 -0
  79. package/dist/core/agent-env.js.map +1 -0
  80. package/dist/core/agent-model-policy.d.ts +10 -0
  81. package/dist/core/agent-model-policy.js +36 -0
  82. package/dist/core/agent-model-policy.js.map +1 -0
  83. package/dist/core/agent-profiles.d.ts +62 -0
  84. package/dist/core/agent-profiles.js +90 -0
  85. package/dist/core/agent-profiles.js.map +1 -0
  86. package/dist/core/agent-runner.d.ts +211 -0
  87. package/dist/core/agent-runner.js +68 -0
  88. package/dist/core/agent-runner.js.map +1 -0
  89. package/dist/core/ask.d.ts +105 -0
  90. package/dist/core/ask.js +187 -0
  91. package/dist/core/ask.js.map +1 -0
  92. package/dist/core/backend-detect.d.ts +16 -0
  93. package/dist/core/backend-detect.js +155 -0
  94. package/dist/core/backend-detect.js.map +1 -0
  95. package/dist/core/claude-cli-runner.d.ts +59 -0
  96. package/dist/core/claude-cli-runner.js +483 -0
  97. package/dist/core/claude-cli-runner.js.map +1 -0
  98. package/dist/core/claude-ui-mapper.d.ts +80 -0
  99. package/dist/core/claude-ui-mapper.js +598 -0
  100. package/dist/core/claude-ui-mapper.js.map +1 -0
  101. package/dist/core/codex-app-server-runner.d.ts +41 -0
  102. package/dist/core/codex-app-server-runner.js +584 -0
  103. package/dist/core/codex-app-server-runner.js.map +1 -0
  104. package/dist/core/codex-app-server-transport.d.ts +35 -0
  105. package/dist/core/codex-app-server-transport.js +150 -0
  106. package/dist/core/codex-app-server-transport.js.map +1 -0
  107. package/dist/core/codex-model-catalog.d.ts +10 -0
  108. package/dist/core/codex-model-catalog.js +110 -0
  109. package/dist/core/codex-model-catalog.js.map +1 -0
  110. package/dist/core/codex-ui-mapper.d.ts +112 -0
  111. package/dist/core/codex-ui-mapper.js +766 -0
  112. package/dist/core/codex-ui-mapper.js.map +1 -0
  113. package/dist/core/model-identity.d.ts +125 -0
  114. package/dist/core/model-identity.js +132 -0
  115. package/dist/core/model-identity.js.map +1 -0
  116. package/dist/core/model-presets.d.ts +21 -0
  117. package/dist/core/model-presets.js +81 -0
  118. package/dist/core/model-presets.js.map +1 -0
  119. package/dist/core/ndjson.d.ts +6 -0
  120. package/dist/core/ndjson.js +23 -0
  121. package/dist/core/ndjson.js.map +1 -0
  122. package/dist/core/opencode-model-catalog.d.ts +32 -0
  123. package/dist/core/opencode-model-catalog.js +153 -0
  124. package/dist/core/opencode-model-catalog.js.map +1 -0
  125. package/dist/core/opencode-server-runner.d.ts +32 -0
  126. package/dist/core/opencode-server-runner.js +882 -0
  127. package/dist/core/opencode-server-runner.js.map +1 -0
  128. package/dist/core/opencode-ui-mapper.d.ts +137 -0
  129. package/dist/core/opencode-ui-mapper.js +800 -0
  130. package/dist/core/opencode-ui-mapper.js.map +1 -0
  131. package/dist/core/pi-model-catalog.d.ts +31 -0
  132. package/dist/core/pi-model-catalog.js +152 -0
  133. package/dist/core/pi-model-catalog.js.map +1 -0
  134. package/dist/core/pi-runner.d.ts +24 -0
  135. package/dist/core/pi-runner.js +403 -0
  136. package/dist/core/pi-runner.js.map +1 -0
  137. package/dist/core/pi-ui-mapper.d.ts +36 -0
  138. package/dist/core/pi-ui-mapper.js +304 -0
  139. package/dist/core/pi-ui-mapper.js.map +1 -0
  140. package/dist/core/process-usage.d.ts +66 -0
  141. package/dist/core/process-usage.js +193 -0
  142. package/dist/core/process-usage.js.map +1 -0
  143. package/dist/core/provider-auth.d.ts +154 -0
  144. package/dist/core/provider-auth.js +509 -0
  145. package/dist/core/provider-auth.js.map +1 -0
  146. package/dist/core/provider-availability.d.ts +3 -0
  147. package/dist/core/provider-availability.js +14 -0
  148. package/dist/core/provider-availability.js.map +1 -0
  149. package/dist/core/runner-factory.d.ts +8 -0
  150. package/dist/core/runner-factory.js +25 -0
  151. package/dist/core/runner-factory.js.map +1 -0
  152. package/dist/core/runner-model-catalog.d.ts +29 -0
  153. package/dist/core/runner-model-catalog.js +78 -0
  154. package/dist/core/runner-model-catalog.js.map +1 -0
  155. package/dist/core/secret-redaction.d.ts +37 -0
  156. package/dist/core/secret-redaction.js +115 -0
  157. package/dist/core/secret-redaction.js.map +1 -0
  158. package/dist/core/shell-env.d.ts +28 -0
  159. package/dist/core/shell-env.js +56 -0
  160. package/dist/core/shell-env.js.map +1 -0
  161. package/dist/core/tool-display.d.ts +31 -0
  162. package/dist/core/tool-display.js +179 -0
  163. package/dist/core/tool-display.js.map +1 -0
  164. package/dist/core/ui-events.d.ts +335 -0
  165. package/dist/core/ui-events.js +25 -0
  166. package/dist/core/ui-events.js.map +1 -0
  167. package/dist/core/usage-limit.d.ts +42 -0
  168. package/dist/core/usage-limit.js +209 -0
  169. package/dist/core/usage-limit.js.map +1 -0
  170. package/dist/core/usage.d.ts +11 -0
  171. package/dist/core/usage.js +15 -0
  172. package/dist/core/usage.js.map +1 -0
  173. package/dist/core/v1-text-coalescer.d.ts +36 -0
  174. package/dist/core/v1-text-coalescer.js +72 -0
  175. package/dist/core/v1-text-coalescer.js.map +1 -0
  176. package/dist/git-diff-base.d.ts +85 -0
  177. package/dist/git-diff-base.js +180 -0
  178. package/dist/git-diff-base.js.map +1 -0
  179. package/dist/git-refs.d.ts +11 -0
  180. package/dist/git-refs.js +14 -0
  181. package/dist/git-refs.js.map +1 -0
  182. package/dist/git-worktree.d.ts +161 -0
  183. package/dist/git-worktree.js +508 -0
  184. package/dist/git-worktree.js.map +1 -0
  185. package/dist/handoff.d.ts +62 -0
  186. package/dist/handoff.js +154 -0
  187. package/dist/handoff.js.map +1 -0
  188. package/dist/index.d.ts +2 -0
  189. package/dist/index.js +680 -0
  190. package/dist/index.js.map +1 -0
  191. package/dist/install-as-command.d.ts +40 -0
  192. package/dist/install-as-command.js +52 -0
  193. package/dist/install-as-command.js.map +1 -0
  194. package/dist/pack-check.d.ts +17 -0
  195. package/dist/pack-check.js +27 -0
  196. package/dist/pack-check.js.map +1 -0
  197. package/dist/paths.d.ts +140 -0
  198. package/dist/paths.js +192 -0
  199. package/dist/paths.js.map +1 -0
  200. package/dist/planner.d.ts +27 -0
  201. package/dist/planner.js +268 -0
  202. package/dist/planner.js.map +1 -0
  203. package/dist/release/manifests.d.ts +81 -0
  204. package/dist/release/manifests.js +74 -0
  205. package/dist/release/manifests.js.map +1 -0
  206. package/dist/release/snapshot.d.ts +67 -0
  207. package/dist/release/snapshot.js +97 -0
  208. package/dist/release/snapshot.js.map +1 -0
  209. package/dist/release/stable.d.ts +38 -0
  210. package/dist/release/stable.js +55 -0
  211. package/dist/release/stable.js.map +1 -0
  212. package/dist/runs/agent-tmpdir.d.ts +41 -0
  213. package/dist/runs/agent-tmpdir.js +183 -0
  214. package/dist/runs/agent-tmpdir.js.map +1 -0
  215. package/dist/runs/auto-name.d.ts +75 -0
  216. package/dist/runs/auto-name.js +179 -0
  217. package/dist/runs/auto-name.js.map +1 -0
  218. package/dist/runs/event-history.d.ts +50 -0
  219. package/dist/runs/event-history.js +613 -0
  220. package/dist/runs/event-history.js.map +1 -0
  221. package/dist/runs/retention.d.ts +60 -0
  222. package/dist/runs/retention.js +86 -0
  223. package/dist/runs/retention.js.map +1 -0
  224. package/dist/runs/review-gate.d.ts +18 -0
  225. package/dist/runs/review-gate.js +21 -0
  226. package/dist/runs/review-gate.js.map +1 -0
  227. package/dist/runs/run-index.d.ts +19 -0
  228. package/dist/runs/run-index.js +43 -0
  229. package/dist/runs/run-index.js.map +1 -0
  230. package/dist/runs/store.d.ts +446 -0
  231. package/dist/runs/store.js +1118 -0
  232. package/dist/runs/store.js.map +1 -0
  233. package/dist/runs/task-markers.d.ts +28 -0
  234. package/dist/runs/task-markers.js +74 -0
  235. package/dist/runs/task-markers.js.map +1 -0
  236. package/dist/runs/task-refs.d.ts +25 -0
  237. package/dist/runs/task-refs.js +74 -0
  238. package/dist/runs/task-refs.js.map +1 -0
  239. package/dist/runs/ui-event-sink.d.ts +81 -0
  240. package/dist/runs/ui-event-sink.js +210 -0
  241. package/dist/runs/ui-event-sink.js.map +1 -0
  242. package/dist/server/app-type.d.ts +21 -0
  243. package/dist/server/app-type.js +2 -0
  244. package/dist/server/app-type.js.map +1 -0
  245. package/dist/server/capabilities.d.ts +70 -0
  246. package/dist/server/capabilities.js +152 -0
  247. package/dist/server/capabilities.js.map +1 -0
  248. package/dist/server/checkout.d.ts +128 -0
  249. package/dist/server/checkout.js +296 -0
  250. package/dist/server/checkout.js.map +1 -0
  251. package/dist/server/forge/github.d.ts +513 -0
  252. package/dist/server/forge/github.js +2364 -0
  253. package/dist/server/forge/github.js.map +1 -0
  254. package/dist/server/forge/index.d.ts +40 -0
  255. package/dist/server/forge/index.js +72 -0
  256. package/dist/server/forge/index.js.map +1 -0
  257. package/dist/server/forge/types.d.ts +242 -0
  258. package/dist/server/forge/types.js +2 -0
  259. package/dist/server/forge/types.js.map +1 -0
  260. package/dist/server/fs-browse.d.ts +105 -0
  261. package/dist/server/fs-browse.js +182 -0
  262. package/dist/server/fs-browse.js.map +1 -0
  263. package/dist/server/git-changes.d.ts +213 -0
  264. package/dist/server/git-changes.js +555 -0
  265. package/dist/server/git-changes.js.map +1 -0
  266. package/dist/server/git.d.ts +28 -0
  267. package/dist/server/git.js +112 -0
  268. package/dist/server/git.js.map +1 -0
  269. package/dist/server/github.d.ts +9 -0
  270. package/dist/server/github.js +8 -0
  271. package/dist/server/github.js.map +1 -0
  272. package/dist/server/launch-key.d.ts +7 -0
  273. package/dist/server/launch-key.js +33 -0
  274. package/dist/server/launch-key.js.map +1 -0
  275. package/dist/server/open-in-app.d.ts +66 -0
  276. package/dist/server/open-in-app.js +211 -0
  277. package/dist/server/open-in-app.js.map +1 -0
  278. package/dist/server/open-in-terminal.d.ts +70 -0
  279. package/dist/server/open-in-terminal.js +179 -0
  280. package/dist/server/open-in-terminal.js.map +1 -0
  281. package/dist/server/pr.d.ts +7 -0
  282. package/dist/server/pr.js +7 -0
  283. package/dist/server/pr.js.map +1 -0
  284. package/dist/server/project-context.d.ts +120 -0
  285. package/dist/server/project-context.js +182 -0
  286. package/dist/server/project-context.js.map +1 -0
  287. package/dist/server/provider-action-gate.d.ts +8 -0
  288. package/dist/server/provider-action-gate.js +56 -0
  289. package/dist/server/provider-action-gate.js.map +1 -0
  290. package/dist/server/provider-auth-runtime.d.ts +21 -0
  291. package/dist/server/provider-auth-runtime.js +66 -0
  292. package/dist/server/provider-auth-runtime.js.map +1 -0
  293. package/dist/server/server.d.ts +13138 -0
  294. package/dist/server/server.js +5263 -0
  295. package/dist/server/server.js.map +1 -0
  296. package/dist/server/static-ui.d.ts +49 -0
  297. package/dist/server/static-ui.js +92 -0
  298. package/dist/server/static-ui.js.map +1 -0
  299. package/dist/server/validators.d.ts +97 -0
  300. package/dist/server/validators.js +86 -0
  301. package/dist/server/validators.js.map +1 -0
  302. package/dist/server/ws.d.ts +85 -0
  303. package/dist/server/ws.js +218 -0
  304. package/dist/server/ws.js.map +1 -0
  305. package/dist/server/wsl.d.ts +25 -0
  306. package/dist/server/wsl.js +92 -0
  307. package/dist/server/wsl.js.map +1 -0
  308. package/dist/server-install/engine.d.ts +50 -0
  309. package/dist/server-install/engine.js +324 -0
  310. package/dist/server-install/engine.js.map +1 -0
  311. package/dist/server-install/platforms/macosx-ngrok.d.ts +6 -0
  312. package/dist/server-install/platforms/macosx-ngrok.js +345 -0
  313. package/dist/server-install/platforms/macosx-ngrok.js.map +1 -0
  314. package/dist/server-install/platforms/ubuntu-vps.d.ts +78 -0
  315. package/dist/server-install/platforms/ubuntu-vps.js +1016 -0
  316. package/dist/server-install/platforms/ubuntu-vps.js.map +1 -0
  317. package/dist/server-install/state.d.ts +52 -0
  318. package/dist/server-install/state.js +182 -0
  319. package/dist/server-install/state.js.map +1 -0
  320. package/dist/server-install/steps.d.ts +109 -0
  321. package/dist/server-install/steps.js +334 -0
  322. package/dist/server-install/steps.js.map +1 -0
  323. package/dist/server-install/strategies.d.ts +4 -0
  324. package/dist/server-install/strategies.js +20 -0
  325. package/dist/server-install/strategies.js.map +1 -0
  326. package/dist/server-install/types.d.ts +287 -0
  327. package/dist/server-install/types.js +121 -0
  328. package/dist/server-install/types.js.map +1 -0
  329. package/dist/server-install/ui.d.ts +42 -0
  330. package/dist/server-install/ui.js +130 -0
  331. package/dist/server-install/ui.js.map +1 -0
  332. package/dist/skills-banner.d.ts +22 -0
  333. package/dist/skills-banner.js +41 -0
  334. package/dist/skills-banner.js.map +1 -0
  335. package/dist/skills-remote.d.ts +84 -0
  336. package/dist/skills-remote.js +468 -0
  337. package/dist/skills-remote.js.map +1 -0
  338. package/dist/skills-update.d.ts +88 -0
  339. package/dist/skills-update.js +392 -0
  340. package/dist/skills-update.js.map +1 -0
  341. package/dist/skills.d.ts +82 -0
  342. package/dist/skills.js +251 -0
  343. package/dist/skills.js.map +1 -0
  344. package/dist/todos.d.ts +48 -0
  345. package/dist/todos.js +201 -0
  346. package/dist/todos.js.map +1 -0
  347. package/dist/ui-state.d.ts +26 -0
  348. package/dist/ui-state.js +38 -0
  349. package/dist/ui-state.js.map +1 -0
  350. package/dist/update-check.d.ts +12 -0
  351. package/dist/update-check.js +41 -0
  352. package/dist/update-check.js.map +1 -0
  353. package/dist/workflows/load.d.ts +15 -0
  354. package/dist/workflows/load.js +56 -0
  355. package/dist/workflows/load.js.map +1 -0
  356. package/dist/workflows/run.d.ts +758 -0
  357. package/dist/workflows/run.js +3389 -0
  358. package/dist/workflows/run.js.map +1 -0
  359. package/dist/workflows/types.d.ts +153 -0
  360. package/dist/workflows/types.js +212 -0
  361. package/dist/workflows/types.js.map +1 -0
  362. package/dist/workspace/agent-accounts.d.ts +153 -0
  363. package/dist/workspace/agent-accounts.js +304 -0
  364. package/dist/workspace/agent-accounts.js.map +1 -0
  365. package/dist/workspace/agent-profiles.d.ts +78 -0
  366. package/dist/workspace/agent-profiles.js +115 -0
  367. package/dist/workspace/agent-profiles.js.map +1 -0
  368. package/dist/workspace/config.d.ts +169 -0
  369. package/dist/workspace/config.js +379 -0
  370. package/dist/workspace/config.js.map +1 -0
  371. package/dist/workspace/migrations.d.ts +45 -0
  372. package/dist/workspace/migrations.js +147 -0
  373. package/dist/workspace/migrations.js.map +1 -0
  374. package/dist/workspace/projects-cli.d.ts +25 -0
  375. package/dist/workspace/projects-cli.js +172 -0
  376. package/dist/workspace/projects-cli.js.map +1 -0
  377. package/dist/workspace/projects.d.ts +109 -0
  378. package/dist/workspace/projects.js +250 -0
  379. package/dist/workspace/projects.js.map +1 -0
  380. package/dist/workspace/semaphore.d.ts +179 -0
  381. package/dist/workspace/semaphore.js +195 -0
  382. package/dist/workspace/semaphore.js.map +1 -0
  383. package/dist/workspace/ui-state.d.ts +34 -0
  384. package/dist/workspace/ui-state.js +53 -0
  385. package/dist/workspace/ui-state.js.map +1 -0
  386. package/package.json +70 -0
  387. package/scripts/check-pack.mjs +46 -0
  388. package/scripts/inline-contract.mjs +112 -0
  389. package/scripts/install-as-command.mjs +120 -0
  390. package/scripts/mock-claude.mjs +520 -0
  391. package/scripts/mock-pi-rpc.mjs +83 -0
  392. package/scripts/sync-readme.mjs +20 -0
  393. package/scripts/test-process-usage.mjs +47 -0
  394. package/web/dist/assets/alert-dialog-B4Ofsgv7.js +1 -0
  395. package/web/dist/assets/arrow-down-Dy8dup7j.js +1 -0
  396. package/web/dist/assets/arrow-left-BJaucbhn.js +1 -0
  397. package/web/dist/assets/bundle-mjs-BT31bpU6.js +1 -0
  398. package/web/dist/assets/centered-state-duPW0phQ.js +43 -0
  399. package/web/dist/assets/chevron-right-Be4A5TCS.js +1 -0
  400. package/web/dist/assets/chunk-BO2N2NFS-DE6qKn3r.js +131 -0
  401. package/web/dist/assets/collapsible-DdcNBdSk.js +1 -0
  402. package/web/dist/assets/commit-list-CgvN9vec.js +1 -0
  403. package/web/dist/assets/compare-variants-CQA2nd65.js +1 -0
  404. package/web/dist/assets/core-BCsw8oQw.js +12 -0
  405. package/web/dist/assets/css-BsVw1vtW.js +1 -0
  406. package/web/dist/assets/diff-B6Agp5Hl.js +3 -0
  407. package/web/dist/assets/diff-stat-BoXuGkgq.js +1 -0
  408. package/web/dist/assets/diff-view-CD8XI-fj.js +6 -0
  409. package/web/dist/assets/diff-woXpYk--.js +1 -0
  410. package/web/dist/assets/dropdown-menu-B3SYw-k5.js +1 -0
  411. package/web/dist/assets/editable-title-B-hjp5wl.js +1 -0
  412. package/web/dist/assets/ellipsis-vertical-BYwzw0xl.js +1 -0
  413. package/web/dist/assets/engine-javascript-FQvzRocB.js +141 -0
  414. package/web/dist/assets/file-BRj5eISx.js +1 -0
  415. package/web/dist/assets/folder-z4oT5981.js +1 -0
  416. package/web/dist/assets/git-toolbar-owSEkYld.js +1 -0
  417. package/web/dist/assets/github-Bz2VgRX3.js +1 -0
  418. package/web/dist/assets/go-rLFTqkRN.js +1 -0
  419. package/web/dist/assets/highlighted-body-OFNGDK62-BL-MfFgl.js +1 -0
  420. package/web/dist/assets/highlighter-CdHqIwFr.js +3 -0
  421. package/web/dist/assets/html-BY76lXLH.js +1 -0
  422. package/web/dist/assets/image-preview-h3WFluuy.js +1 -0
  423. package/web/dist/assets/index-BbcQNT92.css +2 -0
  424. package/web/dist/assets/index-EtQQQ6Kj.js +7 -0
  425. package/web/dist/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  426. package/web/dist/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  427. package/web/dist/assets/javascript-BgS3c2Ky.js +1 -0
  428. package/web/dist/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
  429. package/web/dist/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
  430. package/web/dist/assets/json-qhed-kSA.js +1 -0
  431. package/web/dist/assets/jsonc-CYpm1nAK.js +1 -0
  432. package/web/dist/assets/jsx-Bz0zcwM4.js +1 -0
  433. package/web/dist/assets/lib-BQXq3kEf.js +1 -0
  434. package/web/dist/assets/lib-BxQXEXDF.js +1 -0
  435. package/web/dist/assets/markdown-BYOwaDjH.js +1 -0
  436. package/web/dist/assets/markdown-DqBKYPiB.js +2 -0
  437. package/web/dist/assets/mermaid-GHXKKRXX-C4jxqUUb.js +1 -0
  438. package/web/dist/assets/new-task-form-BdJKRBJX.js +1 -0
  439. package/web/dist/assets/pill-BQfmfpYp.js +1 -0
  440. package/web/dist/assets/project-router-DxgFZY1l.js +1 -0
  441. package/web/dist/assets/prompt-templates-B6m16gq-.js +15 -0
  442. package/web/dist/assets/python-gzcpVVnB.js +1 -0
  443. package/web/dist/assets/react-runtime-CCIEwYL0.js +9 -0
  444. package/web/dist/assets/refresh-cw-mhSpxf2a.js +1 -0
  445. package/web/dist/assets/repo-git-CUNRxR3_.js +1 -0
  446. package/web/dist/assets/rolldown-runtime-QTnfLwEv.js +1 -0
  447. package/web/dist/assets/run-diff-DsmmDVfx.js +3 -0
  448. package/web/dist/assets/run-header-BkhrseLJ.js +1 -0
  449. package/web/dist/assets/rust-Cfkwpbl8.js +1 -0
  450. package/web/dist/assets/search-x-BqDMB2g8.js +1 -0
  451. package/web/dist/assets/shellscript-CLZ0U2zV.js +1 -0
  452. package/web/dist/assets/skill-empty-hint-BWEvTggc.js +1 -0
  453. package/web/dist/assets/skills-9oR_oHse.js +1 -0
  454. package/web/dist/assets/skills-DwIxnnWO.js +1 -0
  455. package/web/dist/assets/sparkles-DIoTQpyx.js +1 -0
  456. package/web/dist/assets/sql-BsFa4tDR.js +1 -0
  457. package/web/dist/assets/square-terminal-Cc7CuQxc.js +1 -0
  458. package/web/dist/assets/tab-link-D1fQgpmO.js +1 -0
  459. package/web/dist/assets/task-changes-BKeLlDpK.js +1 -0
  460. package/web/dist/assets/task-commits-gcEFZIa5.js +1 -0
  461. package/web/dist/assets/task-files-BGAqoXTW.js +2 -0
  462. package/web/dist/assets/task-thread-DT8aUYTS.js +9 -0
  463. package/web/dist/assets/textarea-BOVbfy5C.js +1 -0
  464. package/web/dist/assets/thread-loading-CypW73KD.js +1 -0
  465. package/web/dist/assets/toml-CcmNWLt0.js +1 -0
  466. package/web/dist/assets/trash-2-CJq6LHWn.js +1 -0
  467. package/web/dist/assets/triangle-alert-CjDFvU27.js +1 -0
  468. package/web/dist/assets/tsx-udAQXfEw.js +1 -0
  469. package/web/dist/assets/typescript-bsJCZSQ-.js +1 -0
  470. package/web/dist/assets/upload-CPDZlJeK.js +1 -0
  471. package/web/dist/assets/use-desktop-5JsLmi0a.js +1 -0
  472. package/web/dist/assets/use-submit-shortcut-CHVFevty.js +1 -0
  473. package/web/dist/assets/utils-DiO6zyJd.js +64 -0
  474. package/web/dist/assets/workflows-rQDFzWRt.js +11 -0
  475. package/web/dist/assets/yaml-rwi0_p6S.js +1 -0
  476. package/web/dist/assets/zoomable-image-COWqb11v.js +1 -0
  477. package/web/dist/index.html +80 -0
  478. package/web/dist/open-mercato.svg +11 -0
@@ -0,0 +1,800 @@
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: `.ai/analysis/cockpit-ui-redesign/agent-event-protocols.md` §4
9
+ * (wire format: Message/Part model, ToolState lifecycle) and §7.1
10
+ * "OpenCode (SSE)" (the mapping). Golden fixtures replaying wire-faithful
11
+ * bus-event sequences live in `__fixtures__/opencode/`.
12
+ *
13
+ * Robustness rule: input is untrusted wire data — the mapper never throws;
14
+ * unknown event/part types map to zero events.
15
+ *
16
+ * State is explicit and treated as immutable: callers thread the returned
17
+ * `state` into the next call. Ids are deterministic — items reuse the wire
18
+ * part ids, turns get `turn_<n>` minted at each prompt POST — so replaying
19
+ * a stored transcript reproduces the exact event sequence.
20
+ *
21
+ * Opencode-specific mechanics baked in:
22
+ * - text/reasoning parts carry the FULL accumulated text on every update;
23
+ * a per-part cursor diffs it into true `item.delta`s (a server-provided
24
+ * `delta` field wins when present — newer servers send it);
25
+ * - tool parts have the ONLY real `pending` phase of the three backends
26
+ * (`pending→pending`, `running→running`, `completed→completed`,
27
+ * `error→failed`);
28
+ * - the SSE bus is server-wide: parts from a foreign session id are a
29
+ * subtask's child session and nest via `parentItemId` (§7.1). A `subtask`
30
+ * part or a top-level `task` tool call opens a scope: the task tool names
31
+ * its child (`metadata.sessionId`) and binds to it outright, while a
32
+ * scope with no wire link queues and child sessions claim queued scopes
33
+ * first-in-first-out as they are heard from (#5). Closed children are
34
+ * tombstoned for the mapper's lifetime; anything foreign outside a
35
+ * subtask scope is dropped.
36
+ */
37
+ import { toolDisplay } from './tool-display.js';
38
+ export function createOpencodeUiState() {
39
+ return {
40
+ sessionId: null,
41
+ sessionStarted: false,
42
+ turnSeq: 0,
43
+ currentTurnId: null,
44
+ currentTurnMessageIds: new Set(),
45
+ turnErrored: false,
46
+ msgRoles: new Map(),
47
+ cursors: new Map(),
48
+ startedItems: new Set(),
49
+ endedItems: new Set(),
50
+ tools: new Map(),
51
+ lastPlanJson: null,
52
+ subtasks: new Map(),
53
+ unboundSubtasks: [],
54
+ closedSessions: new Set(),
55
+ usageByMessage: new Map(),
56
+ lastUsage: null,
57
+ };
58
+ }
59
+ /**
60
+ * Opencode has no wire-level session-start event — the session is created by
61
+ * the runner's `POST /session`, so the runner calls this once the response
62
+ * carries the id (like codex's out-of-band thread/start result).
63
+ */
64
+ export function opencodeSessionStarted(sessionId, state) {
65
+ if (state.sessionStarted || sessionId === '')
66
+ return { events: [], state };
67
+ return {
68
+ events: [{ type: 'session.started', sessionId, backend: 'opencode' }],
69
+ state: { ...state, sessionId, sessionStarted: true },
70
+ };
71
+ }
72
+ /**
73
+ * Opencode has no wire-level turn-start either — the runner POSTing a prompt
74
+ * IS the turn boundary, so the runner calls this on each prompt POST. The
75
+ * matching `turn.completed` comes from the wire `session.idle` (never from
76
+ * the HTTP prompt response — that is v1's known fidelity gap).
77
+ */
78
+ export function opencodeTurnStarted(state) {
79
+ const turnId = `turn_${state.turnSeq + 1}`;
80
+ return {
81
+ events: [{ type: 'turn.started', turnId }],
82
+ state: {
83
+ ...state,
84
+ turnSeq: state.turnSeq + 1,
85
+ currentTurnId: turnId,
86
+ currentTurnMessageIds: new Set(),
87
+ turnErrored: false,
88
+ },
89
+ };
90
+ }
91
+ /** Fold one parsed SSE bus event into v2 events. Never throws. */
92
+ export function mapOpencodeEvent(evt, state) {
93
+ if (!isRecord(evt) || typeof evt.type !== 'string')
94
+ return { events: [], state };
95
+ const props = isRecord(evt.properties) ? evt.properties : {};
96
+ switch (evt.type) {
97
+ case 'message.updated':
98
+ case 'message.created':
99
+ case 'message.completed':
100
+ return mapMessageInfo(props, state);
101
+ case 'message.part.updated':
102
+ case 'message.part.created':
103
+ return mapPart(props, state);
104
+ case 'session.idle':
105
+ return mapIdle(props, state);
106
+ case 'session.error':
107
+ return mapSessionError(props, state);
108
+ default:
109
+ // server.connected, session.updated, message.part.removed,
110
+ // permission.* (reserved for the permission.* events later), …
111
+ return { events: [], state };
112
+ }
113
+ }
114
+ // ---- message info → roles + usage.updated -----------------------------------
115
+ function mapMessageInfo(props, state) {
116
+ const info = isRecord(props.info) ? props.info : props;
117
+ const id = str(info.id);
118
+ const role = str(info.role);
119
+ let next = state;
120
+ const messageSession = str(info.sessionID);
121
+ const foreign = messageSession !== undefined && state.sessionId !== null && messageSession !== state.sessionId;
122
+ if (foreign && messageSession !== undefined) {
123
+ next = resolveSubtask(messageSession, next).state;
124
+ }
125
+ if (id !== undefined && role !== undefined && state.msgRoles.get(id) !== role) {
126
+ const msgRoles = new Map(state.msgRoles);
127
+ msgRoles.set(id, role);
128
+ next = { ...next, msgRoles };
129
+ }
130
+ if (id !== undefined && role === 'assistant' && next.currentTurnId !== null && !next.currentTurnMessageIds.has(id)) {
131
+ next = { ...next, currentTurnMessageIds: new Set(next.currentTurnMessageIds).add(id) };
132
+ }
133
+ // Telemetry rides only on assistant messages (cumulative per message).
134
+ if (id !== undefined && role === 'assistant') {
135
+ const usage = tokensToUsage(info.tokens);
136
+ const cost = num(info.cost);
137
+ if (usage || cost !== undefined) {
138
+ const prev = next.usageByMessage.get(id) ?? EMPTY_MESSAGE_USAGE;
139
+ const merged = {
140
+ // Monotonic guard: a stale/zero snapshot never shrinks the record.
141
+ info: usage && (prev.info === null || usage.total >= prev.info.total) ? usage : prev.info,
142
+ infoCost: maxCost(prev.infoCost, cost),
143
+ steps: prev.steps,
144
+ stepsCost: prev.stepsCost,
145
+ };
146
+ const usageByMessage = new Map(next.usageByMessage);
147
+ usageByMessage.set(id, merged);
148
+ return emitUsage({ ...next, usageByMessage });
149
+ }
150
+ }
151
+ return { events: [], state: next };
152
+ }
153
+ // ---- parts -------------------------------------------------------------------
154
+ function mapPart(props, state) {
155
+ const part = isRecord(props.part) ? props.part : props;
156
+ const type = str(part.type);
157
+ const messageID = str(part.messageID);
158
+ const id = str(part.id) ?? messageID;
159
+ if (type === undefined || id === undefined)
160
+ return { events: [], state };
161
+ // Foreign-session parts nest only under the subtask bound to that child
162
+ // session. A newly seen child claims the oldest pending subtask; with none
163
+ // pending the part has no home, so the event is dropped.
164
+ const partSession = str(part.sessionID);
165
+ const foreign = partSession !== undefined && state.sessionId !== null && partSession !== state.sessionId;
166
+ const resolved = foreign && partSession !== undefined ? resolveSubtask(partSession, state) : undefined;
167
+ if (foreign && resolved?.subtask === undefined)
168
+ return { events: [], state };
169
+ state = resolved?.state ?? state;
170
+ const parentItemId = resolved?.subtask?.id;
171
+ // Only assistant parts surface — the user's own prompt streams as parts
172
+ // over the same feed. Role is known early (message.updated precedes its
173
+ // parts); an unknown role means "not assistant yet" → skip.
174
+ if (messageID !== undefined && state.msgRoles.get(messageID) !== 'assistant') {
175
+ return { events: [], state };
176
+ }
177
+ switch (type) {
178
+ case 'text':
179
+ return mapTextLike(part, id, 'text', props.delta, parentItemId, state);
180
+ case 'reasoning':
181
+ return mapTextLike(part, id, 'reasoning', props.delta, parentItemId, state);
182
+ case 'tool':
183
+ return mapTool(part, id, parentItemId, state);
184
+ case 'patch':
185
+ return mapPatch(part, id, parentItemId, state);
186
+ case 'subtask':
187
+ return mapSubtask(part, id, parentItemId, state);
188
+ case 'step-finish':
189
+ return mapStepFinish(part, messageID, state);
190
+ default:
191
+ // file, snapshot, step-start, agent, retry, compaction, … — nothing to
192
+ // render yet.
193
+ return { events: [], state };
194
+ }
195
+ }
196
+ /** Text/reasoning parts carry the FULL accumulated text each update — the
197
+ * cursor diffs it into true deltas; a server-sent `delta` wins when present.
198
+ * `time.end` marks the part finished → `item.completed` (once). */
199
+ function mapTextLike(part, id, field, serverDelta, parentItemId, state) {
200
+ const full = typeof part.text === 'string' ? part.text : '';
201
+ const events = [];
202
+ let startedItems = state.startedItems;
203
+ let cursors = state.cursors;
204
+ let endedItems = state.endedItems;
205
+ const makeItem = (text) => {
206
+ const item = field === 'text'
207
+ ? { kind: 'message', id, role: 'assistant', text }
208
+ : { kind: 'reasoning', id, text };
209
+ if (parentItemId !== undefined)
210
+ item.parentItemId = parentItemId;
211
+ return item;
212
+ };
213
+ if (!startedItems.has(id)) {
214
+ events.push({ type: 'item.started', item: makeItem('') });
215
+ startedItems = new Set(startedItems).add(id);
216
+ }
217
+ const cursor = cursors.get(id) ?? 0;
218
+ const winning = str(serverDelta);
219
+ let delta;
220
+ let nextCursor = cursor;
221
+ if (winning !== undefined) {
222
+ delta = winning;
223
+ // Keep the cursor consistent with the accumulated text so a later
224
+ // full-text-only update doesn't re-emit what the server delta covered.
225
+ nextCursor = Math.max(cursor + winning.length, full.length);
226
+ }
227
+ else if (full.length > cursor) {
228
+ delta = full.slice(cursor);
229
+ nextCursor = full.length;
230
+ }
231
+ if (delta !== undefined) {
232
+ events.push({ type: 'item.delta', itemId: id, field, delta });
233
+ const nextCursors = new Map(cursors);
234
+ nextCursors.set(id, nextCursor);
235
+ cursors = nextCursors;
236
+ }
237
+ const time = isRecord(part.time) ? part.time : undefined;
238
+ if (time && num(time.end) !== undefined && !endedItems.has(id)) {
239
+ events.push({ type: 'item.completed', item: makeItem(full) });
240
+ endedItems = new Set(endedItems).add(id);
241
+ }
242
+ if (events.length === 0)
243
+ return { events, state };
244
+ return { events, state: { ...state, startedItems, cursors, endedItems } };
245
+ }
246
+ /** The §7.1 direct status map — opencode is the only backend with a real
247
+ * pending phase, and its `error` state is v2's `failed`. */
248
+ const STATUS_MAP = {
249
+ pending: 'pending',
250
+ running: 'running',
251
+ completed: 'completed',
252
+ error: 'failed',
253
+ };
254
+ function mapTool(part, id, parentItemId, state) {
255
+ const name = str(part.tool) ?? str(part.name) ?? 'tool';
256
+ const toolState = isRecord(part.state) ? part.state : {};
257
+ const prev = state.tools.get(id);
258
+ const mapped = typeof toolState.status === 'string' ? STATUS_MAP[toolState.status] : undefined;
259
+ const status = mapped ?? prev?.status ?? 'pending';
260
+ const display = toolDisplay(name, toolState.input);
261
+ // The running/completed states carry a live human title ("npm test") — the
262
+ // wire word wins over the derived one (§7.1). The error state has no title
263
+ // field (§4.2), so the last LIVE title carries over instead of regressing.
264
+ // A derived title is re-derived: the pending snapshot's input is often `{}`
265
+ // (arguments still parsing), and "Task" must become "Task: Dig in" once
266
+ // the running snapshot brings the description.
267
+ const wireTitle = str(toolState.title);
268
+ const title = wireTitle ?? (prev?.live ? prev.title : display.title);
269
+ const live = wireTitle !== undefined || (prev?.live ?? false);
270
+ const item = { kind: 'tool', id, name, toolKind: display.toolKind, title, status };
271
+ if (toolState.input !== undefined)
272
+ item.input = toolState.input;
273
+ if (status === 'completed') {
274
+ const output = str(toolState.output);
275
+ if (output !== undefined)
276
+ item.output = output;
277
+ }
278
+ if (status === 'failed') {
279
+ const error = errorText(toolState.error);
280
+ if (error !== undefined)
281
+ item.error = error;
282
+ }
283
+ const metadata = isRecord(toolState.metadata) ? toolState.metadata : undefined;
284
+ const exitCode = metadata ? num(metadata.exit) : undefined;
285
+ if (exitCode !== undefined)
286
+ item.exitCode = exitCode;
287
+ if (parentItemId !== undefined)
288
+ item.parentItemId = parentItemId;
289
+ const events = [];
290
+ const settled = status === 'completed' || status === 'failed';
291
+ if (prev === undefined) {
292
+ // First sight — a part already settled is a lone final snapshot
293
+ // (consumers upsert by id, so it renders fine).
294
+ events.push({ type: settled ? 'item.completed' : 'item.started', item });
295
+ }
296
+ else if (prev.status !== status) {
297
+ events.push({ type: settled ? 'item.completed' : 'item.updated', item });
298
+ }
299
+ else if (prev.title !== title && !settled) {
300
+ // Same state, new live title (running-state metadata updates).
301
+ events.push({ type: 'item.updated', item });
302
+ }
303
+ let next = state;
304
+ if (events.length > 0) {
305
+ const tools = new Map(state.tools);
306
+ tools.set(id, { status, title, live });
307
+ next = { ...next, tools };
308
+ }
309
+ // A task tool call spawns a child session exactly like a `subtask` part
310
+ // does (#5). When the snapshot names that child (`metadata.sessionId`,
311
+ // published as soon as the child exists) the scope binds to it outright;
312
+ // otherwise it queues for the next child session heard from. A task issued
313
+ // from inside a child session opens a scope of its own, nested under the
314
+ // outer one, so its grandchild's output has a home too.
315
+ if (isSubtaskTool(name)) {
316
+ const childSession = metadata ? (str(metadata.sessionId) ?? str(metadata.sessionID)) : undefined;
317
+ const scope = {
318
+ id,
319
+ name,
320
+ title,
321
+ ...(item.input !== undefined ? { input: item.input } : {}),
322
+ ...(childSession !== undefined ? { childSession } : {}),
323
+ ...(parentItemId !== undefined ? { parentItemId } : {}),
324
+ };
325
+ if (!settled) {
326
+ // OpenCode publishes the part before its arguments finish parsing, so
327
+ // the first snapshot is often `{}` and later ones fill the input in —
328
+ // sometimes without moving the status or the derived title, i.e. with
329
+ // no item event. The scope follows every snapshot regardless, or the
330
+ // child's idle would complete it with stale metadata.
331
+ next = prev === undefined ? { ...next, unboundSubtasks: [...next.unboundSubtasks, scope] } : refreshScope(scope, next);
332
+ if (childSession !== undefined)
333
+ next = bindScope(scope, childSession, next);
334
+ }
335
+ else if (events.length > 0) {
336
+ // The tool's own settlement is authoritative (it carries the output), so
337
+ // its scope is released: a later child idle must not re-complete it. A
338
+ // child the wire named is closed too, even one that never spoke —
339
+ // otherwise its late first event would take a sibling's scope.
340
+ next = releaseScope(id, childSession, next);
341
+ }
342
+ }
343
+ // todowrite IS the plan (full-replacement semantics, deduplicated).
344
+ if (name.toLowerCase() === 'todowrite') {
345
+ const entries = planEntriesOf(toolState.input);
346
+ if (entries) {
347
+ const json = JSON.stringify(entries);
348
+ if (json !== next.lastPlanJson) {
349
+ events.push({ type: 'plan.updated', entries });
350
+ next = { ...next, lastPlanJson: json };
351
+ }
352
+ }
353
+ }
354
+ if (events.length === 0 && next === state)
355
+ return { events, state };
356
+ return { events, state: next };
357
+ }
358
+ /**
359
+ * todowrite input `{todos:[{content,status,priority}]}` → plan entries
360
+ * (an empty list is a valid plan; malformed rows are filtered).
361
+ *
362
+ * `status` is a free-form string upstream (`Schema.String`, not an enum) — its
363
+ * documented vocabulary is pending|in_progress|completed|cancelled. Rows with
364
+ * an unrecognized status fall back to `pending` rather than being dropped: a
365
+ * todo the agent wrote must stay on screen, and dropping it silently shrinks
366
+ * the plan mid-run for no visible reason.
367
+ *
368
+ * A `pending` tool part carries `input: {}` (opencode publishes the part before
369
+ * the arguments finish parsing), which lands on the `!Array.isArray` guard and
370
+ * maps to zero events — so a streaming part cannot clobber a good plan.
371
+ */
372
+ function planEntriesOf(input) {
373
+ if (!isRecord(input) || !Array.isArray(input.todos))
374
+ return undefined;
375
+ const entries = [];
376
+ for (const todo of input.todos) {
377
+ if (!isRecord(todo) || typeof todo.content !== 'string')
378
+ continue;
379
+ const status = PLAN_STATUSES.find((s) => s === todo.status) ?? 'pending';
380
+ const entry = { content: todo.content, status };
381
+ if (todo.priority === 'high' || todo.priority === 'medium' || todo.priority === 'low') {
382
+ entry.priority = todo.priority;
383
+ }
384
+ entries.push(entry);
385
+ }
386
+ return entries;
387
+ }
388
+ const PLAN_STATUSES = ['pending', 'in_progress', 'completed', 'cancelled'];
389
+ /** `patch` parts snapshot applied file changes → a completed edit-tool item
390
+ * carrying `diffs` (unified when the wire includes content; the older
391
+ * paths-only shape still yields per-file entries + locations). */
392
+ function mapPatch(part, id, parentItemId, state) {
393
+ if (state.endedItems.has(id))
394
+ return { events: [], state };
395
+ const artifacts = patchArtifacts(part.files);
396
+ if (!artifacts)
397
+ return { events: [], state };
398
+ const { diffs, locations } = artifacts;
399
+ const label = locations.length === 1 ? locations[0]?.path : locations.length > 1 ? `${locations.length} files` : undefined;
400
+ const item = {
401
+ kind: 'tool',
402
+ id,
403
+ name: 'patch',
404
+ toolKind: 'edit',
405
+ title: label !== undefined ? `Edit ${label}` : 'Edit',
406
+ status: 'completed',
407
+ diffs,
408
+ locations,
409
+ };
410
+ if (parentItemId !== undefined)
411
+ item.parentItemId = parentItemId;
412
+ return {
413
+ events: [{ type: 'item.completed', item }],
414
+ state: { ...state, endedItems: new Set(state.endedItems).add(id) },
415
+ };
416
+ }
417
+ /** `files` as `{path: unifiedDiff}` record (or `[{path, diff}]`) carries the
418
+ * content; the paths-only `string[]` shape still yields diff entries.
419
+ * Opencode sends unified diffs only — old text is unknown, never "empty". */
420
+ function patchArtifacts(files) {
421
+ const diffs = [];
422
+ const push = (path, unified) => {
423
+ const diff = { path, oldText: null };
424
+ if (unified !== undefined)
425
+ diff.unified = unified;
426
+ diffs.push(diff);
427
+ };
428
+ if (Array.isArray(files)) {
429
+ for (const entry of files) {
430
+ if (typeof entry === 'string' && entry !== '')
431
+ push(entry);
432
+ else if (isRecord(entry)) {
433
+ const path = str(entry.path) ?? str(entry.file) ?? str(entry.filename);
434
+ if (path !== undefined)
435
+ push(path, str(entry.diff) ?? str(entry.patch));
436
+ }
437
+ }
438
+ }
439
+ else if (isRecord(files)) {
440
+ for (const [path, value] of Object.entries(files)) {
441
+ if (path === '')
442
+ continue;
443
+ if (typeof value === 'string')
444
+ push(path, str(value));
445
+ else if (isRecord(value))
446
+ push(path, str(value.diff) ?? str(value.patch));
447
+ else
448
+ push(path);
449
+ }
450
+ }
451
+ if (diffs.length === 0)
452
+ return undefined;
453
+ return { diffs, locations: diffs.map((d) => ({ path: d.path })) };
454
+ }
455
+ /** `subtask` parts spawn a child session → a task-kind tool item whose id
456
+ * scopes subsequent foreign-session items via `parentItemId` (§7.1); the
457
+ * child's `session.idle` completes it. */
458
+ function mapSubtask(part, id, parentItemId, state) {
459
+ if (state.startedItems.has(id))
460
+ return { events: [], state };
461
+ const description = str(part.description);
462
+ const display = toolDisplay('task', { description });
463
+ const item = {
464
+ kind: 'tool',
465
+ id,
466
+ name: 'subtask',
467
+ toolKind: display.toolKind,
468
+ title: display.title,
469
+ status: 'running',
470
+ };
471
+ const input = {};
472
+ if (str(part.prompt) !== undefined)
473
+ input.prompt = part.prompt;
474
+ if (description !== undefined)
475
+ input.description = description;
476
+ if (str(part.agent) !== undefined)
477
+ input.agent = part.agent;
478
+ if (Object.keys(input).length > 0)
479
+ item.input = input;
480
+ if (parentItemId !== undefined)
481
+ item.parentItemId = parentItemId;
482
+ const scope = {
483
+ id,
484
+ name: item.name,
485
+ title: item.title,
486
+ ...(item.input !== undefined ? { input: item.input } : {}),
487
+ ...(parentItemId !== undefined ? { parentItemId } : {}),
488
+ };
489
+ return {
490
+ events: [{ type: 'item.started', item }],
491
+ state: {
492
+ ...state,
493
+ startedItems: new Set(state.startedItems).add(id),
494
+ unboundSubtasks: [...state.unboundSubtasks, scope],
495
+ },
496
+ };
497
+ }
498
+ /** `step-finish` parts carry per-LLM-round-trip cost + tokens → summed as
499
+ * usage increments (the larger of this sum and the `message.updated`
500
+ * snapshot wins per message — see `MessageUsage`). */
501
+ function mapStepFinish(part, messageID, state) {
502
+ if (messageID === undefined)
503
+ return { events: [], state };
504
+ const tokens = tokensToUsage(part.tokens);
505
+ const cost = num(part.cost);
506
+ if (!tokens && cost === undefined)
507
+ return { events: [], state };
508
+ const prev = state.usageByMessage.get(messageID) ?? EMPTY_MESSAGE_USAGE;
509
+ const merged = {
510
+ info: prev.info,
511
+ infoCost: prev.infoCost,
512
+ steps: tokens ? addUsage(prev.steps, tokens) : prev.steps,
513
+ stepsCost: cost !== undefined ? (prev.stepsCost ?? 0) + cost : prev.stepsCost,
514
+ };
515
+ const usageByMessage = new Map(state.usageByMessage);
516
+ usageByMessage.set(messageID, merged);
517
+ const currentTurnMessageIds = state.currentTurnId !== null
518
+ ? new Set(state.currentTurnMessageIds).add(messageID)
519
+ : state.currentTurnMessageIds;
520
+ return emitUsage({ ...state, usageByMessage, currentTurnMessageIds });
521
+ }
522
+ /** Replace the scope owned by `scope.id`, bound or still pending, with the
523
+ * latest snapshot of its title and input. */
524
+ function refreshScope(scope, state) {
525
+ let changed = false;
526
+ const unboundSubtasks = state.unboundSubtasks.map((s) => {
527
+ if (s.id !== scope.id || sameScope(s, scope))
528
+ return s;
529
+ changed = true;
530
+ return scope;
531
+ });
532
+ const subtasks = new Map(state.subtasks);
533
+ for (const [sessionId, s] of state.subtasks) {
534
+ if (s.id !== scope.id || sameScope(s, scope))
535
+ continue;
536
+ subtasks.set(sessionId, scope);
537
+ changed = true;
538
+ }
539
+ return changed ? { ...state, subtasks, unboundSubtasks } : state;
540
+ }
541
+ function sameScope(a, b) {
542
+ return (a.name === b.name &&
543
+ a.title === b.title &&
544
+ a.childSession === b.childSession &&
545
+ a.parentItemId === b.parentItemId &&
546
+ JSON.stringify(a.input) === JSON.stringify(b.input));
547
+ }
548
+ /** Bind `scope` to the child session the wire named for it: out of the
549
+ * pending queue and into the session map. A scope FIFO had already guessed
550
+ * onto that session goes back to the head of the queue — the wire outranks
551
+ * the guess, and that scope's real child is still to be heard from. */
552
+ function bindScope(scope, childSession, state) {
553
+ if (state.closedSessions.has(childSession))
554
+ return releaseScope(scope.id, undefined, state);
555
+ const current = state.subtasks.get(childSession);
556
+ if (current?.id === scope.id && !state.unboundSubtasks.some((s) => s.id === scope.id))
557
+ return state;
558
+ const unboundSubtasks = state.unboundSubtasks.filter((s) => s.id !== scope.id);
559
+ if (current !== undefined && current.id !== scope.id)
560
+ unboundSubtasks.unshift(current);
561
+ const subtasks = new Map(state.subtasks);
562
+ for (const [sessionId, s] of state.subtasks)
563
+ if (s.id === scope.id && sessionId !== childSession)
564
+ subtasks.delete(sessionId);
565
+ subtasks.set(childSession, scope);
566
+ return { ...state, subtasks, unboundSubtasks };
567
+ }
568
+ /** Drop the scope owned by item `id`, bound or still pending, closing every
569
+ * child session it was bound to plus the one the wire named (if any). */
570
+ function releaseScope(id, childSession, state) {
571
+ const pending = state.unboundSubtasks.filter((scope) => scope.id !== id);
572
+ const bound = [...state.subtasks].filter(([, scope]) => scope.id === id);
573
+ const named = childSession ?? state.unboundSubtasks.find((scope) => scope.id === id)?.childSession;
574
+ const closeNamed = named !== undefined && !state.closedSessions.has(named);
575
+ if (pending.length === state.unboundSubtasks.length && bound.length === 0 && !closeNamed)
576
+ return state;
577
+ const subtasks = new Map(state.subtasks);
578
+ const closedSessions = new Set(state.closedSessions);
579
+ for (const [sessionId] of bound) {
580
+ subtasks.delete(sessionId);
581
+ closedSessions.add(sessionId);
582
+ }
583
+ if (named !== undefined)
584
+ closedSessions.add(named);
585
+ return { ...state, subtasks, unboundSubtasks: pending, closedSessions };
586
+ }
587
+ function isSubtaskTool(name) {
588
+ const lower = name.toLowerCase();
589
+ return lower === 'task' || lower === 'subtask';
590
+ }
591
+ // ---- session lifecycle -------------------------------------------------------
592
+ /** `session.idle` is THE turn-end signal (§4.1). The main session's idle
593
+ * closes the current turn; a foreign idle is the subtask's child session
594
+ * going quiet → the subtask item completes. */
595
+ function mapIdle(props, state) {
596
+ const sid = str(props.sessionID);
597
+ const isMain = sid === undefined || state.sessionId === null || sid === state.sessionId;
598
+ if (!isMain) {
599
+ if (sid === undefined)
600
+ return { events: [], state };
601
+ const resolved = resolveSubtask(sid, state);
602
+ if (resolved.subtask === undefined)
603
+ return { events: [], state };
604
+ const subtasks = new Map(resolved.state.subtasks);
605
+ subtasks.delete(sid);
606
+ return {
607
+ events: [{ type: 'item.completed', item: completedSubtask(resolved.subtask) }],
608
+ state: { ...resolved.state, subtasks, closedSessions: new Set(resolved.state.closedSessions).add(sid) },
609
+ };
610
+ }
611
+ // Idle with no turn in flight (or a repeated idle) closes nothing.
612
+ if (state.currentTurnId === null)
613
+ return { events: [], state };
614
+ const openSubtasks = [...state.subtasks.values(), ...state.unboundSubtasks];
615
+ const completed = {
616
+ type: 'turn.completed',
617
+ turnId: state.currentTurnId,
618
+ stopReason: state.turnErrored ? 'error' : 'end_turn',
619
+ };
620
+ const turnUsage = usageForMessages(state.currentTurnMessageIds, state.usageByMessage);
621
+ if (turnUsage.usage !== null)
622
+ completed.usage = turnUsage.usage;
623
+ if (turnUsage.cost !== null)
624
+ completed.costUsd = turnUsage.cost;
625
+ return {
626
+ events: [
627
+ ...openSubtasks.map((subtask) => ({ type: 'item.completed', item: completedSubtask(subtask) })),
628
+ completed,
629
+ ],
630
+ state: {
631
+ ...state,
632
+ currentTurnId: null,
633
+ currentTurnMessageIds: new Set(),
634
+ turnErrored: false,
635
+ subtasks: new Map(),
636
+ unboundSubtasks: [],
637
+ // Children the turn settled are over too: a delayed event from one must
638
+ // not bind to a scope the NEXT turn queues.
639
+ closedSessions: new Set([...state.closedSessions, ...state.subtasks.keys()]),
640
+ },
641
+ };
642
+ }
643
+ /** `session.error` → non-fatal `session.error` (the mapper can't know the
644
+ * session died — the runner owns fatality) + the turn closes as 'error'. */
645
+ function mapSessionError(props, state) {
646
+ const sid = str(props.sessionID);
647
+ const foreign = sid !== undefined && state.sessionId !== null && sid !== state.sessionId;
648
+ const resolved = foreign && sid !== undefined ? resolveSubtask(sid, state) : undefined;
649
+ if (foreign && resolved?.subtask === undefined)
650
+ return { events: [], state };
651
+ state = resolved?.state ?? state;
652
+ const message = errorText(props.error) ?? 'opencode session error';
653
+ return {
654
+ events: [{ type: 'session.error', message, fatal: false }],
655
+ state: { ...state, turnErrored: state.currentTurnId !== null ? true : state.turnErrored },
656
+ };
657
+ }
658
+ function resolveSubtask(sessionId, state) {
659
+ const existing = state.subtasks.get(sessionId);
660
+ if (existing !== undefined)
661
+ return { state, subtask: existing };
662
+ // A closed child's late events have no home — never a sibling's scope.
663
+ if (state.closedSessions.has(sessionId))
664
+ return { state };
665
+ // First-in-first-out: the oldest pending subtask claims this child session
666
+ // and the rest stay queued for the children still to come (#5).
667
+ const [subtask, ...rest] = state.unboundSubtasks;
668
+ if (subtask === undefined)
669
+ return { state };
670
+ const subtasks = new Map(state.subtasks);
671
+ subtasks.set(sessionId, subtask);
672
+ return { state: { ...state, subtasks, unboundSubtasks: rest }, subtask };
673
+ }
674
+ function completedSubtask(subtask) {
675
+ const item = {
676
+ kind: 'tool',
677
+ id: subtask.id,
678
+ name: subtask.name,
679
+ toolKind: 'task',
680
+ title: subtask.title,
681
+ status: 'completed',
682
+ };
683
+ if (subtask.input !== undefined)
684
+ item.input = subtask.input;
685
+ if (subtask.parentItemId !== undefined)
686
+ item.parentItemId = subtask.parentItemId;
687
+ return item;
688
+ }
689
+ // ---- telemetry ----------------------------------------------------------------
690
+ const EMPTY_MESSAGE_USAGE = { info: null, infoCost: null, steps: null, stepsCost: null };
691
+ /** `{input, output, reasoning, cache:{read,write}}` → raw TokenUsage
692
+ * (opencode reports no total — the sum of the parts is the total). */
693
+ function tokensToUsage(tokens) {
694
+ if (!isRecord(tokens))
695
+ return undefined;
696
+ const input = num(tokens.input) ?? 0;
697
+ const output = num(tokens.output) ?? 0;
698
+ const reasoning = num(tokens.reasoning);
699
+ const cache = isRecord(tokens.cache) ? tokens.cache : undefined;
700
+ const cacheRead = cache ? num(cache.read) : undefined;
701
+ const cacheWrite = cache ? num(cache.write) : undefined;
702
+ const usage = {
703
+ input,
704
+ output,
705
+ total: input + output + (reasoning ?? 0) + (cacheRead ?? 0) + (cacheWrite ?? 0),
706
+ };
707
+ if (cacheRead !== undefined)
708
+ usage.cacheRead = cacheRead;
709
+ if (cacheWrite !== undefined)
710
+ usage.cacheWrite = cacheWrite;
711
+ if (reasoning !== undefined)
712
+ usage.reasoning = reasoning;
713
+ return usage;
714
+ }
715
+ function addUsage(a, b) {
716
+ if (a === null)
717
+ return b;
718
+ const sum = { input: a.input + b.input, output: a.output + b.output, total: a.total + b.total };
719
+ const cacheRead = optSum(a.cacheRead, b.cacheRead);
720
+ if (cacheRead !== undefined)
721
+ sum.cacheRead = cacheRead;
722
+ const cacheWrite = optSum(a.cacheWrite, b.cacheWrite);
723
+ if (cacheWrite !== undefined)
724
+ sum.cacheWrite = cacheWrite;
725
+ const reasoning = optSum(a.reasoning, b.reasoning);
726
+ if (reasoning !== undefined)
727
+ sum.reasoning = reasoning;
728
+ return sum;
729
+ }
730
+ function optSum(a, b) {
731
+ if (a === undefined && b === undefined)
732
+ return undefined;
733
+ return (a ?? 0) + (b ?? 0);
734
+ }
735
+ function maxCost(a, b) {
736
+ if (b === undefined)
737
+ return a;
738
+ return a === null ? b : Math.max(a, b);
739
+ }
740
+ /** Session totals = per-message effective usage summed across messages;
741
+ * emitted only when the snapshot actually changed and is non-zero. */
742
+ function emitUsage(state) {
743
+ let usage = { input: 0, output: 0, total: 0 };
744
+ let cost = null;
745
+ for (const mu of state.usageByMessage.values()) {
746
+ const effective = mu.info !== null && (mu.steps === null || mu.info.total >= mu.steps.total) ? mu.info : mu.steps;
747
+ if (effective !== null)
748
+ usage = addUsage(usage, effective);
749
+ const effCost = maxCost(mu.infoCost, mu.stepsCost ?? undefined);
750
+ if (effCost !== null)
751
+ cost = (cost ?? 0) + effCost;
752
+ }
753
+ if (usage.total === 0 && (cost === null || cost === 0))
754
+ return { events: [], state };
755
+ if (state.lastUsage !== null && state.lastUsage.total === usage.total && state.lastUsage.cost === cost) {
756
+ return { events: [], state };
757
+ }
758
+ const event = { type: 'usage.updated', usage };
759
+ if (cost !== null)
760
+ event.costUsd = cost;
761
+ return { events: [event], state: { ...state, lastUsage: { total: usage.total, cost } } };
762
+ }
763
+ function usageForMessages(messageIds, usageByMessage) {
764
+ let usage = null;
765
+ let cost = null;
766
+ for (const id of messageIds) {
767
+ const message = usageByMessage.get(id);
768
+ if (message === undefined)
769
+ continue;
770
+ const effective = message.info !== null && (message.steps === null || message.info.total >= message.steps.total)
771
+ ? message.info
772
+ : message.steps;
773
+ if (effective !== null && (effective.input > 0 || effective.output > 0))
774
+ usage = addUsage(usage, effective);
775
+ const effectiveCost = maxCost(message.infoCost, message.stepsCost ?? undefined);
776
+ if (effectiveCost !== null && effectiveCost > 0)
777
+ cost = (cost ?? 0) + effectiveCost;
778
+ }
779
+ return { usage, cost };
780
+ }
781
+ // ---- tiny guards ---------------------------------------------------------------
782
+ function isRecord(value) {
783
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
784
+ }
785
+ function str(value) {
786
+ return typeof value === 'string' && value !== '' ? value : undefined;
787
+ }
788
+ function num(value) {
789
+ return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
790
+ }
791
+ /** Opencode error objects are `{name, data:{message}}` (or plain strings). */
792
+ function errorText(error) {
793
+ if (typeof error === 'string')
794
+ return str(error);
795
+ if (!isRecord(error))
796
+ return undefined;
797
+ const data = isRecord(error.data) ? error.data : undefined;
798
+ return str(error.message) ?? (data && str(data.message)) ?? str(error.name);
799
+ }
800
+ //# sourceMappingURL=opencode-ui-mapper.js.map