@antelopejs/dms-ai 0.1.5 → 0.2.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 (564) hide show
  1. package/README.md +54 -11
  2. package/dist/channels/bridge.d.ts +6 -1
  3. package/dist/channels/bridge.js +29 -1
  4. package/dist/channels/bridge.js.map +1 -1
  5. package/dist/channels/channel-service.d.ts +2 -1
  6. package/dist/channels/channel-service.js +3 -2
  7. package/dist/channels/channel-service.js.map +1 -1
  8. package/dist/channels/sse-stream.d.ts +3 -2
  9. package/dist/config.d.ts +0 -2
  10. package/dist/config.js +0 -7
  11. package/dist/config.js.map +1 -1
  12. package/dist/constants/http.d.ts +9 -0
  13. package/dist/constants/http.js +14 -0
  14. package/dist/constants/http.js.map +1 -0
  15. package/dist/constants/i18n.d.ts +11 -0
  16. package/dist/constants/i18n.js +15 -0
  17. package/dist/constants/i18n.js.map +1 -0
  18. package/dist/constants/pages.d.ts +50 -0
  19. package/dist/constants/pages.js +58 -0
  20. package/dist/constants/pages.js.map +1 -0
  21. package/dist/constants/sidecar.d.ts +3 -1
  22. package/dist/constants/sidecar.js +4 -2
  23. package/dist/constants/sidecar.js.map +1 -1
  24. package/dist/index.js +0 -8
  25. package/dist/index.js.map +1 -1
  26. package/dist/lifecycle/sidecar-owner.d.ts +14 -0
  27. package/dist/lifecycle/sidecar-owner.js +102 -0
  28. package/dist/lifecycle/sidecar-owner.js.map +1 -0
  29. package/dist/lifecycle/spawn-sidecar.d.ts +1 -0
  30. package/dist/lifecycle/spawn-sidecar.js +59 -145
  31. package/dist/lifecycle/spawn-sidecar.js.map +1 -1
  32. package/dist/lifecycle/terminate-process.d.ts +1 -0
  33. package/dist/lifecycle/terminate-process.js +34 -0
  34. package/dist/lifecycle/terminate-process.js.map +1 -0
  35. package/dist/logging/log-buffer.d.ts +0 -6
  36. package/dist/logging/log-buffer.js +0 -1
  37. package/dist/logging/log-buffer.js.map +1 -1
  38. package/dist/pages/activity/columns.d.ts +2 -0
  39. package/dist/pages/activity/columns.js +103 -0
  40. package/dist/pages/activity/columns.js.map +1 -0
  41. package/dist/pages/activity/page.d.ts +1 -2
  42. package/dist/pages/activity/page.js +79 -44
  43. package/dist/pages/activity/page.js.map +1 -1
  44. package/dist/pages/all.d.ts +1 -0
  45. package/dist/pages/all.js +1 -0
  46. package/dist/pages/all.js.map +1 -1
  47. package/dist/pages/changes/page.d.ts +9 -0
  48. package/dist/pages/changes/page.js +22 -0
  49. package/dist/pages/changes/page.js.map +1 -0
  50. package/dist/pages/meta.d.ts +9 -0
  51. package/dist/pages/meta.js +31 -0
  52. package/dist/pages/meta.js.map +1 -0
  53. package/dist/pages/module.js +9 -5
  54. package/dist/pages/module.js.map +1 -1
  55. package/dist/pages/overview/insights.d.ts +3 -0
  56. package/dist/pages/overview/insights.js +77 -0
  57. package/dist/pages/overview/insights.js.map +1 -0
  58. package/dist/pages/overview/kpis.d.ts +2 -0
  59. package/dist/pages/overview/kpis.js +39 -0
  60. package/dist/pages/overview/kpis.js.map +1 -0
  61. package/dist/pages/overview/page.d.ts +6 -3
  62. package/dist/pages/overview/page.js +19 -62
  63. package/dist/pages/overview/page.js.map +1 -1
  64. package/dist/pages/overview/recent-changes.d.ts +2 -0
  65. package/dist/pages/overview/recent-changes.js +144 -0
  66. package/dist/pages/overview/recent-changes.js.map +1 -0
  67. package/dist/pages/overview/status.d.ts +3 -0
  68. package/dist/pages/overview/status.js +36 -0
  69. package/dist/pages/overview/status.js.map +1 -0
  70. package/dist/pages/settings/availability.d.ts +2 -0
  71. package/dist/pages/settings/availability.js +46 -0
  72. package/dist/pages/settings/availability.js.map +1 -0
  73. package/dist/pages/settings/options.d.ts +10 -0
  74. package/dist/pages/settings/options.js +58 -0
  75. package/dist/pages/settings/options.js.map +1 -0
  76. package/dist/pages/settings/page.d.ts +2 -1
  77. package/dist/pages/settings/page.js +39 -13
  78. package/dist/pages/settings/page.js.map +1 -1
  79. package/dist/pages/settings/sections.d.ts +2 -0
  80. package/dist/pages/settings/sections.js +164 -0
  81. package/dist/pages/settings/sections.js.map +1 -0
  82. package/dist/pages/skills/page.d.ts +2 -1
  83. package/dist/pages/skills/page.js +122 -12
  84. package/dist/pages/skills/page.js.map +1 -1
  85. package/dist/routes/activity-csv.d.ts +2 -0
  86. package/dist/routes/activity-csv.js +42 -0
  87. package/dist/routes/activity-csv.js.map +1 -0
  88. package/dist/routes/activity.d.ts +8 -0
  89. package/dist/routes/activity.js +105 -0
  90. package/dist/routes/activity.js.map +1 -0
  91. package/dist/routes/actor.d.ts +2 -0
  92. package/dist/routes/actor.js +8 -0
  93. package/dist/routes/actor.js.map +1 -0
  94. package/dist/routes/banner.d.ts +3 -0
  95. package/dist/routes/banner.js +9 -0
  96. package/dist/routes/banner.js.map +1 -0
  97. package/dist/routes/builder.js +1 -5
  98. package/dist/routes/builder.js.map +1 -1
  99. package/dist/routes/changes.d.ts +17 -0
  100. package/dist/routes/changes.js +152 -0
  101. package/dist/routes/changes.js.map +1 -0
  102. package/dist/routes/channels.js +2 -1
  103. package/dist/routes/channels.js.map +1 -1
  104. package/dist/routes/index.d.ts +3 -0
  105. package/dist/routes/index.js +3 -0
  106. package/dist/routes/index.js.map +1 -1
  107. package/dist/routes/list-query.d.ts +9 -0
  108. package/dist/routes/list-query.js +34 -0
  109. package/dist/routes/list-query.js.map +1 -0
  110. package/dist/routes/metric-shapes.d.ts +8 -0
  111. package/dist/routes/metric-shapes.js +107 -0
  112. package/dist/routes/metric-shapes.js.map +1 -0
  113. package/dist/routes/metrics.d.ts +5 -48
  114. package/dist/routes/metrics.js +52 -42
  115. package/dist/routes/metrics.js.map +1 -1
  116. package/dist/routes/settings.d.ts +3 -16
  117. package/dist/routes/settings.js +40 -14
  118. package/dist/routes/settings.js.map +1 -1
  119. package/dist/routes/sidecar-results.d.ts +6 -0
  120. package/dist/routes/sidecar-results.js +44 -0
  121. package/dist/routes/sidecar-results.js.map +1 -0
  122. package/dist/routes/skills.d.ts +4 -14
  123. package/dist/routes/skills.js +91 -6
  124. package/dist/routes/skills.js.map +1 -1
  125. package/dist/routes/status-shapes.d.ts +5 -0
  126. package/dist/routes/status-shapes.js +176 -0
  127. package/dist/routes/status-shapes.js.map +1 -0
  128. package/dist/routes/status.d.ts +9 -0
  129. package/dist/routes/status.js +92 -0
  130. package/dist/routes/status.js.map +1 -0
  131. package/dist/routes/undo-confirm.d.ts +3 -0
  132. package/dist/routes/undo-confirm.js +51 -0
  133. package/dist/routes/undo-confirm.js.map +1 -0
  134. package/dist/sidecar/http-client.d.ts +11 -0
  135. package/dist/sidecar/http-client.js +59 -0
  136. package/dist/sidecar/http-client.js.map +1 -0
  137. package/dist/sidecar/index.d.ts +2 -0
  138. package/dist/sidecar/index.js +19 -0
  139. package/dist/sidecar/index.js.map +1 -0
  140. package/dist/sidecar/query.d.ts +3 -0
  141. package/dist/sidecar/query.js +25 -0
  142. package/dist/sidecar/query.js.map +1 -0
  143. package/dist/types/activity.d.ts +31 -0
  144. package/dist/types/activity.js +3 -0
  145. package/dist/types/activity.js.map +1 -0
  146. package/dist/types/changes.d.ts +45 -0
  147. package/dist/types/changes.js +3 -0
  148. package/dist/types/changes.js.map +1 -0
  149. package/dist/types/index.d.ts +5 -0
  150. package/dist/types/index.js +5 -0
  151. package/dist/types/index.js.map +1 -1
  152. package/dist/types/metrics.d.ts +76 -0
  153. package/dist/types/metrics.js +3 -0
  154. package/dist/types/metrics.js.map +1 -0
  155. package/dist/types/skills.d.ts +51 -0
  156. package/dist/types/skills.js +3 -0
  157. package/dist/types/skills.js.map +1 -0
  158. package/dist/types/status.d.ts +16 -0
  159. package/dist/types/status.js +3 -0
  160. package/dist/types/status.js.map +1 -0
  161. package/dist/vocabulary/enumerations.d.ts +9 -0
  162. package/dist/vocabulary/enumerations.js +52 -0
  163. package/dist/vocabulary/enumerations.js.map +1 -0
  164. package/dist/vocabulary/index.d.ts +5 -0
  165. package/dist/vocabulary/index.js +22 -0
  166. package/dist/vocabulary/index.js.map +1 -0
  167. package/dist/vocabulary/keys.d.ts +1 -0
  168. package/dist/vocabulary/keys.js +8 -0
  169. package/dist/vocabulary/keys.js.map +1 -0
  170. package/dist/vocabulary/options.d.ts +7 -0
  171. package/dist/vocabulary/options.js +33 -0
  172. package/dist/vocabulary/options.js.map +1 -0
  173. package/dist/vocabulary/tools.d.ts +7 -0
  174. package/dist/vocabulary/tools.js +99 -0
  175. package/dist/vocabulary/tools.js.map +1 -0
  176. package/dist/vocabulary/types.d.ts +20 -0
  177. package/dist/vocabulary/types.js +3 -0
  178. package/dist/vocabulary/types.js.map +1 -0
  179. package/frontend-vue/app/chat/components/AnswerRecord.vue +95 -0
  180. package/frontend-vue/app/chat/components/ApprovalDock.vue +371 -0
  181. package/frontend-vue/app/chat/components/ChangeSetCard.vue +297 -0
  182. package/frontend-vue/app/chat/components/ChatEmpty.vue +142 -0
  183. package/frontend-vue/app/chat/components/ChatView.vue +664 -406
  184. package/frontend-vue/app/chat/components/Composer.vue +589 -0
  185. package/frontend-vue/app/chat/components/ConnectionBanner.vue +41 -65
  186. package/frontend-vue/app/chat/components/ConversationDrawer.vue +387 -177
  187. package/frontend-vue/app/chat/components/DiffView.vue +131 -0
  188. package/frontend-vue/app/chat/components/FullAutoBanner.vue +76 -0
  189. package/frontend-vue/app/chat/components/FullAutoDialog.vue +103 -0
  190. package/frontend-vue/app/chat/components/MarkdownContent.vue +15 -15
  191. package/frontend-vue/app/chat/components/MessageList.vue +389 -295
  192. package/frontend-vue/app/chat/components/NoticeCard.vue +193 -0
  193. package/frontend-vue/app/chat/components/PanelHeader.vue +242 -0
  194. package/frontend-vue/app/chat/components/PermissionCard.vue +470 -0
  195. package/frontend-vue/app/chat/components/PlanCard.vue +115 -0
  196. package/frontend-vue/app/chat/components/QuestionDock.vue +407 -0
  197. package/frontend-vue/app/chat/components/QueueDock.vue +310 -0
  198. package/frontend-vue/app/chat/components/RulesList.vue +97 -0
  199. package/frontend-vue/app/chat/components/StepsDock.vue +181 -0
  200. package/frontend-vue/app/chat/components/ToolCluster.vue +186 -178
  201. package/frontend-vue/app/chat/components/ToolRow.vue +251 -0
  202. package/frontend-vue/app/chat/components/TurnErrorCard.vue +135 -0
  203. package/frontend-vue/app/chat/composables/conversation-events.ts +404 -0
  204. package/frontend-vue/app/chat/composables/useChangeSetActions.ts +135 -0
  205. package/frontend-vue/app/chat/composables/useChatChannel.ts +11 -3
  206. package/frontend-vue/app/chat/composables/useChatI18n.ts +35 -0
  207. package/frontend-vue/app/chat/composables/useComposerAttachments.ts +111 -0
  208. package/frontend-vue/app/chat/composables/useConversation.ts +149 -651
  209. package/frontend-vue/app/chat/composables/useConversationId.ts +2 -10
  210. package/frontend-vue/app/chat/composables/useConversationList.ts +77 -21
  211. package/frontend-vue/app/chat/composables/useConversationMode.ts +73 -0
  212. package/frontend-vue/app/chat/composables/usePaletteTurn.ts +124 -0
  213. package/frontend-vue/app/chat/composables/usePermissionQueue.ts +211 -34
  214. package/frontend-vue/app/chat/composables/useQuestionQueue.ts +103 -21
  215. package/frontend-vue/app/chat/composables/useQueueActions.ts +55 -0
  216. package/frontend-vue/app/chat/composables/useSettings.ts +17 -34
  217. package/frontend-vue/app/chat/constants/attachments.ts +2 -1
  218. package/frontend-vue/app/chat/constants/conversation.ts +18 -32
  219. package/frontend-vue/app/chat/constants/protocol.ts +25 -2
  220. package/frontend-vue/app/chat/constants/run-status.ts +8 -14
  221. package/frontend-vue/app/chat/constants/settings.ts +5 -47
  222. package/frontend-vue/app/chat/types/conversation.ts +72 -2
  223. package/frontend-vue/app/chat/types/permission.ts +31 -0
  224. package/frontend-vue/app/chat/types/protocol.ts +226 -0
  225. package/frontend-vue/app/chat/types/question.ts +10 -1
  226. package/frontend-vue/app/chat/types/settings.ts +9 -5
  227. package/frontend-vue/app/chat/utils/approval-keyboard.ts +49 -0
  228. package/frontend-vue/app/chat/utils/arrays.ts +10 -0
  229. package/frontend-vue/app/chat/utils/conversation-groups.ts +96 -0
  230. package/frontend-vue/app/chat/utils/conversation-messages.ts +251 -0
  231. package/frontend-vue/app/chat/utils/diff.ts +78 -0
  232. package/frontend-vue/app/chat/utils/format.ts +43 -0
  233. package/frontend-vue/app/chat/utils/markdown.ts +1 -1
  234. package/frontend-vue/app/chat/utils/permission-view.ts +159 -0
  235. package/frontend-vue/app/chat/utils/platform.ts +34 -0
  236. package/frontend-vue/app/chat/utils/queue.ts +18 -0
  237. package/frontend-vue/app/chat/utils/render-items.ts +164 -0
  238. package/frontend-vue/app/chat/utils/run-status.ts +19 -23
  239. package/frontend-vue/app/chat/utils/suggestions.ts +101 -0
  240. package/frontend-vue/app/chat/utils/todos.ts +2 -2
  241. package/frontend-vue/app/chat/utils/tool-lexicon.ts +540 -0
  242. package/frontend-vue/app/chat/utils/tool-state.ts +60 -0
  243. package/frontend-vue/app/components/ActivityDetail.vue +235 -0
  244. package/frontend-vue/app/components/ChangesView.vue +249 -0
  245. package/frontend-vue/app/components/ChatPanel.vue +141 -196
  246. package/frontend-vue/app/components/PaletteAnswer.vue +185 -0
  247. package/frontend-vue/app/components/SkillCard.vue +77 -0
  248. package/frontend-vue/app/components/SkillDetail.vue +188 -0
  249. package/frontend-vue/app/plugins/ai.client.ts +349 -57
  250. package/frontend-vue/app/plugins/side-panel.ts +13 -0
  251. package/frontend-vue/app/runtime/assistant-activity.ts +105 -0
  252. package/frontend-vue/app/runtime/assistant-commands.ts +210 -0
  253. package/frontend-vue/app/runtime/assistant-notifications.ts +181 -0
  254. package/frontend-vue/app/runtime/assistant-session.ts +49 -6
  255. package/frontend-vue/app/runtime/channel-client.ts +3 -6
  256. package/frontend-vue/app/runtime/constants.ts +29 -35
  257. package/frontend-vue/app/runtime/host-commands.ts +4 -4
  258. package/frontend-vue/app/runtime/listeners.ts +1 -1
  259. package/frontend-vue/app/runtime/navigation-complete.ts +1 -1
  260. package/frontend-vue/app/runtime/panel-intents.ts +55 -0
  261. package/frontend-vue/app/runtime/shortcuts.ts +3 -1
  262. package/frontend-vue/app/runtime/sidecar-status.ts +9 -1
  263. package/frontend-vue/app/runtime/stream-holds.ts +24 -0
  264. package/frontend-vue/app/views/ChangeSetPanel.vue +222 -0
  265. package/frontend-vue/app/views/DecisionLabel.vue +30 -0
  266. package/frontend-vue/app/views/DiffView.vue +215 -0
  267. package/frontend-vue/app/views/ResultPill.vue +32 -0
  268. package/frontend-vue/app/views/RowStepper.vue +48 -0
  269. package/frontend-vue/app/views/UnavailableState.vue +66 -0
  270. package/frontend-vue/app/views/composables/useAiRequest.ts +89 -0
  271. package/frontend-vue/app/views/composables/useAssistant.ts +33 -0
  272. package/frontend-vue/app/views/composables/useChangeSetActions.ts +102 -0
  273. package/frontend-vue/app/views/composables/useViewFormat.ts +55 -0
  274. package/frontend-vue/app/views/constants.ts +43 -0
  275. package/frontend-vue/app/views/types.ts +189 -0
  276. package/frontend-vue/app/views/utils/activity.ts +77 -0
  277. package/frontend-vue/app/views/utils/change-sets.ts +44 -0
  278. package/frontend-vue/app/views/utils/diff.ts +98 -0
  279. package/frontend-vue/app/views/utils/moment.ts +92 -0
  280. package/frontend-vue/app/views/utils/skills.ts +27 -0
  281. package/frontend-vue/app/views/utils/tools.ts +73 -0
  282. package/frontend-vue/dms.frontend.ts +17 -5
  283. package/frontend-vue/i18n/locales/dms-ai-pages-en-GB.json +607 -0
  284. package/frontend-vue/i18n/locales/dms-ai-pages-fr-FR.json +607 -0
  285. package/frontend-vue/i18n/locales/dms-ai-panel-en-GB.json +425 -0
  286. package/frontend-vue/i18n/locales/dms-ai-panel-fr-FR.json +425 -0
  287. package/frontend-vue/i18n/locales/dms-ai-views-en-GB.json +142 -0
  288. package/frontend-vue/i18n/locales/dms-ai-views-fr-FR.json +142 -0
  289. package/frontend-vue/package.json +1 -1
  290. package/frontend-vue/tests/chat/conversation-events.test.ts +590 -0
  291. package/frontend-vue/tests/chat/diff-and-keys.test.ts +178 -0
  292. package/frontend-vue/tests/chat/tool-lexicon.test.ts +188 -0
  293. package/frontend-vue/tests/chat/useConversation.test.ts +36 -33
  294. package/frontend-vue/tests/chat-panel.test.ts +78 -131
  295. package/frontend-vue/tests/i18n-panel.test.ts +118 -0
  296. package/frontend-vue/tests/palette-assistant.test.ts +220 -0
  297. package/frontend-vue/tests/panel-states.test.ts +806 -0
  298. package/frontend-vue/tests/sidecar-guest.test.ts +35 -3
  299. package/frontend-vue/tests/support/i18n.ts +49 -0
  300. package/frontend-vue/tests/support/panel-harness.ts +198 -0
  301. package/frontend-vue/tests/support/stubs.ts +201 -0
  302. package/frontend-vue/tests/views/diff-view.test.ts +149 -0
  303. package/frontend-vue/tests/views/view-format.test.ts +59 -0
  304. package/package.json +5 -3
  305. package/sidecar/dist/agent/attachment-files.d.ts +0 -1
  306. package/sidecar/dist/agent/attachment-files.js +1 -1
  307. package/sidecar/dist/agent/attachment-files.js.map +1 -1
  308. package/sidecar/dist/agent/call-ledger.d.ts +6 -0
  309. package/sidecar/dist/agent/call-ledger.js +41 -0
  310. package/sidecar/dist/agent/call-ledger.js.map +1 -0
  311. package/sidecar/dist/agent/command-analysis.d.ts +9 -0
  312. package/sidecar/dist/agent/command-analysis.js +104 -0
  313. package/sidecar/dist/agent/command-analysis.js.map +1 -0
  314. package/sidecar/dist/agent/conversation-modes.d.ts +32 -0
  315. package/sidecar/dist/agent/conversation-modes.js +122 -0
  316. package/sidecar/dist/agent/conversation-modes.js.map +1 -0
  317. package/sidecar/dist/agent/edit-targets.d.ts +5 -0
  318. package/sidecar/dist/agent/edit-targets.js +41 -0
  319. package/sidecar/dist/agent/edit-targets.js.map +1 -0
  320. package/sidecar/dist/agent/effective-mode.d.ts +9 -2
  321. package/sidecar/dist/agent/effective-mode.js +14 -16
  322. package/sidecar/dist/agent/effective-mode.js.map +1 -1
  323. package/sidecar/dist/agent/host-context.js +2 -2
  324. package/sidecar/dist/agent/host-context.js.map +1 -1
  325. package/sidecar/dist/agent/line-diff.d.ts +8 -0
  326. package/sidecar/dist/agent/line-diff.js +204 -0
  327. package/sidecar/dist/agent/line-diff.js.map +1 -0
  328. package/sidecar/dist/agent/permission-bus.d.ts +55 -10
  329. package/sidecar/dist/agent/permission-bus.js +130 -100
  330. package/sidecar/dist/agent/permission-bus.js.map +1 -1
  331. package/sidecar/dist/agent/permission-preview.d.ts +20 -0
  332. package/sidecar/dist/agent/permission-preview.js +203 -0
  333. package/sidecar/dist/agent/permission-preview.js.map +1 -0
  334. package/sidecar/dist/agent/permission-rules.d.ts +17 -0
  335. package/sidecar/dist/agent/permission-rules.js +95 -0
  336. package/sidecar/dist/agent/permission-rules.js.map +1 -0
  337. package/sidecar/dist/agent/provider.d.ts +12 -4
  338. package/sidecar/dist/agent/question-bus.d.ts +14 -2
  339. package/sidecar/dist/agent/question-bus.js +30 -11
  340. package/sidecar/dist/agent/question-bus.js.map +1 -1
  341. package/sidecar/dist/agent/runner-events.d.ts +3 -1
  342. package/sidecar/dist/agent/runner.d.ts +6 -4
  343. package/sidecar/dist/agent/runner.js +24 -7
  344. package/sidecar/dist/agent/runner.js.map +1 -1
  345. package/sidecar/dist/agent/switching-runner.js +1 -0
  346. package/sidecar/dist/agent/switching-runner.js.map +1 -1
  347. package/sidecar/dist/agent/tool-kinds.d.ts +12 -0
  348. package/sidecar/dist/agent/tool-kinds.js +50 -0
  349. package/sidecar/dist/agent/tool-kinds.js.map +1 -0
  350. package/sidecar/dist/agent/typecheck.d.ts +2 -6
  351. package/sidecar/dist/audit/activity-query.d.ts +37 -0
  352. package/sidecar/dist/audit/activity-query.js +111 -0
  353. package/sidecar/dist/audit/activity-query.js.map +1 -0
  354. package/sidecar/dist/audit/activity-target.d.ts +2 -0
  355. package/sidecar/dist/audit/activity-target.js +46 -0
  356. package/sidecar/dist/audit/activity-target.js.map +1 -0
  357. package/sidecar/dist/audit/activity.d.ts +45 -0
  358. package/sidecar/dist/audit/activity.js +255 -0
  359. package/sidecar/dist/audit/activity.js.map +1 -0
  360. package/sidecar/dist/audit/call-audit.d.ts +11 -0
  361. package/sidecar/dist/audit/call-audit.js +23 -0
  362. package/sidecar/dist/audit/call-audit.js.map +1 -0
  363. package/sidecar/dist/checkpoints/checkpoints.d.ts +69 -0
  364. package/sidecar/dist/checkpoints/checkpoints.js +244 -0
  365. package/sidecar/dist/checkpoints/checkpoints.js.map +1 -0
  366. package/sidecar/dist/checkpoints/shadow-git.d.ts +23 -0
  367. package/sidecar/dist/checkpoints/shadow-git.js +173 -0
  368. package/sidecar/dist/checkpoints/shadow-git.js.map +1 -0
  369. package/sidecar/dist/constants/agent.d.ts +2 -0
  370. package/sidecar/dist/constants/agent.js +4 -0
  371. package/sidecar/dist/constants/agent.js.map +1 -1
  372. package/sidecar/dist/constants/audit.d.ts +22 -0
  373. package/sidecar/dist/constants/audit.js +49 -0
  374. package/sidecar/dist/constants/audit.js.map +1 -0
  375. package/sidecar/dist/constants/builder.d.ts +3 -0
  376. package/sidecar/dist/constants/builder.js +2 -0
  377. package/sidecar/dist/constants/builder.js.map +1 -1
  378. package/sidecar/dist/constants/checkpoints.d.ts +15 -0
  379. package/sidecar/dist/constants/checkpoints.js +26 -0
  380. package/sidecar/dist/constants/checkpoints.js.map +1 -0
  381. package/sidecar/dist/constants/claude.d.ts +1 -0
  382. package/sidecar/dist/constants/claude.js +1 -0
  383. package/sidecar/dist/constants/claude.js.map +1 -1
  384. package/sidecar/dist/constants/codex.d.ts +2 -4
  385. package/sidecar/dist/constants/codex.js +2 -4
  386. package/sidecar/dist/constants/codex.js.map +1 -1
  387. package/sidecar/dist/constants/http.d.ts +1 -0
  388. package/sidecar/dist/constants/http.js +1 -0
  389. package/sidecar/dist/constants/http.js.map +1 -1
  390. package/sidecar/dist/constants/mcp.d.ts +3 -0
  391. package/sidecar/dist/constants/mcp.js +9 -0
  392. package/sidecar/dist/constants/mcp.js.map +1 -1
  393. package/sidecar/dist/constants/permissions.d.ts +9 -3
  394. package/sidecar/dist/constants/permissions.js +9 -2
  395. package/sidecar/dist/constants/permissions.js.map +1 -1
  396. package/sidecar/dist/constants/settings.d.ts +2 -1
  397. package/sidecar/dist/constants/settings.js +7 -1
  398. package/sidecar/dist/constants/settings.js.map +1 -1
  399. package/sidecar/dist/constants/tool-kinds.d.ts +14 -0
  400. package/sidecar/dist/constants/tool-kinds.js +65 -0
  401. package/sidecar/dist/constants/tool-kinds.js.map +1 -0
  402. package/sidecar/dist/index.d.ts +4 -0
  403. package/sidecar/dist/index.js +35 -5
  404. package/sidecar/dist/index.js.map +1 -1
  405. package/sidecar/dist/mcp/define-tool.d.ts +3 -2
  406. package/sidecar/dist/mcp/tool-definitions.js +4 -1
  407. package/sidecar/dist/mcp/tool-definitions.js.map +1 -1
  408. package/sidecar/dist/mcp/tools/ask-user.d.ts +2 -2
  409. package/sidecar/dist/mcp/tools/ask-user.js +7 -4
  410. package/sidecar/dist/mcp/tools/ask-user.js.map +1 -1
  411. package/sidecar/dist/mcp/tools/builder-catalog.d.ts +3 -0
  412. package/sidecar/dist/mcp/tools/builder-catalog.js +86 -0
  413. package/sidecar/dist/mcp/tools/builder-catalog.js.map +1 -0
  414. package/sidecar/dist/mcp/tools/builder-gate.d.ts +8 -0
  415. package/sidecar/dist/mcp/tools/builder-gate.js +22 -0
  416. package/sidecar/dist/mcp/tools/builder-gate.js.map +1 -0
  417. package/sidecar/dist/mcp/tools/builder.d.ts +7 -2
  418. package/sidecar/dist/mcp/tools/builder.js +48 -7
  419. package/sidecar/dist/mcp/tools/builder.js.map +1 -1
  420. package/sidecar/dist/mcp/types.d.ts +2 -0
  421. package/sidecar/dist/metrics/aggregate.d.ts +13 -10
  422. package/sidecar/dist/metrics/aggregate.js +140 -143
  423. package/sidecar/dist/metrics/aggregate.js.map +1 -1
  424. package/sidecar/dist/metrics/types.d.ts +36 -23
  425. package/sidecar/dist/metrics/types.js +3 -1
  426. package/sidecar/dist/metrics/types.js.map +1 -1
  427. package/sidecar/dist/pages/imports-scanner.d.ts +1 -1
  428. package/sidecar/dist/pages/imports-scanner.js +2 -5
  429. package/sidecar/dist/pages/imports-scanner.js.map +1 -1
  430. package/sidecar/dist/prompts/agent.d.ts +1 -3
  431. package/sidecar/dist/prompts/agent.js +4 -4
  432. package/sidecar/dist/prompts/agent.js.map +1 -1
  433. package/sidecar/dist/prompts/builder.d.ts +2 -2
  434. package/sidecar/dist/prompts/builder.js +2 -2
  435. package/sidecar/dist/protocol/events.d.ts +1084 -18
  436. package/sidecar/dist/protocol/events.js +239 -5
  437. package/sidecar/dist/protocol/events.js.map +1 -1
  438. package/sidecar/dist/protocol/messages.d.ts +273 -19
  439. package/sidecar/dist/protocol/messages.js +107 -7
  440. package/sidecar/dist/protocol/messages.js.map +1 -1
  441. package/sidecar/dist/providers/claude/config.d.ts +3 -2
  442. package/sidecar/dist/providers/claude/config.js +10 -4
  443. package/sidecar/dist/providers/claude/config.js.map +1 -1
  444. package/sidecar/dist/providers/claude/provider.d.ts +2 -8
  445. package/sidecar/dist/providers/claude/provider.js +37 -35
  446. package/sidecar/dist/providers/claude/provider.js.map +1 -1
  447. package/sidecar/dist/providers/claude/safe-mode.d.ts +6 -1
  448. package/sidecar/dist/providers/claude/safe-mode.js +13 -5
  449. package/sidecar/dist/providers/claude/safe-mode.js.map +1 -1
  450. package/sidecar/dist/providers/codex/adapter.d.ts +6 -0
  451. package/sidecar/dist/providers/codex/adapter.js +14 -4
  452. package/sidecar/dist/providers/codex/adapter.js.map +1 -1
  453. package/sidecar/dist/providers/codex/client.d.ts +0 -11
  454. package/sidecar/dist/providers/codex/config.d.ts +1 -3
  455. package/sidecar/dist/providers/codex/config.js +5 -11
  456. package/sidecar/dist/providers/codex/config.js.map +1 -1
  457. package/sidecar/dist/providers/codex/permissions.d.ts +7 -4
  458. package/sidecar/dist/providers/codex/permissions.js +32 -16
  459. package/sidecar/dist/providers/codex/permissions.js.map +1 -1
  460. package/sidecar/dist/providers/codex/process.js +1 -5
  461. package/sidecar/dist/providers/codex/process.js.map +1 -1
  462. package/sidecar/dist/providers/codex/provider.js +14 -3
  463. package/sidecar/dist/providers/codex/provider.js.map +1 -1
  464. package/sidecar/dist/providers/codex/skills.d.ts +0 -1
  465. package/sidecar/dist/providers/codex/skills.js +1 -1
  466. package/sidecar/dist/providers/codex/skills.js.map +1 -1
  467. package/sidecar/dist/providers/codex/stop.js +1 -10
  468. package/sidecar/dist/providers/codex/stop.js.map +1 -1
  469. package/sidecar/dist/server/change-set-actions.d.ts +10 -0
  470. package/sidecar/dist/server/change-set-actions.js +14 -0
  471. package/sidecar/dist/server/change-set-actions.js.map +1 -0
  472. package/sidecar/dist/server/chat-events.d.ts +15 -0
  473. package/sidecar/dist/server/chat-events.js +115 -0
  474. package/sidecar/dist/server/chat-events.js.map +1 -0
  475. package/sidecar/dist/server/chat-socket-registry.d.ts +2 -0
  476. package/sidecar/dist/server/chat-socket-registry.js +48 -37
  477. package/sidecar/dist/server/chat-socket-registry.js.map +1 -1
  478. package/sidecar/dist/server/conversation-runs.d.ts +13 -0
  479. package/sidecar/dist/server/conversation-runs.js +114 -0
  480. package/sidecar/dist/server/conversation-runs.js.map +1 -0
  481. package/sidecar/dist/server/http-io.d.ts +4 -0
  482. package/sidecar/dist/server/http-io.js +31 -0
  483. package/sidecar/dist/server/http-io.js.map +1 -0
  484. package/sidecar/dist/server/http-params.d.ts +9 -0
  485. package/sidecar/dist/server/http-params.js +79 -0
  486. package/sidecar/dist/server/http-params.js.map +1 -0
  487. package/sidecar/dist/server/http-routes.d.ts +27 -0
  488. package/sidecar/dist/server/http-routes.js +281 -0
  489. package/sidecar/dist/server/http-routes.js.map +1 -0
  490. package/sidecar/dist/server/http.d.ts +6 -1
  491. package/sidecar/dist/server/http.js +76 -164
  492. package/sidecar/dist/server/http.js.map +1 -1
  493. package/sidecar/dist/server/pending-queue.d.ts +2 -0
  494. package/sidecar/dist/server/pending-queue.js +16 -0
  495. package/sidecar/dist/server/pending-queue.js.map +1 -1
  496. package/sidecar/dist/server/permission-events.d.ts +15 -0
  497. package/sidecar/dist/server/permission-events.js +163 -0
  498. package/sidecar/dist/server/permission-events.js.map +1 -0
  499. package/sidecar/dist/server/routing.d.ts +4 -52
  500. package/sidecar/dist/server/routing.js +190 -501
  501. package/sidecar/dist/server/routing.js.map +1 -1
  502. package/sidecar/dist/server/safety-net.d.ts +7 -0
  503. package/sidecar/dist/server/safety-net.js +34 -6
  504. package/sidecar/dist/server/safety-net.js.map +1 -1
  505. package/sidecar/dist/server/services.d.ts +55 -0
  506. package/sidecar/dist/server/services.js +2 -0
  507. package/sidecar/dist/server/services.js.map +1 -0
  508. package/sidecar/dist/server/tool-calls.d.ts +6 -0
  509. package/sidecar/dist/server/tool-calls.js +134 -0
  510. package/sidecar/dist/server/tool-calls.js.map +1 -0
  511. package/sidecar/dist/server/turn-registry.d.ts +44 -0
  512. package/sidecar/dist/server/turn-registry.js +40 -0
  513. package/sidecar/dist/server/turn-registry.js.map +1 -0
  514. package/sidecar/dist/server/turns.d.ts +17 -0
  515. package/sidecar/dist/server/turns.js +335 -0
  516. package/sidecar/dist/server/turns.js.map +1 -0
  517. package/sidecar/dist/server/ws.d.ts +4 -1
  518. package/sidecar/dist/server/ws.js +102 -62
  519. package/sidecar/dist/server/ws.js.map +1 -1
  520. package/sidecar/dist/skills/build-catalog.d.ts +1 -0
  521. package/sidecar/dist/skills/build-catalog.js +14 -1
  522. package/sidecar/dist/skills/build-catalog.js.map +1 -1
  523. package/sidecar/dist/skills/skill-usage.d.ts +22 -0
  524. package/sidecar/dist/skills/skill-usage.js +97 -0
  525. package/sidecar/dist/skills/skill-usage.js.map +1 -0
  526. package/sidecar/dist/state/change-sets.d.ts +12 -0
  527. package/sidecar/dist/state/change-sets.js +77 -0
  528. package/sidecar/dist/state/change-sets.js.map +1 -0
  529. package/sidecar/dist/state/conversations.d.ts +19 -7
  530. package/sidecar/dist/state/conversations.js +61 -20
  531. package/sidecar/dist/state/conversations.js.map +1 -1
  532. package/sidecar/dist/state/host-state.d.ts +2 -1
  533. package/sidecar/dist/state/settings-store.d.ts +1 -0
  534. package/sidecar/dist/state/settings-store.js +27 -26
  535. package/sidecar/dist/state/settings-store.js.map +1 -1
  536. package/sidecar/dist/state/settings-types.d.ts +11 -1
  537. package/sidecar/dist/state/settings-types.js +3 -1
  538. package/sidecar/dist/state/settings-types.js.map +1 -1
  539. package/sidecar/dist/state/types.d.ts +114 -8
  540. package/sidecar/dist/state/types.js +6 -3
  541. package/sidecar/dist/state/types.js.map +1 -1
  542. package/skills/dms-builder-safe/REFERENCE.md +1 -1
  543. package/skills/dms-builder-safe/SKILL.md +12 -7
  544. package/dist/routes/proxy.d.ts +0 -4
  545. package/dist/routes/proxy.js +0 -55
  546. package/dist/routes/proxy.js.map +0 -1
  547. package/frontend-vue/app/chat/components/ComposerInput.vue +0 -742
  548. package/frontend-vue/app/chat/components/PermissionRequests.vue +0 -323
  549. package/frontend-vue/app/chat/components/QuestionPrompt.vue +0 -275
  550. package/frontend-vue/app/chat/components/QueuedMessages.vue +0 -109
  551. package/frontend-vue/app/chat/components/TodoList.vue +0 -291
  552. package/frontend-vue/app/chat/components/ToolCallEntry.vue +0 -218
  553. package/frontend-vue/app/chat/constants/connection-banner.ts +0 -7
  554. package/frontend-vue/app/chat/constants/conversation-drawer.ts +0 -13
  555. package/frontend-vue/app/chat/constants/permissions.ts +0 -50
  556. package/frontend-vue/app/chat/utils/tool-summary.ts +0 -53
  557. package/frontend-vue/app/components/ActivityView.vue +0 -94
  558. package/frontend-vue/app/components/SettingsView.vue +0 -387
  559. package/frontend-vue/app/components/SkillsView.vue +0 -230
  560. package/frontend-vue/app/runtime/header-action.ts +0 -64
  561. package/frontend-vue/app/runtime/overlay-prefs.ts +0 -89
  562. package/frontend-vue/app/runtime/panel-state.ts +0 -88
  563. package/frontend-vue/tests/overlay-prefs.test.ts +0 -91
  564. package/frontend-vue/tests/panel-state.test.ts +0 -58
