@antelopejs/dms-ai 0.1.4 → 0.1.6

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 (250) hide show
  1. package/README.md +55 -29
  2. package/dist/channels/bridge.d.ts +2 -8
  3. package/dist/channels/bridge.js +26 -42
  4. package/dist/channels/bridge.js.map +1 -1
  5. package/dist/channels/channel-service.d.ts +2 -2
  6. package/dist/channels/channel-service.js +12 -31
  7. package/dist/channels/channel-service.js.map +1 -1
  8. package/dist/channels/registry.d.ts +2 -2
  9. package/dist/channels/registry.js +7 -7
  10. package/dist/channels/registry.js.map +1 -1
  11. package/dist/config.d.ts +1 -0
  12. package/dist/config.js +8 -1
  13. package/dist/config.js.map +1 -1
  14. package/dist/constants/channels.d.ts +5 -10
  15. package/dist/constants/channels.js +6 -10
  16. package/dist/constants/channels.js.map +1 -1
  17. package/dist/constants/sidecar.d.ts +5 -1
  18. package/dist/constants/sidecar.js +6 -2
  19. package/dist/constants/sidecar.js.map +1 -1
  20. package/dist/index.js +8 -0
  21. package/dist/index.js.map +1 -1
  22. package/dist/lifecycle/build-id.d.ts +1 -0
  23. package/dist/lifecycle/build-id.js +32 -0
  24. package/dist/lifecycle/build-id.js.map +1 -0
  25. package/dist/lifecycle/sidecar-owner.d.ts +13 -0
  26. package/dist/lifecycle/sidecar-owner.js +89 -0
  27. package/dist/lifecycle/sidecar-owner.js.map +1 -0
  28. package/dist/lifecycle/sidecar-socket.d.ts +1 -1
  29. package/dist/lifecycle/sidecar-socket.js +2 -2
  30. package/dist/lifecycle/sidecar-socket.js.map +1 -1
  31. package/dist/lifecycle/spawn-sidecar.d.ts +0 -1
  32. package/dist/lifecycle/spawn-sidecar.js +51 -159
  33. package/dist/lifecycle/spawn-sidecar.js.map +1 -1
  34. package/dist/lifecycle/terminate-process.d.ts +1 -0
  35. package/dist/lifecycle/terminate-process.js +34 -0
  36. package/dist/lifecycle/terminate-process.js.map +1 -0
  37. package/dist/routes/channels.d.ts +3 -3
  38. package/dist/routes/channels.js +11 -12
  39. package/dist/routes/channels.js.map +1 -1
  40. package/dist/routes/index.d.ts +0 -1
  41. package/dist/routes/index.js +0 -1
  42. package/dist/routes/index.js.map +1 -1
  43. package/frontend-vue/.prettierignore +3 -0
  44. package/frontend-vue/.prettierrc +10 -0
  45. package/frontend-vue/app/chat/components/ChatView.vue +582 -0
  46. package/frontend-vue/app/chat/components/ComposerInput.vue +742 -0
  47. package/frontend-vue/app/chat/components/ConnectionBanner.vue +105 -0
  48. package/frontend-vue/app/chat/components/ConversationDrawer.vue +266 -0
  49. package/frontend-vue/app/chat/components/MarkdownContent.vue +196 -0
  50. package/frontend-vue/app/chat/components/MessageList.vue +474 -0
  51. package/frontend-vue/app/chat/components/PermissionRequests.vue +323 -0
  52. package/frontend-vue/app/chat/components/QuestionPrompt.vue +275 -0
  53. package/frontend-vue/app/chat/components/QueuedMessages.vue +109 -0
  54. package/frontend-vue/app/chat/components/TodoList.vue +291 -0
  55. package/frontend-vue/app/chat/components/ToolCallEntry.vue +218 -0
  56. package/frontend-vue/app/chat/components/ToolCluster.vue +282 -0
  57. package/frontend-vue/app/chat/composables/useChatChannel.ts +116 -0
  58. package/frontend-vue/app/chat/composables/useConversation.ts +838 -0
  59. package/frontend-vue/app/chat/composables/useConversationId.ts +34 -0
  60. package/frontend-vue/app/chat/composables/useConversationList.ts +56 -0
  61. package/frontend-vue/app/chat/composables/usePermissionQueue.ts +59 -0
  62. package/frontend-vue/app/chat/composables/useQuestionQueue.ts +50 -0
  63. package/frontend-vue/app/chat/composables/useRunClock.ts +28 -0
  64. package/frontend-vue/app/chat/composables/useSettings.ts +67 -0
  65. package/frontend-vue/app/chat/constants/attachments.ts +16 -0
  66. package/frontend-vue/app/chat/constants/connection-banner.ts +7 -0
  67. package/frontend-vue/app/chat/constants/conversation-drawer.ts +13 -0
  68. package/frontend-vue/app/chat/constants/conversation.ts +75 -0
  69. package/frontend-vue/app/chat/constants/permissions.ts +50 -0
  70. package/frontend-vue/app/chat/constants/protocol.ts +48 -0
  71. package/frontend-vue/app/chat/constants/run-status.ts +50 -0
  72. package/frontend-vue/app/chat/constants/settings.ts +60 -0
  73. package/frontend-vue/app/chat/types/conversation.ts +87 -0
  74. package/frontend-vue/app/chat/types/permission.ts +7 -0
  75. package/frontend-vue/app/chat/types/question.ts +17 -0
  76. package/frontend-vue/app/chat/types/settings.ts +27 -0
  77. package/frontend-vue/app/chat/utils/attachments.ts +62 -0
  78. package/frontend-vue/app/chat/utils/format.ts +14 -0
  79. package/frontend-vue/app/chat/utils/ids.ts +34 -0
  80. package/frontend-vue/app/chat/utils/markdown.ts +188 -0
  81. package/frontend-vue/app/chat/utils/run-status.ts +90 -0
  82. package/frontend-vue/app/chat/utils/todos.ts +64 -0
  83. package/frontend-vue/app/chat/utils/tool-summary.ts +53 -0
  84. package/frontend-vue/app/components/ActivityView.vue +34 -34
  85. package/frontend-vue/app/components/ChatPanel.vue +276 -0
  86. package/frontend-vue/app/components/SettingsView.vue +120 -112
  87. package/frontend-vue/app/components/SkillsView.vue +55 -53
  88. package/frontend-vue/app/plugins/ai.client.ts +145 -129
  89. package/frontend-vue/app/runtime/assistant-session.ts +21 -0
  90. package/frontend-vue/app/runtime/backoff.ts +11 -14
  91. package/frontend-vue/app/runtime/channel-client.ts +130 -141
  92. package/frontend-vue/app/runtime/chat-transport.ts +25 -55
  93. package/frontend-vue/app/runtime/constants.ts +69 -59
  94. package/frontend-vue/app/runtime/current-page.ts +49 -15
  95. package/frontend-vue/app/runtime/event-stream.ts +35 -35
  96. package/frontend-vue/app/runtime/frame-router.ts +30 -0
  97. package/frontend-vue/app/runtime/header-action.ts +18 -18
  98. package/frontend-vue/app/runtime/host-commands.ts +57 -56
  99. package/frontend-vue/app/runtime/listeners.ts +31 -0
  100. package/frontend-vue/app/runtime/navigation-complete.ts +7 -7
  101. package/frontend-vue/app/runtime/overlay-prefs.ts +36 -36
  102. package/frontend-vue/app/runtime/panel-state.ts +88 -0
  103. package/frontend-vue/app/runtime/session-gate.ts +8 -8
  104. package/frontend-vue/app/runtime/shortcuts.ts +12 -12
  105. package/frontend-vue/app/runtime/sidecar-status.ts +61 -61
  106. package/frontend-vue/app/runtime/typed-message.ts +11 -0
  107. package/frontend-vue/dms.frontend.ts +12 -12
  108. package/frontend-vue/eslint.config.mjs +13 -13
  109. package/frontend-vue/package.json +11 -4
  110. package/frontend-vue/pnpm-lock.yaml +298 -96
  111. package/frontend-vue/tests/backoff.test.ts +26 -30
  112. package/frontend-vue/tests/channel-client.test.ts +187 -188
  113. package/frontend-vue/tests/chat/markdown.test.ts +271 -0
  114. package/frontend-vue/tests/chat/useChatChannel.test.ts +124 -0
  115. package/frontend-vue/tests/chat/useConversation.test.ts +283 -0
  116. package/frontend-vue/tests/chat-panel.test.ts +354 -0
  117. package/frontend-vue/tests/chat-transport.test.ts +84 -57
  118. package/frontend-vue/tests/host-commands.test.ts +126 -87
  119. package/frontend-vue/tests/navigation.test.ts +65 -34
  120. package/frontend-vue/tests/overlay-prefs.test.ts +49 -49
  121. package/frontend-vue/tests/panel-state.test.ts +58 -0
  122. package/frontend-vue/tests/session-gate.test.ts +33 -33
  123. package/frontend-vue/tests/sidecar-guest.test.ts +46 -46
  124. package/frontend-vue/tests/sidecar-status.test.ts +29 -29
  125. package/frontend-vue/tsconfig.chat.json +16 -0
  126. package/frontend-vue/vitest.config.ts +6 -4
  127. package/package.json +6 -5
  128. package/sidecar/dist/agent/effective-mode.d.ts +2 -2
  129. package/sidecar/dist/agent/effective-mode.js +1 -1
  130. package/sidecar/dist/agent/effective-mode.js.map +1 -1
  131. package/sidecar/dist/agent/host-context.js +7 -9
  132. package/sidecar/dist/agent/host-context.js.map +1 -1
  133. package/sidecar/dist/agent/permission-bus.d.ts +1 -1
  134. package/sidecar/dist/agent/permission-bus.js +2 -2
  135. package/sidecar/dist/agent/permission-bus.js.map +1 -1
  136. package/sidecar/dist/agent/provider.d.ts +2 -2
  137. package/sidecar/dist/agent/question-bus.d.ts +1 -1
  138. package/sidecar/dist/agent/question-bus.js +2 -2
  139. package/sidecar/dist/agent/question-bus.js.map +1 -1
  140. package/sidecar/dist/agent/runner.d.ts +2 -2
  141. package/sidecar/dist/agent/runner.js +24 -8
  142. package/sidecar/dist/agent/runner.js.map +1 -1
  143. package/sidecar/dist/agent/session.d.ts +2 -2
  144. package/sidecar/dist/agent/session.js +49 -9
  145. package/sidecar/dist/agent/session.js.map +1 -1
  146. package/sidecar/dist/agent/switching-runner.js +10 -5
  147. package/sidecar/dist/agent/switching-runner.js.map +1 -1
  148. package/sidecar/dist/agent/turn-end-reasons.d.ts +2 -0
  149. package/sidecar/dist/agent/turn-end-reasons.js +6 -1
  150. package/sidecar/dist/agent/turn-end-reasons.js.map +1 -1
  151. package/sidecar/dist/constants/agent.d.ts +4 -1
  152. package/sidecar/dist/constants/agent.js +4 -1
  153. package/sidecar/dist/constants/agent.js.map +1 -1
  154. package/sidecar/dist/constants/cli.d.ts +0 -1
  155. package/sidecar/dist/constants/cli.js +0 -1
  156. package/sidecar/dist/constants/cli.js.map +1 -1
  157. package/sidecar/dist/constants/codex.d.ts +5 -2
  158. package/sidecar/dist/constants/codex.js +5 -2
  159. package/sidecar/dist/constants/codex.js.map +1 -1
  160. package/sidecar/dist/constants/http.d.ts +0 -9
  161. package/sidecar/dist/constants/http.js +0 -19
  162. package/sidecar/dist/constants/http.js.map +1 -1
  163. package/sidecar/dist/constants/mcp.d.ts +1 -1
  164. package/sidecar/dist/constants/mcp.js +1 -1
  165. package/sidecar/dist/constants/mcp.js.map +1 -1
  166. package/sidecar/dist/constants/paths.d.ts +0 -1
  167. package/sidecar/dist/constants/paths.js +0 -1
  168. package/sidecar/dist/constants/paths.js.map +1 -1
  169. package/sidecar/dist/constants/ws.d.ts +3 -4
  170. package/sidecar/dist/constants/ws.js +3 -4
  171. package/sidecar/dist/constants/ws.js.map +1 -1
  172. package/sidecar/dist/index.d.ts +4 -1
  173. package/sidecar/dist/index.js +13 -13
  174. package/sidecar/dist/index.js.map +1 -1
  175. package/sidecar/dist/mcp/tools/find-pages-using.js +5 -10
  176. package/sidecar/dist/mcp/tools/find-pages-using.js.map +1 -1
  177. package/sidecar/dist/mcp/types.d.ts +1 -1
  178. package/sidecar/dist/pages/page-filepath.d.ts +4 -0
  179. package/sidecar/dist/pages/page-filepath.js +28 -0
  180. package/sidecar/dist/pages/page-filepath.js.map +1 -0
  181. package/sidecar/dist/prompts/agent.d.ts +1 -1
  182. package/sidecar/dist/prompts/agent.js +1 -1
  183. package/sidecar/dist/prompts/agent.js.map +1 -1
  184. package/sidecar/dist/protocol/events.js +2 -2
  185. package/sidecar/dist/protocol/events.js.map +1 -1
  186. package/sidecar/dist/protocol/messages.d.ts +4 -15
  187. package/sidecar/dist/protocol/messages.js +4 -11
  188. package/sidecar/dist/protocol/messages.js.map +1 -1
  189. package/sidecar/dist/providers/claude/config.d.ts +2 -2
  190. package/sidecar/dist/providers/claude/config.js +2 -2
  191. package/sidecar/dist/providers/claude/config.js.map +1 -1
  192. package/sidecar/dist/providers/claude/provider.js +1 -1
  193. package/sidecar/dist/providers/claude/provider.js.map +1 -1
  194. package/sidecar/dist/providers/codex/config.d.ts +3 -2
  195. package/sidecar/dist/providers/codex/config.js +3 -3
  196. package/sidecar/dist/providers/codex/config.js.map +1 -1
  197. package/sidecar/dist/providers/codex/process.js +107 -74
  198. package/sidecar/dist/providers/codex/process.js.map +1 -1
  199. package/sidecar/dist/providers/codex/provider.js +68 -31
  200. package/sidecar/dist/providers/codex/provider.js.map +1 -1
  201. package/sidecar/dist/providers/codex/skills.d.ts +1 -0
  202. package/sidecar/dist/providers/codex/skills.js +4 -1
  203. package/sidecar/dist/providers/codex/skills.js.map +1 -1
  204. package/sidecar/dist/providers/codex/stop.d.ts +4 -0
  205. package/sidecar/dist/providers/codex/stop.js +71 -0
  206. package/sidecar/dist/providers/codex/stop.js.map +1 -0
  207. package/sidecar/dist/server/{iframe-socket-registry.d.ts → chat-socket-registry.d.ts} +3 -2
  208. package/sidecar/dist/server/{iframe-socket-registry.js → chat-socket-registry.js} +4 -3
  209. package/sidecar/dist/server/chat-socket-registry.js.map +1 -0
  210. package/sidecar/dist/server/client-auth.js +2 -14
  211. package/sidecar/dist/server/client-auth.js.map +1 -1
  212. package/sidecar/dist/server/host-command-router.d.ts +5 -0
  213. package/sidecar/dist/server/host-command-router.js +4 -0
  214. package/sidecar/dist/server/host-command-router.js.map +1 -0
  215. package/sidecar/dist/server/host-socket-registry.d.ts +1 -1
  216. package/sidecar/dist/server/host-socket-registry.js +16 -13
  217. package/sidecar/dist/server/host-socket-registry.js.map +1 -1
  218. package/sidecar/dist/server/http.d.ts +0 -1
  219. package/sidecar/dist/server/http.js +1 -44
  220. package/sidecar/dist/server/http.js.map +1 -1
  221. package/sidecar/dist/server/routing.d.ts +5 -6
  222. package/sidecar/dist/server/routing.js +18 -28
  223. package/sidecar/dist/server/routing.js.map +1 -1
  224. package/sidecar/dist/server/ws.d.ts +2 -2
  225. package/sidecar/dist/server/ws.js +41 -39
  226. package/sidecar/dist/server/ws.js.map +1 -1
  227. package/sidecar/dist/state/host-state.d.ts +10 -2
  228. package/sidecar/dist/state/host-state.js +13 -3
  229. package/sidecar/dist/state/host-state.js.map +1 -1
  230. package/sidecar/dist/state/settings-store.js +2 -2
  231. package/sidecar/dist/state/settings-store.js.map +1 -1
  232. package/sidecar/dist/state/settings-types.d.ts +3 -3
  233. package/sidecar/dist/state/settings-types.js +1 -1
  234. package/sidecar/dist/state/settings-types.js.map +1 -1
  235. package/sidecar/package.json +3 -5
  236. package/dist/chatbox/passthrough.d.ts +0 -3
  237. package/dist/chatbox/passthrough.js +0 -53
  238. package/dist/chatbox/passthrough.js.map +0 -1
  239. package/dist/constants/chatbox.d.ts +0 -10
  240. package/dist/constants/chatbox.js +0 -35
  241. package/dist/constants/chatbox.js.map +0 -1
  242. package/dist/routes/chatbox.d.ts +0 -7
  243. package/dist/routes/chatbox.js +0 -47
  244. package/dist/routes/chatbox.js.map +0 -1
  245. package/frontend-vue/app/runtime/overlay.ts +0 -400
  246. package/frontend-vue/app/runtime/theme-bridge.ts +0 -189
  247. package/sidecar/chatbox/dist/assets/index-C8u7mkHn.css +0 -1
  248. package/sidecar/chatbox/dist/assets/index-tdZvY7ee.js +0 -52
  249. package/sidecar/chatbox/dist/index.html +0 -13
  250. package/sidecar/dist/server/iframe-socket-registry.js.map +0 -1
