@ljwei-stak/dsh-model-route-bot 0.66.4 → 0.67.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 (271) hide show
  1. package/.dsh-plugin/bot-product.mjs +81 -5
  2. package/.dsh-plugin/client.js +17490 -1791
  3. package/README.i18n.yaml +4 -4
  4. package/README.md +409 -364
  5. package/README.zh.md +409 -364
  6. package/apps/integration-client/README.md +31 -7
  7. package/apps/integration-client/api.mjs +14 -3
  8. package/apps/integration-client/binding-editor.jsx +308 -109
  9. package/apps/integration-client/binding-model.mjs +262 -0
  10. package/apps/integration-client/binding.css +144 -0
  11. package/apps/integration-client/bot-model-status.mjs +18 -0
  12. package/apps/integration-client/bot-profile-identity.jsx +197 -0
  13. package/apps/integration-client/bot-profile.css +57 -0
  14. package/apps/integration-client/bot-profile.mjs +97 -0
  15. package/apps/integration-client/bot-settings-dialog.css +18 -0
  16. package/apps/integration-client/bot-settings-dialog.jsx +111 -0
  17. package/apps/integration-client/bot-thread-header-bridge.css +20 -0
  18. package/apps/integration-client/bot-thread-header.jsx +278 -0
  19. package/apps/integration-client/bot-threads-panel.jsx +378 -0
  20. package/apps/integration-client/bot-threads.css +169 -0
  21. package/apps/integration-client/chat-design.mjs +250 -0
  22. package/apps/integration-client/chat-ui.jsx +175 -0
  23. package/apps/integration-client/chat.css +477 -0
  24. package/apps/integration-client/composer-draft-binding.mjs +50 -0
  25. package/apps/integration-client/composer-draft-bound.jsx +14 -0
  26. package/apps/integration-client/composer-draft-host.jsx +142 -0
  27. package/apps/integration-client/composer-draft-session.jsx +287 -0
  28. package/apps/integration-client/composer-draft-witness.mjs +115 -0
  29. package/apps/integration-client/composer-draft.css +4 -0
  30. package/apps/integration-client/composer-draft.mjs +322 -0
  31. package/apps/integration-client/contact-attention.jsx +54 -0
  32. package/apps/integration-client/data-panel.jsx +439 -0
  33. package/apps/integration-client/data.css +69 -0
  34. package/apps/integration-client/desktop-bridge.mjs +1 -0
  35. package/apps/integration-client/desktop-http-socket.mjs +49 -0
  36. package/apps/integration-client/desktop-keyboard.mjs +32 -0
  37. package/apps/integration-client/desktop-pane.jsx +99 -30
  38. package/apps/integration-client/desktop-stream.mjs +13 -3
  39. package/apps/integration-client/desktop-tools.jsx +19 -0
  40. package/apps/integration-client/desktop-touch.mjs +27 -0
  41. package/apps/integration-client/desktop.css +41 -0
  42. package/apps/integration-client/independent-chat-controller.mjs +224 -0
  43. package/apps/integration-client/independent-chat-entry.jsx +61 -0
  44. package/apps/integration-client/independent-chat-navigation.mjs +21 -0
  45. package/apps/integration-client/independent-chat-page.jsx +148 -0
  46. package/apps/integration-client/independent-chat-rich.jsx +64 -0
  47. package/apps/integration-client/independent-chat-rich.mjs +30 -0
  48. package/apps/integration-client/independent-chat.css +73 -0
  49. package/apps/integration-client/index.jsx +24 -16
  50. package/apps/integration-client/library-panel.jsx +4 -1
  51. package/apps/integration-client/licenses/jsqr-1.4.0-LICENSE.txt +202 -0
  52. package/apps/integration-client/main-route-editor.jsx +94 -0
  53. package/apps/integration-client/main-route-model.mjs +100 -0
  54. package/apps/integration-client/model-picker.css +37 -0
  55. package/apps/integration-client/model-picker.jsx +83 -0
  56. package/apps/integration-client/native-activity.css +141 -0
  57. package/apps/integration-client/native-activity.jsx +276 -0
  58. package/apps/integration-client/native-activity.mjs +384 -0
  59. package/apps/integration-client/notifications-panel.jsx +186 -0
  60. package/apps/integration-client/notifications.css +126 -0
  61. package/apps/integration-client/pairing-qr.jsx +79 -0
  62. package/apps/integration-client/panels.jsx +126 -115
  63. package/apps/integration-client/product-slots.jsx +46 -0
  64. package/apps/integration-client/routine-recorder.mjs +23 -2
  65. package/apps/integration-client/secure-pairing.jsx +84 -0
  66. package/apps/integration-client/tasks-panel.jsx +32 -10
  67. package/apps/integration-client/ui-icons.jsx +17 -0
  68. package/apps/integration-client/usage-explorer.jsx +43 -0
  69. package/apps/integration-client/usage-report.mjs +71 -0
  70. package/apps/integration-client/usage.css +34 -0
  71. package/apps/integration-client/web-panel-model.mjs +140 -0
  72. package/apps/integration-client/web-panel-page.jsx +221 -0
  73. package/apps/integration-client/web-panel-pins-live.jsx +28 -0
  74. package/apps/integration-client/web-panel.css +139 -0
  75. package/apps/integration-client/workspace-model.mjs +67 -0
  76. package/apps/integration-client/workspace-navigation.mjs +56 -0
  77. package/apps/integration-client/workspace-ui.jsx +173 -0
  78. package/apps/integration-client/workspace.css +332 -0
  79. package/modules/bot-runtime/SOURCE.json +176 -50
  80. package/modules/bot-runtime/index.mjs +169 -13
  81. package/modules/bot-runtime/product-overlay/OVERLAY.json +128 -2
  82. package/modules/bot-runtime/product-overlay/base/src/client/header.js +244 -0
  83. package/modules/bot-runtime/product-overlay/base/src/client/learning-card.js +202 -0
  84. package/modules/bot-runtime/product-overlay/base/src/client/model-menu.js +371 -0
  85. package/modules/bot-runtime/product-overlay/base/src/client/secret-card.js +363 -0
  86. package/modules/bot-runtime/product-overlay/base/src/client/sources.js +68 -0
  87. package/modules/bot-runtime/product-overlay/base/src/client/turn-error.js +260 -0
  88. package/modules/bot-runtime/product-overlay/base/src/host/channel.js +647 -0
  89. package/modules/bot-runtime/product-overlay/base/src/host/memory.js +2050 -0
  90. package/modules/bot-runtime/product-overlay/base/src/host/models.js +314 -0
  91. package/modules/bot-runtime/product-overlay/base/src/host/parts.js +1473 -0
  92. package/modules/bot-runtime/product-overlay/base/src/host/privacy.js +368 -0
  93. package/modules/bot-runtime/product-overlay/base/src/host/roster.js +776 -0
  94. package/modules/bot-runtime/product-overlay/base/src/host/store.js +512 -0
  95. package/modules/bot-runtime/product-overlay/base/src/host/usage.js +653 -0
  96. package/modules/bot-runtime/product-overlay/patches/src/client/details-drawer.js.patch +48 -2
  97. package/modules/bot-runtime/product-overlay/patches/src/client/header.js.patch +41 -0
  98. package/modules/bot-runtime/product-overlay/patches/src/client/index.js.patch +33 -1
  99. package/modules/bot-runtime/product-overlay/patches/src/client/learning-card.js.patch +20 -0
  100. package/modules/bot-runtime/product-overlay/patches/src/client/model-menu.js.patch +24 -0
  101. package/modules/bot-runtime/product-overlay/patches/src/client/secret-card.js.patch +25 -0
  102. package/modules/bot-runtime/product-overlay/patches/src/client/sources.js.patch +52 -0
  103. package/modules/bot-runtime/product-overlay/patches/src/client/turn-error.js.patch +23 -0
  104. package/modules/bot-runtime/product-overlay/patches/src/host/channel.js.patch +46 -0
  105. package/modules/bot-runtime/product-overlay/patches/src/host/memory.js.patch +11 -0
  106. package/modules/bot-runtime/product-overlay/patches/src/host/models.js.patch +16 -0
  107. package/modules/bot-runtime/product-overlay/patches/src/host/parts.js.patch +95 -0
  108. package/modules/bot-runtime/product-overlay/patches/src/host/privacy.js.patch +11 -0
  109. package/modules/bot-runtime/product-overlay/patches/src/host/roster.js.patch +145 -0
  110. package/modules/bot-runtime/product-overlay/patches/src/host/store.js.patch +68 -0
  111. package/modules/bot-runtime/product-overlay/patches/src/host/usage.js.patch +11 -0
  112. package/modules/bot-runtime/read-model.mjs +19 -4
  113. package/modules/bot-runtime/vendor/ds-bot/src/client/details-drawer.js +15 -5
  114. package/modules/bot-runtime/vendor/ds-bot/src/client/header.js +9 -2
  115. package/modules/bot-runtime/vendor/ds-bot/src/client/index.js +9 -2
  116. package/modules/bot-runtime/vendor/ds-bot/src/client/learning-card.js +2 -2
  117. package/modules/bot-runtime/vendor/ds-bot/src/client/model-menu.js +5 -3
  118. package/modules/bot-runtime/vendor/ds-bot/src/client/secret-card.js +3 -3
  119. package/modules/bot-runtime/vendor/ds-bot/src/client/sources.js +25 -2
  120. package/modules/bot-runtime/vendor/ds-bot/src/client/turn-error.js +3 -2
  121. package/modules/bot-runtime/vendor/ds-bot/src/host/channel.js +14 -2
  122. package/modules/bot-runtime/vendor/ds-bot/src/host/memory.js +1 -1
  123. package/modules/bot-runtime/vendor/ds-bot/src/host/models.js +7 -0
  124. package/modules/bot-runtime/vendor/ds-bot/src/host/parts.js +26 -9
  125. package/modules/bot-runtime/vendor/ds-bot/src/host/privacy.js +1 -1
  126. package/modules/bot-runtime/vendor/ds-bot/src/host/roster.js +112 -3
  127. package/modules/bot-runtime/vendor/ds-bot/src/host/store.js +34 -1
  128. package/modules/bot-runtime/vendor/ds-bot/src/host/usage.js +1 -1
  129. package/modules/independent-runtime/index.mjs +152 -62
  130. package/modules/independent-runtime/remote-tools.mjs +8 -5
  131. package/modules/openmaus-protocol/NOTICE +10 -0
  132. package/modules/openmaus-protocol/README.md +15 -0
  133. package/modules/openmaus-protocol/SOURCE.json +68 -0
  134. package/modules/openmaus-protocol/dist/protocol.mjs +1203 -0
  135. package/modules/openmaus-protocol/index.mjs +1 -0
  136. package/modules/openmaus-protocol/transport.mjs +77 -0
  137. package/modules/openmaus-protocol/vendor/LICENSE +202 -0
  138. package/modules/openmaus-protocol/vendor/companion/src/e2e/README.md +405 -0
  139. package/modules/openmaus-protocol/vendor/companion/src/e2e/credentials.ts +128 -0
  140. package/modules/openmaus-protocol/vendor/companion/src/e2e/descriptor.ts +84 -0
  141. package/modules/openmaus-protocol/vendor/companion/src/e2e/noise.ts +456 -0
  142. package/modules/openmaus-protocol/vendor/companion/src/e2e/phone.ts +104 -0
  143. package/modules/openmaus-protocol/vendor/companion/src/e2e/session.ts +417 -0
  144. package/modules/openmaus-protocol/vendor/companion/src/e2e/vectors/v1.json +2565 -0
  145. package/modules/openmaus-protocol/vendor/companion/src/e2e/vectors/v1.sha256 +1 -0
  146. package/modules/openmaus-protocol/vendor/companion/src/e2e/yamux.ts +335 -0
  147. package/package.json +18 -6
  148. package/packages/bot-acp/README.md +156 -0
  149. package/packages/bot-acp/licenses/LICENSE-OpenMausBot +202 -0
  150. package/packages/bot-acp/licenses/NOTICE.md +27 -0
  151. package/packages/bot-acp/src/acp-adapter.mjs +795 -0
  152. package/packages/bot-acp/src/acp-host.mjs +148 -0
  153. package/packages/bot-acp/src/native-launch.mjs +121 -0
  154. package/packages/bot-acp/src/permission-policy.mjs +283 -0
  155. package/packages/bot-acp/src/rpc-codec.mjs +265 -0
  156. package/packages/bot-acp/src/session-core.mjs +581 -0
  157. package/packages/bot-acp/src/stdio-rpc.mjs +329 -0
  158. package/packages/bot-engines/README.md +281 -0
  159. package/packages/bot-engines/licenses/LICENSE-OpenMausBot +202 -0
  160. package/packages/bot-engines/licenses/NOTICE.md +32 -0
  161. package/packages/bot-engines/src/claude-engine.mjs +772 -0
  162. package/packages/bot-engines/src/claude-llm-adapter.mjs +797 -0
  163. package/packages/bot-engines/src/claude-llm-turn.mjs +292 -0
  164. package/packages/bot-engines/src/claude-permission-broker.mjs +130 -0
  165. package/packages/bot-engines/src/claude-permission-proxy.mjs +87 -0
  166. package/packages/bot-engines/src/claude-protocol.mjs +177 -0
  167. package/packages/bot-engines/src/driver-catalog.mjs +334 -0
  168. package/packages/bot-engines/src/host-loop-request.mjs +95 -0
  169. package/packages/bot-engines/src/host-registrations.mjs +105 -0
  170. package/packages/capability-broker/src/cli-bootstrap.mjs +86 -16
  171. package/packages/capability-broker/src/cli-bridge-response.mjs +80 -0
  172. package/packages/capability-broker/src/cli-stdio-bridge.mjs +21 -8
  173. package/packages/cli-runtime/src/codex-session-core.mjs +4 -0
  174. package/packages/cli-runtime/src/native-cli-output.mjs +57 -0
  175. package/packages/cli-runtime/src/native-peer.ps1 +51 -3
  176. package/packages/cli-runtime/src/native-process.mjs +77 -14
  177. package/packages/model-router-plugin/package.json +1 -1
  178. package/packages/orchestration/src/binding-product.mjs +19 -0
  179. package/packages/orchestration/src/bot-data-actions.mjs +45 -0
  180. package/packages/orchestration/src/bot-data-chart.mjs +109 -0
  181. package/packages/orchestration/src/bot-data-context.mjs +44 -0
  182. package/packages/orchestration/src/bot-data-engine.mjs +809 -0
  183. package/packages/orchestration/src/bot-data-io.mjs +186 -0
  184. package/packages/orchestration/src/bot-data-sql.mjs +195 -0
  185. package/packages/orchestration/src/bot-data-surface.mjs +144 -0
  186. package/packages/orchestration/src/bot-data-tools.mjs +68 -0
  187. package/packages/orchestration/src/bot-data-worker.mjs +228 -0
  188. package/packages/orchestration/src/bot-independent-execution.mjs +195 -0
  189. package/packages/orchestration/src/bot-independent-stream.mjs +74 -0
  190. package/packages/orchestration/src/bot-loop.mjs +152 -19
  191. package/packages/orchestration/src/bot-notifications.mjs +159 -0
  192. package/packages/orchestration/src/bot-policy.mjs +43 -4
  193. package/packages/orchestration/src/bot-profile.mjs +171 -0
  194. package/packages/orchestration/src/bot-routine.mjs +4 -4
  195. package/packages/orchestration/src/bot-runtime-assembly.mjs +255 -8
  196. package/packages/orchestration/src/bot-runtime-switch.mjs +13 -2
  197. package/packages/orchestration/src/bot-serving.mjs +164 -0
  198. package/packages/orchestration/src/bot-session-store.mjs +105 -9
  199. package/packages/orchestration/src/bot-settings.mjs +50 -11
  200. package/packages/orchestration/src/bot-thread-admission.mjs +84 -0
  201. package/packages/orchestration/src/bot-thread-host.mjs +187 -0
  202. package/packages/orchestration/src/bot-threads.mjs +790 -0
  203. package/packages/orchestration/src/data-product-access.mjs +37 -0
  204. package/packages/orchestration/src/data-tool-contract.mjs +291 -0
  205. package/packages/orchestration/src/desktop-http-carrier.mjs +120 -0
  206. package/packages/orchestration/src/desktop-proxy.mjs +311 -0
  207. package/packages/orchestration/src/desktop-sessions.mjs +43 -9
  208. package/packages/orchestration/src/ds-lifecycle.mjs +31 -4
  209. package/packages/orchestration/src/grant-refresh-queue.mjs +17 -0
  210. package/packages/orchestration/src/independent-chat-page.mjs +39 -0
  211. package/packages/orchestration/src/independent-chat-service.mjs +308 -0
  212. package/packages/orchestration/src/independent-context-state.mjs +44 -0
  213. package/packages/orchestration/src/independent-message-wire.mjs +84 -0
  214. package/packages/orchestration/src/independent-tool-catalog.mjs +175 -0
  215. package/packages/orchestration/src/independent-tool-families.mjs +73 -0
  216. package/packages/orchestration/src/independent-tool-host.mjs +344 -0
  217. package/packages/orchestration/src/main-bot-grant.mjs +15 -0
  218. package/packages/orchestration/src/main-model-routes.mjs +208 -0
  219. package/packages/orchestration/src/model-accounting.mjs +99 -35
  220. package/packages/orchestration/src/model-auxiliary-dispatch.mjs +187 -0
  221. package/packages/orchestration/src/model-loop-frame.mjs +179 -0
  222. package/packages/orchestration/src/model-prepared-generation.mjs +175 -0
  223. package/packages/orchestration/src/model-request-bounds.mjs +111 -0
  224. package/packages/orchestration/src/native-activity-contract.mjs +491 -0
  225. package/packages/orchestration/src/native-activity-service.mjs +102 -0
  226. package/packages/orchestration/src/native-activity-store.mjs +249 -0
  227. package/packages/orchestration/src/native-conversation-tools.mjs +78 -0
  228. package/packages/orchestration/src/native-data-tools.mjs +100 -0
  229. package/packages/orchestration/src/native-remote-actions.mjs +742 -0
  230. package/packages/orchestration/src/native-team-tools.mjs +73 -0
  231. package/packages/orchestration/src/pairing-invite.mjs +37 -0
  232. package/packages/orchestration/src/product-composition.mjs +1559 -1001
  233. package/packages/orchestration/src/remote-machines.mjs +82 -14
  234. package/packages/orchestration/src/routine-execution.mjs +5 -3
  235. package/packages/orchestration/src/routine-session.mjs +19 -13
  236. package/packages/orchestration/src/secure-pairing-host.mjs +112 -0
  237. package/packages/orchestration/src/task-journal.mjs +29 -0
  238. package/packages/orchestration/src/task-product.mjs +17 -0
  239. package/packages/orchestration/src/team-assignment-store.mjs +120 -0
  240. package/packages/orchestration/src/team-bridge.mjs +282 -0
  241. package/packages/orchestration/src/team-scheduler.mjs +83 -0
  242. package/packages/orchestration/src/team-sdk-tools.mjs +84 -0
  243. package/packages/orchestration/src/team-tool-contract.mjs +284 -0
  244. package/packages/orchestration/src/ui-host-namespace.mjs +23 -0
  245. package/packages/orchestration/src/web-panel-actions.mjs +103 -0
  246. package/packages/orchestration/src/web-panel-framing.mjs +227 -0
  247. package/packages/orchestration/src/web-panel-store.mjs +206 -0
  248. package/remote-computer-agent/README.md +39 -29
  249. package/remote-computer-agent/build.mjs +3 -0
  250. package/remote-computer-agent/dist/OPENMAUSBOT_LICENSE +202 -0
  251. package/remote-computer-agent/dist/OPENMAUSBOT_NOTICE +10 -0
  252. package/remote-computer-agent/dist/OPENMAUSBOT_SOURCE.json +68 -0
  253. package/remote-computer-agent/dist/cli-stdio-bridge.mjs +215 -25
  254. package/remote-computer-agent/dist/cli-stdio-bridge.mjs.map +4 -4
  255. package/remote-computer-agent/dist/cli.mjs +1688 -168
  256. package/remote-computer-agent/dist/cli.mjs.map +4 -4
  257. package/remote-computer-agent/dist/index.mjs +1579 -122
  258. package/remote-computer-agent/dist/index.mjs.map +4 -4
  259. package/remote-computer-agent/dist/native-peer.ps1 +51 -3
  260. package/remote-computer-agent/package-lock.json +308 -2
  261. package/remote-computer-agent/package.json +2 -1
  262. package/remote-computer-agent/pair-device.ps1 +20 -0
  263. package/remote-computer-agent/setup.ps1 +38 -16
  264. package/remote-computer-agent/src/cli.ts +24 -3
  265. package/remote-computer-agent/src/desktop-session.ts +11 -3
  266. package/remote-computer-agent/src/e2e-server.ts +81 -0
  267. package/remote-computer-agent/src/pairing-page.ts +35 -0
  268. package/remote-computer-agent/src/protocol.ts +25 -25
  269. package/remote-computer-agent/src/secure-pairing.ts +105 -0
  270. package/remote-computer-agent/src/store.ts +20 -5
  271. package/remote-computer-agent/src/transport.ts +39 -15
