@antelopejs/dms-ai 0.6.0 → 0.7.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 (330) hide show
  1. package/README.md +2 -2
  2. package/dist/builder/presence.js.map +1 -1
  3. package/dist/channels/bridge.js +4 -2
  4. package/dist/channels/bridge.js.map +1 -1
  5. package/dist/channels/sse-stream.d.ts +1 -1
  6. package/dist/config.d.ts +6 -1
  7. package/dist/config.js +9 -21
  8. package/dist/config.js.map +1 -1
  9. package/dist/constants/channels.d.ts +5 -1
  10. package/dist/constants/channels.js.map +1 -1
  11. package/dist/index.js +1 -1
  12. package/dist/index.js.map +1 -1
  13. package/dist/lifecycle/build-id.js +1 -1
  14. package/dist/lifecycle/build-id.js.map +1 -1
  15. package/dist/lifecycle/module-roots.js +12 -14
  16. package/dist/lifecycle/module-roots.js.map +1 -1
  17. package/dist/lifecycle/sidecar-owner.js.map +1 -1
  18. package/dist/lifecycle/skill-sources.js +35 -22
  19. package/dist/lifecycle/skill-sources.js.map +1 -1
  20. package/dist/lifecycle/spawn-sidecar.js +11 -6
  21. package/dist/lifecycle/spawn-sidecar.js.map +1 -1
  22. package/dist/logging/log-buffer.js +6 -2
  23. package/dist/logging/log-buffer.js.map +1 -1
  24. package/dist/pages/activity/columns.d.ts +66 -2
  25. package/dist/pages/activity/columns.js.map +1 -1
  26. package/dist/pages/activity/page.js.map +1 -1
  27. package/dist/pages/index.js.map +1 -1
  28. package/dist/pages/overview/page.js.map +1 -1
  29. package/dist/pages/overview/recent-changes.js.map +1 -1
  30. package/dist/pages/settings/availability.d.ts +1 -1
  31. package/dist/pages/settings/availability.js +19 -5
  32. package/dist/pages/settings/availability.js.map +1 -1
  33. package/dist/pages/settings/page.js +1 -1
  34. package/dist/pages/settings/page.js.map +1 -1
  35. package/dist/pages/skills/page.js.map +1 -1
  36. package/dist/pages-registry.js +9 -10
  37. package/dist/pages-registry.js.map +1 -1
  38. package/dist/routes/activity.d.ts +5 -4
  39. package/dist/routes/activity.js.map +1 -1
  40. package/dist/routes/changes.d.ts +6 -4
  41. package/dist/routes/changes.js.map +1 -1
  42. package/dist/routes/codex-account.d.ts +5 -1
  43. package/dist/routes/codex-account.js +2 -2
  44. package/dist/routes/codex-account.js.map +1 -1
  45. package/dist/routes/database.d.ts +21 -4
  46. package/dist/routes/database.js.map +1 -1
  47. package/dist/routes/metric-shapes.js +8 -5
  48. package/dist/routes/metric-shapes.js.map +1 -1
  49. package/dist/routes/metrics.d.ts +4 -2
  50. package/dist/routes/metrics.js +2 -2
  51. package/dist/routes/metrics.js.map +1 -1
  52. package/dist/routes/pages-registry.js.map +1 -1
  53. package/dist/routes/settings.d.ts +4 -3
  54. package/dist/routes/settings.js +4 -15
  55. package/dist/routes/settings.js.map +1 -1
  56. package/dist/routes/sidecar-info.js.map +1 -1
  57. package/dist/routes/sidecar-results.d.ts +2 -2
  58. package/dist/routes/sidecar-results.js +10 -10
  59. package/dist/routes/sidecar-results.js.map +1 -1
  60. package/dist/routes/skills.d.ts +2 -1
  61. package/dist/routes/skills.js +6 -4
  62. package/dist/routes/skills.js.map +1 -1
  63. package/dist/routes/status-shapes.js +12 -12
  64. package/dist/routes/status-shapes.js.map +1 -1
  65. package/dist/routes/undo-confirm.js.map +1 -1
  66. package/dist/sidecar/http-client.js.map +1 -1
  67. package/dist/sidecar/index.d.ts +1 -0
  68. package/dist/sidecar/index.js +1 -0
  69. package/dist/sidecar/index.js.map +1 -1
  70. package/dist/sidecar/settings-values.d.ts +3 -0
  71. package/dist/sidecar/settings-values.js +21 -0
  72. package/dist/sidecar/settings-values.js.map +1 -0
  73. package/dist/vocabulary/tools.js.map +1 -1
  74. package/frontend-vue/app/chat/components/ChatView.vue +33 -133
  75. package/frontend-vue/app/chat/components/ProviderNotice.vue +77 -0
  76. package/frontend-vue/app/chat/components/UndoConflictModal.vue +98 -0
  77. package/frontend-vue/app/chat/composables/useChangeSetActions.ts +1 -1
  78. package/frontend-vue/app/plugins/ai.client.ts +10 -2
  79. package/frontend-vue/app/runtime/assistant-actions.ts +41 -0
  80. package/frontend-vue/app/runtime/assistant-session.ts +8 -2
  81. package/frontend-vue/app/runtime/panel-intents.ts +3 -1
  82. package/frontend-vue/build/backend-boundary.ts +89 -0
  83. package/frontend-vue/dms.frontend.build.ts +6 -0
  84. package/frontend-vue/package.json +2 -1
  85. package/frontend-vue/pnpm-lock.yaml +3 -0
  86. package/frontend-vue/tests/assistant-actions.test.ts +72 -0
  87. package/frontend-vue/tests/backend-boundary.test.ts +130 -0
  88. package/frontend-vue/tests/panel-approvals.test.ts +190 -0
  89. package/frontend-vue/tests/panel-questions.test.ts +169 -0
  90. package/frontend-vue/tests/panel-states.test.ts +1 -556
  91. package/frontend-vue/tests/panel-tools.test.ts +165 -0
  92. package/frontend-vue/tests/sidecar-guest.test.ts +39 -71
  93. package/frontend-vue/tests/support/panel-fixtures.ts +110 -0
  94. package/frontend-vue/tests/support/panel-harness.ts +2 -2
  95. package/frontend-vue/vitest.config.ts +2 -1
  96. package/package.json +21 -10
  97. package/sidecar/dist/agent/attachment-files.js.map +1 -1
  98. package/sidecar/dist/agent/call-ledger.d.ts +3 -2
  99. package/sidecar/dist/agent/call-ledger.js +1 -1
  100. package/sidecar/dist/agent/call-ledger.js.map +1 -1
  101. package/sidecar/dist/agent/command-analysis.js +13 -14
  102. package/sidecar/dist/agent/command-analysis.js.map +1 -1
  103. package/sidecar/dist/agent/conversation-modes.js.map +1 -1
  104. package/sidecar/dist/agent/edit-targets.d.ts +5 -1
  105. package/sidecar/dist/agent/edit-targets.js +8 -6
  106. package/sidecar/dist/agent/edit-targets.js.map +1 -1
  107. package/sidecar/dist/agent/edit-tracker.d.ts +2 -1
  108. package/sidecar/dist/agent/edit-tracker.js +3 -4
  109. package/sidecar/dist/agent/edit-tracker.js.map +1 -1
  110. package/sidecar/dist/agent/effective-mode.js.map +1 -1
  111. package/sidecar/dist/agent/line-diff.js +10 -8
  112. package/sidecar/dist/agent/line-diff.js.map +1 -1
  113. package/sidecar/dist/agent/permission-bus.js +2 -1
  114. package/sidecar/dist/agent/permission-bus.js.map +1 -1
  115. package/sidecar/dist/agent/permission-preview.d.ts +1 -1
  116. package/sidecar/dist/agent/permission-preview.js +54 -37
  117. package/sidecar/dist/agent/permission-preview.js.map +1 -1
  118. package/sidecar/dist/agent/permission-rules.js +4 -6
  119. package/sidecar/dist/agent/permission-rules.js.map +1 -1
  120. package/sidecar/dist/agent/provider.d.ts +2 -1
  121. package/sidecar/dist/agent/question-bus.js.map +1 -1
  122. package/sidecar/dist/agent/read-access.d.ts +2 -1
  123. package/sidecar/dist/agent/read-access.js +4 -7
  124. package/sidecar/dist/agent/read-access.js.map +1 -1
  125. package/sidecar/dist/agent/runner.js.map +1 -1
  126. package/sidecar/dist/agent/session.js +2 -6
  127. package/sidecar/dist/agent/session.js.map +1 -1
  128. package/sidecar/dist/agent/switching-runner.js.map +1 -1
  129. package/sidecar/dist/agent/system-prompt.js.map +1 -1
  130. package/sidecar/dist/agent/tool-summary.d.ts +2 -1
  131. package/sidecar/dist/agent/tool-summary.js +26 -13
  132. package/sidecar/dist/agent/tool-summary.js.map +1 -1
  133. package/sidecar/dist/agent/typecheck.d.ts +1 -4
  134. package/sidecar/dist/agent/typecheck.js +3 -2
  135. package/sidecar/dist/agent/typecheck.js.map +1 -1
  136. package/sidecar/dist/audit/activity-query.js +4 -8
  137. package/sidecar/dist/audit/activity-query.js.map +1 -1
  138. package/sidecar/dist/audit/activity-target.d.ts +4 -2
  139. package/sidecar/dist/audit/activity-target.js +10 -9
  140. package/sidecar/dist/audit/activity-target.js.map +1 -1
  141. package/sidecar/dist/audit/activity.js +4 -3
  142. package/sidecar/dist/audit/activity.js.map +1 -1
  143. package/sidecar/dist/audit/call-audit.js.map +1 -1
  144. package/sidecar/dist/builder/builder-client.d.ts +2 -1
  145. package/sidecar/dist/builder/builder-client.js +6 -8
  146. package/sidecar/dist/builder/builder-client.js.map +1 -1
  147. package/sidecar/dist/builder/capability.js.map +1 -1
  148. package/sidecar/dist/checkpoints/checkpoints.js.map +1 -1
  149. package/sidecar/dist/checkpoints/shadow-git.js +6 -2
  150. package/sidecar/dist/checkpoints/shadow-git.js.map +1 -1
  151. package/sidecar/dist/constants/agent.js.map +1 -1
  152. package/sidecar/dist/constants/attachments.js.map +1 -1
  153. package/sidecar/dist/constants/builder.js.map +1 -1
  154. package/sidecar/dist/constants/chatgpt.js.map +1 -1
  155. package/sidecar/dist/constants/checkpoints.d.ts +1 -1
  156. package/sidecar/dist/constants/checkpoints.js +6 -6
  157. package/sidecar/dist/constants/checkpoints.js.map +1 -1
  158. package/sidecar/dist/constants/claude.d.ts +3 -4
  159. package/sidecar/dist/constants/claude.js +16 -16
  160. package/sidecar/dist/constants/claude.js.map +1 -1
  161. package/sidecar/dist/constants/cli.js.map +1 -1
  162. package/sidecar/dist/constants/codex.d.ts +4 -5
  163. package/sidecar/dist/constants/codex.js +25 -25
  164. package/sidecar/dist/constants/codex.js.map +1 -1
  165. package/sidecar/dist/constants/database.js.map +1 -1
  166. package/sidecar/dist/constants/mcp.js.map +1 -1
  167. package/sidecar/dist/constants/paths.js.map +1 -1
  168. package/sidecar/dist/constants/project.d.ts +1 -1
  169. package/sidecar/dist/constants/project.js.map +1 -1
  170. package/sidecar/dist/constants/providers.js.map +1 -1
  171. package/sidecar/dist/constants/questions.js.map +1 -1
  172. package/sidecar/dist/constants/read-access.d.ts +1 -1
  173. package/sidecar/dist/constants/read-access.js +7 -7
  174. package/sidecar/dist/constants/read-access.js.map +1 -1
  175. package/sidecar/dist/constants/timing.js.map +1 -1
  176. package/sidecar/dist/database/database-client.d.ts +3 -2
  177. package/sidecar/dist/database/database-client.js +13 -9
  178. package/sidecar/dist/database/database-client.js.map +1 -1
  179. package/sidecar/dist/host/project-info.js +13 -7
  180. package/sidecar/dist/host/project-info.js.map +1 -1
  181. package/sidecar/dist/index.d.ts +1 -1
  182. package/sidecar/dist/index.js +60 -34
  183. package/sidecar/dist/index.js.map +1 -1
  184. package/sidecar/dist/logs/logs-client.js +12 -2
  185. package/sidecar/dist/logs/logs-client.js.map +1 -1
  186. package/sidecar/dist/mcp/define-tool.d.ts +9 -8
  187. package/sidecar/dist/mcp/define-tool.js.map +1 -1
  188. package/sidecar/dist/mcp/http-binding.js.map +1 -1
  189. package/sidecar/dist/mcp/tools/ask-user.js.map +1 -1
  190. package/sidecar/dist/mcp/tools/builder-catalog.d.ts +6 -1
  191. package/sidecar/dist/mcp/tools/builder-catalog.js +32 -24
  192. package/sidecar/dist/mcp/tools/builder-catalog.js.map +1 -1
  193. package/sidecar/dist/mcp/tools/builder-gate.js.map +1 -1
  194. package/sidecar/dist/mcp/tools/builder-project.d.ts +2 -1
  195. package/sidecar/dist/mcp/tools/builder-project.js +60 -43
  196. package/sidecar/dist/mcp/tools/builder-project.js.map +1 -1
  197. package/sidecar/dist/mcp/tools/builder.js +8 -9
  198. package/sidecar/dist/mcp/tools/builder.js.map +1 -1
  199. package/sidecar/dist/mcp/tools/database.js +5 -9
  200. package/sidecar/dist/mcp/tools/database.js.map +1 -1
  201. package/sidecar/dist/mcp/tools/find-pages-using.js.map +1 -1
  202. package/sidecar/dist/mcp/tools/get-current-page.js.map +1 -1
  203. package/sidecar/dist/mcp/tools/list-pages.js.map +1 -1
  204. package/sidecar/dist/mcp/tools/navigate-to-page.js +6 -6
  205. package/sidecar/dist/mcp/tools/navigate-to-page.js.map +1 -1
  206. package/sidecar/dist/mcp/tools/preview-blocks.js +15 -11
  207. package/sidecar/dist/mcp/tools/preview-blocks.js.map +1 -1
  208. package/sidecar/dist/mcp/tools/query-logs.js.map +1 -1
  209. package/sidecar/dist/mcp/tools/typecheck.js.map +1 -1
  210. package/sidecar/dist/metrics/aggregate.js.map +1 -1
  211. package/sidecar/dist/metrics/types.js.map +1 -1
  212. package/sidecar/dist/pages/registry-client.js +14 -5
  213. package/sidecar/dist/pages/registry-client.js.map +1 -1
  214. package/sidecar/dist/pages/route-match.js.map +1 -1
  215. package/sidecar/dist/protocol/events.d.ts +7 -7
  216. package/sidecar/dist/protocol/events.js.map +1 -1
  217. package/sidecar/dist/protocol/json.d.ts +5 -0
  218. package/sidecar/dist/protocol/json.js +3 -0
  219. package/sidecar/dist/protocol/json.js.map +1 -0
  220. package/sidecar/dist/protocol/messages.d.ts +4 -4
  221. package/sidecar/dist/protocol/messages.js +3 -3
  222. package/sidecar/dist/protocol/messages.js.map +1 -1
  223. package/sidecar/dist/providers/claude/activity.d.ts +4 -2
  224. package/sidecar/dist/providers/claude/activity.js +29 -38
  225. package/sidecar/dist/providers/claude/activity.js.map +1 -1
  226. package/sidecar/dist/providers/claude/adapter.js +62 -91
  227. package/sidecar/dist/providers/claude/adapter.js.map +1 -1
  228. package/sidecar/dist/providers/claude/attachments.js +4 -4
  229. package/sidecar/dist/providers/claude/attachments.js.map +1 -1
  230. package/sidecar/dist/providers/claude/config.js.map +1 -1
  231. package/sidecar/dist/providers/claude/module.js.map +1 -1
  232. package/sidecar/dist/providers/claude/provider.d.ts +4 -2
  233. package/sidecar/dist/providers/claude/provider.js.map +1 -1
  234. package/sidecar/dist/providers/claude/resolve-binary.js +6 -4
  235. package/sidecar/dist/providers/claude/resolve-binary.js.map +1 -1
  236. package/sidecar/dist/providers/claude/safe-mode.js +14 -3
  237. package/sidecar/dist/providers/claude/safe-mode.js.map +1 -1
  238. package/sidecar/dist/providers/codex/adapter.js +124 -46
  239. package/sidecar/dist/providers/codex/adapter.js.map +1 -1
  240. package/sidecar/dist/providers/codex/attachments.js +1 -1
  241. package/sidecar/dist/providers/codex/attachments.js.map +1 -1
  242. package/sidecar/dist/providers/codex/chatgpt/credentials.js.map +1 -1
  243. package/sidecar/dist/providers/codex/chatgpt/http.js +8 -5
  244. package/sidecar/dist/providers/codex/chatgpt/http.js.map +1 -1
  245. package/sidecar/dist/providers/codex/chatgpt/lock.js +3 -3
  246. package/sidecar/dist/providers/codex/chatgpt/lock.js.map +1 -1
  247. package/sidecar/dist/providers/codex/chatgpt/login.js.map +1 -1
  248. package/sidecar/dist/providers/codex/chatgpt/oauth.js +51 -8
  249. package/sidecar/dist/providers/codex/chatgpt/oauth.js.map +1 -1
  250. package/sidecar/dist/providers/codex/chatgpt/store.js +23 -23
  251. package/sidecar/dist/providers/codex/chatgpt/store.js.map +1 -1
  252. package/sidecar/dist/providers/codex/client.d.ts +4 -3
  253. package/sidecar/dist/providers/codex/client.js +10 -3
  254. package/sidecar/dist/providers/codex/client.js.map +1 -1
  255. package/sidecar/dist/providers/codex/config.js.map +1 -1
  256. package/sidecar/dist/providers/codex/module.js.map +1 -1
  257. package/sidecar/dist/providers/codex/permissions.d.ts +2 -2
  258. package/sidecar/dist/providers/codex/permissions.js +20 -6
  259. package/sidecar/dist/providers/codex/permissions.js.map +1 -1
  260. package/sidecar/dist/providers/codex/process.d.ts +3 -1
  261. package/sidecar/dist/providers/codex/process.js +35 -36
  262. package/sidecar/dist/providers/codex/process.js.map +1 -1
  263. package/sidecar/dist/providers/codex/provider.d.ts +2 -0
  264. package/sidecar/dist/providers/codex/provider.js +23 -7
  265. package/sidecar/dist/providers/codex/provider.js.map +1 -1
  266. package/sidecar/dist/providers/codex/resolve-binary.js +2 -2
  267. package/sidecar/dist/providers/codex/resolve-binary.js.map +1 -1
  268. package/sidecar/dist/providers/codex/stop.d.ts +6 -1
  269. package/sidecar/dist/providers/codex/stop.js +29 -22
  270. package/sidecar/dist/providers/codex/stop.js.map +1 -1
  271. package/sidecar/dist/providers/registry.js +4 -5
  272. package/sidecar/dist/providers/registry.js.map +1 -1
  273. package/sidecar/dist/server/chat-socket-registry.d.ts +6 -6
  274. package/sidecar/dist/server/chat-socket-registry.js.map +1 -1
  275. package/sidecar/dist/server/conversation-runs.d.ts +1 -1
  276. package/sidecar/dist/server/conversation-runs.js +4 -5
  277. package/sidecar/dist/server/conversation-runs.js.map +1 -1
  278. package/sidecar/dist/server/host-socket-registry.d.ts +4 -3
  279. package/sidecar/dist/server/host-socket-registry.js.map +1 -1
  280. package/sidecar/dist/server/http-io.d.ts +1 -1
  281. package/sidecar/dist/server/http-io.js +2 -3
  282. package/sidecar/dist/server/http-io.js.map +1 -1
  283. package/sidecar/dist/server/http-params.js.map +1 -1
  284. package/sidecar/dist/server/http-routes.d.ts +9 -2
  285. package/sidecar/dist/server/http-routes.js +15 -8
  286. package/sidecar/dist/server/http-routes.js.map +1 -1
  287. package/sidecar/dist/server/http.js +21 -10
  288. package/sidecar/dist/server/http.js.map +1 -1
  289. package/sidecar/dist/server/pending-queue.js +4 -1
  290. package/sidecar/dist/server/pending-queue.js.map +1 -1
  291. package/sidecar/dist/server/raw-data.js +2 -1
  292. package/sidecar/dist/server/raw-data.js.map +1 -1
  293. package/sidecar/dist/server/routing.js +1 -1
  294. package/sidecar/dist/server/routing.js.map +1 -1
  295. package/sidecar/dist/server/safety-net.js +20 -9
  296. package/sidecar/dist/server/safety-net.js.map +1 -1
  297. package/sidecar/dist/server/tool-calls.js +7 -5
  298. package/sidecar/dist/server/tool-calls.js.map +1 -1
  299. package/sidecar/dist/server/turns.js +2 -1
  300. package/sidecar/dist/server/turns.js.map +1 -1
  301. package/sidecar/dist/server/ws.js +2 -6
  302. package/sidecar/dist/server/ws.js.map +1 -1
  303. package/sidecar/dist/skills/build-catalog.js.map +1 -1
  304. package/sidecar/dist/skills/frontmatter.js.map +1 -1
  305. package/sidecar/dist/skills/plugin-wrapper.js.map +1 -1
  306. package/sidecar/dist/skills/resolve-sources.js.map +1 -1
  307. package/sidecar/dist/skills/skill-usage.js +18 -12
  308. package/sidecar/dist/skills/skill-usage.js.map +1 -1
  309. package/sidecar/dist/state/conversations.js.map +1 -1
  310. package/sidecar/dist/state/lock.js +6 -2
  311. package/sidecar/dist/state/lock.js.map +1 -1
  312. package/sidecar/dist/state/settings-store.d.ts +31 -1
  313. package/sidecar/dist/state/settings-store.js +23 -24
  314. package/sidecar/dist/state/settings-store.js.map +1 -1
  315. package/sidecar/dist/state/settings-types.js.map +1 -1
  316. package/sidecar/dist/state/sidecar-version.js +3 -1
  317. package/sidecar/dist/state/sidecar-version.js.map +1 -1
  318. package/sidecar/dist/state/store.js +1 -1
  319. package/sidecar/dist/state/store.js.map +1 -1
  320. package/sidecar/dist/state/types.js.map +1 -1
  321. package/sidecar/package.json +1 -7
  322. package/skills/dms-ai/cases.json +47 -0
  323. package/skills/dms-ai-code-mode/cases.json +38 -0
  324. package/skills/dms-builder-safe/cases.json +67 -0
  325. package/skills/dms-external-database/REFERENCE.md +34 -9
  326. package/skills/dms-external-database/SKILL.md +24 -11
  327. package/skills/dms-external-database/cases.json +47 -0
  328. package/frontend-vue/tests/i18n-panel.test.ts +0 -118
  329. package/frontend-vue/tests/i18n-views.test.ts +0 -63
  330. package/frontend-vue/tests/panel-header-height.test.ts +0 -40