package/README.md CHANGED
@@ -8,8 +8,10 @@
8
8
 
9
9
  An AntelopeJS DMS development assistant. It adds an owner-only AI workspace to the dashboard and
10
10
  runs a coding agent in a local sidecar that can inspect the loaded modules and their declared skills,
11
- edit the host project, and stream activity back to the dashboard. Claude Code drives it by default;
12
- OpenAI's Codex is selectable once its CLI is installed.
11
+ edit the host project, and stream activity back to the dashboard. The chat is a panel of the
12
+ dashboard itself: it stays open across page navigations, follows the dashboard's theme, and is toggled
13
+ from the header or with Ctrl+Shift+K (⌘⇧K on macOS). Claude Code drives it by default; OpenAI's Codex
14
+ is selectable once its CLI is installed.
13
15
 
14
16
  ## Installation
15
17
 
@@ -23,6 +25,12 @@ The module starts its bundled sidecar with the project as its working directory.
23
25
  set `DMS_AI=0` before starting the backend to disable the sidecar. If
24
26
  `@antelopejs/dms-builder` is installed, the assistant also exposes its builder integration.
25
27
 
28
+ The sidecar is a child process of the backend. A hot reload of the module keeps it running, unless
29
+ its build changed. Stopping the project stops it: Ctrl+C reaches it through the terminal's process
30
+ group, and `@antelopejs/core` 1.13.2 or later terminates it on shutdown (Linux only). A sidecar left
31
+ running by a backend that crashed or was killed is stopped when the next run starts; otherwise it
32
+ exits on its own after 15 idle minutes.
33
+
26
34
  The assistant is a development tool, on purpose: the backend and the sidecar refuse to run with