@@ -0,0 +1,251 @@
1
+ import {
2
+ MESSAGE_ROLES,
3
+ STORED_ERROR_ROLE,
4
+ STORED_TOOL_RESULT_ROLE,
5
+ STORED_TOOL_USE_ROLE,
6
+ TOOL_STATUS,
7
+ } from "../constants/conversation";
8
+ import type {
9
+ AssistantMessage,
10
+ ConversationMessage,
11
+ ErrorMessage,
12
+ MessageAttachment,
13
+ ToolCallMessage,
14
+ ToolStatus,
15
+ UserMessage,
16
+ } from "../types/conversation";
17
+ import type { SnapshotMessage, ToolOutcome } from "../types/protocol";
18
+ import { newUuid } from "./ids";
19
+
20
+ const STOPPED_OUTCOME: ToolOutcome = "stopped";
21
+
22
+ const STATUS_BY_OUTCOME: Record<ToolOutcome, ToolStatus> = {
23
+ done: TOOL_STATUS.SUCCESS,
24
+ failed: TOOL_STATUS.ERROR,
25
+ denied: TOOL_STATUS.ERROR,
26
+ blocked: TOOL_STATUS.ERROR,
27
+ stopped: TOOL_STATUS.ERROR,
28
+ };
29
+
30
+ export function buildUserMessage(
31
+ content: string,
32
+ attachments?: MessageAttachment[],
33
+ pagePath?: string,
34
+ timestampMs: number = Date.now(),
35
+ ): UserMessage {
36
+ return {
37
+ id: newUuid(),
38
+ role: MESSAGE_ROLES.USER,
39
+ content,
40
+ attachments,
41
+ pagePath,
42
+ timestampMs,
43
+ };
44
+ }
45
+
46
+ export function buildAssistantMessage(
47
+ content: string,
48
+ timestampMs: number = Date.now(),
49
+ ): AssistantMessage {
50
+ return {
51
+ id: newUuid(),
52
+ role: MESSAGE_ROLES.ASSISTANT,
53
+ content,
54
+ timestampMs,
55
+ };
56
+ }
57
+
58
+ export function buildErrorMessage(
59
+ content: string,
60
+ isRetryable: boolean,
61
+ timestampMs: number = Date.now(),
62
+ ): ErrorMessage {
63
+ return {
64
+ id: newUuid(),
65
+ role: MESSAGE_ROLES.ERROR,
66
+ content,
67
+ isRetryable,
68
+ timestampMs,
69
+ };
70
+ }
71
+
72
+ /** An error the chat raises itself, translated when drawn. */
73
+ export function buildLocalError(
74
+ contentKey: string,
75
+ isRetryable = true,
76
+ ): ErrorMessage {
77
+ return {
78
+ ...buildErrorMessage("", isRetryable),
79
+ contentKey,
80
+ isLocal: true,
81
+ };
82
+ }
83
+
84
+ function normalizeToolStatus(raw: string | undefined): ToolStatus {
85
+ if (raw === TOOL_STATUS.SUCCESS) return TOOL_STATUS.SUCCESS;
86
+ if (raw === TOOL_STATUS.ERROR) return TOOL_STATUS.ERROR;
87
+ return TOOL_STATUS.PENDING;
88
+ }
89
+
90
+ /** The status a closed call reports: its outcome's, else the wire status. */
91
+ export function closedStatus(
92
+ outcome: ToolOutcome | undefined,
93
+ status: string | undefined,
94
+ ): ToolStatus {
95
+ if (outcome !== undefined) return STATUS_BY_OUTCOME[outcome];
96
+ const normalized = normalizeToolStatus(status);
97
+ return normalized === TOOL_STATUS.PENDING ? TOOL_STATUS.SUCCESS : normalized;
98
+ }
99
+
100
+ function safeParse(raw: string): unknown {
101
+ try {
102
+ return JSON.parse(raw);
103
+ } catch {
104
+ return raw;
105
+ }
106
+ }
107
+
108
+ function isOpenTool(msg: ConversationMessage): msg is ToolCallMessage {
109
+ return (
110
+ msg.role === MESSAGE_ROLES.TOOL &&
111
+ msg.outcome === undefined &&
112
+ msg.status === TOOL_STATUS.PENDING
113
+ );
114
+ }
115
+
116
+ /** Calls a finished turn left open: it ended before they did. */
117
+ export function settleOpenTools(
118
+ list: ConversationMessage[],
119
+ ): ConversationMessage[] {
120
+ if (!list.some(isOpenTool)) return list;
121
+ return list.map((msg) => {
122
+ if (!isOpenTool(msg)) return msg;
123
+ return { ...msg, status: TOOL_STATUS.ERROR, outcome: STOPPED_OUTCOME };
124
+ });
125
+ }
126
+
127
+ interface SnapshotBuild {
128
+ out: ConversationMessage[];
129
+ toolByCallId: Map<string, ToolCallMessage>;
130
+ }
131
+
132
+ function toolFromUse(snap: SnapshotMessage): ToolCallMessage | null {
133
+ if (snap.callId === undefined || snap.toolName === undefined) return null;
134
+ return {
135
+ id: newUuid(),
136
+ role: MESSAGE_ROLES.TOOL,
137
+ callId: snap.callId,
138
+ toolName: snap.toolName,
139
+ args: safeParse(snap.content),
140
+ status: TOOL_STATUS.PENDING,
141
+ allowedBy: snap.allowedBy,
142
+ timestampMs: snap.timestampMs,
143
+ };
144
+ }
145
+
146
+ function closeFromResult(tool: ToolCallMessage, snap: SnapshotMessage): void {
147
+ tool.result = safeParse(snap.content);
148
+ tool.status = closedStatus(snap.outcome, snap.status);
149
+ tool.outcome = snap.outcome;
150
+ tool.allowedBy = snap.allowedBy ?? tool.allowedBy;
151
+ tool.changeSetId = snap.changeSetId;
152
+ tool.endedAtMs = snap.timestampMs;
153
+ }
154
+
155
+ function addToolUse(build: SnapshotBuild, snap: SnapshotMessage): void {
156
+ const tool = toolFromUse(snap);
157
+ if (tool === null) return;
158
+ build.out.push(tool);
159
+ build.toolByCallId.set(tool.callId, tool);
160
+ }
161
+
162
+ function addToolResult(build: SnapshotBuild, snap: SnapshotMessage): void {
163
+ if (snap.callId === undefined) return;
164
+ const existing = build.toolByCallId.get(snap.callId);
165
+ if (existing !== undefined) {
166
+ closeFromResult(existing, snap);
167
+ return;
168
+ }
169
+ const orphan = toolFromUse({ ...snap, toolName: snap.toolName ?? "" });
170
+ if (orphan === null) return;
171
+ closeFromResult(orphan, snap);
172
+ build.out.push(orphan);
173
+ }
174
+
175
+ function addUser(build: SnapshotBuild, snap: SnapshotMessage): void {
176
+ build.out.push(
177
+ buildUserMessage(
178
+ snap.content,
179
+ snap.attachments,
180
+ undefined,
181
+ snap.timestampMs,
182
+ ),
183
+ );
184
+ }
185
+
186
+ function addAssistant(build: SnapshotBuild, snap: SnapshotMessage): void {
187
+ build.out.push(buildAssistantMessage(snap.content, snap.timestampMs));
188
+ }
189
+
190
+ function addError(build: SnapshotBuild, snap: SnapshotMessage): void {
191
+ build.out.push(
192
+ buildErrorMessage(snap.content, snap.isRetryable ?? true, snap.timestampMs),
193
+ );
194
+ }
195
+
196
+ function addNotice(build: SnapshotBuild, snap: SnapshotMessage): void {
197
+ if (snap.notice === undefined) return;
198
+ build.out.push({
199
+ id: newUuid(),
200
+ role: MESSAGE_ROLES.NOTICE,
201
+ notice: snap.notice,
202
+ timestampMs: snap.timestampMs,
203
+ });
204
+ }
205
+
206
+ function addChangeSet(build: SnapshotBuild, snap: SnapshotMessage): void {
207
+ if (snap.changeSetId === undefined) return;
208
+ build.out.push({
209
+ id: newUuid(),
210
+ role: MESSAGE_ROLES.CHANGE_SET,
211
+ changeSetId: snap.changeSetId,
212
+ timestampMs: snap.timestampMs,
213
+ });
214
+ }
215
+
216
+ function addQuestionAnswer(build: SnapshotBuild, snap: SnapshotMessage): void {
217
+ if (snap.answers === undefined || snap.answers.length === 0) return;
218
+ build.out.push({
219
+ id: newUuid(),
220
+ role: MESSAGE_ROLES.QUESTION_ANSWER,
221
+ answers: snap.answers,
222
+ timestampMs: snap.timestampMs,
223
+ });
224
+ }
225
+
226
+ const SNAPSHOT_BUILDERS: Record<
227
+ string,
228
+ (build: SnapshotBuild, snap: SnapshotMessage) => void
229
+ > = {
230
+ [MESSAGE_ROLES.USER]: addUser,
231
+ [MESSAGE_ROLES.ASSISTANT]: addAssistant,
232
+ [STORED_ERROR_ROLE]: addError,
233
+ [STORED_TOOL_USE_ROLE]: addToolUse,
234
+ [STORED_TOOL_RESULT_ROLE]: addToolResult,
235
+ [MESSAGE_ROLES.NOTICE]: addNotice,
236
+ [MESSAGE_ROLES.CHANGE_SET]: addChangeSet,
237
+ [MESSAGE_ROLES.QUESTION_ANSWER]: addQuestionAnswer,
238
+ };
239
+
240
+ /**
241
+ * The stored transcript as the chat draws it. Calls left open stay open: the
242
+ * turn may be resuming, and the row tells running from stopped by whether it
243
+ * is.
244
+ */
245
+ export function snapshotToMessages(
246
+ snapshot: readonly SnapshotMessage[],
247
+ ): ConversationMessage[] {
248
+ const build: SnapshotBuild = { out: [], toolByCallId: new Map() };
249
+ for (const item of snapshot) SNAPSHOT_BUILDERS[item.role]?.(build, item);
250
+ return build.out;
251
+ }
@@ -0,0 +1,78 @@
1
+ import type { DiffHunk, DiffLine } from "../types/protocol";
2
+
3
+ type DiffRowKind = "hunk" | "context" | "add" | "remove";
4
+
5
+ /** One line of a unified diff as drawn: number, sign, text. */
6
+ export interface DiffRow {
7
+ key: string;
8
+ kind: DiffRowKind;
9
+ /** The line's number in the file it belongs to: new for added and context, old for removed. */
10
+ number: string;
11
+ sign: string;
12
+ text: string;
13
+ }
14
+
15
+ const SIGN_BY_KIND: Record<DiffLine["kind"], string> = {
16
+ context: "",
17
+ add: "+",
18
+ remove: "−",
19
+ };
20
+
21
+ function lineNumber(line: DiffLine): string {
22
+ const value = line.kind === "remove" ? line.oldLine : line.newLine;
23
+ return value === undefined ? "" : String(value);
24
+ }
25
+
26
+ function hunkHeader(hunk: DiffHunk): string {
27
+ return `@@ −${hunk.oldStart} +${hunk.newStart} @@`;
28
+ }
29
+
30
+ /**
31
+ * Rows of a unified diff with line numbers, each hunk led by its header.
32
+ * Numbers the sidecar left out are counted from the hunk's start.
33
+ */
34
+ export function diffRows(hunks: readonly DiffHunk[]): DiffRow[] {
35
+ return hunks.flatMap((hunk, hunkIndex) => {
36
+ let oldLine = hunk.oldStart;
37
+ let newLine = hunk.newStart;
38
+ const header: DiffRow = {
39
+ key: `h${hunkIndex}`,
40
+ kind: "hunk",
41
+ number: "",
42
+ sign: "",
43
+ text: hunkHeader(hunk),
44
+ };
45
+ const lines = hunk.lines.map((line, lineIndex): DiffRow => {
46
+ const numbered: DiffLine = {
47
+ ...line,
48
+ oldLine: line.oldLine ?? (line.kind === "add" ? undefined : oldLine),
49
+ newLine: line.newLine ?? (line.kind === "remove" ? undefined : newLine),
50
+ };
51
+ if (line.kind !== "add") oldLine += 1;
52
+ if (line.kind !== "remove") newLine += 1;
53
+ return {
54
+ key: `h${hunkIndex}l${lineIndex}`,
55
+ kind: line.kind,
56
+ number: lineNumber(numbered),
57
+ sign: SIGN_BY_KIND[line.kind],
58
+ text: line.text,
59
+ };
60
+ });
61
+ return [header, ...lines];
62
+ });
63
+ }
64
+
65
+ export interface LimitedRows {
66
+ rows: DiffRow[];
67
+ /** How many more rows the full diff has. */
68
+ hidden: number;
69
+ }
70
+
71
+ /** The first `limit` rows of a diff. */
72
+ export function limitRows(
73
+ rows: readonly DiffRow[],
74
+ limit: number,
75
+ ): LimitedRows {
76
+ if (rows.length <= limit) return { rows: [...rows], hidden: 0 };
77
+ return { rows: rows.slice(0, limit), hidden: rows.length - limit };
78
+ }
@@ -1,3 +1,9 @@
1
+ const THOUSAND = 1_000;
2
+ const MILLION = 1_000_000;
3
+ const MS_PER_SECOND = 1_000;
4
+ const SECONDS_PER_MINUTE = 60;
5
+ const SECONDS_WIDTH = 2;
6
+
1
7
  /**
2
8
  * Render an arbitrary tool argument / result value for display: strings pass
3
9
  * through, everything else is pretty-printed JSON, with a safe fallback for
@@ -12,3 +18,40 @@ export function stringifyValue(value: unknown): string {
12
18
  return String(value);
13
19
  }
14
20
  }
21
+
22
+ function trimZero(value: number): string {
23
+ return value.toFixed(1).replace(/\.0$/, "");
24
+ }
25
+
26
+ /** A token count as the composer and the drawer show it: 840, 9.6k, 1.2M. */
27
+ export function formatTokens(count: number): string {
28
+ if (count < THOUSAND) return String(Math.max(0, Math.round(count)));
29
+ if (count < MILLION) return `${trimZero(count / THOUSAND)}k`;
30
+ return `${trimZero(count / MILLION)}M`;
31
+ }
32
+
33
+ /** A duration as m:ss. */
34
+ export function formatClock(ms: number): string {
35
+ const totalSeconds = Math.max(0, Math.floor(ms / MS_PER_SECOND));
36
+ const minutes = Math.floor(totalSeconds / SECONDS_PER_MINUTE);
37
+ const seconds = String(totalSeconds % SECONDS_PER_MINUTE).padStart(
38
+ SECONDS_WIDTH,
39
+ "0",
40
+ );
41
+ return `${minutes}:${seconds}`;
42
+ }
43
+
44
+ /** A tool's run time: 0.6s under a minute, m:ss beyond. */
45
+ export function formatDuration(ms: number): string {
46
+ if (ms < SECONDS_PER_MINUTE * MS_PER_SECOND)
47
+ return `${trimZero(ms / MS_PER_SECOND)}s`;
48
+ return formatClock(ms);
49
+ }
50
+
51
+ /** A time of day in the interface language, 14:02. */
52
+ export function formatTimeOfDay(timestampMs: number, locale: string): string {
53
+ return new Date(timestampMs).toLocaleTimeString(locale, {
54
+ hour: "2-digit",
55
+ minute: "2-digit",
56
+ });
57
+ }
@@ -136,7 +136,7 @@ function lineOffset(text: string, line: number): number {
136
136
  return offset;
137
137
  }