@@ -0,0 +1,165 @@
1
+ // @vitest-environment jsdom
2
+ import { flushPromises } from "@vue/test-utils";
3
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
4
+ import { nextTick } from "vue";
5
+ import {
6
+ buttonWithText,
7
+ CONVERSATION_ID,
8
+ createHarness,
9
+ deliver,
10
+ openPanel,
11
+ sendMessage,
12
+ sentOfType,
13
+ unmountPanel,
14
+ } from "./support/panel-harness";
15
+ import { CHANGE_SET, DIFF_REQUEST } from "./support/panel-fixtures";
16
+
17
+ beforeEach(() => {
18
+ localStorage.setItem("dms-ai-conversation-id", CONVERSATION_ID);
19
+ });
20
+
21
+ afterEach(() => {
22
+ unmountPanel();
23
+ localStorage.clear();
24
+ vi.useRealTimers();
25
+ });
26
+
27
+ describe("tool rows and change sets", () => {
28
+ it("draws each call with the lexicon's words and its state", async () => {
29
+ const harness = createHarness();
30
+ const panel = await openPanel(harness);
31
+ await sendMessage(panel, "go");
32
+ deliver(harness, {
33
+ type: "tool_call_start",
34
+ callId: "c0",
35
+ toolName: "Read",
36
+ args: { file_path: "/a/customer.form.ts" },
37
+ });
38
+ deliver(harness, {
39
+ type: "tool_call_end",
40
+ callId: "c0",
41
+ status: "success",
42
+ result: "",
43
+ outcome: "done",
44
+ });
45
+ deliver(harness, {
46
+ type: "tool_call_start",
47
+ callId: "c9",
48
+ toolName: "Bash",
49
+ args: { command: "pnpm add dayjs" },
50
+ });
51
+ deliver(harness, {
52
+ type: "tool_call_end",
53
+ callId: "c9",
54
+ status: "error",
55
+ result: "",
56
+ outcome: "denied",
57
+ });
58
+ deliver(harness, {
59
+ type: "tool_call_start",
60
+ callId: "c1",
61
+ toolName: "Edit",
62
+ args: { file_path: "/repo/crm/customers/customer.form.ts" },
63
+ });
64
+ deliver(harness, DIFF_REQUEST);
65
+ await nextTick();
66
+ const rows = panel.findAll(".cb-tool");
67
+ expect(
68
+ rows.map((row) => row.classes().find((name) => name.startsWith("is-"))),
69
+ ).toEqual(["is-done", "is-denied", "is-waiting"]);
70
+ expect(rows[0].text()).toContain("Read file");
71
+ expect(rows[0].text()).toContain("customer.form.ts");
72
+ expect(rows[2].text()).toContain("1 of 1 · below");
73
+ expect(panel.find(".cb-tools__head").text()).toContain("Used 3 tools");
74
+ });
75
+
76
+ it("shows the raw JSON of a call on demand", async () => {
77
+ const harness = createHarness();
78
+ const panel = await openPanel(harness);
79
+ await sendMessage(panel, "go");
80
+ deliver(harness, {
81
+ type: "tool_call_start",
82
+ callId: "c0",
83
+ toolName: "mcp__dms-ai__BuilderAddBlock",
84
+ args: { name: "Top customers", type: "TopListCard" },
85
+ });
86
+ deliver(harness, {
87
+ type: "tool_call_end",
88
+ callId: "c0",
89
+ status: "success",
90
+ result: "ok",
91
+ outcome: "done",
92
+ });
93
+ await nextTick();
94
+ await panel.find(".cb-tool").trigger("click");
95
+ expect(panel.find(".cb-kv").text()).toContain("TopListCard");
96
+ await buttonWithText(panel, "Raw JSON").trigger("click");
97
+ expect(panel.find(".cb-raw").text()).toContain('"type": "TopListCard"');
98
+ });
99
+
100
+ it("ends a turn with its change set: undo, review, then redo", async () => {
101
+ const harness = createHarness();
102
+ const panel = await openPanel(harness);
103
+ await sendMessage(panel, "go");
104
+ deliver(harness, { type: "change_set", changeSet: CHANGE_SET });
105
+ deliver(harness, { type: "run_done" });
106
+ await nextTick();
107
+ const card = panel.find(".cb-change");
108
+ expect(card.text()).toContain("Applied · checkpoint 14");
109
+ expect(card.text()).toContain("2 files changed · 2 Builder operations");
110
+ expect(card.text()).toContain("new");
111
+ await buttonWithText(card, "Review diff").trigger("click");
112
+ expect(harness.navigate).toHaveBeenCalledWith(
113
+ "/modules/ai/changes?set=cs-14",
114
+ );
115
+ await buttonWithText(card, "Undo").trigger("click");
116
+ await flushPromises();
117
+ expect(sentOfType(harness, "change_set_action")).toEqual([
118
+ {
119
+ type: "change_set_action",
120
+ conversationId: CONVERSATION_ID,
121
+ changeSetId: "cs-14",
122
+ action: "undo",
123
+ },
124
+ ]);
125
+ deliver(harness, {
126
+ type: "change_set",
127
+ changeSet: { ...CHANGE_SET, state: "undone", stateChangedBy: "Camille" },
128
+ });
129
+ await nextTick();
130
+ expect(panel.find(".cb-change").text()).toContain(
131
+ "Undone · checkpoint 14 restored",
132
+ );
133
+ expect(panel.find(".cb-change").text()).toContain("by Camille");
134
+ await buttonWithText(panel.find(".cb-change"), "Redo").trigger("click");
135
+ expect(sentOfType(harness, "change_set_action").at(-1)).toMatchObject({
136
+ action: "redo",
137
+ });
138
+ });
139
+
140
+ it("asks before undoing a set later ones build on", async () => {
141
+ const harness = createHarness();
142
+ vi.mocked(harness.api.get).mockResolvedValueOnce({
143
+ conflicts: [
144
+ {
145
+ changeSetId: "cs-15",
146
+ number: 15,
147
+ title: "Refund rate",
148
+ files: ["sales/overview.page.ts"],
149
+ },
150
+ ],
151
+ });
152
+ const panel = await openPanel(harness);
153
+ deliver(harness, { type: "change_set", changeSet: CHANGE_SET });
154
+ await nextTick();
155
+ await buttonWithText(panel.find(".cb-change"), "Undo").trigger("click");
156
+ await flushPromises();
157
+ expect(panel.find(".u-modal").text()).toContain("#15 Refund rate");
158
+ await buttonWithText(panel.find(".u-modal"), "Undo them together").trigger(
159
+ "click",
160
+ );
161
+ expect(sentOfType(harness, "change_set_action")[0]).toMatchObject({
162
+ includeLater: true,
163
+ });
164
+ });
165
+ });
@@ -1,15 +1,11 @@
1
- import { readFileSync } from "node:fs";
2
- import { resolve } from "node:path";
3
- import ts from "typescript";
4
- import * as vue from "vue";
1
+ import { afterEach, expect, it, vi } from "vitest";
5
2
  import { nextTick, ref, type Ref } from "vue";