27
35
  `NODE_ENV=production`, and the chat is reserved to owners. Remote *development* is supported (see
28
36
  below); a hosted use would be a separate product with its own design.
@@ -35,34 +43,50 @@ therefore works wherever the dashboard does — another machine on the LAN, Tail
35
43
  the frontend port, a reverse proxy or a gateway — and the sidecar's port and client credential stay on
36
44
  the server.
37
45
 
38
- | Route (owner only) | Purpose |
39
- | ------------------------------------------ | ------------------------------------------------------------------------ |
40
- | `GET /ai/channels/host,chat/events` | One event stream per tab: the dashboard's and the chat's sidecar frames. |
41
- | `POST /ai/channels/:connectionId/messages` | One client message, relayed to that channel's sidecar socket. |
42
- | `GET /api/ai/chatbox/*` | The chat document and its assets, from the sidecar's static server. |
43
-
44
- Browsers keep at most six HTTP/1.1 connections per origin, and every dashboard tab already holds two
45
- long-lived ones for the DMS. The assistant adds its stream only in the visible tab whose panel is
46
- open, which leaves two dashboard tabs usable side by side; over HTTPS with HTTP/2 the limit goes away.
47
- Over plain HTTP on an address other than `localhost`, start the frontend server with
48
- `DMS_COOKIE_SECURE=false`, or the browser drops the `Secure` session cookie.
49
-
50
- The chat document is served from the dashboard's own origin and renders model output, so it runs
51
- under a strict Content-Security-Policy: scripts from the bundle only, and no image, font or request
52
- outside the origin (bar the Iconify API its icons come from). The frame is not sandboxed: without
53
- `allow-same-origin` its own module scripts are refused, and with it a same-origin frame can lift the
54
- sandbox anyway.
46
+ | Route (owner only) | Purpose |
47
+ | ----------------------------------------- | --------------------------------------------------------------------------- |
48
+ | `GET /ai/channel/events` | The tab's one event stream: the sidecar frames for the dashboard and chat. |
49
+ | `POST /ai/channel/:connectionId/messages` | One client message, relayed to that stream's sidecar socket. |
50
+
51
+ Each stream is bridged to a single sidecar socket, which the dashboard identifies as the host (the
52
+ current page, the agent's navigation requests) and as the chat. Browsers keep at most six HTTP/1.1
53
+ connections per origin, and every dashboard tab already holds two long-lived ones for the DMS. The
54
+ assistant adds its stream only in the visible tab whose panel is open, which leaves two dashboard tabs
55
+ usable side by side; over HTTPS with HTTP/2 the limit goes away. Over plain HTTP on an address other
56
+ than `localhost`, start the frontend server with `DMS_COOKIE_SECURE=false`, or the browser drops the
57
+ `Secure` session cookie.
58
+
59
+ ## Model output in the dashboard
60
+
61
+ The chat renders model output inside the dashboard, next to the owner's session, and that output can
62
+ carry a prompt injection read from a file or a page. So nothing the agent writes is trusted as markup:
63
+
64
+ - Markdown is rendered with raw HTML off, then sanitized by a DOMPurify instance of the chat's own
65
+ (hooks do not leak to the dashboard's), against an allowlist: text formatting, lists, quotes, code,
66
+ tables and links, and no attribute but `href`, `title`, `target`, `rel` and `start` — no `style`,
67
+ `class`, `id` or event handler.
68
+ - Links only go to `http`, `https`, `mailto` or a page of the dashboard, never `javascript:` or
69
+ `data:`, and open in a new tab with `rel="noopener noreferrer"`.
70
+ - An image the model writes is shown as a link: loading it on its own could send what the agent read
71
+ to its address.
72
+ - The agent can only navigate the dashboard to one of its own pages.
73
+
74
+ ## Sidecar
75
+
76
+ The sidecar is an agent server only: `/health`, the settings, metrics and skills routes the backend
77
+ proxies, the MCP endpoint of its agents, and one WebSocket endpoint, `/ws`, which only accepts the
78
+ client credential as a `Bearer` header. It serves no page or asset. Run by hand (`node
79
+ sidecar/dist/index.js --port 0 --root <dir>`), it keeps its standalone default for the backend
80
+ origin, which is how its tests drive it.
55
81
 
56
82
  ## Configuration
57
83
 
58
- Both keys are optional. Left out, the sidecar keeps the defaults it uses when run standalone
59
- (`http://localhost:5010` and `http://localhost:3001`), which is the behaviour every existing project
60
- already has.
84
+ The key is optional. Left out, the sidecar keeps the default it uses when run standalone
85
+ (`http://localhost:5010`), which is the behaviour every existing project already has.
61
86
 
62
87
  | Key | What it is |
63
88
  | ------------ | ------------------------------------------------------------------------------ |
64
89
  | `backendUrl` | Origin the sidecar calls the DMS backend on — its pages registry, logs and builder clients. |
65
- | `hostOrigin` | Origin the DMS frontend is served from. |
66
90
 
67
91
  The api module publishes the origin it actually reserved, so `backendUrl` should reference it rather
68
92
  than repeat a port that may already be taken:
@@ -74,16 +98,12 @@ export default defineConfig({
74
98
  source: { type: "package", package: "@antelopejs/dms-ai" },
75
99
  config: {
76
100
  backendUrl: "${@api.API_LOCAL_BASE_URL}",
77
- hostOrigin: "http://localhost:3001",
78
101
  },
79
102
  },
80
103
  },
81
104
  });
82
105
  ```
83
106
 
84
- `hostOrigin` is the *frontend* origin, which the api module cannot publish: write it out, using the
85
- same value as `dms`'s `clientBaseUrl`.
86
-
87
107
  ## Agent providers
88
108
 
89
109
  The assistant runs on either Claude Code or Codex, picked in the AI settings page. Both go through
@@ -154,14 +174,19 @@ of the app-server with it.
154
174
 
155
175
  ## Vue frontend
156
176
 
157
- The module registers `frontend-vue` through `AddFrontendModule` with the Vue 3 renderer. The host DMS supplies authentication and shared state.
177
+ The module registers `frontend-vue` through `AddFrontendModule` with the Vue 3 renderer. The host DMS
178
+ supplies authentication, shared state, Nuxt UI and the icons. The chat panel, `DmsAiChatPanel`, is
179
+ rendered among the dashboard's persistent overlays (`dms-app-overlays`), so it lives through Inertia
180
+ navigations; its code is under `frontend-vue/app/chat`. The renderer bundles the icons it finds in
181
+ `.vue` files, so an icon name belongs in the component that shows it.
158
182
 
159
183
  ## Development
160
184
 
161
- Install dependencies and run the backend and sidecar checks from the repository root:
185
+ Install dependencies and run the backend, sidecar and dashboard checks from the repository root:
162
186
 
163
187
  ```bash
164
188
  pnpm install
189
+ pnpm --dir frontend-vue install
165
190
  pnpm build
166
191
  pnpm build:sidecar
167
192
  pnpm test
