@open-mercato/cezar 0.13.0 → 0.14.0

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 (294) hide show
  1. package/README.md +3 -2
  2. package/dist/agent-config/catalog.d.ts +4 -0
  3. package/dist/agent-config/catalog.js +85 -3
  4. package/dist/agent-config/catalog.js.map +1 -1
  5. package/dist/agent-config/model-settings/copilot.d.ts +15 -0
  6. package/dist/agent-config/model-settings/copilot.js +25 -0
  7. package/dist/agent-config/model-settings/copilot.js.map +1 -0
  8. package/dist/agent-config/model-settings/junie.d.ts +12 -0
  9. package/dist/agent-config/model-settings/junie.js +18 -0
  10. package/dist/agent-config/model-settings/junie.js.map +1 -0
  11. package/dist/agent-config/models.js +4 -0
  12. package/dist/agent-config/models.js.map +1 -1
  13. package/dist/automations/prompts.d.ts +2 -2
  14. package/dist/automations/prompts.js +1 -1
  15. package/dist/automations/types.d.ts +12 -0
  16. package/dist/config.d.ts +4 -0
  17. package/dist/config.js +2 -0
  18. package/dist/config.js.map +1 -1
  19. package/dist/contract/agent-config.d.ts +4 -0
  20. package/dist/contract/agent-profiles.d.ts +30 -0
  21. package/dist/contract/automations.d.ts +32 -0
  22. package/dist/contract/dashboard-insights.d.ts +186 -0
  23. package/dist/contract/dashboard.d.ts +88 -0
  24. package/dist/contract/dispatch.d.ts +6 -0
  25. package/dist/contract/health.d.ts +8 -0
  26. package/dist/contract/index.d.ts +2 -0
  27. package/dist/contract/index.js +249 -72
  28. package/dist/contract/runs.d.ts +144 -0
  29. package/dist/contract/self-update.d.ts +111 -2
  30. package/dist/contract/skills.d.ts +19 -0
  31. package/dist/contract/star-count.d.ts +18 -0
  32. package/dist/contract/workflows.d.ts +12 -0
  33. package/dist/contract/workspace.d.ts +42 -2
  34. package/dist/core/acp-client.d.ts +99 -0
  35. package/dist/core/acp-client.js +198 -0
  36. package/dist/core/acp-client.js.map +1 -0
  37. package/dist/core/acp-ui-mapper.d.ts +95 -0
  38. package/dist/core/acp-ui-mapper.js +444 -0
  39. package/dist/core/acp-ui-mapper.js.map +1 -0
  40. package/dist/core/agent-env.js +10 -0
  41. package/dist/core/agent-env.js.map +1 -1
  42. package/dist/core/agent-profiles.d.ts +10 -0
  43. package/dist/core/agent-profiles.js +16 -0
  44. package/dist/core/agent-profiles.js.map +1 -1
  45. package/dist/core/agent-runner.d.ts +5 -3
  46. package/dist/core/agent-runner.js +5 -3
  47. package/dist/core/agent-runner.js.map +1 -1
  48. package/dist/core/backend-detect.d.ts +3 -3
  49. package/dist/core/backend-detect.js +61 -2
  50. package/dist/core/backend-detect.js.map +1 -1
  51. package/dist/core/claude-cli-runner.d.ts +5 -2
  52. package/dist/core/claude-cli-runner.js +11 -6
  53. package/dist/core/claude-cli-runner.js.map +1 -1
  54. package/dist/core/claude-ui-mapper.d.ts +14 -0
  55. package/dist/core/claude-ui-mapper.js +102 -11
  56. package/dist/core/claude-ui-mapper.js.map +1 -1
  57. package/dist/core/codex-app-server-transport.js +8 -4
  58. package/dist/core/codex-app-server-transport.js.map +1 -1
  59. package/dist/core/copilot-acp-runner.d.ts +60 -0
  60. package/dist/core/copilot-acp-runner.js +528 -0
  61. package/dist/core/copilot-acp-runner.js.map +1 -0
  62. package/dist/core/copilot-ui-mapper.d.ts +47 -0
  63. package/dist/core/copilot-ui-mapper.js +111 -0
  64. package/dist/core/copilot-ui-mapper.js.map +1 -0
  65. package/dist/core/cursor-agent-runner.js +4 -4
  66. package/dist/core/cursor-agent-runner.js.map +1 -1
  67. package/dist/core/disclaim-spawn.d.ts +9 -0
  68. package/dist/core/disclaim-spawn.js +53 -0
  69. package/dist/core/disclaim-spawn.js.map +1 -0
  70. package/dist/core/junie-acp-transport.d.ts +58 -0
  71. package/dist/core/junie-acp-transport.js +179 -0
  72. package/dist/core/junie-acp-transport.js.map +1 -0
  73. package/dist/core/junie-auth-probe.d.ts +12 -0
  74. package/dist/core/junie-auth-probe.js +30 -0
  75. package/dist/core/junie-auth-probe.js.map +1 -0
  76. package/dist/core/junie-model-catalog.d.ts +10 -0
  77. package/dist/core/junie-model-catalog.js +104 -0
  78. package/dist/core/junie-model-catalog.js.map +1 -0
  79. package/dist/core/junie-runner.d.ts +45 -0
  80. package/dist/core/junie-runner.js +533 -0
  81. package/dist/core/junie-runner.js.map +1 -0
  82. package/dist/core/junie-ui-mapper.d.ts +132 -0
  83. package/dist/core/junie-ui-mapper.js +459 -0
  84. package/dist/core/junie-ui-mapper.js.map +1 -0
  85. package/dist/core/model-identity.js +17 -0
  86. package/dist/core/model-identity.js.map +1 -1
  87. package/dist/core/model-presets.js +10 -0
  88. package/dist/core/model-presets.js.map +1 -1
  89. package/dist/core/opencode-server-runner.js +4 -4
  90. package/dist/core/opencode-server-runner.js.map +1 -1
  91. package/dist/core/pi-runner.js +4 -4
  92. package/dist/core/pi-runner.js.map +1 -1
  93. package/dist/core/provider-auth.d.ts +16 -2
  94. package/dist/core/provider-auth.js +113 -7
  95. package/dist/core/provider-auth.js.map +1 -1
  96. package/dist/core/runner-factory.js +6 -0
  97. package/dist/core/runner-factory.js.map +1 -1
  98. package/dist/core/runner-model-catalog.js +12 -8
  99. package/dist/core/runner-model-catalog.js.map +1 -1
  100. package/dist/core/tool-display.js +6 -1
  101. package/dist/core/tool-display.js.map +1 -1
  102. package/dist/core/ui-events.d.ts +6 -2
  103. package/dist/git-diff-base.js +23 -2
  104. package/dist/git-diff-base.js.map +1 -1
  105. package/dist/git-worktree.d.ts +21 -2
  106. package/dist/git-worktree.js +68 -5
  107. package/dist/git-worktree.js.map +1 -1
  108. package/dist/index.js +14 -4
  109. package/dist/index.js.map +1 -1
  110. package/dist/paths.js +2 -0
  111. package/dist/paths.js.map +1 -1
  112. package/dist/runs/event-history.js +3 -0
  113. package/dist/runs/event-history.js.map +1 -1
  114. package/dist/runs/store.d.ts +42 -3
  115. package/dist/runs/store.js +112 -6
  116. package/dist/runs/store.js.map +1 -1
  117. package/dist/self-update/checkouts.d.ts +53 -0
  118. package/dist/self-update/checkouts.js +268 -0
  119. package/dist/self-update/checkouts.js.map +1 -0
  120. package/dist/self-update/cli.d.ts +5 -3
  121. package/dist/self-update/cli.js +75 -8
  122. package/dist/self-update/cli.js.map +1 -1
  123. package/dist/self-update/layout.d.ts +33 -1
  124. package/dist/self-update/layout.js +102 -3
  125. package/dist/self-update/layout.js.map +1 -1
  126. package/dist/self-update/pulls.d.ts +40 -0
  127. package/dist/self-update/pulls.js +127 -0
  128. package/dist/self-update/pulls.js.map +1 -0
  129. package/dist/self-update/service.d.ts +26 -3
  130. package/dist/self-update/service.js +85 -9
  131. package/dist/self-update/service.js.map +1 -1
  132. package/dist/server/dashboard.d.ts +107 -0
  133. package/dist/server/dashboard.js +2 -1
  134. package/dist/server/dashboard.js.map +1 -1
  135. package/dist/server/forge/github.js +4 -1
  136. package/dist/server/forge/github.js.map +1 -1
  137. package/dist/server/fs-browse.d.ts +3 -1
  138. package/dist/server/fs-browse.js +27 -5
  139. package/dist/server/fs-browse.js.map +1 -1
  140. package/dist/server/open-in-app.js +2 -0
  141. package/dist/server/open-in-app.js.map +1 -1
  142. package/dist/server/provider-action-gate.js +5 -1
  143. package/dist/server/provider-action-gate.js.map +1 -1
  144. package/dist/server/server.d.ts +880 -511
  145. package/dist/server/server.js +40 -5
  146. package/dist/server/server.js.map +1 -1
  147. package/dist/server/star-count.d.ts +67 -0
  148. package/dist/server/star-count.js +186 -0
  149. package/dist/server/star-count.js.map +1 -0
  150. package/dist/skills-banner.d.ts +19 -0
  151. package/dist/skills-banner.js +24 -0
  152. package/dist/skills-banner.js.map +1 -1
  153. package/dist/workflows/run.d.ts +0 -2
  154. package/dist/workflows/run.js +45 -29
  155. package/dist/workflows/run.js.map +1 -1
  156. package/dist/workflows/types.d.ts +6 -0
  157. package/dist/workspace/agent-accounts.d.ts +9 -1
  158. package/dist/workspace/agent-accounts.js +2 -0
  159. package/dist/workspace/agent-accounts.js.map +1 -1
  160. package/dist/workspace/agent-profiles.d.ts +2 -2
  161. package/dist/workspace/agent-profiles.js +25 -6
  162. package/dist/workspace/agent-profiles.js.map +1 -1
  163. package/dist/workspace/config.d.ts +9 -1
  164. package/dist/workspace/config.js +10 -3
  165. package/dist/workspace/config.js.map +1 -1
  166. package/dist/workspace/dashboard-insights.d.ts +42 -0
  167. package/dist/workspace/dashboard-insights.js +220 -0
  168. package/dist/workspace/dashboard-insights.js.map +1 -0
  169. package/dist/workspace/dashboard.d.ts +71 -1
  170. package/dist/workspace/dashboard.js +14 -1
  171. package/dist/workspace/dashboard.js.map +1 -1
  172. package/dist/workspace/semaphore.d.ts +3 -0
  173. package/dist/workspace/semaphore.js +8 -1
  174. package/dist/workspace/semaphore.js.map +1 -1
  175. package/package.json +3 -3
  176. package/scripts/mock-claude.mjs +34 -1
  177. package/scripts/mock-copilot-acp.mjs +190 -0
  178. package/scripts/mock-junie-acp.mjs +208 -0
  179. package/web/dist/assets/agent-task-pickers-BeQi-UTm.js +1 -0
  180. package/web/dist/assets/alert-dialog-CnRAuqwb.js +1 -0
  181. package/web/dist/assets/arrow-down-Da0kNRNH.js +1 -0
  182. package/web/dist/assets/arrow-left-BIZHhBIP.js +1 -0
  183. package/web/dist/assets/automation-format-CfPmkcsg.js +1 -0
  184. package/web/dist/assets/automations-route-AMJbFP53.js +1 -0
  185. package/web/dist/assets/centered-state-3r2Kaar_.js +1 -0
  186. package/web/dist/assets/chevron-left-DLAUPC66.js +1 -0
  187. package/web/dist/assets/chevron-right-KVZcXiPL.js +1 -0
  188. package/web/dist/assets/{circle-x-C9UoMP1V.js → circle-x-C0Jm5Ppb.js} +1 -1
  189. package/web/dist/assets/collapsible-DG_SIWqU.js +1 -0
  190. package/web/dist/assets/command-Dfln3D4A.js +1 -0
  191. package/web/dist/assets/{commit-list-BSfPsVsu.js → commit-list-_RA72yB_.js} +1 -1
  192. package/web/dist/assets/compare-variants-D6Ji6od4.js +1 -0
  193. package/web/dist/assets/dashboard-B3-tPimG.js +44 -0
  194. package/web/dist/assets/dialog-CiDREdUK.js +1 -0
  195. package/web/dist/assets/{diff-I0xowULh.js → diff-CxdyRumG.js} +2 -2
  196. package/web/dist/assets/diff-controls-DqJMMV4z.js +1 -0
  197. package/web/dist/assets/{diff-stat-yKn7joEr.js → diff-stat-Hupj4hxh.js} +1 -1
  198. package/web/dist/assets/{diff-view-DjvMeW1M.js → diff-view-BBYT5k6c.js} +1 -1
  199. package/web/dist/assets/dist-BqMwqJFX.js +1 -0
  200. package/web/dist/assets/dist-DpiX6WjA.js +1 -0
  201. package/web/dist/assets/{download-BcgZ2yk4.js → download-BR7EN9gW.js} +1 -1
  202. package/web/dist/assets/dropdown-menu-Ci4HFML0.js +1 -0
  203. package/web/dist/assets/editable-title-DDtUgRKZ.js +1 -0
  204. package/web/dist/assets/{ellipsis-vertical-g4O4NlLV.js → ellipsis-vertical-DBklom4U.js} +1 -1
  205. package/web/dist/assets/facet-filter-CfI4QvOd.js +1 -0
  206. package/web/dist/assets/{file-wXNeZwi7.js → file-CZb7cKNH.js} +1 -1
  207. package/web/dist/assets/{file-text-DV1gE2L6.js → file-text-Dm6CrEGW.js} +1 -1
  208. package/web/dist/assets/{folder-wjVId5un.js → folder-zQj-FYOo.js} +1 -1
  209. package/web/dist/assets/{git-pull-request-BBEDdTLK.js → git-pull-request-AhwzJc7s.js} +1 -1
  210. package/web/dist/assets/git-toolbar-j7gKkhGL.js +1 -0
  211. package/web/dist/assets/github-De-DFy8s.js +1 -0
  212. package/web/dist/assets/{image-preview-u1f-wzxC.js → image-preview-Dd3NVB7N.js} +1 -1
  213. package/web/dist/assets/index-HS1hr5Sz.js +12 -0
  214. package/web/dist/assets/index-YwgrLyBj.css +2 -0
  215. package/web/dist/assets/loader-circle-sk4vKJKp.js +1 -0
  216. package/web/dist/assets/{markdown-Bnm47qUl.js → markdown-DjNR-1p8.js} +2 -2
  217. package/web/dist/assets/new-task-form-vLs2G1_z.js +1 -0
  218. package/web/dist/assets/picker-pill-VW-M1ZiV.js +1 -0
  219. package/web/dist/assets/{pill-7dm3vWF7.js → pill-CPl6sysj.js} +1 -1
  220. package/web/dist/assets/popover-CNGONAql.js +1 -0
  221. package/web/dist/assets/project-router-dCZQu1wQ.js +1 -0
  222. package/web/dist/assets/{prompt-templates-BMZ5q5H_.js → prompt-templates-jNjVTAws.js} +1 -1
  223. package/web/dist/assets/{refresh-cw-C69euZ2H.js → refresh-cw-BfkEydKA.js} +1 -1
  224. package/web/dist/assets/repo-git-BZWZ6_pR.js +1 -0
  225. package/web/dist/assets/{run-diff-CoNVGn23.js → run-diff-u_roDsAJ.js} +2 -2
  226. package/web/dist/assets/run-header-Br1yJR0m.js +1 -0
  227. package/web/dist/assets/{search-x-BNLFOxI6.js → search-x-CT0NTqK1.js} +1 -1
  228. package/web/dist/assets/segmented-IDD4ucht.js +1 -0
  229. package/web/dist/assets/skills-Dsi5YdLG.js +1 -0
  230. package/web/dist/assets/{sparkles-ChorK-gZ.js → sparkles-CvOeAoyJ.js} +1 -1
  231. package/web/dist/assets/{square-terminal-C7KCPznz.js → square-terminal-eSs8YYZe.js} +1 -1
  232. package/web/dist/assets/{tab-link-E5O2Cesc.js → tab-link-CPF6ORha.js} +1 -1
  233. package/web/dist/assets/task-changes-DIT9Y1rh.js +1 -0
  234. package/web/dist/assets/task-commits-B4VvdiHH.js +1 -0
  235. package/web/dist/assets/task-files-BMm9C0DW.js +2 -0
  236. package/web/dist/assets/task-thread-RXabJAt0.js +9 -0
  237. package/web/dist/assets/{textarea-DLAfWPb0.js → textarea-DtBqPhIs.js} +1 -1
  238. package/web/dist/assets/thread-loading-Dnxb6Ar-.js +1 -0
  239. package/web/dist/assets/toaster-CfRVb8vH.js +43 -0
  240. package/web/dist/assets/token-metrics-DldVlr6m.js +1 -0
  241. package/web/dist/assets/tooltip-_O50N3pt.js +1 -0
  242. package/web/dist/assets/tracker-J0fdcH1G.js +4 -0
  243. package/web/dist/assets/{trash-2-_vwSMdPG.js → trash-2-CUH7GOVh.js} +1 -1
  244. package/web/dist/assets/{triangle-alert-fBRUkB46.js → triangle-alert-D5K_zyD3.js} +1 -1
  245. package/web/dist/assets/{upload-B4OIpdyq.js → upload-D7_n-9cl.js} +1 -1
  246. package/web/dist/assets/{use-now-sqAvRMna.js → use-now-3lElDuTi.js} +1 -1
  247. package/web/dist/assets/utils-BXvEm7Ve.js +64 -0
  248. package/web/dist/assets/workflows-D-dx9c_0.js +7 -0
  249. package/web/dist/assets/x-kLybIvX4.js +1 -0
  250. package/web/dist/assets/{zoomable-image-X81SApIg.js → zoomable-image-CnyQ9wyw.js} +1 -1
  251. package/web/dist/index.html +38 -36
  252. package/web/dist/assets/agent-task-pickers-DQ1qvgrD.js +0 -1
  253. package/web/dist/assets/alert-dialog-B_2uU4Bg.js +0 -1
  254. package/web/dist/assets/arrow-down-DieVZxSE.js +0 -1
  255. package/web/dist/assets/arrow-left-C8M0efjn.js +0 -1
  256. package/web/dist/assets/automation-format-CzinzpHK.js +0 -1
  257. package/web/dist/assets/automations-route-DYHUjV9R.js +0 -1
  258. package/web/dist/assets/centered-state-DJLgwvA4.js +0 -43
  259. package/web/dist/assets/chevron-left-BhXrOEE3.js +0 -1
  260. package/web/dist/assets/chevron-right-B3Ta8VKK.js +0 -1
  261. package/web/dist/assets/collapsible-BcKvItwg.js +0 -1
  262. package/web/dist/assets/command-BvGGv2_u.js +0 -1
  263. package/web/dist/assets/compare-variants-DBvMYMs3.js +0 -1
  264. package/web/dist/assets/dashboard-CGaFh4RV.js +0 -44
  265. package/web/dist/assets/dialog-B6NgKh0-.js +0 -1
  266. package/web/dist/assets/diff-controls-DskkZqmD.js +0 -1
  267. package/web/dist/assets/dist-BvXEdcbG.js +0 -1
  268. package/web/dist/assets/dist-CTksUkKh.js +0 -1
  269. package/web/dist/assets/dropdown-menu-B7HeKCfN.js +0 -1
  270. package/web/dist/assets/editable-title-BHbHmSIK.js +0 -1
  271. package/web/dist/assets/facet-filter-DZ3wfvN9.js +0 -1
  272. package/web/dist/assets/git-toolbar-EZuX4Cuz.js +0 -1
  273. package/web/dist/assets/github-zcLRxv77.js +0 -1
  274. package/web/dist/assets/index-BrZhA4_u.css +0 -2
  275. package/web/dist/assets/index-CSNFuBvj.js +0 -12
  276. package/web/dist/assets/loader-circle-Cwgo6onL.js +0 -1
  277. package/web/dist/assets/new-task-form-CQODCzBP.js +0 -1
  278. package/web/dist/assets/picker-pill-DNB9ETjS.js +0 -1
  279. package/web/dist/assets/popover-BRq6QnwI.js +0 -1
  280. package/web/dist/assets/project-router-I8Pbsrxy.js +0 -1
  281. package/web/dist/assets/repo-git-G436Abni.js +0 -1
  282. package/web/dist/assets/run-header-CxdaA86t.js +0 -1
  283. package/web/dist/assets/skills-C_kBDesq.js +0 -1
  284. package/web/dist/assets/task-changes-Bhw4Ysvg.js +0 -1
  285. package/web/dist/assets/task-commits-DBuGXuGm.js +0 -1
  286. package/web/dist/assets/task-files-CYDbeffM.js +0 -2
  287. package/web/dist/assets/task-thread-RuxHMJgN.js +0 -9
  288. package/web/dist/assets/thread-loading-BAuVAbcA.js +0 -1
  289. package/web/dist/assets/token-metrics-rVl4kXe_.js +0 -1
  290. package/web/dist/assets/tooltip-Bdl8mQG8.js +0 -1
  291. package/web/dist/assets/tracker-DJ8JW59-.js +0 -4
  292. package/web/dist/assets/utils-DoBmOlX3.js +0 -64
  293. package/web/dist/assets/workflows-C54D7mlm.js +0 -7
  294. package/web/dist/assets/x-HXr9KZBr.js +0 -1