6
- import { expect, it, vi } from "vitest";
7
- import * as constants from "../app/runtime/constants";
8
- import { runWhenLoggedIn } from "../app/runtime/session-gate";
3
+ import plugin from "../app/plugins/ai.client";
9
4
 
10
- interface PluginExports {
11
- default: (context: unknown) => void | Promise<void>;
12
- }
5
+ vi.mock("#dms/frontend-module", () => ({
6
+ defineDmsPlugin: (definition: unknown) => definition,
7
+ useDmsRouter: () => ({ push: vi.fn() }),
8
+ }));
13
9
 
14
10
  interface PluginHarness {
15
11
  useAuthFetch: ReturnType<typeof vi.fn>;
@@ -17,66 +13,32 @@ interface PluginHarness {
17
13
  run: () => void | Promise<void>;
18
14
  }
19
15
 
20
- const SESSION_GATE_MODULE = "../runtime/session-gate";
21
- const SIDECAR_STATUS_MODULE = "../runtime/sidecar-status";
22
- const CONSTANTS_MODULE = "../runtime/constants";
23
-
24
- // A first probe reporting "no assistant here" stops the startup right after the
16
+ // A first probe reporting a disabled sidecar stops the startup right after the
25
17
  // authenticated fetch, which is all these tests need to observe.
26
- const silentController = {
27
- createSidecarStatusController: () => ({ init: async () => false }),
28
- };
18
+ function disabledSidecarRead() {
19
+ return {
20
+ data: ref({ disabled: true }),
21
+ error: ref(null),
22
+ pending: ref(false),
23
+ execute: async () => undefined,
24
+ refresh: async () => undefined,
25
+ };
26
+ }
29
27
 
30
28
  function loadPlugin(loggedIn: Ref<boolean>): PluginHarness {
31
- const source = readFileSync(
32
- resolve(__dirname, "../app/plugins/ai.client.ts"),
33
- "utf8",
34
- );
35
- const compiled = ts.transpileModule(
36
- source
37
- .replace("import.meta.env.DEV", "true")
38
- .replace("import.meta.hot", "undefined"),
39
- { compilerOptions: { module: ts.ModuleKind.CommonJS } },
40
- );
41
- const exports = {} as PluginExports;
42
29
  const useAuthFetch = vi.fn(() => ({ $authFetch: vi.fn() }));
43
30
  const unregisterSidePanel = vi.fn();
44
- const requireModule = (name: string) => {
45
- if (name === "#dms/frontend-module") {
46
- return {
47
- defineDmsPlugin: (plugin: unknown) => plugin,
48
- useDmsRouter: () => ({ push: vi.fn() }),
49
- };
50
- }
51
- if (name === "vue") return vue;
52
- if (name === CONSTANTS_MODULE) return constants;
53
- if (name === SESSION_GATE_MODULE) return { runWhenLoggedIn };
54
- if (name === SIDECAR_STATUS_MODULE) return silentController;
55
- return {};
56
- };
57
- new Function(
58
- "require",
59
- "exports",
60
- "useDmsUserSession",
61
- "useAuthFetch",
62
- "useToast",
63
- "useDevReload",
64
- "unregisterSidePanel",
65
- compiled.outputText,
66
- )(
67
- requireModule,
68
- exports,
69
- () => ({ loggedIn }),
70
- useAuthFetch,
71
- () => ({ add: vi.fn() }),
72
- () => ({ awaitRoute: vi.fn() }),
73
- unregisterSidePanel,
74
- );
31
+ vi.stubGlobal("useDmsUserSession", () => ({ loggedIn }));
32
+ vi.stubGlobal("useAuthFetch", useAuthFetch);
33
+ vi.stubGlobal("useToast", () => ({ add: vi.fn() }));
34
+ vi.stubGlobal("useDevReload", () => ({ awaitRoute: vi.fn() }));
35
+ vi.stubGlobal("useApiData", disabledSidecarRead);
36
+ vi.stubGlobal("unregisterSidePanel", unregisterSidePanel);
75
37
  return {
76
38
  useAuthFetch,
77
39
  unregisterSidePanel,
78
40
  run: () =>
79
- exports.default({
41
+ plugin({
80
42
  vueApp: { onUnmount: vi.fn(), provide: vi.fn() },
81
43
  $i18n: { t: (key: string) => key, locale: ref("en-GB") },
82
44
  hook: vi.fn(),
@@ -85,27 +47,33 @@ function loadPlugin(loggedIn: Ref<boolean>): PluginHarness {
85
47
  };
86
48
  }
87
49
 
50
+ afterEach(() => {
51
+ vi.unstubAllGlobals();
52
+ });
53
+
88
54
  it("does not invoke authenticated fetching or inject the assistant for a guest", async () => {
89
- const plugin = loadPlugin(ref(false));
90
- await plugin.run();
91
- expect(plugin.useAuthFetch).not.toHaveBeenCalled();
55
+ const harness = loadPlugin(ref(false));
56
+ await harness.run();
57
+ expect(harness.useAuthFetch).not.toHaveBeenCalled();
92
58
  });
93
59
 
94
60
  it("starts the assistant when a guest signs in without reloading the page", async () => {
95
61
  const loggedIn = ref(false);
96
- const plugin = loadPlugin(loggedIn);
97
- await plugin.run();
98
- expect(plugin.useAuthFetch).not.toHaveBeenCalled();
62
+ const harness = loadPlugin(loggedIn);
63
+ await harness.run();
64
+ expect(harness.useAuthFetch).not.toHaveBeenCalled();
99
65
 
100
66
  loggedIn.value = true;
101
67
  await nextTick();
102
- expect(plugin.useAuthFetch).toHaveBeenCalledTimes(1);
68
+ expect(harness.useAuthFetch).toHaveBeenCalledTimes(1);
103
69
  });
104
70
 
105
71
  it("withdraws the docked panel when the first probe finds no assistant", async () => {
106
- const plugin = loadPlugin(ref(true));
107
- await plugin.run();
72
+ const harness = loadPlugin(ref(true));
73
+ await harness.run();
108
74
  await vi.waitFor(() =>
109
- expect(plugin.unregisterSidePanel).toHaveBeenCalledWith("dms-ai:assistant"),
75
+ expect(harness.unregisterSidePanel).toHaveBeenCalledWith(
76
+ "dms-ai:assistant",
77
+ ),
110
78
  );
111
79
  });
@@ -0,0 +1,110 @@
1
+ import { CONVERSATION_ID } from "./panel-harness";
2
+
3
+ export const DIFF_REQUEST = {
4
+ type: "permission_request",
5
+ requestId: "r1",
6
+ callId: "c1",
7
+ toolName: "Edit",
8
+ args: { file_path: "/repo/crm/customers/customer.form.ts" },
9
+ summary: "Edit customer.form.ts",
10
+ kind: "edit",
11
+ alwaysAsk: false,
12
+ preview: {
13
+ type: "diff",
14
+ path: "/repo/crm/customers/customer.form.ts",
15
+ relativePath: "crm/customers/customer.form.ts",
16
+ isNewFile: false,
17
+ added: 1,
18
+ removed: 1,
19
+ hunks: [
20
+ {
21
+ oldStart: 42,
22
+ newStart: 42,
23
+ lines: [
24
+ { kind: "remove", text: 'label: "VAT",' },
25
+ { kind: "add", text: 'label: "VAT number",' },
26
+ ],
27
+ },
28
+ ],
29
+ },
30
+ ruleOptions: [
31
+ { kind: "file", value: "crm/customers/customer.form.ts" },
32
+ { kind: "directory", value: "crm/customers/" },
33
+ ],
34
+ createdAtMs: Date.now(),
35
+ expiresAtMs: Date.now() + 252_000,
36
+ };
37
+
38
+ export const COMMAND_REQUEST = {
39
+ ...DIFF_REQUEST,
40
+ requestId: "r2",
41
+ callId: "c2",
42
+ toolName: "Bash",
43
+ args: { command: "pnpm add jsvat" },
44
+ summary: "Run pnpm add jsvat",
45
+ kind: "command",
46
+ preview: {
47
+ type: "command",
48
+ command: "pnpm add jsvat",
49
+ cwd: "/repo",
50
+ effect: "adds_dependency",
51
+ touches: ["package.json", "pnpm-lock.yaml"],
52
+ },
53
+ ruleOptions: [{ kind: "command", value: "pnpm add" }],
54
+ };
55
+
56
+ export const DELETE_REQUEST = {
57
+ ...DIFF_REQUEST,
58
+ requestId: "r3",
59
+ callId: "c3",
60
+ toolName: "mcp__dms-ai__BuilderDeleteResource",
61
+ args: { ref: "legacy_coupons" },
62
+ summary: "Delete the table legacy_coupons",
63
+ kind: "destructive",
64
+ alwaysAsk: true,
65
+ preview: {
66
+ type: "destructive",
67
+ operation: "resource · API routes",
68
+ target: "legacy_coupons",
69
+ consequence: "deletes_data",
70
+ confirmText: "legacy_coupons",
71
+ canKeepData: true,
72
+ },
73
+ ruleOptions: [],
74
+ };
75
+
76
+ export const CHANGE_SET = {
77
+ id: "cs-14",
78
+ number: 14,
79
+ conversationId: CONVERSATION_ID,
80
+ title: "Top customers",
81
+ createdAtMs: Date.now(),
82
+ agent: "claude",
83
+ scope: "safe",
84
+ isAutoFix: false,
85
+ overlapped: false,
86
+ files: [
87
+ {
88
+ path: "sales/overview.page.ts",
89
+ status: "modified",
90
+ added: 14,
91
+ removed: 1,
92
+ },
93
+ {
94
+ path: "sales/queries/top-customers.ts",
95
+ status: "added",
96
+ added: 22,
97
+ removed: 0,
98
+ },
99
+ ],
100
+ added: 36,
101
+ removed: 1,
102
+ typecheck: "passed",
103
+ state: "applied",
104
+ approvalsNeeded: 0,
105
+ builderOps: 2,
106
+ };
107
+
108
+ export function keydown(target: Element, key: string): void {
109
+ target.dispatchEvent(new KeyboardEvent("keydown", { key, bubbles: true }));
110
+ }
@@ -94,8 +94,8 @@ export function createHarness(): Harness {
94
94
  intents.push({ kind: "open", conversationId });
95
95
  panel.open();
96
96
  },
97
- startConversation: (prompt) => {
98
- intents.push({ kind: "start", prompt });
97
+ startConversation: (prompt, mode) => {
98
+ intents.push({ kind: "start", prompt, mode });
99
99
  panel.open();
100
100
  },
101
101
  holdStream: () => {
@@ -1,9 +1,10 @@
1
1
  import { resolve } from "node:path";
2
2
  import vue from "@vitejs/plugin-vue";
3
3
  import { defineConfig } from "vitest/config";
4
+ import { backendBoundary } from "./build/backend-boundary.ts";
4
5
 
5
6
  export default defineConfig({
6
- plugins: [vue()],
7
+ plugins: [backendBoundary(), vue()],
7
8
  resolve: {
8
9
  alias: {
9
10
  // The renderer's runtime exists in the generated application only.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@antelopejs/dms-ai",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "AI development assistant for the AntelopeJS DMS: a chat panel next to every page and a coding agent that edits the project in reviewable, undoable change sets.",
5
5
  "keywords": [
6
6
  "ai",
@@ -47,10 +47,10 @@
47
47
  "prepack": "pnpm run build && pnpm run build:sidecar",
48
48
  "frontend:dev": "cd playground && pnpm frontend:dev",
49
49
  "dev": "cd playground && pnpm dev",
50
- "lint": "oxlint --disable-nested-config && oxfmt --disable-nested-config --check . && cd frontend-vue && pnpm lint && cd ../sidecar && pnpm lint && antelopejs-check-interface-ranges",
51
- "lint:fix": "oxlint --disable-nested-config --fix --max-warnings=1000000 && oxfmt --disable-nested-config . && cd frontend-vue && pnpm lint:fix && cd ../sidecar && pnpm lint:fix",
52
- "typecheck": "tsc --noEmit && cd frontend-vue && pnpm typecheck:chat && pnpm typecheck && cd ../sidecar && pnpm typecheck",
53
- "test": "cd sidecar && pnpm test && cd ../frontend-vue && pnpm test",
50
+ "lint": "oxlint && pnpm --dir frontend-vue lint && antelopejs-check-interface-ranges && node scripts/check-playground-install.mjs && node scripts/check-i18n.mjs",
51
+ "lint:fix": "oxlint --fix && oxfmt . && pnpm --dir frontend-vue lint:fix",
52
+ "typecheck": "tsc --noEmit && pnpm --dir frontend-vue typecheck:chat && pnpm --dir sidecar typecheck",
53
+ "test": "pnpm run test:node",
54
54
  "test:node": "([ -n \"$DMS_PREBUILT\" ] || pnpm run build) && node --test \"tests/!(sidecar-build).test.cjs\"",
55
55
  "test:sidecar-smoke": "pnpm run build:sidecar && node --test tests/sidecar-build.test.cjs",
56
56
  "test:frontend-registration": "pnpm run build && node --test tests/frontend-registration.test.cjs",
@@ -61,14 +61,24 @@
61
61
  "test:build-id": "node --test tests/build-id.test.cjs",
62
62
  "test:e2e": "cd sidecar && pnpm test:e2e",
63
63
  "release": "pnpm install --frozen-lockfile && release-it",
64
- "format": "oxfmt --disable-nested-config . && cd frontend-vue && pnpm format",
65
- "knip": "knip --dependencies",
66
- "knip:all": "knip"
64
+ "format": "oxfmt . && pnpm --dir frontend-vue format",
65
+ "knip": "knip --dependencies && pnpm --dir sidecar knip",
66
+ "knip:all": "knip",
67
+ "prepare": "if git rev-parse --is-inside-work-tree >/dev/null 2>&1 && command -v lefthook >/dev/null 2>&1; then lefthook install; fi",
68
+ "checks": "antelopejs-checks",
69
+ "size": "antelopejs-check-size",
70
+ "ratchet": "antelopejs-ratchet",
71
+ "sync": "antelopejs-sync",
72
+ "ratchet:update": "antelopejs-ratchet --update",
73
+ "sync:check": "antelopejs-sync --check",
74
+ "format:check": "oxfmt --check .",
75
+ "suppressions": "antelopejs-suppressions",
76
+ "suppressions:update": "antelopejs-suppressions --update"
67
77
  },
68
78
  "dependencies": {
69
79
  "@antelopejs/interface-api": ">=0.0.15 <1.0.0",
70
80
  "@antelopejs/interface-core": ">=0.2.4 <1.0.0",
71
- "@antelopejs/interface-dms": ">=0.8.0 <1.0.0",
81
+ "@antelopejs/interface-dms": ">=0.9.0 <1.0.0",
72
82
  "@anthropic-ai/claude-agent-sdk": "^0.2.131",
73
83
  "@anthropic-ai/claude-code": "^2.1.131",
74
84
  "@modelcontextprotocol/sdk": "1.29.0",
@@ -76,10 +86,11 @@
76
86
  "zod": "^4.0.0"
77
87
  },
78
88
  "devDependencies": {
79
- "@antelopejs/tooling-configs": ">=0.0.9 <1.0.0",
89
+ "@antelopejs/tooling-configs": "^0.2.11",
80
90
  "@types/node": "^24.0.0",
81
91
  "@types/ws": "^8.5.12",
82
92
  "knip": "^6.34.0",
93
+ "lefthook": "^2.2.2",
83
94
  "oxfmt": "^0.66.0",
84
95
  "oxlint": "1.81.0",
85
96
  "oxlint-tsgolint": "^7.0.2001",
@@ -1 +1 @@
1
- {"version":3,"file":"attachment-files.js","sourceRoot":"","sources":["../../src/agent/attachment-files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE3D,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAIlC,SAAS,gBAAgB,CAAC,IAAY;IACpC,MAAM,IAAI,GAAG,IAAI;SACd,QAAQ,CAAC,IAAI,CAAC;SACd,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,IAAI,EAAE,CAAC;IACV,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,eAAuB,EACvB,cAAsB;IAEtB,OAAO,IAAI,CAAC,IAAI,CACd,eAAe,EACf,GAAG,kBAAkB,EACrB,mBAAmB,EACnB,cAAc,CAAC,cAAc,CAAC,CAC/B,CAAC;AACJ,CAAC;AAID,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,GAAmB,EACnB,KAAa,EACb,GAAW;IAEX,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,KAAK,IAAI,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;IACxE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC1C,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC9D,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,SAAmB;IAChE,MAAM,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;IAChE,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,QAAQ,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAClE,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC"}
1
+ {"version":3,"file":"attachment-files.js","sourceRoot":"","sources":["../../src/agent/attachment-files.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE3D,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE1D,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAMlC,SAAS,gBAAgB,CAAC,IAAY;IACpC,MAAM,IAAI,GAAG,IAAI;SACd,QAAQ,CAAC,IAAI,CAAC;SACd,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,IAAI,EAAE,CAAC;IACV,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC;AACrD,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,eAAuB,EACvB,cAAsB;IAEtB,OAAO,IAAI,CAAC,IAAI,CACd,eAAe,EACf,GAAG,kBAAkB,EACrB,mBAAmB,EACnB,cAAc,CAAC,cAAc,CAAC,CAC/B,CAAC;AACJ,CAAC;AAMD,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,GAAmB,EACnB,KAAa,EACb,GAAW;IAEX,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,KAAK,IAAI,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;IACxE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC1C,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC9D,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,SAAmB;IAChE,MAAM,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;IAChE,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,QAAQ,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAClE,OAAO,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC"}
@@ -1,6 +1,7 @@
1
+ import type { ToolArgs } from "./edit-targets.js";
1
2
  export interface CallLedger {
2
- announce(conversationId: string, callId: string, toolName: string, args: unknown): void;
3
- claim(conversationId: string, toolName: string, args: unknown): string | undefined;
3
+ announce(conversationId: string, callId: string, toolName: string, args: ToolArgs): void;
4
+ claim(conversationId: string, toolName: string, args: ToolArgs): string | undefined;
4
5
  forget(conversationId: string): void;
5
6
  }
6
7
  export declare function createCallLedger(): CallLedger;
@@ -2,7 +2,7 @@ import { bareToolName } from "./tool-kinds.js";
2
2
  const MAX_ANNOUNCED_CALLS = 100;
3
3
  function argsKey(args) {
4
4
  try {
5
- return JSON.stringify(args ?? null);
5
+ return JSON.stringify(args);
6
6
  }
7
7
  catch {
8
8
  return "";
@@ -1 +1 @@
1
- {"version":3,"file":"call-ledger.js","sourceRoot":"","sources":["../../src/agent/call-ledger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG/C,MAAM,mBAAmB,GAAG,GAAG,CAAC;AA6BhC,SAAS,OAAO,CAAC,IAAa;IAC5B,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,MAAM,cAAc,GAAG,IAAI,GAAG,EAA2B,CAAC;IAC1D,OAAO;QACL,QAAQ,CAAC,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI;YAC7C,MAAM,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;YACvD,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC;gBAAE,OAAO;YACzD,KAAK,CAAC,IAAI,CAAC;gBACT,MAAM;gBACN,QAAQ,EAAE,YAAY,CAAC,QAAQ,CAAC;gBAChC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC;aACvB,CAAC,CAAC;YACH,cAAc,CAAC,GAAG,CAAC,cAAc,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC;QACxE,CAAC;QACD,KAAK,CAAC,cAAc,EAAE,QAAQ,EAAE,IAAI;YAClC,MAAM,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;YACvD,MAAM,IAAI,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;YACpC,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;YAC1B,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAC3B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,IAAI,IAAI,CAAC,CAAC,OAAO,KAAK,GAAG,CAChD,CAAC;YACF,MAAM,KAAK,GACT,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC;YACnE,IAAI,KAAK,GAAG,CAAC;gBAAE,OAAO,SAAS,CAAC;YAChC,MAAM,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YACzC,OAAO,OAAO,EAAE,MAAM,CAAC;QACzB,CAAC;QACD,MAAM,CAAC,cAAc;YACnB,cAAc,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;QACxC,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"call-ledger.js","sourceRoot":"","sources":["../../src/agent/call-ledger.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG/C,MAAM,mBAAmB,GAAG,GAAG,CAAC;AA6BhC,SAAS,OAAO,CAAC,IAAc;IAC7B,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB;IAC9B,MAAM,cAAc,GAAG,IAAI,GAAG,EAA2B,CAAC;IAC1D,OAAO;QACL,QAAQ,CAAC,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI;YAC7C,MAAM,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;YACvD,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC;gBAAE,OAAO;YACzD,KAAK,CAAC,IAAI,CAAC;gBACT,MAAM;gBACN,QAAQ,EAAE,YAAY,CAAC,QAAQ,CAAC;gBAChC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC;aACvB,CAAC,CAAC;YACH,cAAc,CAAC,GAAG,CAAC,cAAc,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC;QACxE,CAAC;QACD,KAAK,CAAC,cAAc,EAAE,QAAQ,EAAE,IAAI;YAClC,MAAM,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;YACvD,MAAM,IAAI,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;YACpC,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;YAC1B,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAC3B,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,IAAI,IAAI,CAAC,CAAC,OAAO,KAAK,GAAG,CAChD,CAAC;YACF,MAAM,KAAK,GACT,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC;YACnE,IAAI,KAAK,GAAG,CAAC;gBAAE,OAAO,SAAS,CAAC;YAChC,MAAM,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YACzC,OAAO,OAAO,EAAE,MAAM,CAAC;QACzB,CAAC;QACD,MAAM,CAAC,cAAc;YACnB,cAAc,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;QACxC,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -3,7 +3,6 @@ const UNRULABLE_CONSTRUCTS = /`|\$\(|>|</;
3
3
  const WHITESPACE = /\s+/;
4
4
  const FLAG_PREFIX = "-";
5
5
  const COMMAND_RULE_WORDS = 2;
6
- const PACKAGE_MANAGERS = ["pnpm", "npm", "yarn", "bun"];
7
6
  const ADD_VERBS = ["add"];
8
7
  const INSTALL_VERBS = ["install", "i"];
9
8
  const REMOVE_VERBS = ["remove", "rm", "uninstall", "un"];
@@ -15,12 +14,12 @@ const VALUE_FLAGS = [
15
14
  "--prefix",
16
15
  "--cwd",
17
16
  ];
18
- const LOCKFILE_BY_MANAGER = {
19
- pnpm: "pnpm-lock.yaml",
20
- npm: "package-lock.json",
21
- yarn: "yarn.lock",
22
- bun: "bun.lock",
23
- };
17
+ const LOCKFILE_BY_MANAGER = new Map([
18
+ ["pnpm", "pnpm-lock.yaml"],
19
+ ["npm", "package-lock.json"],
20
+ ["yarn", "yarn.lock"],
21
+ ["bun", "bun.lock"],
22
+ ]);
24
23
  const PACKAGE_MANIFEST = "package.json";
25
24
  function splitSegments(command) {
26
25
  return command
@@ -34,6 +33,8 @@ function words(segment) {
34
33
  function findVerb(args) {
35
34
  for (let i = 0; i < args.length; i++) {
36
35
  const word = args[i];
36
+ if (word === undefined)
37
+ break;
37
38
  if (VALUE_FLAGS.includes(word)) {
38
39
  i++;
39
40
  continue;
@@ -59,14 +60,13 @@ function effectOfVerb(at) {
59
60
  }
60
61
  function segmentChange(segment) {
61
62
  const [manager, ...args] = words(segment);
62
- if (manager === undefined || !PACKAGE_MANAGERS.includes(manager)) {
63
+ const lockfile = manager === undefined ? undefined : LOCKFILE_BY_MANAGER.get(manager);
64
+ if (lockfile === undefined)
63
65
  return null;
64
- }
65
66
  const at = findVerb(args);
66
67
  const effect = at === null ? null : effectOfVerb(at);
67
68
  if (effect === null)
68
69
  return null;
69
- const lockfile = LOCKFILE_BY_MANAGER[manager];
70
70
  return { effect, touches: [PACKAGE_MANIFEST, lockfile] };
71
71
  }
72
72
  export function detectDependencyChange(command) {
@@ -81,11 +81,10 @@ export function commandRulePrefix(command) {
81
81
  if (UNRULABLE_CONSTRUCTS.test(command))
82
82
  return null;
83
83
  const segments = splitSegments(command);
84
- if (segments.length !== 1)
84
+ const [segment] = segments;
85
+ if (segments.length !== 1 || segment === undefined)
85
86
  return null;
86
- const prefix = words(segments[0])
87
- .slice(0, COMMAND_RULE_WORDS)
88
- .join(" ");
87
+ const prefix = words(segment).slice(0, COMMAND_RULE_WORDS).join(" ");
89
88
  return prefix.length > 0 ? prefix : null;
90
89
  }
91
90
  function startsWithWords(segment, prefix) {
@@ -1 +1 @@
1
- {"version":3,"file":"command-analysis.js","sourceRoot":"","sources":["../../src/agent/command-analysis.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"command-analysis.js","sourceRoot":"","sources":["../../src/agent/command-analysis.ts"],"names":[],"mappings":"AAIA,MAAM,kBAAkB,GAAG,iBAAiB,CAAC;AAK7C,MAAM,oBAAoB,GAAG,YAAY,CAAC;AAC1C,MAAM,UAAU,GAAG,KAAK,CAAC;AACzB,MAAM,WAAW,GAAG,GAAG,CAAC;AAExB,MAAM,kBAAkB,GAAG,CAAC,CAAC;AAE7B,MAAM,SAAS,GAAsB,CAAC,KAAK,CAAC,CAAC;AAE7C,MAAM,aAAa,GAAsB,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;AAC1D,MAAM,YAAY,GAAsB,CAAC,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;AAE5E,MAAM,WAAW,GAAsB;IACrC,UAAU;IACV,IAAI;IACJ,OAAO;IACP,IAAI;IACJ,UAAU;IACV,OAAO;CACR,CAAC;AAEF,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAiB;IAClD,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAC1B,CAAC,KAAK,EAAE,mBAAmB,CAAC;IAC5B,CAAC,MAAM,EAAE,WAAW,CAAC;IACrB,CAAC,KAAK,EAAE,UAAU,CAAC;CACpB,CAAC,CAAC;AACH,MAAM,gBAAgB,GAAG,cAAc,CAAC;AAcxC,SAAS,aAAa,CAAC,OAAe;IACpC,OAAO,OAAO;SACX,KAAK,CAAC,kBAAkB,CAAC;SACzB,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;SAChC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,KAAK,CAAC,OAAe;IAC5B,OAAO,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AACrE,CAAC;AAED,SAAS,QAAQ,CAAC,IAAc;IAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACrB,IAAI,IAAI,KAAK,SAAS;YAAE,MAAM;QAC9B,IAAI,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,CAAC,EAAE,CAAC;YACJ,SAAS;QACX,CAAC;QACD,IAAI,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;YAAE,SAAS;QAC3C,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;IACjD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,YAAY,CAAC,IAAc;IAClC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,SAAS,YAAY,CAAC,EAAU;IAC9B,IAAI,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC;QAAE,OAAO,iBAAiB,CAAC;IAC1D,IAAI,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC;QAAE,OAAO,oBAAoB,CAAC;IAChE,IAAI,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7D,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,aAAa,CAAC,OAAe;IACpC,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;IAC1C,MAAM,QAAQ,GACZ,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,mBAAmB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACvE,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACxC,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC1B,MAAM,MAAM,GAAG,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;IACrD,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACjC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,gBAAgB,EAAE,QAAQ,CAAC,EAAE,CAAC;AAC3D,CAAC;AAGD,MAAM,UAAU,sBAAsB,CACpC,OAAe;IAEf,KAAK,MAAM,OAAO,IAAI,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7C,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO,MAAM,CAAC;IACrC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAGD,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC/C,IAAI,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IACpD,MAAM,QAAQ,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAC;IAC3B,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAChE,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACrE,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AAC3C,CAAC;AAED,SAAS,eAAe,CAAC,OAAe,EAAE,MAAc;IACtD,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5C,OAAO,UAAU,KAAK,MAAM,IAAI,UAAU,CAAC,UAAU,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC;AACtE,CAAC;AAMD,MAAM,UAAU,gBAAgB,CAC9B,OAAe,EACf,QAA2B;IAE3B,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAChE,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,QAAQ,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACxC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACxC,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,OAAO,EAAE,EAAE,CAChC,QAAQ,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAC5D,CAAC;AACJ,CAAC"}