@@ -175,3 +200,4 @@ pnpm --dir frontend-vue typecheck
175
200
  ```
176
201
 
177
202
  `pnpm test:frontend-registration` checks backend registration and sidecar inputs with the sidecar launcher mocked.
203
+ `pnpm test:sidecar-lifecycle` starts a stand-in sidecar to check that a hot reload keeps it, a sidecar left by an earlier run is stopped, and Ctrl+C on the backend stops it.
@@ -1,22 +1,16 @@
1
1
  import WebSocket from "ws";
2
- import { type ChannelName } from "../constants/channels";
3
2
  import type { SseStream } from "./sse-stream";
4
3
  export interface ChannelBridge {
5
4
  id: string;
6
5
  userId: string;
7
- channel: ChannelName;
8
6
  forward: (message: Buffer) => Promise<boolean>;
9
7
  close: () => void;
10
8
  }
11
- export interface ChannelSocket {
12
- channel: ChannelName;
13
- socket: WebSocket;
14
- }
15
9
  export interface BridgeOptions {
16
10
  userId: string;
17
- sockets: readonly ChannelSocket[];
11
+ socket: WebSocket;
18
12
  stream: SseStream;
19
13
  onOpened: (bridge: ChannelBridge) => void;
20
14
  onClosed: (bridge: ChannelBridge) => void;
21
15
  }
22
- export declare function openBridges(options: BridgeOptions): ChannelBridge[];
16
+ export declare function openBridge(options: BridgeOptions): ChannelBridge;
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.openBridges = openBridges;
6
+ exports.openBridge = openBridge;
7
7
  const node_crypto_1 = require("node:crypto");
8
8
  const ws_1 = __importDefault(require("ws"));
9
9
  const channels_1 = require("../constants/channels");
@@ -22,11 +22,10 @@ function forwardTo(socket, message) {
22
22
  socket.send(message, { binary: false }, (error) => resolve(!error));
23
23
  });
24
24
  }
25
- function relayFrames(opened, stream) {
26
- const { socket, bridge } = opened;
25
+ function relayFrames(socket, stream) {
27
26
  let isPaused = false;
28
27
  socket.on("message", (data) => {
29
- if (stream.send(bridge.channel, rawDataToText(data)))
28
+ if (stream.send(channels_1.CHANNEL_EVENTS.FRAME, rawDataToText(data)))
30
29
  return;
31
30
  if (stream.isClosed() || isPaused)
32
31
  return;
@@ -38,50 +37,35 @@ function relayFrames(opened, stream) {
38
37
  });
39
38
  });
40
39
  }
41
- function announce(opened, stream) {
42
- const connections = Object.fromEntries(opened.map(({ bridge }) => [bridge.channel, bridge.id]));
43
- stream.send(channels_1.CHANNEL_EVENTS.READY, JSON.stringify({ connections }));
44
- }
45
- function openBridges(options) {
46
- const { stream } = options;
40
+ function openBridge(options) {
41
+ const { socket, stream } = options;
47
42
  let isOpen = true;
48
- const teardown = () => {
43
+ function teardown() {
49
44
  if (!isOpen)
50
45
  return;
51
46
  isOpen = false;
52
47
  stream.close();
53
- for (const { bridge, socket } of opened) {
54
- socket.close(channels_1.BRIDGE_CLOSE_CODE);
55
- options.onClosed(bridge);
56
- }
57
- };
58
- const opened = options.sockets.map(({ channel, socket }) => ({
59
- socket,
60
- bridge: {
61
- id: (0, node_crypto_1.randomUUID)(),
62
- userId: options.userId,
63
- channel,
64
- forward: (message) => forwardTo(socket, message),
65
- close: teardown,
66
- },
67
- }));
68
- for (const { bridge } of opened)
69
- options.onOpened(bridge);
70
- for (const { socket } of opened) {
71
- socket.on("error", () => undefined);
72
- socket.once("close", () => {
73
- if (!isOpen)
74
- return;
75
- stream.send(channels_1.CHANNEL_EVENTS.SIDECAR_DOWN, EMPTY_PAYLOAD);
76
- teardown();
77
- });
48
+ socket.close(channels_1.BRIDGE_CLOSE_CODE);
49
+ options.onClosed(bridge);
78
50
  }
51
+ const bridge = {
52
+ id: (0, node_crypto_1.randomUUID)(),
53
+ userId: options.userId,
54
+ forward: (message) => forwardTo(socket, message),
55
+ close: teardown,
56
+ };
57
+ options.onOpened(bridge);
58
+ socket.on("error", () => undefined);
59
+ socket.once("close", () => {
60
+ if (!isOpen)
61
+ return;
62
+ stream.send(channels_1.CHANNEL_EVENTS.SIDECAR_DOWN, EMPTY_PAYLOAD);
63
+ teardown();
64
+ });
79
65
  stream.onClose(teardown);
80
- for (const entry of opened)
81
- relayFrames(entry, stream);
82
- announce(opened, stream);
83
- for (const { socket } of opened)
84
- socket.resume();
85
- return opened.map(({ bridge }) => bridge);
66
+ relayFrames(socket, stream);
67
+ stream.send(channels_1.CHANNEL_EVENTS.READY, JSON.stringify({ connectionId: bridge.id }));
68
+ socket.resume();
69
+ return bridge;
86
70
  }
87
71
  //# sourceMappingURL=bridge.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bridge.js","sourceRoot":"","sources":["../../src/channels/bridge.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bridge.js","sourceRoot":"","sources":["../../src/channels/bridge.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { HTTPResult, type RequestContext } from "@antelopejs/interface-api";
2
2
  import type WebSocket from "ws";
3
- export type SidecarConnector = (path: string) => Promise<WebSocket>;
4
- export declare function openChannel(ctx: RequestContext, channels: string, userId: string, connect?: SidecarConnector): Promise<HTTPResult | undefined>;
3
+ export type SidecarConnector = () => Promise<WebSocket>;
4
+ export declare function openChannel(ctx: RequestContext, userId: string, connect?: SidecarConnector): Promise<HTTPResult | undefined>;
5
5
  export declare function postChannelMessage(connectionId: string, userId: string, message: Buffer): Promise<HTTPResult>;
@@ -9,46 +9,27 @@ const sidecar_socket_1 = require("../lifecycle/sidecar-socket");
9
9
  const bridge_1 = require("./bridge");
10
10
  const registry_1 = require("./registry");
11
11
  const sse_stream_1 = require("./sse-stream");
12
- const UNKNOWN_CHANNEL = { error: "unknown_channel" };
13
12
  const UNKNOWN_CONNECTION = { error: "unknown_connection" };
14
13
  const TOO_MANY_STREAMS = { error: "too_many_streams" };
15
- function isChannelName(value) {
16
- return Object.hasOwn(channels_1.CHANNEL_SIDECAR_PATHS, value);
17
- }
18
- function parseChannels(value) {
19
- const names = value.split(channels_1.CHANNEL_LIST_SEPARATOR);
20
- if (new Set(names).size !== names.length)
21
- return null;
22
- if (!names.every(isChannelName))
14
+ async function tryConnect(connect) {
15
+ try {
16
+ return await connect();
17
+ }
18
+ catch {
23
19
  return null;
24
- return names;
25
- }
26
- async function connectAll(connect, channels) {
27
- const attempts = await Promise.allSettled(channels.map((channel) => connect(channels_1.CHANNEL_SIDECAR_PATHS[channel])));
28
- const sockets = attempts.flatMap((attempt, index) => attempt.status === "fulfilled"
29
- ? [{ channel: channels[index], socket: attempt.value }]
30
- : []);
31
- if (sockets.length === channels.length)
32
- return sockets;
33
- for (const { socket } of sockets)
34
- socket.terminate();
35
- return null;
36
- }
37
- async function openChannel(ctx, channels, userId, connect = sidecar_socket_1.connectSidecarSocket) {
38
- const names = parseChannels(channels);
39
- if (names === null) {
40
- return new interface_api_1.HTTPResult(channels_1.CHANNEL_STATUS.NOT_FOUND, UNKNOWN_CHANNEL);
41
20
  }
42
- if (!(0, registry_1.reserveSockets)(userId, names.length, channels_1.CHANNEL_MAX_SOCKETS_PER_USER)) {
21
+ }
22
+ async function openChannel(ctx, userId, connect = sidecar_socket_1.connectSidecarSocket) {
23
+ if (!(0, registry_1.reserveSocket)(userId, channels_1.CHANNEL_MAX_SOCKETS_PER_USER)) {
43
24
  return new interface_api_1.HTTPResult(channels_1.CHANNEL_STATUS.TOO_MANY_REQUESTS, TOO_MANY_STREAMS);
44
25
  }
45
- const sockets = await connectAll(connect, names).finally(() => (0, registry_1.releaseSockets)(userId, names.length));
46
- if (sockets === null) {
26
+ const socket = await tryConnect(connect).finally(() => (0, registry_1.releaseSocket)(userId));
27
+ if (socket === null) {
47
28
  return new interface_api_1.HTTPResult(channels_1.CHANNEL_STATUS.SERVICE_UNAVAILABLE, sidecar_1.SIDECAR_UNAVAILABLE_BODY);
48
29
  }
49
- (0, bridge_1.openBridges)({
30
+ (0, bridge_1.openBridge)({
50
31
  userId,
51
- sockets,
32
+ socket,
52
33
  stream: (0, sse_stream_1.openSseStream)(ctx),
53
34
  onOpened: registry_1.trackBridge,
54
35
  onClosed: registry_1.forgetBridge,
@@ -1 +1 @@
1
- {"version":3,"file":"channel-service.js","sourceRoot":"","sources":["../../src/channels/channel-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"channel-service.js","sourceRoot":"","sources":["../../src/channels/channel-service.ts"],"names":[],"mappings":";;AAwCA,kCAuBC;AAOD,gDAgBC;AAtFD,6DAA4E;AAE5E,oDAG+B;AAC/B,kDAAgE;AAChE,gEAAmE;AACnE,qCAAsC;AACtC,yCAMoB;AACpB,6CAA6C;AAK7C,MAAM,kBAAkB,GAAG,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC;AAC3D,MAAM,gBAAgB,GAAG,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC;AAEvD,KAAK,UAAU,UAAU,CACvB,OAAyB;IAEzB,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,EAAE,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAQM,KAAK,UAAU,WAAW,CAC/B,GAAmB,EACnB,MAAc,EACd,UAA4B,qCAAoB;IAEhD,IAAI,CAAC,IAAA,wBAAa,EAAC,MAAM,EAAE,uCAA4B,CAAC,EAAE,CAAC;QACzD,OAAO,IAAI,0BAAU,CAAC,yBAAc,CAAC,iBAAiB,EAAE,gBAAgB,CAAC,CAAC;IAC5E,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAA,wBAAa,EAAC,MAAM,CAAC,CAAC,CAAC;IAC9E,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,OAAO,IAAI,0BAAU,CACnB,yBAAc,CAAC,mBAAmB,EAClC,kCAAwB,CACzB,CAAC;IACJ,CAAC;IACD,IAAA,mBAAU,EAAC;QACT,MAAM;QACN,MAAM;QACN,MAAM,EAAE,IAAA,0BAAa,EAAC,GAAG,CAAC;QAC1B,QAAQ,EAAE,sBAAW;QACrB,QAAQ,EAAE,uBAAY;KACvB,CAAC,CAAC;IACH,OAAO,SAAS,CAAC;AACnB,CAAC;AAOM,KAAK,UAAU,kBAAkB,CACtC,YAAoB,EACpB,MAAc,EACd,OAAe;IAEf,MAAM,MAAM,GAAG,IAAA,0BAAe,EAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACrD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,IAAI,0BAAU,CAAC,yBAAc,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;IACtE,CAAC;IACD,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;QACrC,OAAO,IAAI,0BAAU,CACnB,yBAAc,CAAC,mBAAmB,EAClC,kCAAwB,CACzB,CAAC;IACJ,CAAC;IACD,OAAO,IAAI,0BAAU,CAAC,yBAAc,CAAC,QAAQ,CAAC,CAAC;AACjD,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import type { ChannelBridge } from "./bridge";
2
- export declare function reserveSockets(userId: string, count: number, limit: number): boolean;
3
- export declare function releaseSockets(userId: string, count: number): void;
2
+ export declare function reserveSocket(userId: string, limit: number): boolean;
3
+ export declare function releaseSocket(userId: string): void;
4
4
  export declare function trackBridge(bridge: ChannelBridge): void;
5
5
  export declare function forgetBridge(bridge: ChannelBridge): void;
6
6
  export declare function findOwnedBridge(connectionId: string, userId: string): ChannelBridge | undefined;
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.reserveSockets = reserveSockets;
4
- exports.releaseSockets = releaseSockets;
3
+ exports.reserveSocket = reserveSocket;
4
+ exports.releaseSocket = releaseSocket;
5
5
  exports.trackBridge = trackBridge;
6
6
  exports.forgetBridge = forgetBridge;
7
7
  exports.findOwnedBridge = findOwnedBridge;
@@ -16,14 +16,14 @@ function openSocketsOf(userId) {
16
16
  }
17
17
  return count;
18
18
  }
19
- function reserveSockets(userId, count, limit) {
20
- if (openSocketsOf(userId) + count > limit)
19
+ function reserveSocket(userId, limit) {
20
+ if (openSocketsOf(userId) >= limit)
21
21
  return false;
22
- pendingSockets.set(userId, (pendingSockets.get(userId) ?? 0) + count);
22
+ pendingSockets.set(userId, (pendingSockets.get(userId) ?? 0) + 1);
23
23
  return true;
24
24
  }
25
- function releaseSockets(userId, count) {
26
- const left = (pendingSockets.get(userId) ?? 0) - count;
25
+ function releaseSocket(userId) {
26
+ const left = (pendingSockets.get(userId) ?? 0) - 1;
27
27
  if (left > 0)
28
28
  pendingSockets.set(userId, left);
29
29
  else
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/channels/registry.ts"],"names":[],"mappings":";;AAcA,wCAQC;AAGD,wCAIC;AAED,kCAEC;AAED,oCAEC;AAGD,0CAMC;AAGD,0CAGC;AAlDD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAyB,CAAC;AACjD,MAAM,cAAc,GAAG,IAAI,GAAG,EAAkB,CAAC;AAEjD,SAAS,aAAa,CAAC,MAAc;IACnC,IAAI,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC5C,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QACtC,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM;YAAE,KAAK,IAAI,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAGD,SAAgB,cAAc,CAC5B,MAAc,EACd,KAAa,EACb,KAAa;IAEb,IAAI,aAAa,CAAC,MAAM,CAAC,GAAG,KAAK,GAAG,KAAK;QAAE,OAAO,KAAK,CAAC;IACxD,cAAc,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;IACtE,OAAO,IAAI,CAAC;AACd,CAAC;AAGD,SAAgB,cAAc,CAAC,MAAc,EAAE,KAAa;IAC1D,MAAM,IAAI,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC;IACvD,IAAI,IAAI,GAAG,CAAC;QAAE,cAAc,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;;QAC1C,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AACrC,CAAC;AAED,SAAgB,WAAW,CAAC,MAAqB;IAC/C,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;AACjC,CAAC;AAED,SAAgB,YAAY,CAAC,MAAqB;IAChD,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAC5B,CAAC;AAGD,SAAgB,eAAe,CAC7B,YAAoB,EACpB,MAAc;IAEd,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACzC,OAAO,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AACxD,CAAC;AAGD,SAAgB,eAAe;IAC7B,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,MAAM,EAAE;QAAE,MAAM,CAAC,KAAK,EAAE,CAAC;IACtD,OAAO,CAAC,KAAK,EAAE,CAAC;AAClB,CAAC"}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/channels/registry.ts"],"names":[],"mappings":";;AAcA,sCAIC;AAGD,sCAIC;AAED,kCAEC;AAED,oCAEC;AAGD,0CAMC;AAGD,0CAGC;AA9CD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAyB,CAAC;AACjD,MAAM,cAAc,GAAG,IAAI,GAAG,EAAkB,CAAC;AAEjD,SAAS,aAAa,CAAC,MAAc;IACnC,IAAI,KAAK,GAAG,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC5C,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QACtC,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM;YAAE,KAAK,IAAI,CAAC,CAAC;IAC3C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAGD,SAAgB,aAAa,CAAC,MAAc,EAAE,KAAa;IACzD,IAAI,aAAa,CAAC,MAAM,CAAC,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC;IACjD,cAAc,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAClE,OAAO,IAAI,CAAC;AACd,CAAC;AAGD,SAAgB,aAAa,CAAC,MAAc;IAC1C,MAAM,IAAI,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IACnD,IAAI,IAAI,GAAG,CAAC;QAAE,cAAc,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;;QAC1C,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AACrC,CAAC;AAED,SAAgB,WAAW,CAAC,MAAqB;IAC/C,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;AACjC,CAAC;AAED,SAAgB,YAAY,CAAC,MAAqB;IAChD,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;AAC5B,CAAC;AAGD,SAAgB,eAAe,CAC7B,YAAoB,EACpB,MAAc;IAEd,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACzC,OAAO,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AACxD,CAAC;AAGD,SAAgB,eAAe;IAC7B,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,MAAM,EAAE;QAAE,MAAM,CAAC,KAAK,EAAE,CAAC;IACtD,OAAO,CAAC,KAAK,EAAE,CAAC;AAClB,CAAC"}
package/dist/config.d.ts CHANGED
@@ -3,5 +3,6 @@ export interface AIConfig {
3
3
  hostOrigin?: string;
4
4
  }
5
5
  export declare function parseConfig(raw: unknown): AIConfig;
6
+ export declare function hasDeprecatedHostOrigin(raw: unknown): boolean;
6
7
  export declare function setConfig(config: AIConfig): void;
7
8
  export declare function getConfig(): AIConfig;
package/dist/config.js CHANGED
@@ -1,9 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.parseConfig = parseConfig;
4
+ exports.hasDeprecatedHostOrigin = hasDeprecatedHostOrigin;
4
5
  exports.setConfig = setConfig;
5
6
  exports.getConfig = getConfig;
6
- const CONFIG_KEYS = ["backendUrl", "hostOrigin"];
7
+ const CONFIG_KEYS = ["backendUrl"];
8
+ const DEPRECATED_HOST_ORIGIN_KEY = "hostOrigin";
7
9
  let current = {};
8
10
  function readOrigin(raw, key) {
9
11
  const value = raw[key];
@@ -24,6 +26,11 @@ function parseConfig(raw) {
24
26
  }
25
27
  return parsed;
26
28
  }
29
+ function hasDeprecatedHostOrigin(raw) {
30
+ if (raw === null || typeof raw !== "object")
31
+ return false;
32
+ return (raw[DEPRECATED_HOST_ORIGIN_KEY] !== undefined);
33
+ }
27
34
  function setConfig(config) {
28
35
  current = config;
29
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;AA0BA,kCASC;AAED,8BAEC;AAED,8BAEC;AAnCD,MAAM,WAAW,GAAG,CAAC,YAAY,EAAE,YAAY,CAAU,CAAC;AAE1D,IAAI,OAAO,GAAa,EAAE,CAAC;AAE3B,SAAS,UAAU,CACjB,GAA4B,EAC5B,GAAW;IAEX,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAChD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AAClD,CAAC;AAMD,SAAgB,WAAW,CAAC,GAAY;IACtC,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC;IACvD,MAAM,MAAM,GAAG,GAA8B,CAAC;IAC9C,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACvC,IAAI,MAAM,KAAK,SAAS;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;IACjD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAgB,SAAS,CAAC,MAAgB;IACxC,OAAO,GAAG,MAAM,CAAC;AACnB,CAAC;AAED,SAAgB,SAAS;IACvB,OAAO,OAAO,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;AA+BA,kCASC;AAKD,0DAKC;AAED,8BAEC;AAED,8BAEC;AA9CD,MAAM,WAAW,GAAG,CAAC,YAAY,CAAU,CAAC;AAC5C,MAAM,0BAA0B,GAAG,YAAY,CAAC;AAEhD,IAAI,OAAO,GAAa,EAAE,CAAC;AAE3B,SAAS,UAAU,CACjB,GAA4B,EAC5B,GAAW;IAEX,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAChD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,OAAO,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AAClD,CAAC;AAMD,SAAgB,WAAW,CAAC,GAAY;IACtC,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC;IACvD,MAAM,MAAM,GAAG,GAA8B,CAAC;IAC9C,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACvC,IAAI,MAAM,KAAK,SAAS;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;IACjD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAKD,SAAgB,uBAAuB,CAAC,GAAY;IAClD,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC1D,OAAO,CACJ,GAA+B,CAAC,0BAA0B,CAAC,KAAK,SAAS,CAC3E,CAAC;AACJ,CAAC;AAED,SAAgB,SAAS,CAAC,MAAgB;IACxC,OAAO,GAAG,MAAM,CAAC;AACnB,CAAC;AAED,SAAgB,SAAS;IACvB,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -1,16 +1,11 @@
1
- export declare const CHANNELS_ROUTE_PREFIX = "/ai/channels";
2
- export declare const CHANNEL_EVENTS_ROUTE = "/:channels/events";
1
+ export declare const CHANNEL_ROUTE_PREFIX = "/ai/channel";
2
+ export declare const CHANNEL_EVENTS_ROUTE = "/events";
3
3
  export declare const CHANNEL_MESSAGES_ROUTE = "/:connectionId/messages";
4
- export declare const CHANNELS_PARAM = "channels";
5
4
  export declare const CONNECTION_ID_PARAM = "connectionId";
6
- export declare const CHANNEL_LIST_SEPARATOR = ",";
7
- export declare const CHANNEL_SIDECAR_PATHS: {
8
- readonly host: "/ws/host";
9
- readonly chat: "/ws/iframe";
10
- };
11
- export type ChannelName = keyof typeof CHANNEL_SIDECAR_PATHS;
5
+ export declare const SIDECAR_SOCKET_PATH = "/ws";
12
6
  export declare const CHANNEL_EVENTS: {
13
7
  readonly READY: "ready";
8
+ readonly FRAME: "message";
14
9
  readonly SIDECAR_DOWN: "sidecar_down";
15
10
  };
16
11
  export declare const SSE_CONTENT_TYPE = "text/event-stream";
@@ -19,7 +14,7 @@ export declare const SSE_KEEPALIVE_INTERVAL_MS = 15000;
19
14
  export declare const SSE_KEEPALIVE_FRAME = ": keepalive\n\n";
20
15
  export declare const SSE_HEADERS: Readonly<Record<string, string>>;
21
16
  export declare const CHANNEL_MESSAGE_MAX_BYTES: number;
22
- export declare const CHANNEL_MAX_SOCKETS_PER_USER = 16;
17
+ export declare const CHANNEL_MAX_SOCKETS_PER_USER = 8;
23
18
  export declare const CHANNEL_PENDING_MESSAGES_MAX_BYTES: number;
24
19
  export declare const CHANNEL_STATUS: {
25
20
  readonly ACCEPTED: 204;
@@ -1,19 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.BRIDGE_CLOSE_CODE = exports.CHANNEL_STATUS = exports.CHANNEL_PENDING_MESSAGES_MAX_BYTES = exports.CHANNEL_MAX_SOCKETS_PER_USER = exports.CHANNEL_MESSAGE_MAX_BYTES = exports.SSE_HEADERS = exports.SSE_KEEPALIVE_FRAME = exports.SSE_KEEPALIVE_INTERVAL_MS = exports.SSE_OK_STATUS = exports.SSE_CONTENT_TYPE = exports.CHANNEL_EVENTS = exports.CHANNEL_SIDECAR_PATHS = exports.CHANNEL_LIST_SEPARATOR = exports.CONNECTION_ID_PARAM = exports.CHANNELS_PARAM = exports.CHANNEL_MESSAGES_ROUTE = exports.CHANNEL_EVENTS_ROUTE = exports.CHANNELS_ROUTE_PREFIX = void 0;
3
+ exports.BRIDGE_CLOSE_CODE = exports.CHANNEL_STATUS = exports.CHANNEL_PENDING_MESSAGES_MAX_BYTES = exports.CHANNEL_MAX_SOCKETS_PER_USER = exports.CHANNEL_MESSAGE_MAX_BYTES = exports.SSE_HEADERS = exports.SSE_KEEPALIVE_FRAME = exports.SSE_KEEPALIVE_INTERVAL_MS = exports.SSE_OK_STATUS = exports.SSE_CONTENT_TYPE = exports.CHANNEL_EVENTS = exports.SIDECAR_SOCKET_PATH = exports.CONNECTION_ID_PARAM = exports.CHANNEL_MESSAGES_ROUTE = exports.CHANNEL_EVENTS_ROUTE = exports.CHANNEL_ROUTE_PREFIX = void 0;
4
4
  const sidecar_1 = require("./sidecar");
5
- exports.CHANNELS_ROUTE_PREFIX = "/ai/channels";
6
- exports.CHANNEL_EVENTS_ROUTE = "/:channels/events";
5
+ exports.CHANNEL_ROUTE_PREFIX = "/ai/channel";
6
+ exports.CHANNEL_EVENTS_ROUTE = "/events";
7
7
  exports.CHANNEL_MESSAGES_ROUTE = "/:connectionId/messages";
8
- exports.CHANNELS_PARAM = "channels";
9
8
  exports.CONNECTION_ID_PARAM = "connectionId";
10
- exports.CHANNEL_LIST_SEPARATOR = ",";
11
- exports.CHANNEL_SIDECAR_PATHS = {
12
- host: "/ws/host",
13
- chat: "/ws/iframe",
14
- };
9
+ exports.SIDECAR_SOCKET_PATH = "/ws";
15
10
  exports.CHANNEL_EVENTS = {
16
11
  READY: "ready",
12
+ FRAME: "message",
17
13
  SIDECAR_DOWN: "sidecar_down",
18
14
  };
19
15
  exports.SSE_CONTENT_TYPE = "text/event-stream";
@@ -26,7 +22,7 @@ exports.SSE_HEADERS = {
26
22
  Connection: "keep-alive",
27
23
  };
28
24
  exports.CHANNEL_MESSAGE_MAX_BYTES = 384 * 1024 * 1024;
29
- exports.CHANNEL_MAX_SOCKETS_PER_USER = 16;
25
+ exports.CHANNEL_MAX_SOCKETS_PER_USER = 8;
30
26
  exports.CHANNEL_PENDING_MESSAGES_MAX_BYTES = 2 * exports.CHANNEL_MESSAGE_MAX_BYTES;
31
27
  exports.CHANNEL_STATUS = {
32
28
  ACCEPTED: 204,
@@ -1 +1 @@
1
- {"version":3,"file":"channels.js","sourceRoot":"","sources":["../../src/constants/channels.ts"],"names":[],"mappings":";;;AAAA,uCAAuD;AAG1C,QAAA,qBAAqB,GAAG,cAAc,CAAC;AACvC,QAAA,oBAAoB,GAAG,mBAAmB,CAAC;AAC3C,QAAA,sBAAsB,GAAG,yBAAyB,CAAC;AACnD,QAAA,cAAc,GAAG,UAAU,CAAC;AAC5B,QAAA,mBAAmB,GAAG,cAAc,CAAC;AAOrC,QAAA,sBAAsB,GAAG,GAAG,CAAC;AAM7B,QAAA,qBAAqB,GAAG;IACnC,IAAI,EAAE,UAAU;IAChB,IAAI,EAAE,YAAY;CACV,CAAC;AAIE,QAAA,cAAc,GAAG;IAC5B,KAAK,EAAE,OAAO;IACd,YAAY,EAAE,cAAc;CACpB,CAAC;AAEE,QAAA,gBAAgB,GAAG,mBAAmB,CAAC;AACvC,QAAA,aAAa,GAAG,GAAG,CAAC;AACpB,QAAA,yBAAyB,GAAG,MAAM,CAAC;AACnC,QAAA,mBAAmB,GAAG,iBAAiB,CAAC;AACxC,QAAA,WAAW,GAAqC;IAC3D,eAAe,EAAE,wBAAwB;IACzC,mBAAmB,EAAE,IAAI;IACzB,UAAU,EAAE,YAAY;CACzB,CAAC;AAOW,QAAA,yBAAyB,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC;AAG9C,QAAA,4BAA4B,GAAG,EAAE,CAAC;AAOlC,QAAA,kCAAkC,GAAG,CAAC,GAAG,iCAAyB,CAAC;AAEnE,QAAA,cAAc,GAAG;IAC5B,QAAQ,EAAE,GAAG;IACb,SAAS,EAAE,GAAG;IACd,iBAAiB,EAAE,GAAG;IACtB,mBAAmB,EAAE,oCAA0B;CACvC,CAAC;AAGE,QAAA,iBAAiB,GAAG,IAAI,CAAC"}
1
+ {"version":3,"file":"channels.js","sourceRoot":"","sources":["../../src/constants/channels.ts"],"names":[],"mappings":";;;AAAA,uCAAuD;AAG1C,QAAA,oBAAoB,GAAG,aAAa,CAAC;AACrC,QAAA,oBAAoB,GAAG,SAAS,CAAC;AACjC,QAAA,sBAAsB,GAAG,yBAAyB,CAAC;AACnD,QAAA,mBAAmB,GAAG,cAAc,CAAC;AAQrC,QAAA,mBAAmB,GAAG,KAAK,CAAC;AAE5B,QAAA,cAAc,GAAG;IAC5B,KAAK,EAAE,OAAO;IAEd,KAAK,EAAE,SAAS;IAChB,YAAY,EAAE,cAAc;CACpB,CAAC;AAEE,QAAA,gBAAgB,GAAG,mBAAmB,CAAC;AACvC,QAAA,aAAa,GAAG,GAAG,CAAC;AACpB,QAAA,yBAAyB,GAAG,MAAM,CAAC;AACnC,QAAA,mBAAmB,GAAG,iBAAiB,CAAC;AACxC,QAAA,WAAW,GAAqC;IAC3D,eAAe,EAAE,wBAAwB;IACzC,mBAAmB,EAAE,IAAI;IACzB,UAAU,EAAE,YAAY;CACzB,CAAC;AAOW,QAAA,yBAAyB,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC;AAG9C,QAAA,4BAA4B,GAAG,CAAC,CAAC;AAOjC,QAAA,kCAAkC,GAAG,CAAC,GAAG,iCAAyB,CAAC;AAEnE,QAAA,cAAc,GAAG;IAC5B,QAAQ,EAAE,GAAG;IACb,SAAS,EAAE,GAAG;IACd,iBAAiB,EAAE,GAAG;IACtB,mBAAmB,EAAE,oCAA0B;CACvC,CAAC;AAGE,QAAA,iBAAiB,GAAG,IAAI,CAAC"}
@@ -14,17 +14,21 @@ export declare const SIDECAR_LOG_FILE_NAME = "sidecar.log";
14
14
  export declare const SIDECAR_HEALTH_PATH = "/health";
15
15
  export declare const SIDECAR_HEALTH_TIMEOUT_MS = 1000;
16
16
  export declare const SIDECAR_LOCK_POLL_INTERVAL_MS = 100;
17
+ export declare const SIDECAR_STOP_TIMEOUT_MS = 5000;
18
+ export declare const SIDECAR_EXIT_POLL_INTERVAL_MS = 100;
19
+ export declare const SIDECAR_OWNER_KEY = "@antelopejs/dms-ai/sidecar-owner";
17
20
  export declare const SIDECAR_BUILD_ID_FLAG = "--build-id";
18
21
  export declare const SIDECAR_MODULE_ROOTS_FLAG = "--module-roots";
19
22
  export declare const SIDECAR_SKILL_DIRS_FLAG = "--skill-dirs";
20
23
  export declare const SIDECAR_BUILDER_FLAG = "--builder-enabled";
21
24
  export declare const SIDECAR_BACKEND_URL_FLAG = "--backend-url";
22
- export declare const SIDECAR_HOST_ORIGIN_FLAG = "--host-origin";
23
25
  export declare const MODULE_ROOTS_TIMEOUT_MS = 3000;
24
26
  export declare const SIDECAR_DIST_EXTENSION = ".js";
27
+ export declare const SIDECAR_BUILD_ID_HASH_ALGORITHM = "sha256";
25
28
  export declare const SIDECAR_LOOPBACK_HOST = "127.0.0.1";
26
29
  export declare const SIDECAR_AUTH_HEADER = "x-dms-ai-token";
27
30
  export declare const SIDECAR_UNAVAILABLE_STATUS = 503;
28
31
  export declare const SIDECAR_UNAVAILABLE_BODY: {
29
32
  error: string;
30
33
  };
34
+ export declare const HOST_ORIGIN_DEPRECATION_WARNING = "[dms-ai] the \"hostOrigin\" config option is deprecated and ignored: remove it from the module config.";
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SIDECAR_UNAVAILABLE_BODY = exports.SIDECAR_UNAVAILABLE_STATUS = exports.SIDECAR_AUTH_HEADER = exports.SIDECAR_LOOPBACK_HOST = exports.SIDECAR_DIST_EXTENSION = exports.MODULE_ROOTS_TIMEOUT_MS = exports.SIDECAR_HOST_ORIGIN_FLAG = exports.SIDECAR_BACKEND_URL_FLAG = exports.SIDECAR_BUILDER_FLAG = exports.SIDECAR_SKILL_DIRS_FLAG = exports.SIDECAR_MODULE_ROOTS_FLAG = exports.SIDECAR_BUILD_ID_FLAG = exports.SIDECAR_LOCK_POLL_INTERVAL_MS = exports.SIDECAR_HEALTH_TIMEOUT_MS = exports.SIDECAR_HEALTH_PATH = exports.SIDECAR_LOG_FILE_NAME = exports.SIDECAR_LOCK_FILE_NAME = exports.SIDECAR_CACHE_DIR_SEGMENTS = exports.SIDECAR_SUCCESS_EXIT_CODE = exports.SIDECAR_DIST_REL = exports.SIDECAR_ENV_DISABLE_KEY = exports.SIDECAR_DISABLED_FLAG = exports.SIDECAR_LOG_PREFIX = exports.SIDECAR_RESPAWN_DELAY_MS = exports.SIDECAR_RESPAWN_WINDOW_MS = exports.SIDECAR_RESPAWN_MAX = exports.SIDECAR_SPAWN_TIMEOUT_MS = exports.SIDECAR_BIN_NAME = void 0;
3
+ exports.HOST_ORIGIN_DEPRECATION_WARNING = exports.SIDECAR_UNAVAILABLE_BODY = exports.SIDECAR_UNAVAILABLE_STATUS = exports.SIDECAR_AUTH_HEADER = exports.SIDECAR_LOOPBACK_HOST = exports.SIDECAR_BUILD_ID_HASH_ALGORITHM = exports.SIDECAR_DIST_EXTENSION = exports.MODULE_ROOTS_TIMEOUT_MS = exports.SIDECAR_BACKEND_URL_FLAG = exports.SIDECAR_BUILDER_FLAG = exports.SIDECAR_SKILL_DIRS_FLAG = exports.SIDECAR_MODULE_ROOTS_FLAG = exports.SIDECAR_BUILD_ID_FLAG = exports.SIDECAR_OWNER_KEY = exports.SIDECAR_EXIT_POLL_INTERVAL_MS = exports.SIDECAR_STOP_TIMEOUT_MS = exports.SIDECAR_LOCK_POLL_INTERVAL_MS = exports.SIDECAR_HEALTH_TIMEOUT_MS = exports.SIDECAR_HEALTH_PATH = exports.SIDECAR_LOG_FILE_NAME = exports.SIDECAR_LOCK_FILE_NAME = exports.SIDECAR_CACHE_DIR_SEGMENTS = exports.SIDECAR_SUCCESS_EXIT_CODE = exports.SIDECAR_DIST_REL = exports.SIDECAR_ENV_DISABLE_KEY = exports.SIDECAR_DISABLED_FLAG = exports.SIDECAR_LOG_PREFIX = exports.SIDECAR_RESPAWN_DELAY_MS = exports.SIDECAR_RESPAWN_WINDOW_MS = exports.SIDECAR_RESPAWN_MAX = exports.SIDECAR_SPAWN_TIMEOUT_MS = exports.SIDECAR_BIN_NAME = void 0;
4
4
  exports.SIDECAR_BIN_NAME = "dms-ai-sidecar";
5
5
  exports.SIDECAR_SPAWN_TIMEOUT_MS = 10_000;
6
6
  exports.SIDECAR_RESPAWN_MAX = 3;
@@ -21,16 +21,20 @@ exports.SIDECAR_LOG_FILE_NAME = "sidecar.log";
21
21
  exports.SIDECAR_HEALTH_PATH = "/health";
22
22
  exports.SIDECAR_HEALTH_TIMEOUT_MS = 1000;
23
23
  exports.SIDECAR_LOCK_POLL_INTERVAL_MS = 100;
24
+ exports.SIDECAR_STOP_TIMEOUT_MS = 5_000;
25
+ exports.SIDECAR_EXIT_POLL_INTERVAL_MS = 100;
26
+ exports.SIDECAR_OWNER_KEY = "@antelopejs/dms-ai/sidecar-owner";
24
27
  exports.SIDECAR_BUILD_ID_FLAG = "--build-id";
25
28
  exports.SIDECAR_MODULE_ROOTS_FLAG = "--module-roots";
26
29
  exports.SIDECAR_SKILL_DIRS_FLAG = "--skill-dirs";
27
30
  exports.SIDECAR_BUILDER_FLAG = "--builder-enabled";
28
31
  exports.SIDECAR_BACKEND_URL_FLAG = "--backend-url";
29
- exports.SIDECAR_HOST_ORIGIN_FLAG = "--host-origin";
30
32
  exports.MODULE_ROOTS_TIMEOUT_MS = 3_000;
31
33
  exports.SIDECAR_DIST_EXTENSION = ".js";
34
+ exports.SIDECAR_BUILD_ID_HASH_ALGORITHM = "sha256";
32
35
  exports.SIDECAR_LOOPBACK_HOST = "127.0.0.1";
33
36
  exports.SIDECAR_AUTH_HEADER = "x-dms-ai-token";
34
37
  exports.SIDECAR_UNAVAILABLE_STATUS = 503;
35
38
  exports.SIDECAR_UNAVAILABLE_BODY = { error: "sidecar_unavailable" };
39
+ exports.HOST_ORIGIN_DEPRECATION_WARNING = `${exports.SIDECAR_LOG_PREFIX} the "hostOrigin" config option is deprecated and ignored: remove it from the module config.`;
36
40
  //# sourceMappingURL=sidecar.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sidecar.js","sourceRoot":"","sources":["../../src/constants/sidecar.ts"],"names":[],"mappings":";;;AAAa,QAAA,gBAAgB,GAAG,gBAAgB,CAAC;AACpC,QAAA,wBAAwB,GAAG,MAAM,CAAC;AAClC,QAAA,mBAAmB,GAAG,CAAC,CAAC;AACxB,QAAA,yBAAyB,GAAG,MAAM,CAAC;AACnC,QAAA,wBAAwB,GAAG,GAAG,CAAC;AAC/B,QAAA,kBAAkB,GAAG,UAAU,CAAC;AAChC,QAAA,qBAAqB,GAAG,GAAG,CAAC;AAC5B,QAAA,uBAAuB,GAAG,QAAQ,CAAC;AACnC,QAAA,gBAAgB,GAAG,6BAA6B,CAAC;AACjD,QAAA,yBAAyB,GAAG,CAAC,CAAC;AAC9B,QAAA,0BAA0B,GAAG;IACxC,cAAc;IACd,QAAQ;IACR,QAAQ;CACA,CAAC;AACE,QAAA,sBAAsB,GAAG,cAAc,CAAC;AACxC,QAAA,qBAAqB,GAAG,aAAa,CAAC;AACtC,QAAA,mBAAmB,GAAG,SAAS,CAAC;AAChC,QAAA,yBAAyB,GAAG,IAAI,CAAC;AACjC,QAAA,6BAA6B,GAAG,GAAG,CAAC;AACpC,QAAA,qBAAqB,GAAG,YAAY,CAAC;AACrC,QAAA,yBAAyB,GAAG,gBAAgB,CAAC;AAC7C,QAAA,uBAAuB,GAAG,cAAc,CAAC;AACzC,QAAA,oBAAoB,GAAG,mBAAmB,CAAC;AAC3C,QAAA,wBAAwB,GAAG,eAAe,CAAC;AAC3C,QAAA,wBAAwB,GAAG,eAAe,CAAC;AAC3C,QAAA,uBAAuB,GAAG,KAAK,CAAC;AAChC,QAAA,sBAAsB,GAAG,KAAK,CAAC;AAC/B,QAAA,qBAAqB,GAAG,WAAW,CAAC;AACpC,QAAA,mBAAmB,GAAG,gBAAgB,CAAC;AAGvC,QAAA,0BAA0B,GAAG,GAAG,CAAC;AACjC,QAAA,wBAAwB,GAAG,EAAE,KAAK,EAAE,qBAAqB,EAAE,CAAC"}
1
+ {"version":3,"file":"sidecar.js","sourceRoot":"","sources":["../../src/constants/sidecar.ts"],"names":[],"mappings":";;;AAAa,QAAA,gBAAgB,GAAG,gBAAgB,CAAC;AACpC,QAAA,wBAAwB,GAAG,MAAM,CAAC;AAClC,QAAA,mBAAmB,GAAG,CAAC,CAAC;AACxB,QAAA,yBAAyB,GAAG,MAAM,CAAC;AACnC,QAAA,wBAAwB,GAAG,GAAG,CAAC;AAC/B,QAAA,kBAAkB,GAAG,UAAU,CAAC;AAChC,QAAA,qBAAqB,GAAG,GAAG,CAAC;AAC5B,QAAA,uBAAuB,GAAG,QAAQ,CAAC;AACnC,QAAA,gBAAgB,GAAG,6BAA6B,CAAC;AACjD,QAAA,yBAAyB,GAAG,CAAC,CAAC;AAC9B,QAAA,0BAA0B,GAAG;IACxC,cAAc;IACd,QAAQ;IACR,QAAQ;CACA,CAAC;AACE,QAAA,sBAAsB,GAAG,cAAc,CAAC;AACxC,QAAA,qBAAqB,GAAG,aAAa,CAAC;AACtC,QAAA,mBAAmB,GAAG,SAAS,CAAC;AAChC,QAAA,yBAAyB,GAAG,IAAI,CAAC;AACjC,QAAA,6BAA6B,GAAG,GAAG,CAAC;AACpC,QAAA,uBAAuB,GAAG,KAAK,CAAC;AAChC,QAAA,6BAA6B,GAAG,GAAG,CAAC;AACpC,QAAA,iBAAiB,GAAG,kCAAkC,CAAC;AACvD,QAAA,qBAAqB,GAAG,YAAY,CAAC;AACrC,QAAA,yBAAyB,GAAG,gBAAgB,CAAC;AAC7C,QAAA,uBAAuB,GAAG,cAAc,CAAC;AACzC,QAAA,oBAAoB,GAAG,mBAAmB,CAAC;AAC3C,QAAA,wBAAwB,GAAG,eAAe,CAAC;AAC3C,QAAA,uBAAuB,GAAG,KAAK,CAAC;AAChC,QAAA,sBAAsB,GAAG,KAAK,CAAC;AAC/B,QAAA,+BAA+B,GAAG,QAAQ,CAAC;AAC3C,QAAA,qBAAqB,GAAG,WAAW,CAAC;AACpC,QAAA,mBAAmB,GAAG,gBAAgB,CAAC;AAGvC,QAAA,0BAA0B,GAAG,GAAG,CAAC;AACjC,QAAA,wBAAwB,GAAG,EAAE,KAAK,EAAE,qBAAqB,EAAE,CAAC;AAC5D,QAAA,+BAA+B,GAAG,GAAG,0BAAkB,8FAA8F,CAAC"}
package/dist/index.js CHANGED
@@ -20,7 +20,15 @@ const spawn_sidecar_1 = require("./lifecycle/spawn-sidecar");
20
20
  const log_buffer_1 = require("./logging/log-buffer");
21
21
  require("./pages");
22
22
  require("./routes");
23
+ let hasWarnedHostOrigin = false;
24
+ function warnDeprecatedHostOrigin(config) {
25
+ if (hasWarnedHostOrigin || !(0, config_1.hasDeprecatedHostOrigin)(config))
26
+ return;
27
+ hasWarnedHostOrigin = true;
28
+ logging_1.Logging.Warn(sidecar_1.HOST_ORIGIN_DEPRECATION_WARNING);
29
+ }
23
30
  function construct(config) {
31
+ warnDeprecatedHostOrigin(config);
24
32
  (0, config_1.setConfig)((0, config_1.parseConfig)(config));
25
33
  }
26
34
  async function start() {