@@ -0,0 +1,265 @@
1
+ // Pure JSON-RPC 2.0 codec for the ACP (Agent Client Protocol) stdio wire.
2
+ //
3
+ // Ported and re-grounded from OpenMausBot server/drivers/acp/host.ts and
4
+ // rpc-error.ts at pin 1bc4749aa8307d7d6998bf86de4ef6478460dd93 (Apache-2.0);
5
+ // see licenses/NOTICE.md. Everything here is pure: no child process, no clock,
6
+ // no policy. Bounds are explicit so a hostile or broken peer cannot grow an
7
+ // unbounded buffer, and a message that does not match the documented shape is
8
+ // counted as malformed instead of being guessed at.
9
+
10
+ import { StringDecoder } from 'node:string_decoder'
11
+
12
+ export const JSONRPC_VERSION = '2.0'
13
+
14
+ /** Default bounds. Every one is a hard limit; none of them are advisory. */
15
+ export const DEFAULT_MAX_FRAME_BYTES = 262_144
16
+ export const DEFAULT_MAX_PENDING = 64
17
+ export const DEFAULT_MAX_BACKLOG_BYTES = 1_048_576
18
+ export const DEFAULT_REQUEST_TIMEOUT_MS = 300_000
19
+ export const DEFAULT_IDLE_TIMEOUT_MS = 180_000
20
+ export const MAX_ERROR_TEXT = 1500
21
+ export const MAX_LOG_PREVIEW = 512
22
+
23
+ /** Fixed JSON-RPC error codes. Vendor codes are never remapped onto these. */
24
+ export const RPC_PARSE_ERROR = -32700
25
+ export const RPC_INVALID_REQUEST = -32600
26
+ export const RPC_METHOD_NOT_FOUND = -32601
27
+ export const RPC_INVALID_PARAMS = -32602
28
+ export const RPC_INTERNAL_ERROR = -32603
29
+
30
+ /** ACP wire constants, taken from the upstream driver at the recorded pin. */
31
+ export const ACP_PROTOCOL_VERSION = 1
32
+ export const ACP_METHODS = Object.freeze({
33
+ initialize: 'initialize',
34
+ authenticate: 'authenticate',
35
+ sessionNew: 'session/new',
36
+ sessionLoad: 'session/load',
37
+ sessionPrompt: 'session/prompt',
38
+ sessionCancel: 'session/cancel',
39
+ sessionUpdate: 'session/update',
40
+ sessionClose: 'session/close',
41
+ sessionRequestPermission: 'session/request_permission',
42
+ sessionSetModel: 'session/set_model',
43
+ sessionSetConfigOption: 'session/set_config_option',
44
+ sessionSetMode: 'session/set_mode',
45
+ fsReadTextFile: 'fs/read_text_file',
46
+ fsWriteTextFile: 'fs/write_text_file',
47
+ })
48
+
49
+ /** Client methods this adapter refuses for every session, in every version. */
50
+ export const CLIENT_FILE_METHODS = Object.freeze([ACP_METHODS.fsReadTextFile, ACP_METHODS.fsWriteTextFile])
51
+ export const TERMINAL_METHOD_PREFIX = 'terminal/'
52
+
53
+ /** A JSON-RPC id is a string or an integer. Floats, booleans and null are not ids. */
54
+ export function isValidMessageId(value) {
55
+ if (typeof value === 'string') return value.length > 0 && value.length <= 128
56
+ return Number.isInteger(value)
57
+ }
58
+
59
+ const bounded = value => (value.length > MAX_ERROR_TEXT ? `${value.slice(0, MAX_ERROR_TEXT - 1)}…` : value)
60
+
61
+ /**
62
+ * A wire error to Error. Vendors put the actionable cause under `data`; only
63
+ * known text fields surface, bounded, never a whole response body.
64
+ */
65
+ export function errorFromWire(value, method) {
66
+ const error = value && typeof value === 'object' && !Array.isArray(value) ? value : {}
67
+ const message = typeof error.message === 'string' && error.message ? error.message : 'ACP request failed'
68
+ const data = error.data
69
+ const detail = typeof data === 'string' && data
70
+ ? data
71
+ : typeof data?.details === 'string' && data.details
72
+ ? data.details
73
+ : typeof data?.message === 'string' && data.message
74
+ ? data.message
75
+ : typeof data?.error?.message === 'string' && data.error.message
76
+ ? data.error.message
77
+ : ''
78
+ const context = [
79
+ typeof method === 'string' && method ? method : '',
80
+ typeof data?.service === 'string' && data.service ? `service: ${data.service}` : '',
81
+ typeof data?.errorName === 'string' && data.errorName ? data.errorName : '',
82
+ ].filter(Boolean).join(', ')
83
+ const diagnostic = `${detail && detail !== message ? `${message}: ${detail}` : message}${context ? ` (${context})` : ''}`
84
+ const failure = new Error(bounded(diagnostic))
85
+ return Object.assign(failure, {
86
+ rpcCode: typeof error.code === 'number' ? error.code : null,
87
+ rpcData: data,
88
+ // -32603 is JSON-RPC's internal error; invalid params, unknown methods and
89
+ // auth refusals keep the session usable.
90
+ acpSessionFailure: error.code === RPC_INTERNAL_ERROR,
91
+ })
92
+ }
93
+
94
+ export function rpcErrorObject(code, message, data) {
95
+ const error = { code, message: typeof message === 'string' ? message : 'error' }
96
+ if (data !== undefined) error.data = data
97
+ return error
98
+ }
99
+
100
+ /**
101
+ * Newline-delimited JSON framing with a hard frame cap. A multi-byte character
102
+ * split across reads is decoded as one unit; a frame over the cap is dropped as
103
+ * a whole and reported once, never parsed in pieces.
104
+ */
105
+ export function createFrameDecoder({ maxFrameBytes = DEFAULT_MAX_FRAME_BYTES, onFrame, onError } = {}) {
106
+ if (!Number.isSafeInteger(maxFrameBytes) || maxFrameBytes < 1024) throw new TypeError('ACP_FRAME_LIMIT_INVALID')
107
+ if (typeof onFrame !== 'function') throw new TypeError('ACP_FRAME_SINK_REQUIRED')
108
+ const decoder = new StringDecoder('utf8')
109
+ let buffer = ''
110
+ let dropping = false
111
+ let frames = 0, malformed = 0, oversize = 0, bytes = 0, blank = 0
112
+ const reportOversize = () => {
113
+ oversize++
114
+ if (typeof onError === 'function') onError(Object.assign(new Error('ACP_FRAME_LIMIT'), { acpFrameLimit: true }))
115
+ }
116
+ return Object.freeze({
117
+ write(chunk) {
118
+ let text = typeof chunk === 'string' ? chunk : decoder.write(chunk)
119
+ if (!text) return
120
+ bytes += Buffer.byteLength(text)
121
+ if (dropping) {
122
+ // An oversized frame is dropped whole: discard through its terminator.
123
+ const end = text.indexOf('\n')
124
+ if (end === -1) return
125
+ text = text.slice(end + 1)
126
+ dropping = false
127
+ reportOversize()
128
+ }
129
+ buffer += text
130
+ if (Buffer.byteLength(buffer) > maxFrameBytes) {
131
+ const end = buffer.indexOf('\n')
132
+ if (end === -1) { dropping = true; buffer = ''; reportOversize(); return }
133
+ buffer = buffer.slice(end + 1)
134
+ reportOversize()
135
+ }
136
+ let end
137
+ while ((end = buffer.indexOf('\n')) !== -1) {
138
+ const line = buffer.slice(0, end).replace(/\r$/, '')
139
+ buffer = buffer.slice(end + 1)
140
+ if (!line.trim()) { blank++; continue }
141
+ if (Buffer.byteLength(line) > maxFrameBytes) { reportOversize(); continue }
142
+ frames++
143
+ onFrame(line)
144
+ }
145
+ },
146
+ /** Feed the decoder's trailing bytes and treat a final unterminated frame as nothing said. */
147
+ end() {
148
+ const tail = decoder.end()
149
+ if (tail) this.write(tail)
150
+ buffer = ''
151
+ dropping = false
152
+ },
153
+ get stats() {
154
+ return Object.freeze({ frames, malformed, oversize, blank, bytes, pendingBytes: Buffer.byteLength(buffer) })
155
+ },
156
+ })
157
+ }
158
+
159
+ /**
160
+ * Parse one frame. Returns null for anything that is not a single JSON-RPC
161
+ * object: batches, arrays, scalars and parse failures are all malformed.
162
+ */
163
+ export function parseFrame(line) {
164
+ if (typeof line !== 'string' || !line.trim()) return null
165
+ let value
166
+ try {
167
+ value = JSON.parse(line)
168
+ } catch {
169
+ return null
170
+ }
171
+ if (!value || typeof value !== 'object' || Array.isArray(value)) return null
172
+ return value
173
+ }
174
+
175
+ /**
176
+ * Classify a parsed message. A response carries an id and neither method; a
177
+ * server request carries both; a notification carries a method and no id.
178
+ * Anything else is `invalid` and must be counted, not acted on.
179
+ */
180
+ export function classifyMessage(message) {
181
+ if (!message || typeof message !== 'object' || Array.isArray(message)) return { kind: 'invalid', reason: 'not-an-object' }
182
+ if (message.jsonrpc !== undefined && message.jsonrpc !== JSONRPC_VERSION) return { kind: 'invalid', reason: 'bad-jsonrpc' }
183
+ const hasId = Object.hasOwn(message, 'id') && message.id !== null && message.id !== undefined
184
+ const hasMethod = Object.hasOwn(message, 'method') && typeof message.method === 'string' && message.method
185
+ if (hasId && !isValidMessageId(message.id)) return { kind: 'invalid', reason: 'bad-id' }
186
+ if (hasMethod && hasId) {
187
+ return { kind: 'request', id: message.id, method: message.method, params: message.params, raw: message }
188
+ }
189
+ if (hasMethod) {
190
+ return { kind: 'notification', method: message.method, params: message.params, raw: message }
191
+ }
192
+ if (hasId) {
193
+ const hasResult = Object.hasOwn(message, 'result')
194
+ const hasError = Object.hasOwn(message, 'error') && message.error !== undefined && message.error !== null
195
+ if (hasError) return { kind: 'response', id: message.id, error: message.error, raw: message }
196
+ if (hasResult) return { kind: 'response', id: message.id, result: message.result, raw: message }
197
+ return { kind: 'invalid', reason: 'response-without-result-or-error' }
198
+ }
199
+ return { kind: 'invalid', reason: 'no-method-no-id' }
200
+ }
201
+
202
+ /** Bounded preview for diagnostic logs: never a whole tool payload or credential. */
203
+ export function previewMessage(message) {
204
+ try {
205
+ const text = JSON.stringify(message) ?? ''
206
+ return text.length > MAX_LOG_PREVIEW ? `${text.slice(0, MAX_LOG_PREVIEW - 1)}…` : text
207
+ } catch {
208
+ return '[unserializable]'
209
+ }
210
+ }
211
+
212
+ /** True when the agent is asking the client to touch the local filesystem. */
213
+ export function isClientFileMethod(method) {
214
+ return CLIENT_FILE_METHODS.includes(method)
215
+ }
216
+
217
+ /** True when the agent is asking the client to run a local terminal. */
218
+ export function isTerminalMethod(method) {
219
+ return typeof method === 'string' && method.startsWith(TERMINAL_METHOD_PREFIX)
220
+ }
221
+
222
+ /**
223
+ * Client capabilities sent on initialize. File and terminal access are off
224
+ * unless the Host explicitly turns them on; a hand-written prompt is never the
225
+ * security boundary, so the capability and the method refusal agree.
226
+ */
227
+ export function clientCapabilities({ fileSystem = false, terminal = false, meta } = {}) {
228
+ const allow = fileSystem === true
229
+ return Object.freeze({
230
+ fs: { readTextFile: allow, writeTextFile: allow },
231
+ terminal: terminal === true,
232
+ ...(meta && typeof meta === 'object' ? { _meta: meta } : {}),
233
+ })
234
+ }
235
+
236
+ /** ACP advertises optional operations as capability objects; older runtimes send booleans. */
237
+ const advertised = value => value === true || (typeof value === 'object' && value !== null && !Array.isArray(value))
238
+
239
+ /**
240
+ * Read the initialize result against the fixed schema. Unknown fields are kept
241
+ * verbatim under `raw` for diagnostics and never interpreted.
242
+ */
243
+ export function readAgentCapabilities(initializeResult) {
244
+ const result = initializeResult && typeof initializeResult === 'object' && !Array.isArray(initializeResult) ? initializeResult : {}
245
+ const agent = result.agentCapabilities && typeof result.agentCapabilities === 'object' && !Array.isArray(result.agentCapabilities) ? result.agentCapabilities : {}
246
+ const session = agent.sessionCapabilities && typeof agent.sessionCapabilities === 'object' && !Array.isArray(agent.sessionCapabilities) ? agent.sessionCapabilities : {}
247
+ const prompt = agent.promptCapabilities && typeof agent.promptCapabilities === 'object' && !Array.isArray(agent.promptCapabilities) ? agent.promptCapabilities : {}
248
+ const mcp = agent.mcpCapabilities && typeof agent.mcpCapabilities === 'object' && !Array.isArray(agent.mcpCapabilities) ? agent.mcpCapabilities : {}
249
+ const auth = agent.auth && typeof agent.auth === 'object' && !Array.isArray(agent.auth) ? agent.auth : {}
250
+ const info = result.agentInfo && typeof result.agentInfo === 'object' && !Array.isArray(result.agentInfo) ? result.agentInfo : {}
251
+ return Object.freeze({
252
+ protocolVersion: typeof result.protocolVersion === 'number' ? result.protocolVersion : null,
253
+ agentName: typeof info.name === 'string' ? info.name : null,
254
+ agentVersion: typeof info.version === 'string' ? info.version : null,
255
+ authMethods: Array.isArray(result.authMethods) ? result.authMethods : [],
256
+ loadSession: agent.loadSession === true,
257
+ sessionResume: advertised(session.resume),
258
+ sessionClose: advertised(session.close),
259
+ authLogout: advertised(auth.logout),
260
+ promptImage: prompt.image === true,
261
+ mcpHttp: mcp.http === true,
262
+ mcpSse: mcp.sse === true,
263
+ raw: result,
264
+ })
265
+ }