@@ -0,0 +1,132 @@
1
+ /**
2
+ * Pure junie ACP `session/update` → protocol-v2 mapper.
3
+ *
4
+ * Junie speaks the real Agent Client Protocol (`junie --acp=true`, verified
5
+ * against `@jetbrains/junie` 26.9.22 with a live authenticated session — see
6
+ * the wire captures cited inline below). ACP already uses cezar's own v2
7
+ * vocabulary almost verbatim (`AGENT_PROTOCOL.md` §3: "ACP vocabulary
8
+ * wherever a choice is arbitrary") — junie's `tool_call.kind` values
9
+ * (`read`/`edit`/`execute`/`other`, confirmed live) map onto `ToolKind`
10
+ * directly, and junie sends a ready-made human `title` on every tool call, so
11
+ * this mapper needs no `toolDisplay()` guessing the other three backends
12
+ * require.
13
+ *
14
+ * Confirmed live on the wire: `session_info_update`, `available_commands_update`,
15
+ * `config_option_update` (all no-op for v2 — nothing to render), `agent_message_chunk`
16
+ * (`content.type:'text'`, phases `commentary`/`final_answer` in `_meta.junie.phase`,
17
+ * `_meta` itself sometimes absent — e.g. the "Task was interrupted" notice after a
18
+ * `session/cancel`), `tool_call`/`tool_call_update` (`kind: other|edit|execute|read`,
19
+ * `status: in_progress|completed|failed`, `content:[{type:'diff',path,newText}|
20
+ * {type:'content',content:{type:'text',text}}]`, `rawInput:{command,cwd}`,
21
+ * `rawOutput:{output,exitCode}`), and `usage_update` (cumulative context-window
22
+ * usage + running session cost — NOT per-turn input/output, so it feeds only
23
+ * `lastCostUsd` here; the authoritative per-turn `TokenUsage` comes from the
24
+ * `session/prompt` RESPONSE, mapped by `junieUsageFromResponse` and fed into
25
+ * `junieTurnCompleted` by the runner).
26
+ *
27
+ * NOT yet observed live — re-verified post-review (2026-09-27) by driving the
28
+ * REAL ACP `session/set_config_option` knobs directly rather than only
29
+ * choosing a stronger model: `configId: 'effort'` (`low|medium|high`,
30
+ * confirmed live, `category: 'thought_level'`) set to `high`, `configId:
31
+ * 'mode'` (`default|plan`) set to `plan`, and `model` set to
32
+ * `v1:12:jetbrains-ai:claude-opus-5-5` (the strongest JetBrains-AI option
33
+ * `session/new`'s `configOptions` advertised) — a multi-step planning prompt
34
+ * under all three still produced only `agent_message_chunk` prose, no `plan`
35
+ * and no `agent_thought_chunk`. Mapped per the public ACP schema
36
+ * (agentclientprotocol.com) anyway, and exercised by
37
+ * `__fixtures__/junie/schema-plan-reasoning.{ndjson,expected.json}`, a
38
+ * SCHEMA-DERIVED fixture explicitly labelled as such rather than one claiming
39
+ * a live capture that never happened (AGENT_PROTOCOL.md §7's "verify against
40
+ * upstream wire shapes" rule, PR #443 precedent; ui-parity.test.ts's B2 review):
41
+ * - `agent_thought_chunk` (reasoning stream) — junie folded all visible
42
+ * reasoning into the final prose message for every model/effort tried,
43
+ * including the real `effort: 'high'` config option;
44
+ * - a structured `plan` update — junie's own "Plan mode" (now confirmed via
45
+ * the real `mode: 'plan'` config option, not just the `--plan` CLI flag)
46
+ * produces a prose planning document via `agent_message_chunk`, not a
47
+ * checklist, and a plain multi-step task never emitted one either.
48
+ *
49
+ * Genuinely unimplementable, not merely unobserved — no fixture, schema-derived
50
+ * or otherwise, can cover these because the public ACP schema itself has no wire
51
+ * shape to map: junie's `tool_call.kind` is unmodified core ACP
52
+ * (`read`/`edit`/`delete`/`move`/`search`/`execute`/`think`/`fetch`/`other`),
53
+ * which has no `task` kind at all — cezar's `task` `ToolKind` is an extension
54
+ * the OTHER three backends' bespoke sub-agent tool names map onto, not
55
+ * something ACP itself defines. `_meta.jetbrains.air.capabilities` advertises
56
+ * `nativeSubagentSessions`, but that capability has no published wire shape at
57
+ * all (unlike `agent_thought_chunk`/`plan`, which at least have a schema this
58
+ * mapper can implement ahead of observing them). ui-parity.test.ts's
59
+ * "sub-agent task items" row and sub-agent nesting therefore exclude junie through
60
+ * the documented path for a capability that "provably cannot exist on that backend's
61
+ * own wire format" (`BACKWARD_COMPATIBILITY.md` §7): a cited, row-scoped `except` in
62
+ * the `CAPABILITIES` table (`AGENT_PROTOCOL.md` §6), as cursor's rows do.
63
+ * - sub-agent nesting (`parentItemId`) — same reason: no wire shape exists, so
64
+ * no nesting is attempted; a spawned sub-agent (should one ever surface as
65
+ * a `tool_call`) renders as a flat, unnested item.
66
+ *
67
+ * Robustness rule (shared with every other mapper): input is untrusted wire
68
+ * data, so this mapper never throws — malformed frames map to zero events.
69
+ * State is explicit and immutable: callers thread the returned `state` into
70
+ * the next call.
71
+ */
72
+ import type { FileDiff, StopReason, TokenUsage, ToolLocation, UiEvent } from './ui-events.ts';
73
+ interface OpenMessage {
74
+ kind: 'message' | 'reasoning';
75
+ id: string;
76
+ text: string;
77
+ phase?: 'commentary' | 'final';
78
+ }
79
+ export interface JunieUiMapperState {
80
+ readonly sessionStarted: boolean;
81
+ readonly turnSeq: number;
82
+ readonly currentTurnId: string | null;
83
+ readonly openMessage: OpenMessage | null;
84
+ readonly knownTools: ReadonlyMap<string, {
85
+ title: string;
86
+ name: string;
87
+ input?: unknown;
88
+ output?: string;
89
+ diffs?: FileDiff[];
90
+ locations?: ToolLocation[];
91
+ exitCode?: number;
92
+ error?: string;
93
+ }>;
94
+ /** Last `usage_update.cost.amount` seen — cumulative-for-session, same
95
+ * semantics as claude's own `total_cost_usd` (also session-cumulative). */
96
+ readonly lastCostUsd: number | null;
97
+ /** Mints a fresh synthetic id for each NEW id-less message/reasoning item (see
98
+ * `mapMessageChunk`) — a shared per-kind constant folded unrelated id-less items together. */
99
+ readonly noIdCounter: number;
100
+ }
101
+ export interface JunieUiMapping {
102
+ events: UiEvent[];
103
+ state: JunieUiMapperState;
104
+ }
105
+ export declare function createJunieUiState(): JunieUiMapperState;
106
+ /** Junie's `session/new` RESULT carries the session id (no `session.started`
107
+ * notification exists on this wire) — the runner calls this once resolved. */
108
+ export declare function junieSessionStarted(sessionId: string, state: JunieUiMapperState): JunieUiMapping;
109
+ /** Junie has no `turn/started` notification either — the runner calls this
110
+ * the moment it sends `session/prompt`. */
111
+ export declare function junieTurnStarted(state: JunieUiMapperState): JunieUiMapping;
112
+ /**
113
+ * `session/prompt`'s RESPONSE carries `stopReason` + per-turn `usage` — the
114
+ * only point in the whole exchange with a real input/output/cache breakdown,
115
+ * so the runner calls this once that response resolves (or the session ends
116
+ * without one, e.g. a hard timeout) rather than folding it into the
117
+ * notification switch below.
118
+ */
119
+ export declare function junieTurnCompleted(stopReason: StopReason, usage: TokenUsage | undefined, state: JunieUiMapperState): JunieUiMapping;
120
+ /** `session/prompt`'s response `usage` (`inputTokens`/`outputTokens`/
121
+ * `totalTokens`/`cachedReadTokens`/`cachedWriteTokens`, confirmed live) → raw
122
+ * `TokenUsage`. Never pre-weighted. */
123
+ export declare function junieUsageFromResponse(raw: unknown): TokenUsage | undefined;
124
+ /** `session/prompt`'s response `stopReason` — `end_turn`/`cancelled` confirmed
125
+ * live; `refusal`/`max_turn_requests` (→`max_tokens`, the closest cezar word
126
+ * for "a resource limit ended the turn") are the documented ACP values not
127
+ * yet observed. Anything else degrades to `error` rather than guessing. */
128
+ export declare function junieStopReason(value: unknown): StopReason;
129
+ /** Fold one `session/update` notification's `params.update` payload into v2
130
+ * events. Never throws. */
131
+ export declare function mapJunieSessionUpdate(update: unknown, state: JunieUiMapperState): JunieUiMapping;
132
+ export {};
@@ -0,0 +1,459 @@
1
+ /**
2
+ * Pure junie ACP `session/update` → protocol-v2 mapper.
3
+ *
4
+ * Junie speaks the real Agent Client Protocol (`junie --acp=true`, verified
5
+ * against `@jetbrains/junie` 26.9.22 with a live authenticated session — see
6
+ * the wire captures cited inline below). ACP already uses cezar's own v2
7
+ * vocabulary almost verbatim (`AGENT_PROTOCOL.md` §3: "ACP vocabulary
8
+ * wherever a choice is arbitrary") — junie's `tool_call.kind` values
9
+ * (`read`/`edit`/`execute`/`other`, confirmed live) map onto `ToolKind`
10
+ * directly, and junie sends a ready-made human `title` on every tool call, so
11
+ * this mapper needs no `toolDisplay()` guessing the other three backends
12
+ * require.
13
+ *
14
+ * Confirmed live on the wire: `session_info_update`, `available_commands_update`,
15
+ * `config_option_update` (all no-op for v2 — nothing to render), `agent_message_chunk`
16
+ * (`content.type:'text'`, phases `commentary`/`final_answer` in `_meta.junie.phase`,
17
+ * `_meta` itself sometimes absent — e.g. the "Task was interrupted" notice after a
18
+ * `session/cancel`), `tool_call`/`tool_call_update` (`kind: other|edit|execute|read`,
19
+ * `status: in_progress|completed|failed`, `content:[{type:'diff',path,newText}|
20
+ * {type:'content',content:{type:'text',text}}]`, `rawInput:{command,cwd}`,
21
+ * `rawOutput:{output,exitCode}`), and `usage_update` (cumulative context-window
22
+ * usage + running session cost — NOT per-turn input/output, so it feeds only
23
+ * `lastCostUsd` here; the authoritative per-turn `TokenUsage` comes from the
24
+ * `session/prompt` RESPONSE, mapped by `junieUsageFromResponse` and fed into
25
+ * `junieTurnCompleted` by the runner).
26
+ *
27
+ * NOT yet observed live — re-verified post-review (2026-09-27) by driving the
28
+ * REAL ACP `session/set_config_option` knobs directly rather than only
29
+ * choosing a stronger model: `configId: 'effort'` (`low|medium|high`,
30
+ * confirmed live, `category: 'thought_level'`) set to `high`, `configId:
31
+ * 'mode'` (`default|plan`) set to `plan`, and `model` set to
32
+ * `v1:12:jetbrains-ai:claude-opus-5-5` (the strongest JetBrains-AI option
33
+ * `session/new`'s `configOptions` advertised) — a multi-step planning prompt
34
+ * under all three still produced only `agent_message_chunk` prose, no `plan`
35
+ * and no `agent_thought_chunk`. Mapped per the public ACP schema
36
+ * (agentclientprotocol.com) anyway, and exercised by
37
+ * `__fixtures__/junie/schema-plan-reasoning.{ndjson,expected.json}`, a
38
+ * SCHEMA-DERIVED fixture explicitly labelled as such rather than one claiming
39
+ * a live capture that never happened (AGENT_PROTOCOL.md §7's "verify against
40
+ * upstream wire shapes" rule, PR #443 precedent; ui-parity.test.ts's B2 review):
41
+ * - `agent_thought_chunk` (reasoning stream) — junie folded all visible
42
+ * reasoning into the final prose message for every model/effort tried,
43
+ * including the real `effort: 'high'` config option;
44
+ * - a structured `plan` update — junie's own "Plan mode" (now confirmed via
45
+ * the real `mode: 'plan'` config option, not just the `--plan` CLI flag)
46
+ * produces a prose planning document via `agent_message_chunk`, not a
47
+ * checklist, and a plain multi-step task never emitted one either.
48
+ *
49
+ * Genuinely unimplementable, not merely unobserved — no fixture, schema-derived
50
+ * or otherwise, can cover these because the public ACP schema itself has no wire
51
+ * shape to map: junie's `tool_call.kind` is unmodified core ACP
52
+ * (`read`/`edit`/`delete`/`move`/`search`/`execute`/`think`/`fetch`/`other`),
53
+ * which has no `task` kind at all — cezar's `task` `ToolKind` is an extension
54
+ * the OTHER three backends' bespoke sub-agent tool names map onto, not
55
+ * something ACP itself defines. `_meta.jetbrains.air.capabilities` advertises
56
+ * `nativeSubagentSessions`, but that capability has no published wire shape at
57
+ * all (unlike `agent_thought_chunk`/`plan`, which at least have a schema this
58
+ * mapper can implement ahead of observing them). ui-parity.test.ts's
59
+ * "sub-agent task items" row and sub-agent nesting therefore exclude junie through
60
+ * the documented path for a capability that "provably cannot exist on that backend's
61
+ * own wire format" (`BACKWARD_COMPATIBILITY.md` §7): a cited, row-scoped `except` in
62
+ * the `CAPABILITIES` table (`AGENT_PROTOCOL.md` §6), as cursor's rows do.
63
+ * - sub-agent nesting (`parentItemId`) — same reason: no wire shape exists, so
64
+ * no nesting is attempted; a spawned sub-agent (should one ever surface as
65
+ * a `tool_call`) renders as a flat, unnested item.
66
+ *
67
+ * Robustness rule (shared with every other mapper): input is untrusted wire
68
+ * data, so this mapper never throws — malformed frames map to zero events.
69
+ * State is explicit and immutable: callers thread the returned `state` into
70
+ * the next call.
71
+ */
72
+ export function createJunieUiState() {
73
+ return {
74
+ sessionStarted: false,
75
+ turnSeq: 0,
76
+ currentTurnId: null,
77
+ openMessage: null,
78
+ knownTools: new Map(),
79
+ lastCostUsd: null,
80
+ noIdCounter: 0,
81
+ };
82
+ }
83
+ /** Junie's `session/new` RESULT carries the session id (no `session.started`
84
+ * notification exists on this wire) — the runner calls this once resolved. */
85
+ export function junieSessionStarted(sessionId, state) {
86
+ if (state.sessionStarted || sessionId === '')
87
+ return { events: [], state };
88
+ return {
89
+ events: [{ type: 'session.started', sessionId, backend: 'junie' }],
90
+ state: { ...state, sessionStarted: true },
91
+ };
92
+ }
93
+ /** Junie has no `turn/started` notification either — the runner calls this
94
+ * the moment it sends `session/prompt`. */
95
+ export function junieTurnStarted(state) {
96
+ const turnSeq = state.turnSeq + 1;
97
+ const turnId = `turn_${turnSeq}`;
98
+ return {
99
+ events: [{ type: 'turn.started', turnId }],
100
+ state: { ...state, turnSeq, currentTurnId: turnId, openMessage: null, knownTools: new Map() },
101
+ };
102
+ }
103
+ /**
104
+ * `session/prompt`'s RESPONSE carries `stopReason` + per-turn `usage` — the
105
+ * only point in the whole exchange with a real input/output/cache breakdown,
106
+ * so the runner calls this once that response resolves (or the session ends
107
+ * without one, e.g. a hard timeout) rather than folding it into the
108
+ * notification switch below.
109
+ */
110
+ export function junieTurnCompleted(stopReason, usage, state) {
111
+ const closed = closeOpenMessage(state);
112
+ const turnId = closed.state.currentTurnId ?? `turn_${closed.state.turnSeq || 1}`;
113
+ const events = [...closed.events];
114
+ const costUsd = closed.state.lastCostUsd ?? undefined;
115
+ if (usage)
116
+ events.push({ type: 'usage.updated', usage, ...(costUsd !== undefined ? { costUsd } : {}) });
117
+ const completed = { type: 'turn.completed', turnId, stopReason };
118
+ if (usage)
119
+ completed.usage = usage;
120
+ if (costUsd !== undefined)
121
+ completed.costUsd = costUsd;
122
+ events.push(completed);
123
+ return { events, state: { ...closed.state, currentTurnId: null, knownTools: new Map() } };
124
+ }
125
+ /** `session/prompt`'s response `usage` (`inputTokens`/`outputTokens`/
126
+ * `totalTokens`/`cachedReadTokens`/`cachedWriteTokens`, confirmed live) → raw
127
+ * `TokenUsage`. Never pre-weighted. */
128
+ export function junieUsageFromResponse(raw) {
129
+ if (!isRecord(raw))
130
+ return undefined;
131
+ const input = nonNegative(raw.inputTokens);
132
+ const output = nonNegative(raw.outputTokens);
133
+ if (input === undefined || output === undefined)
134
+ return undefined;
135
+ const total = nonNegative(raw.totalTokens) ?? input + output;
136
+ const usage = { input, output, total };
137
+ const cacheRead = nonNegative(raw.cachedReadTokens);
138
+ const cacheWrite = nonNegative(raw.cachedWriteTokens);
139
+ if (cacheRead !== undefined)
140
+ usage.cacheRead = cacheRead;
141
+ if (cacheWrite !== undefined)
142
+ usage.cacheWrite = cacheWrite;
143
+ return usage;
144
+ }
145
+ /** `session/prompt`'s response `stopReason` — `end_turn`/`cancelled` confirmed
146
+ * live; `refusal`/`max_turn_requests` (→`max_tokens`, the closest cezar word
147
+ * for "a resource limit ended the turn") are the documented ACP values not
148
+ * yet observed. Anything else degrades to `error` rather than guessing. */
149
+ export function junieStopReason(value) {
150
+ if (value === 'end_turn' || value === 'cancelled' || value === 'refusal')
151
+ return value;
152
+ if (value === 'max_tokens' || value === 'max_turn_requests')
153
+ return 'max_tokens';
154
+ return 'error';
155
+ }
156
+ /** Fold one `session/update` notification's `params.update` payload into v2
157
+ * events. Never throws. */
158
+ export function mapJunieSessionUpdate(update, state) {
159
+ if (!isRecord(update) || typeof update.sessionUpdate !== 'string')
160
+ return { events: [], state };
161
+ const kind = update.sessionUpdate;
162
+ if (kind === 'agent_message_chunk' || kind === 'agent_thought_chunk') {
163
+ return mapMessageChunk(update, state, kind === 'agent_message_chunk' ? 'message' : 'reasoning');
164
+ }
165
+ // Anything else ends whatever message/reasoning item was streaming — junie
166
+ // gives no explicit "message complete" signal, so the next non-chunk event
167
+ // (a tool call, or the turn ending) is the boundary.
168
+ const closed = closeOpenMessage(state);
169
+ switch (kind) {
170
+ case 'tool_call': {
171
+ const mapped = mapToolCall(update, closed.state);
172
+ return { events: [...closed.events, ...mapped.events], state: mapped.state };
173
+ }
174
+ case 'tool_call_update': {
175
+ const mapped = mapToolCallUpdate(update, closed.state);
176
+ return { events: [...closed.events, ...mapped.events], state: mapped.state };
177
+ }
178
+ // Not yet observed live (see module doc) — mapped per the public ACP
179
+ // schema so a future junie version that emits it renders correctly.
180
+ case 'plan': {
181
+ const mapped = mapPlan(update, closed.state);
182
+ return { events: [...closed.events, ...mapped.events], state: mapped.state };
183
+ }
184
+ case 'usage_update': {
185
+ const cost = isRecord(update.cost) ? num(update.cost.amount) : undefined;
186
+ return { events: closed.events, state: cost !== undefined ? { ...closed.state, lastCostUsd: cost } : closed.state };
187
+ }
188
+ default:
189
+ // session_info_update, available_commands_update, config_option_update,
190
+ // current_mode_update, user_message_chunk (the client already rendered
191
+ // what it sent) — nothing to render in v2 yet.
192
+ return closed;
193
+ }
194
+ }
195
+ // ---- messages / reasoning ---------------------------------------------------
196
+ function closeOpenMessage(state) {
197
+ const open = state.openMessage;
198
+ if (!open)
199
+ return { events: [], state };
200
+ const item = open.kind === 'message'
201
+ ? { kind: 'message', id: open.id, role: 'assistant', text: open.text, ...(open.phase ? { phase: open.phase } : {}) }
202
+ : { kind: 'reasoning', id: open.id, text: open.text };
203
+ return { events: [{ type: 'item.completed', item }], state: { ...state, openMessage: null } };
204
+ }
205
+ function mapMessageChunk(raw, state, itemKind) {
206
+ const text = contentTextOf(raw.content);
207
+ if (text === undefined || text === '')
208
+ return { events: [], state };
209
+ // A frame without `messageId` still has real text to render (unlike a tool call with no id,
210
+ // which `mapToolCall` correctly drops). Absent a wire id, a chunk that arrives while a
211
+ // message/reasoning item of the SAME kind is already open continues that item (junie sends
212
+ // no per-message id at all for some frames — e.g. the "Task was interrupted" notice — and no
213
+ // separate continuation signal either, so this is the closest reading of intent). But a NEW
214
+ // id-less item — nothing open, or a kind switch — must not collide with any other id-less
215
+ // item: it gets a fresh id off `noIdCounter` rather than a shared per-kind constant, which
216
+ // folded unrelated id-less messages together into one (#1111 review).
217
+ const rawMessageId = str(raw.messageId);
218
+ const openBefore = state.openMessage;
219
+ const continuesOpenById = rawMessageId === undefined && openBefore !== null && openBefore.kind === itemKind;
220
+ const mintsNoId = rawMessageId === undefined && !continuesOpenById;
221
+ const noIdCounter = mintsNoId ? state.noIdCounter + 1 : state.noIdCounter;
222
+ const messageId = rawMessageId ?? (continuesOpenById ? openBefore.id : `junie-${itemKind}-no-id-${noIdCounter}`);
223
+ state = { ...state, noIdCounter };
224
+ const events = [];
225
+ let open = state.openMessage;
226
+ if (open && (open.id !== messageId || open.kind !== itemKind)) {
227
+ const closed = closeOpenMessage(state);
228
+ events.push(...closed.events);
229
+ state = closed.state;
230
+ open = null;
231
+ }
232
+ if (!open) {
233
+ const item = itemKind === 'message'
234
+ ? { kind: 'message', id: messageId, role: 'assistant', text: '' }
235
+ : { kind: 'reasoning', id: messageId, text: '' };
236
+ events.push({ type: 'item.started', item });
237
+ open = { kind: itemKind, id: messageId, text: '' };
238
+ }
239
+ events.push({
240
+ type: 'item.delta',
241
+ itemId: messageId,
242
+ field: itemKind === 'message' ? 'text' : 'reasoning',
243
+ delta: text,
244
+ });
245
+ const phase = phaseOf(raw._meta) ?? open.phase;
246
+ return { events, state: { ...state, openMessage: { ...open, text: open.text + text, phase } } };
247
+ }
248
+ /** `_meta.junie.phase` (confirmed live: `commentary`|`final_answer`) —
249
+ * `_meta.codex.phase` is checked as a fallback since junie's own captures
250
+ * duplicated the same value under both keys; `_meta` is sometimes absent
251
+ * entirely (the post-cancel "Task was interrupted" notice carried none). */
252
+ function phaseOf(meta) {
253
+ if (!isRecord(meta))
254
+ return undefined;
255
+ const junie = isRecord(meta.junie) ? meta.junie.phase : undefined;
256
+ const codex = isRecord(meta.codex) ? meta.codex.phase : undefined;
257
+ const phase = junie ?? codex;
258
+ if (phase === 'commentary')
259
+ return 'commentary';
260
+ if (phase === 'final_answer')
261
+ return 'final';
262
+ return undefined;
263
+ }
264
+ function contentTextOf(content) {
265
+ if (!isRecord(content) || content.type !== 'text')
266
+ return undefined;
267
+ return typeof content.text === 'string' ? content.text : undefined;
268
+ }
269
+ // ---- tools -------------------------------------------------------------------
270
+ /** junie's `tool_call.kind` already speaks cezar's `ToolKind` vocabulary
271
+ * (confirmed live: `other`, `edit`, `execute`, `read`) — real ACP defines the
272
+ * same enum cezar's is a superset of, so any recognized value passes through
273
+ * verbatim and only a genuinely unknown one falls back to `other`. */
274
+ const KNOWN_TOOL_KINDS = new Set([
275
+ 'read',
276
+ 'edit',
277
+ 'delete',
278
+ 'move',
279
+ 'search',
280
+ 'execute',
281
+ 'think',
282
+ 'fetch',
283
+ 'other',
284
+ ]);
285
+ function toolKindOf(value) {
286
+ return typeof value === 'string' && KNOWN_TOOL_KINDS.has(value) ? value : 'other';
287
+ }
288
+ const STATUS_MAP = {
289
+ pending: 'pending',
290
+ in_progress: 'running',
291
+ completed: 'completed',
292
+ failed: 'failed',
293
+ };
294
+ function toolStatus(value, fallback) {
295
+ return typeof value === 'string' ? (STATUS_MAP[value] ?? fallback) : fallback;
296
+ }
297
+ /** `content:[{type:'diff',path,oldText?,newText?,unified?}]` (confirmed live
298
+ * for file creation — no `oldText` key at all, which is `null`/"newly
299
+ * created" per `FileDiff`'s own contract) + `{type:'content',content:{type:
300
+ * 'text',text}}` (confirmed live as the human-readable tool result). */
301
+ function toolContent(content) {
302
+ if (!Array.isArray(content))
303
+ return {};
304
+ const texts = [];
305
+ const diffs = [];
306
+ for (const entry of content) {
307
+ if (!isRecord(entry))
308
+ continue;
309
+ if (entry.type === 'diff' && typeof entry.path === 'string' && entry.path !== '') {
310
+ const diff = {
311
+ path: entry.path,
312
+ oldText: typeof entry.oldText === 'string' ? entry.oldText : null,
313
+ };
314
+ if (typeof entry.newText === 'string')
315
+ diff.newText = entry.newText;
316
+ if (typeof entry.unified === 'string')
317
+ diff.unified = entry.unified;
318
+ diffs.push(diff);
319
+ }
320
+ else if (entry.type === 'content') {
321
+ const text = contentTextOf(entry.content);
322
+ if (text !== undefined)
323
+ texts.push(text);
324
+ }
325
+ }
326
+ const out = {};
327
+ if (texts.length > 0)
328
+ out.output = texts.join('\n');
329
+ if (diffs.length > 0) {
330
+ out.diffs = diffs;
331
+ out.locations = diffs.map((d) => ({ path: d.path }));
332
+ }
333
+ return out;
334
+ }
335
+ /** `locations:[{path,line?}]`, confirmed live for both edit and execute
336
+ * tool calls (execute carries an empty array). */
337
+ function toolLocations(value) {
338
+ if (!Array.isArray(value))
339
+ return undefined;
340
+ const locations = [];
341
+ for (const entry of value) {
342
+ if (isRecord(entry) && typeof entry.path === 'string' && entry.path !== '') {
343
+ const location = { path: entry.path };
344
+ const line = num(entry.line);
345
+ if (line !== undefined)
346
+ location.line = line;
347
+ locations.push(location);
348
+ }
349
+ }
350
+ return locations.length > 0 ? locations : undefined;
351
+ }
352
+ /** `rawOutput:{output,exitCode}`, confirmed live on `execute` tool calls
353
+ * (both the failing `false` and the succeeding `echo done`). */
354
+ function rawOutputOf(value) {
355
+ if (!isRecord(value))
356
+ return {};
357
+ const out = {};
358
+ if (typeof value.output === 'string' && value.output !== '')
359
+ out.output = value.output;
360
+ const exitCode = num(value.exitCode);
361
+ if (exitCode !== undefined)
362
+ out.exitCode = exitCode;
363
+ return out;
364
+ }
365
+ function toolItemFrom(raw, id, status, prior) {
366
+ const kind = toolKindOf(raw.kind);
367
+ const title = str(raw.title) ?? prior?.title ?? 'Tool';
368
+ const name = str(raw.kind) ?? prior?.name ?? 'other';
369
+ const input = raw.rawInput !== undefined ? raw.rawInput : prior?.input;
370
+ const fromContent = toolContent(raw.content);
371
+ const fromRawOutput = rawOutputOf(raw.rawOutput);
372
+ const output = fromContent.output ?? fromRawOutput.output ?? prior?.output;
373
+ const diffs = fromContent.diffs ?? prior?.diffs;
374
+ const locations = fromContent.locations ?? toolLocations(raw.locations) ?? prior?.locations;
375
+ const exitCode = fromRawOutput.exitCode ?? prior?.exitCode;
376
+ const error = status === 'failed' ? (fromContent.output ?? fromRawOutput.output ?? prior?.error) : undefined;
377
+ const item = { kind: 'tool', id, name, toolKind: kind, title, status };
378
+ if (input !== undefined)
379
+ item.input = input;
380
+ if (output !== undefined)
381
+ item.output = output;
382
+ if (diffs !== undefined)
383
+ item.diffs = diffs;
384
+ if (locations !== undefined)
385
+ item.locations = locations;
386
+ if (exitCode !== undefined)
387
+ item.exitCode = exitCode;
388
+ if (error !== undefined)
389
+ item.error = error;
390
+ return { item, snapshot: { title, name, input, output, diffs, locations, exitCode, error } };
391
+ }
392
+ function mapToolCall(raw, state) {
393
+ const id = str(raw.toolCallId);
394
+ if (!id)
395
+ return { events: [], state };
396
+ const { item, snapshot } = toolItemFrom(raw, id, toolStatus(raw.status, 'running'), undefined);
397
+ const knownTools = new Map(state.knownTools);
398
+ knownTools.set(id, snapshot);
399
+ return { events: [{ type: 'item.started', item }], state: { ...state, knownTools } };
400
+ }
401
+ function mapToolCallUpdate(raw, state) {
402
+ const id = str(raw.toolCallId);
403
+ if (!id)
404
+ return { events: [], state };
405
+ const prior = state.knownTools.get(id);
406
+ const status = toolStatus(raw.status, 'running');
407
+ const { item, snapshot } = toolItemFrom(raw, id, status, prior);
408
+ const knownTools = new Map(state.knownTools);
409
+ const terminal = status === 'completed' || status === 'failed' || status === 'declined';
410
+ if (terminal)
411
+ knownTools.delete(id);
412
+ else
413
+ knownTools.set(id, snapshot);
414
+ return { events: [{ type: terminal ? 'item.completed' : 'item.updated', item }], state: { ...state, knownTools } };
415
+ }
416
+ // ---- plan (not yet observed live — see module doc) ---------------------------
417
+ function mapPlan(raw, state) {
418
+ const list = Array.isArray(raw.entries) ? raw.entries : undefined;
419
+ if (!list)
420
+ return { events: [], state };
421
+ const entries = [];
422
+ for (const entry of list) {
423
+ if (!isRecord(entry))
424
+ continue;
425
+ const content = str(entry.content);
426
+ if (content === undefined)
427
+ continue;
428
+ const planEntry = { content, status: planStatus(entry.status) };
429
+ if (entry.priority === 'high' || entry.priority === 'medium' || entry.priority === 'low') {
430
+ planEntry.priority = entry.priority;
431
+ }
432
+ entries.push(planEntry);
433
+ }
434
+ if (list.length > 0 && entries.length === 0)
435
+ return { events: [], state };
436
+ return { events: [{ type: 'plan.updated', entries }], state };
437
+ }
438
+ function planStatus(value) {
439
+ if (value === 'completed')
440
+ return 'completed';
441
+ if (value === 'in_progress')
442
+ return 'in_progress';
443
+ return 'pending';
444
+ }
445
+ // ---- tiny guards ---------------------------------------------------------------
446
+ function isRecord(value) {
447
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
448
+ }
449
+ function str(value) {
450
+ return typeof value === 'string' && value !== '' ? value : undefined;
451
+ }
452
+ function num(value) {
453
+ return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
454
+ }
455
+ function nonNegative(value) {
456
+ const parsed = num(value);
457
+ return parsed !== undefined && parsed >= 0 ? parsed : undefined;
458
+ }
459
+ //# sourceMappingURL=junie-ui-mapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"junie-ui-mapper.js","sourceRoot":"","sources":["../../src/core/junie-ui-mapper.ts"],"names":[],"mappings":"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"}
@@ -39,6 +39,23 @@ export const BACKEND_MODEL_MAP = {
39
39
  // opencode (#387) — no default provider, so a bare model is rejected loudly
40
40
  // and `toBackendModel` hands pi the full `provider/model` on its `--model`.
41
41
  pi: {},
42
+ // junie's model ids are its OWN opaque catalog strings
43
+ // (`v1:12:jetbrains-ai:claude-sonnet-5`, `v1:6:custom:custom:qwen3-coder-local`)
44
+ // — already unambiguous, never provider-qualified, and never containing a
45
+ // `/`. `defaultProvider: 'junie'` names the backend itself rather than a real
46
+ // LLM vendor: it exists only to make a bare id resolve instead of being
47
+ // rejected as ambiguous (the opencode/pi rule, which does not apply — a
48
+ // junie id is not naming a provider-agnostic model), and its ONLY visible
49
+ // effect is `toBackendModel` returning the raw string unchanged (the
50
+ // `id.model` branch, since `allowExplicitProvider` is unset). An explicit
51
+ // `foo/bar` string is still rejected loudly, matching a real foreign
52
+ // provider on any other single-provider backend.
53
+ junie: { defaultProvider: 'junie' },
54
+ // Copilot's `--model` takes a bare, provider-less id (`auto`, `gpt-5.4`, `claude-sonnet-4`):
55
+ // GitHub routes it, whichever vendor ultimately answers, so GitHub is the provider that served
56
+ // the run (#405's invariant). Rejecting a bare id the way opencode and pi do would reject the
57
+ // only form Copilot accepts.
58
+ copilot: { defaultProvider: 'github' },
42
59
  };
43
60
  const SLASH = '/';
44
61
  /** Serialize a canonical identity to its `provider/model` string form. */