138
138
 
139
- export interface MarkdownBlocks {
139
+ interface MarkdownBlocks {
140
140
  /** Top-level blocks that the text still to come can no longer change. */
141
141
  settled: readonly string[];
142
142
  /** The last block, which the next text may still extend. */
@@ -0,0 +1,159 @@
1
+ import type { PermissionRequestData } from "../types/permission";
2
+ import type { Translate } from "../composables/useChatI18n";
3
+ import type {
4
+ CommandPreview,
5
+ DestructivePreview,
6
+ DiffPreview,
7
+ PermissionPreview,
8
+ PermissionRule,
9
+ RuleKind,
10
+ WebPreview,
11
+ } from "../types/protocol";
12
+ import { bareToolName, describeTool, toolVerb } from "./tool-lexicon";
13
+
14
+ /** How a card names its request, in the user's language. */
15
+ export interface PermissionCardText {
16
+ title: string;
17
+ sub: string;
18
+ /** "Only this edit", "Only this command"… */
19
+ onceLabel: string;
20
+ allowLabel: string;
21
+ /** Why the request asks even where most do not; empty when it needs no word. */
22
+ why: string;
23
+ }
24
+
25
+ const PATH_SEPARATOR = "/";
26
+
27
+ function baseName(path: string): string {
28
+ return path.split(PATH_SEPARATOR).filter(Boolean).at(-1) ?? path;
29
+ }
30
+
31
+ function verbAndTarget(req: PermissionRequestData, t: Translate): string {
32
+ const description = describeTool(req.toolName, req.args);
33
+ const verb = toolVerb(description, t);
34
+ return description.target === "" ? verb : `${verb} ${description.target}`;
35
+ }
36
+
37
+ type TextBuilder = (
38
+ req: PermissionRequestData,
39
+ preview: never,
40
+ t: Translate,
41
+ ) => PermissionCardText;
42
+
43
+ const TEXT_BY_PREVIEW: Record<PermissionPreview["type"], TextBuilder> = {
44
+ diff: (_req, preview: DiffPreview, t) => ({
45
+ title: t(
46
+ preview.isNewFile
47
+ ? "dms_ai.panel.approvals.create_file"
48
+ : "dms_ai.panel.approvals.edit_file",
49
+ { file: baseName(preview.relativePath || preview.path) },
50
+ ),
51
+ sub: preview.relativePath || preview.path,
52
+ onceLabel: t("dms_ai.panel.approvals.once_edit"),
53
+ allowLabel: t("dms_ai.panel.approvals.allow_edit"),
54
+ why: "",
55
+ }),
56
+ command: (_req, preview: CommandPreview, t) => ({
57
+ title: t("dms_ai.panel.approvals.run", { command: preview.command }),
58
+ sub: commandSub(preview, t),
59
+ onceLabel: t("dms_ai.panel.approvals.once_command"),
60
+ allowLabel: t("dms_ai.panel.approvals.allow_command"),
61
+ why: "",
62
+ }),
63
+ destructive: (req, preview: DestructivePreview, t) => ({
64
+ title: destructiveTitle(req, preview, t),
65
+ sub: t(`dms_ai.panel.approvals.consequence_${preview.consequence}`),
66
+ onceLabel: t("dms_ai.panel.approvals.once_time"),
67
+ allowLabel: t("dms_ai.panel.approvals.confirm_delete"),
68
+ why: t(`dms_ai.panel.approvals.why_${preview.consequence}`),
69
+ }),
70
+ web: (_req, preview: WebPreview, t) => ({
71
+ title: t("dms_ai.panel.approvals.fetch", { host: preview.host }),
72
+ sub: preview.url,
73
+ onceLabel: t("dms_ai.panel.approvals.once_request"),
74
+ allowLabel: t("dms_ai.panel.approvals.allow_request"),
75
+ why: "",
76
+ }),
77
+ generic: (req, _preview, t) => ({
78
+ title: verbAndTarget(req, t),
79
+ sub: "",
80
+ onceLabel: t("dms_ai.panel.approvals.once_time"),
81
+ allowLabel: t("dms_ai.panel.approvals.allow"),
82
+ why: req.kind === "builder" ? t("dms_ai.panel.approvals.why_builder") : "",
83
+ }),
84
+ };
85
+
86
+ /** "Delete the page {target}": the Builder's destructive operations by name. */
87
+ const DESTRUCTIVE_TITLE_KEYS: Record<string, string> = {
88
+ BuilderDeletePage: "dms_ai.panel.approvals.destructive.delete_page",
89
+ BuilderDeleteResource: "dms_ai.panel.approvals.destructive.delete_table",
90
+ BuilderRemoveField: "dms_ai.panel.approvals.destructive.remove_field",
91
+ BuilderDeleteCategory: "dms_ai.panel.approvals.destructive.delete_category",
92
+ BuilderRemoveQuery: "dms_ai.panel.approvals.destructive.remove_query",
93
+ };
94
+
95
+ function destructiveTitle(
96
+ req: PermissionRequestData,
97
+ preview: DestructivePreview,
98
+ t: Translate,
99
+ ): string {
100
+ const operation = bareToolName(preview.operation || req.toolName);
101
+ const key = DESTRUCTIVE_TITLE_KEYS[operation];
102
+ if (key !== undefined) return t(key, { target: preview.target });
103
+ const verb = toolVerb(describeTool(operation, req.args), t);
104
+ return preview.target === "" ? verb : `${verb} ${preview.target}`;
105
+ }
106
+
107
+ function commandSub(preview: CommandPreview, t: Translate): string {
108
+ const touches = (preview.touches ?? []).join(", ");
109
+ if (preview.effect === undefined) return touches || preview.cwd;
110
+ const effect = t(`dms_ai.panel.approvals.effect_${preview.effect}`);
111
+ return touches === "" ? effect : `${effect} · ${touches}`;
112
+ }
113
+
114
+ /** The words of a permission card, read from its preview. */
115
+ export function permissionCardText(
116
+ req: PermissionRequestData,
117
+ t: Translate,
118
+ ): PermissionCardText {
119
+ const build = TEXT_BY_PREVIEW[req.preview.type] ?? TEXT_BY_PREVIEW.generic;
120
+ return build(req, req.preview as never, t);
121
+ }
122
+
123
+ const RULE_LABEL_KEYS: Record<RuleKind, string> = {
124
+ file: "dms_ai.panel.approvals.rule_file",
125
+ directory: "dms_ai.panel.approvals.rule_directory",
126
+ command: "dms_ai.panel.approvals.rule_command",
127
+ domain: "dms_ai.panel.approvals.rule_domain",
128
+ };
129
+
130
+ /** A scope as the card offers it: "Every edit under crm/customers/". */
131
+ export function ruleLabelKey(rule: PermissionRule): string {
132
+ return RULE_LABEL_KEYS[rule.kind];
133
+ }
134
+
135
+ const RULE_ICONS: Record<RuleKind, string> = {
136
+ file: "i-ph-pencil-simple-line",
137
+ directory: "i-ph-folder-simple",
138
+ command: "i-ph-terminal-window",
139
+ domain: "i-ph-globe",
140
+ };
141
+
142
+ export function ruleIcon(kind: RuleKind): string {
143
+ return RULE_ICONS[kind] ?? "i-ph-key";
144
+ }
145
+
146
+ const KIND_ICONS: Record<string, string> = {
147
+ edit: "i-ph-pencil-simple-line",
148
+ command: "i-ph-terminal-window",
149
+ web: "i-ph-globe",
150
+ destructive: "i-ph-trash",
151
+ builder: "i-ph-squares-four",
152
+ other: "i-ph-hand-palm",
153
+ };
154
+
155
+ /** The card's icon: by kind, else the tool's own. */
156
+ export function permissionIcon(req: PermissionRequestData): string {
157
+ if (req.kind === "other") return describeTool(req.toolName, req.args).icon;
158
+ return KIND_ICONS[req.kind] ?? KIND_ICONS.other;
159
+ }
@@ -0,0 +1,34 @@
1
+ interface UserAgentData {
2
+ platform?: string;
3
+ }
4
+
5
+ interface NavigatorUserAgentData {
6
+ userAgentData?: UserAgentData;
7
+ }
8
+
9
+ const APPLE_PLATFORM = /mac|iphone|ipad|ipod/i;
10
+ const APPLE_MODIFIER = "⌘";
11
+ const OTHER_MODIFIER = "Ctrl+";
12
+ const APPLE_SHIFT = "⇧";
13
+ const OTHER_SHIFT = "Shift+";
14
+
15
+ /**
16
+ * Shortcuts accept meta or ctrl, so hints show the modifier each platform
17
+ * actually uses: ⌘ on Apple, Ctrl elsewhere.
18
+ */
19
+ function isApplePlatform(): boolean {
20
+ const nav = globalThis.navigator as
21
+ | (Navigator & NavigatorUserAgentData)
22
+ | undefined;
23
+ if (nav === undefined) return false;
24
+ const platform = nav.userAgentData?.platform ?? nav.platform ?? "";
25
+ return APPLE_PLATFORM.test(platform);
26
+ }
27
+
28
+ /** "⌘J" or "Ctrl+J"; with `withShift`, "⌘⇧K" or "Ctrl+Shift+K". */
29
+ export function shortcutLabel(key: string, withShift = false): string {
30
+ const isApple = isApplePlatform();
31
+ const modifier = isApple ? APPLE_MODIFIER : OTHER_MODIFIER;
32
+ const shift = withShift ? (isApple ? APPLE_SHIFT : OTHER_SHIFT) : "";
33
+ return `${modifier}${shift}${key.toUpperCase()}`;
34
+ }
@@ -0,0 +1,18 @@
1
+ export interface Identified {
2
+ id: string;
3
+ }
4
+
5
+ /** The list with the item `id` moved to `toIndex`, clamped to the list. */
6
+ export function moveItem<T extends Identified>(
7
+ list: readonly T[],
8
+ id: string,
9
+ toIndex: number,
10
+ ): T[] {
11
+ const from = list.findIndex((item) => item.id === id);
12
+ if (from === -1) return [...list];
13
+ const target = Math.min(Math.max(toIndex, 0), list.length - 1);
14
+ const next = [...list];
15
+ const [moved] = next.splice(from, 1);
16
+ next.splice(target, 0, moved);
17
+ return next;
18
+ }