@di-code/coding-agent 0.1.6 → 0.1.8

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 (338) hide show
  1. package/README.md +112 -68
  2. package/compositions/base.yml +54 -0
  3. package/compositions/interactive.yml +14 -0
  4. package/compositions/json.yml +6 -0
  5. package/compositions/print.yml +5 -0
  6. package/compositions/rpc.yml +12 -0
  7. package/compositions/webui.yml +9 -0
  8. package/dist/cli.d.ts +22 -1
  9. package/dist/cli.d.ts.map +1 -1
  10. package/dist/cli.js +97 -3
  11. package/dist/cli.js.map +1 -1
  12. package/dist/composition-loader-entry.d.ts +11 -0
  13. package/dist/composition-loader-entry.d.ts.map +1 -0
  14. package/dist/composition-loader-entry.js +12 -0
  15. package/dist/composition-loader-entry.js.map +1 -0
  16. package/dist/compositions.d.ts +32 -0
  17. package/dist/compositions.d.ts.map +1 -0
  18. package/dist/compositions.js +173 -0
  19. package/dist/compositions.js.map +1 -0
  20. package/dist/core/session/session-manager.d.ts +9 -2
  21. package/dist/core/session/session-manager.d.ts.map +1 -1
  22. package/dist/core/session/session-manager.js +28 -0
  23. package/dist/core/session/session-manager.js.map +1 -1
  24. package/dist/core/session/session-storage.d.ts.map +1 -1
  25. package/dist/core/session/session-storage.js +20 -3
  26. package/dist/core/session/session-storage.js.map +1 -1
  27. package/dist/core/session/types.d.ts +11 -2
  28. package/dist/core/session/types.d.ts.map +1 -1
  29. package/dist/core/session/types.js.map +1 -1
  30. package/dist/core/session-tools.d.ts +5 -0
  31. package/dist/core/session-tools.d.ts.map +1 -0
  32. package/dist/core/session-tools.js +17 -0
  33. package/dist/core/session-tools.js.map +1 -0
  34. package/dist/core/session.d.ts +21 -7
  35. package/dist/core/session.d.ts.map +1 -1
  36. package/dist/core/session.js +77 -41
  37. package/dist/core/session.js.map +1 -1
  38. package/dist/core/tools/bash.d.ts +1 -38
  39. package/dist/core/tools/bash.d.ts.map +1 -1
  40. package/dist/core/tools/bash.js +1 -207
  41. package/dist/core/tools/bash.js.map +1 -1
  42. package/dist/core/tools/edit-diff.d.ts +1 -24
  43. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  44. package/dist/core/tools/edit-diff.js +1 -135
  45. package/dist/core/tools/edit-diff.js.map +1 -1
  46. package/dist/core/tools/edit.d.ts +1 -26
  47. package/dist/core/tools/edit.d.ts.map +1 -1
  48. package/dist/core/tools/edit.js +1 -140
  49. package/dist/core/tools/edit.js.map +1 -1
  50. package/dist/core/tools/file-mutation-queue.d.ts +1 -1
  51. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
  52. package/dist/core/tools/file-mutation-queue.js +1 -23
  53. package/dist/core/tools/file-mutation-queue.js.map +1 -1
  54. package/dist/core/tools/file-search.d.ts +1 -13
  55. package/dist/core/tools/file-search.d.ts.map +1 -1
  56. package/dist/core/tools/file-search.js +1 -98
  57. package/dist/core/tools/file-search.js.map +1 -1
  58. package/dist/core/tools/glob.d.ts +1 -10
  59. package/dist/core/tools/glob.d.ts.map +1 -1
  60. package/dist/core/tools/glob.js +1 -43
  61. package/dist/core/tools/glob.js.map +1 -1
  62. package/dist/core/tools/grep.d.ts +1 -12
  63. package/dist/core/tools/grep.d.ts.map +1 -1
  64. package/dist/core/tools/grep.js +1 -66
  65. package/dist/core/tools/grep.js.map +1 -1
  66. package/dist/core/tools/load-skill.d.ts +1 -9
  67. package/dist/core/tools/load-skill.d.ts.map +1 -1
  68. package/dist/core/tools/load-skill.js +1 -21
  69. package/dist/core/tools/load-skill.js.map +1 -1
  70. package/dist/core/tools/path-boundary.d.ts +1 -4
  71. package/dist/core/tools/path-boundary.d.ts.map +1 -1
  72. package/dist/core/tools/path-boundary.js +1 -65
  73. package/dist/core/tools/path-boundary.js.map +1 -1
  74. package/dist/core/tools/read.d.ts +1 -16
  75. package/dist/core/tools/read.d.ts.map +1 -1
  76. package/dist/core/tools/read.js +1 -131
  77. package/dist/core/tools/read.js.map +1 -1
  78. package/dist/core/tools/write.d.ts +1 -16
  79. package/dist/core/tools/write.d.ts.map +1 -1
  80. package/dist/core/tools/write.js +1 -44
  81. package/dist/core/tools/write.js.map +1 -1
  82. package/dist/entry.js +30 -28
  83. package/dist/entry.js.map +1 -1
  84. package/dist/i18n.d.ts.map +1 -1
  85. package/dist/i18n.js +2 -0
  86. package/dist/i18n.js.map +1 -1
  87. package/dist/index.d.ts +6 -3
  88. package/dist/index.d.ts.map +1 -1
  89. package/dist/index.js +6 -3
  90. package/dist/index.js.map +1 -1
  91. package/dist/interactive/builtin.d.ts +17 -0
  92. package/dist/interactive/builtin.d.ts.map +1 -0
  93. package/dist/interactive/builtin.js +47 -0
  94. package/dist/interactive/builtin.js.map +1 -0
  95. package/dist/interactive/controller.d.ts +85 -0
  96. package/dist/interactive/controller.d.ts.map +1 -0
  97. package/dist/interactive/controller.js +211 -0
  98. package/dist/interactive/controller.js.map +1 -0
  99. package/dist/interactive/index.d.ts +3 -0
  100. package/dist/interactive/index.d.ts.map +1 -0
  101. package/dist/interactive/index.js +3 -0
  102. package/dist/interactive/index.js.map +1 -0
  103. package/dist/interactive-host-entry.d.ts +7 -0
  104. package/dist/interactive-host-entry.d.ts.map +1 -0
  105. package/dist/interactive-host-entry.js +123 -0
  106. package/dist/interactive-host-entry.js.map +1 -0
  107. package/dist/interactive-profile.d.ts +18 -0
  108. package/dist/interactive-profile.d.ts.map +1 -0
  109. package/dist/interactive-profile.js +290 -0
  110. package/dist/interactive-profile.js.map +1 -0
  111. package/dist/interactive-resources-entry.d.ts +7 -0
  112. package/dist/interactive-resources-entry.d.ts.map +1 -0
  113. package/dist/interactive-resources-entry.js +42 -0
  114. package/dist/interactive-resources-entry.js.map +1 -0
  115. package/dist/legacy-main.d.ts +39 -0
  116. package/dist/legacy-main.d.ts.map +1 -0
  117. package/dist/legacy-main.js +611 -0
  118. package/dist/legacy-main.js.map +1 -0
  119. package/dist/main.d.ts +15 -34
  120. package/dist/main.d.ts.map +1 -1
  121. package/dist/main.js +130 -513
  122. package/dist/main.js.map +1 -1
  123. package/dist/mcp/entries.d.ts +42 -0
  124. package/dist/mcp/entries.d.ts.map +1 -0
  125. package/dist/mcp/entries.js +98 -0
  126. package/dist/mcp/entries.js.map +1 -0
  127. package/dist/mcp-client-entry.d.ts +5 -0
  128. package/dist/mcp-client-entry.d.ts.map +1 -0
  129. package/dist/mcp-client-entry.js +6 -0
  130. package/dist/mcp-client-entry.js.map +1 -0
  131. package/dist/mcp-config-entry.d.ts +5 -0
  132. package/dist/mcp-config-entry.d.ts.map +1 -0
  133. package/dist/mcp-config-entry.js +6 -0
  134. package/dist/mcp-config-entry.js.map +1 -0
  135. package/dist/mcp-tools-entry.d.ts +5 -0
  136. package/dist/mcp-tools-entry.d.ts.map +1 -0
  137. package/dist/mcp-tools-entry.js +6 -0
  138. package/dist/mcp-tools-entry.js.map +1 -0
  139. package/dist/mcp-transport-entry.d.ts +5 -0
  140. package/dist/mcp-transport-entry.d.ts.map +1 -0
  141. package/dist/mcp-transport-entry.js +6 -0
  142. package/dist/mcp-transport-entry.js.map +1 -0
  143. package/dist/modes/interactive-entry.d.ts +18 -0
  144. package/dist/modes/interactive-entry.d.ts.map +1 -0
  145. package/dist/modes/interactive-entry.js +21 -0
  146. package/dist/modes/interactive-entry.js.map +1 -0
  147. package/dist/modes/interactive-state.js +1 -1
  148. package/dist/modes/interactive-state.js.map +1 -1
  149. package/dist/modes/interactive.d.ts +16 -6
  150. package/dist/modes/interactive.d.ts.map +1 -1
  151. package/dist/modes/interactive.js +99 -33
  152. package/dist/modes/interactive.js.map +1 -1
  153. package/dist/modes/json-entry.d.ts +13 -0
  154. package/dist/modes/json-entry.d.ts.map +1 -0
  155. package/dist/modes/json-entry.js +14 -0
  156. package/dist/modes/json-entry.js.map +1 -0
  157. package/dist/modes/json.d.ts +4 -1
  158. package/dist/modes/json.d.ts.map +1 -1
  159. package/dist/modes/json.js +3 -3
  160. package/dist/modes/json.js.map +1 -1
  161. package/dist/modes/print-entry.d.ts +10 -0
  162. package/dist/modes/print-entry.d.ts.map +1 -0
  163. package/dist/modes/print-entry.js +11 -0
  164. package/dist/modes/print-entry.js.map +1 -0
  165. package/dist/modes/tree-selector.d.ts.map +1 -1
  166. package/dist/modes/tree-selector.js +4 -0
  167. package/dist/modes/tree-selector.js.map +1 -1
  168. package/dist/plugin-dump-composition.d.ts +6 -0
  169. package/dist/plugin-dump-composition.d.ts.map +1 -0
  170. package/dist/plugin-dump-composition.js +7 -0
  171. package/dist/plugin-dump-composition.js.map +1 -0
  172. package/dist/plugin-inventory.d.ts +7 -0
  173. package/dist/plugin-inventory.d.ts.map +1 -0
  174. package/dist/plugin-inventory.js +8 -0
  175. package/dist/plugin-inventory.js.map +1 -0
  176. package/dist/plugin-manager.d.ts +6 -0
  177. package/dist/plugin-manager.d.ts.map +1 -0
  178. package/dist/plugin-manager.js +7 -0
  179. package/dist/plugin-manager.js.map +1 -0
  180. package/dist/plugin-trace.d.ts +6 -0
  181. package/dist/plugin-trace.d.ts.map +1 -0
  182. package/dist/plugin-trace.js +7 -0
  183. package/dist/plugin-trace.js.map +1 -0
  184. package/dist/plugins/dynamic-broker.d.ts +76 -0
  185. package/dist/plugins/dynamic-broker.d.ts.map +1 -0
  186. package/dist/plugins/dynamic-broker.js +852 -0
  187. package/dist/plugins/dynamic-broker.js.map +1 -0
  188. package/dist/plugins/profile.d.ts +15 -0
  189. package/dist/plugins/profile.d.ts.map +1 -0
  190. package/dist/plugins/profile.js +34 -0
  191. package/dist/plugins/profile.js.map +1 -0
  192. package/dist/plugins/runtime-host.d.ts +37 -0
  193. package/dist/plugins/runtime-host.d.ts.map +1 -0
  194. package/dist/plugins/runtime-host.js +95 -0
  195. package/dist/plugins/runtime-host.js.map +1 -0
  196. package/dist/plugins/trust.d.ts +8 -0
  197. package/dist/plugins/trust.d.ts.map +1 -0
  198. package/dist/plugins/trust.js +59 -0
  199. package/dist/plugins/trust.js.map +1 -0
  200. package/dist/project-trust-entry.d.ts +15 -0
  201. package/dist/project-trust-entry.d.ts.map +1 -0
  202. package/dist/project-trust-entry.js +15 -0
  203. package/dist/project-trust-entry.js.map +1 -0
  204. package/dist/rpc/client.d.ts +78 -6
  205. package/dist/rpc/client.d.ts.map +1 -1
  206. package/dist/rpc/client.js +172 -4
  207. package/dist/rpc/client.js.map +1 -1
  208. package/dist/rpc/dispatcher.d.ts +121 -0
  209. package/dist/rpc/dispatcher.d.ts.map +1 -0
  210. package/dist/rpc/dispatcher.js +994 -0
  211. package/dist/rpc/dispatcher.js.map +1 -0
  212. package/dist/rpc/index.d.ts +2 -0
  213. package/dist/rpc/index.d.ts.map +1 -1
  214. package/dist/rpc/index.js +2 -0
  215. package/dist/rpc/index.js.map +1 -1
  216. package/dist/rpc/lifecycle.d.ts +6 -0
  217. package/dist/rpc/lifecycle.d.ts.map +1 -0
  218. package/dist/rpc/lifecycle.js +24 -0
  219. package/dist/rpc/lifecycle.js.map +1 -0
  220. package/dist/rpc/protocol.d.ts +112 -31
  221. package/dist/rpc/protocol.d.ts.map +1 -1
  222. package/dist/rpc/protocol.js +569 -117
  223. package/dist/rpc/protocol.js.map +1 -1
  224. package/dist/rpc/server-service.d.ts +7 -0
  225. package/dist/rpc/server-service.d.ts.map +1 -0
  226. package/dist/rpc/server-service.js +3 -0
  227. package/dist/rpc/server-service.js.map +1 -0
  228. package/dist/rpc/server.d.ts +16 -19
  229. package/dist/rpc/server.d.ts.map +1 -1
  230. package/dist/rpc/server.js +59 -115
  231. package/dist/rpc/server.js.map +1 -1
  232. package/dist/rpc-client-sdk-entry.d.ts +12 -0
  233. package/dist/rpc-client-sdk-entry.d.ts.map +1 -0
  234. package/dist/rpc-client-sdk-entry.js +11 -0
  235. package/dist/rpc-client-sdk-entry.js.map +1 -0
  236. package/dist/rpc-entry.js +50 -18
  237. package/dist/rpc-entry.js.map +1 -1
  238. package/dist/rpc-server-entry.d.ts +8 -0
  239. package/dist/rpc-server-entry.d.ts.map +1 -0
  240. package/dist/rpc-server-entry.js +67 -0
  241. package/dist/rpc-server-entry.js.map +1 -0
  242. package/dist/runtime/attachment-store.d.ts +13 -0
  243. package/dist/runtime/attachment-store.d.ts.map +1 -0
  244. package/dist/runtime/attachment-store.js +93 -0
  245. package/dist/runtime/attachment-store.js.map +1 -0
  246. package/dist/runtime/bootstrap.d.ts +14 -0
  247. package/dist/runtime/bootstrap.d.ts.map +1 -0
  248. package/dist/runtime/bootstrap.js +29 -0
  249. package/dist/runtime/bootstrap.js.map +1 -0
  250. package/dist/runtime/interactive-host-service.d.ts +22 -0
  251. package/dist/runtime/interactive-host-service.d.ts.map +1 -0
  252. package/dist/runtime/interactive-host-service.js +2 -0
  253. package/dist/runtime/interactive-host-service.js.map +1 -0
  254. package/dist/runtime/interactive-resource-service.d.ts +11 -0
  255. package/dist/runtime/interactive-resource-service.d.ts.map +1 -0
  256. package/dist/runtime/interactive-resource-service.js +3 -0
  257. package/dist/runtime/interactive-resource-service.js.map +1 -0
  258. package/dist/runtime/plugin-inventory-entry.d.ts +5 -0
  259. package/dist/runtime/plugin-inventory-entry.d.ts.map +1 -0
  260. package/dist/runtime/plugin-inventory-entry.js +18 -0
  261. package/dist/runtime/plugin-inventory-entry.js.map +1 -0
  262. package/dist/runtime/plugin-inventory-service.d.ts +8 -0
  263. package/dist/runtime/plugin-inventory-service.d.ts.map +1 -0
  264. package/dist/runtime/plugin-inventory-service.js +3 -0
  265. package/dist/runtime/plugin-inventory-service.js.map +1 -0
  266. package/dist/runtime/plugin-manager-entry.d.ts +20 -0
  267. package/dist/runtime/plugin-manager-entry.d.ts.map +1 -0
  268. package/dist/runtime/plugin-manager-entry.js +96 -0
  269. package/dist/runtime/plugin-manager-entry.js.map +1 -0
  270. package/dist/runtime/plugin-observability-entry.d.ts +12 -0
  271. package/dist/runtime/plugin-observability-entry.d.ts.map +1 -0
  272. package/dist/runtime/plugin-observability-entry.js +73 -0
  273. package/dist/runtime/plugin-observability-entry.js.map +1 -0
  274. package/dist/runtime/product-host.d.ts +91 -0
  275. package/dist/runtime/product-host.d.ts.map +1 -0
  276. package/dist/runtime/product-host.js +529 -0
  277. package/dist/runtime/product-host.js.map +1 -0
  278. package/dist/runtime/session-factory.d.ts +17 -0
  279. package/dist/runtime/session-factory.d.ts.map +1 -0
  280. package/dist/runtime/session-factory.js +75 -0
  281. package/dist/runtime/session-factory.js.map +1 -0
  282. package/dist/runtime/session-host.d.ts +152 -0
  283. package/dist/runtime/session-host.d.ts.map +1 -0
  284. package/dist/runtime/session-host.js +895 -0
  285. package/dist/runtime/session-host.js.map +1 -0
  286. package/dist/runtime-core-entry.d.ts +11 -0
  287. package/dist/runtime-core-entry.d.ts.map +1 -0
  288. package/dist/runtime-core-entry.js +9 -0
  289. package/dist/runtime-core-entry.js.map +1 -0
  290. package/dist/session-factory-entry.d.ts +7 -0
  291. package/dist/session-factory-entry.d.ts.map +1 -0
  292. package/dist/session-factory-entry.js +9 -0
  293. package/dist/session-factory-entry.js.map +1 -0
  294. package/dist/session-store-jsonl-entry.d.ts +7 -0
  295. package/dist/session-store-jsonl-entry.d.ts.map +1 -0
  296. package/dist/session-store-jsonl-entry.js +33 -0
  297. package/dist/session-store-jsonl-entry.js.map +1 -0
  298. package/dist/startup.d.ts +21 -1
  299. package/dist/startup.d.ts.map +1 -1
  300. package/dist/startup.js +179 -10
  301. package/dist/startup.js.map +1 -1
  302. package/dist/subagents/index.d.ts +2 -0
  303. package/dist/subagents/index.d.ts.map +1 -0
  304. package/dist/subagents/index.js +2 -0
  305. package/dist/subagents/index.js.map +1 -0
  306. package/dist/subagents/service.d.ts +50 -0
  307. package/dist/subagents/service.d.ts.map +1 -0
  308. package/dist/subagents/service.js +521 -0
  309. package/dist/subagents/service.js.map +1 -0
  310. package/dist/ui-host.d.ts +125 -0
  311. package/dist/ui-host.d.ts.map +1 -0
  312. package/dist/ui-host.js +275 -0
  313. package/dist/ui-host.js.map +1 -0
  314. package/dist/web/assets/index-BwfuGMvv.css +1 -0
  315. package/dist/web/assets/index-DPUaJqFJ.js +41 -0
  316. package/dist/web/assets/index-DPUaJqFJ.js.map +1 -0
  317. package/dist/web/index.html +14 -0
  318. package/dist/web-command.d.ts +11 -0
  319. package/dist/web-command.d.ts.map +1 -0
  320. package/dist/web-command.js +114 -0
  321. package/dist/web-command.js.map +1 -0
  322. package/dist/web-frontend.d.ts +73 -0
  323. package/dist/web-frontend.d.ts.map +1 -0
  324. package/dist/web-frontend.js +249 -0
  325. package/dist/web-frontend.js.map +1 -0
  326. package/dist/web.d.ts +254 -0
  327. package/dist/web.d.ts.map +1 -0
  328. package/dist/web.js +740 -0
  329. package/dist/web.js.map +1 -0
  330. package/dist/webui-entry.d.ts +3 -0
  331. package/dist/webui-entry.d.ts.map +1 -0
  332. package/dist/webui-entry.js +73 -0
  333. package/dist/webui-entry.js.map +1 -0
  334. package/dist/webui.d.ts +91 -0
  335. package/dist/webui.d.ts.map +1 -0
  336. package/dist/webui.js +882 -0
  337. package/dist/webui.js.map +1 -0
  338. package/package.json +89 -8
@@ -1,6 +1,67 @@
1
+ import { validateWebManifest } from "@di-code/plugin-runtime";
1
2
  export const RPC_PROTOCOL_VERSION = 1;
2
3
  export const RPC_MAX_ID_LENGTH = 128;
3
4
  export const RPC_MAX_PROMPT_LENGTH = 1_000_000;
5
+ export const RPC_MAX_ATTACHMENTS_PER_REQUEST = 4;
6
+ export const RPC_MAX_ATTACHMENT_BYTES = 5 * 1024 * 1024;
7
+ /** Allows one JSONL user entry containing a maximum-sized base64 image to be read in a single transcript page. */
8
+ export const RPC_MAX_TRANSCRIPT_BYTES = 8 * 1024 * 1024;
9
+ const RPC_MAX_ATTACHMENT_BASE64_LENGTH = Math.ceil(RPC_MAX_ATTACHMENT_BYTES / 3) * 4;
10
+ /** v1 grows only by methods and optional fields. Clients must negotiate extended events first. */
11
+ export const RPC_METHODS = [
12
+ "prompt",
13
+ "cancel",
14
+ "get_state",
15
+ "get_capabilities",
16
+ "resume_events",
17
+ "list_sessions",
18
+ "new_session",
19
+ "open_session",
20
+ "inspect_session",
21
+ "rename_session",
22
+ "delete_session",
23
+ "branch_session",
24
+ "get_transcript",
25
+ "get_tree",
26
+ "navigate_tree",
27
+ "steer",
28
+ "retry",
29
+ "get_operation",
30
+ "get_models",
31
+ "set_model",
32
+ "get_runtime",
33
+ "set_runtime",
34
+ "set_thinking_level",
35
+ "compact",
36
+ "set_compaction_enabled",
37
+ "get_usage",
38
+ "list_skills",
39
+ "get_resources",
40
+ "get_product_state",
41
+ "list_providers",
42
+ "get_settings",
43
+ "set_default_provider",
44
+ "set_default_model",
45
+ "set_locale",
46
+ "set_permission_mode",
47
+ "configure_custom_provider",
48
+ "login",
49
+ "logout",
50
+ "get_project_trust",
51
+ "set_project_trust",
52
+ "list_context_files",
53
+ "list_mcp_servers",
54
+ "configure_mcp_server",
55
+ "remove_mcp_server",
56
+ "reconnect_mcp_server",
57
+ "list_plugins",
58
+ "list_web_contributions",
59
+ "list_commands",
60
+ "run_command",
61
+ "set_plugin_enabled",
62
+ "create_attachment",
63
+ "approve_tool",
64
+ ];
4
65
  const RPC_ERROR_CODES = new Set([
5
66
  "PARSE_ERROR",
6
67
  "INVALID_REQUEST",
@@ -10,10 +71,14 @@ const RPC_ERROR_CODES = new Set([
10
71
  "BUSY",
11
72
  "NOT_FOUND",
12
73
  "CANCELLED",
74
+ "DISPOSED",
75
+ "SESSION_IN_USE",
76
+ "INVALID_WORKSPACE",
77
+ "UNAUTHORIZED",
13
78
  "INTERNAL_ERROR",
14
79
  "PROCESS_EXIT",
15
80
  ]);
16
- const RPC_EVENT_TYPES = new Set([
81
+ const LEGACY_EVENT_TYPES = new Set([
17
82
  "agent_start",
18
83
  "turn_start",
19
84
  "message_start",
@@ -25,8 +90,25 @@ const RPC_EVENT_TYPES = new Set([
25
90
  "agent_end",
26
91
  "compaction_start",
27
92
  "compaction_end",
93
+ "queue_update",
94
+ "tree_navigated",
28
95
  "usage_update",
29
96
  ]);
97
+ const EXTENDED_EVENT_TYPES = new Set([
98
+ "snapshot_required",
99
+ "operation_update",
100
+ "session_changed",
101
+ "tool_approval",
102
+ "product_audit",
103
+ ]);
104
+ const EXTENDED_EVENT_NAMES = new Set([
105
+ "sequence",
106
+ "operation_update",
107
+ "snapshot_required",
108
+ "session_changed",
109
+ "tool_approval",
110
+ "product_audit",
111
+ ]);
30
112
  const ASSISTANT_STOP_REASONS = new Set(["stop", "length", "tool_use", "error", "aborted"]);
31
113
  export class RpcProtocolError extends Error {
32
114
  code;
@@ -44,61 +126,214 @@ function objectRecord(value) {
44
126
  : undefined;
45
127
  }
46
128
  function requiredId(value, field, requestId) {
47
- if (typeof value !== "string" || value.length === 0 || value.length > RPC_MAX_ID_LENGTH) {
129
+ if (typeof value !== "string" || value.length === 0 || value.length > RPC_MAX_ID_LENGTH)
48
130
  throw new RpcProtocolError("INVALID_REQUEST", `${field} must be a non-empty string of at most ${RPC_MAX_ID_LENGTH} characters.`, requestId);
49
- }
50
131
  return value;
51
132
  }
52
133
  function parseJsonObject(line) {
53
- let value;
54
134
  try {
55
- value = JSON.parse(line);
135
+ const result = objectRecord(JSON.parse(line));
136
+ if (!result)
137
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC input must be a JSON object.");
138
+ return result;
56
139
  }
57
- catch {
140
+ catch (cause) {
141
+ if (cause instanceof RpcProtocolError)
142
+ throw cause;
58
143
  throw new RpcProtocolError("PARSE_ERROR", "RPC input must be valid JSON.");
59
144
  }
60
- const record = objectRecord(value);
61
- if (!record)
62
- throw new RpcProtocolError("INVALID_REQUEST", "RPC input must be a JSON object.");
63
- return record;
64
145
  }
65
146
  function assertVersion(record, requestId) {
66
- if (record.version !== RPC_PROTOCOL_VERSION) {
147
+ if (record.version !== RPC_PROTOCOL_VERSION)
67
148
  throw new RpcProtocolError("UNSUPPORTED_VERSION", `Unsupported RPC protocol version; expected ${RPC_PROTOCOL_VERSION}.`, requestId);
68
- }
69
149
  }
150
+ function stringParam(params, name, id, optional = false) {
151
+ const value = params[name];
152
+ if (optional && value === undefined)
153
+ return;
154
+ if (typeof value !== "string" || value.length === 0 || value.length > RPC_MAX_PROMPT_LENGTH)
155
+ throw new RpcProtocolError("INVALID_PARAMS", `${name} must be a non-empty string.`, id);
156
+ }
157
+ function booleanParam(params, name, id) {
158
+ if (typeof params[name] !== "boolean")
159
+ throw new RpcProtocolError("INVALID_PARAMS", `${name} must be a boolean.`, id);
160
+ }
161
+ function attachmentIdsParam(params, id) {
162
+ if (params.attachmentIds === undefined)
163
+ return;
164
+ if (!Array.isArray(params.attachmentIds) ||
165
+ params.attachmentIds.length > RPC_MAX_ATTACHMENTS_PER_REQUEST ||
166
+ !params.attachmentIds.every((value) => typeof value === "string" && value.length > 0 && value.length <= RPC_MAX_ID_LENGTH))
167
+ throw new RpcProtocolError("INVALID_PARAMS", `attachmentIds must contain at most ${RPC_MAX_ATTACHMENTS_PER_REQUEST} attachment IDs.`, id);
168
+ }
169
+ function attachmentDataParam(params, id) {
170
+ const data = params.data;
171
+ if (typeof data !== "string" || data.length === 0 || data.length > RPC_MAX_ATTACHMENT_BASE64_LENGTH)
172
+ throw new RpcProtocolError("INVALID_PARAMS", "Attachment data exceeds the permitted size.", id);
173
+ }
174
+ /** Parses every public v1 method before any dispatcher or transport observes it. */
70
175
  export function parseRpcRequest(line) {
71
176
  const record = parseJsonObject(line);
72
177
  const candidateId = typeof record.id === "string" ? record.id : undefined;
73
178
  assertVersion(record, candidateId);
74
- if (record.kind !== "request") {
179
+ if (record.kind !== "request")
75
180
  throw new RpcProtocolError("INVALID_REQUEST", 'RPC request kind must be "request".', candidateId);
76
- }
77
181
  const id = requiredId(record.id, "id", candidateId);
78
182
  const params = objectRecord(record.params);
79
183
  if (!params)
80
184
  throw new RpcProtocolError("INVALID_PARAMS", "RPC params must be an object.", id);
81
- switch (record.method) {
82
- case "prompt": {
83
- const message = params.message;
84
- if (typeof message !== "string" || message.trim().length === 0 || message.length > RPC_MAX_PROMPT_LENGTH) {
85
- throw new RpcProtocolError("INVALID_PARAMS", `prompt.message must be non-empty and at most ${RPC_MAX_PROMPT_LENGTH} characters.`, id);
86
- }
87
- return { version: RPC_PROTOCOL_VERSION, kind: "request", id, method: "prompt", params: { message } };
88
- }
185
+ if (typeof record.method !== "string" || !RPC_METHODS.includes(record.method))
186
+ throw new RpcProtocolError("METHOD_NOT_FOUND", "Unknown RPC method.", id);
187
+ const method = record.method;
188
+ switch (method) {
189
+ case "prompt":
190
+ case "steer":
191
+ stringParam(params, "message", id);
192
+ attachmentIdsParam(params, id);
193
+ break;
89
194
  case "cancel":
90
- return {
91
- version: RPC_PROTOCOL_VERSION,
92
- kind: "request",
93
- id,
94
- method: "cancel",
95
- params: { requestId: requiredId(params.requestId, "cancel.requestId", id) },
96
- };
97
- case "get_state":
98
- return { version: RPC_PROTOCOL_VERSION, kind: "request", id, method: "get_state", params: {} };
99
- default:
100
- throw new RpcProtocolError("METHOD_NOT_FOUND", "Unknown RPC method.", id);
195
+ case "get_operation":
196
+ case "open_session":
197
+ case "inspect_session":
198
+ case "rename_session":
199
+ case "delete_session":
200
+ case "navigate_tree":
201
+ case "set_model":
202
+ case "logout":
203
+ case "reconnect_mcp_server":
204
+ stringParam(params, method === "cancel" || method === "get_operation"
205
+ ? "requestId"
206
+ : method === "open_session"
207
+ ? "sessionId"
208
+ : method === "inspect_session" || method === "rename_session" || method === "delete_session"
209
+ ? "sessionId"
210
+ : method === "navigate_tree"
211
+ ? "entryId"
212
+ : method === "set_model"
213
+ ? "modelId"
214
+ : method === "logout"
215
+ ? "providerId"
216
+ : "serverId", id);
217
+ if (method === "rename_session")
218
+ stringParam(params, "label", id);
219
+ if (method === "delete_session")
220
+ stringParam(params, "confirmation", id);
221
+ break;
222
+ case "branch_session":
223
+ if (params.sessionId !== undefined)
224
+ stringParam(params, "sessionId", id, true);
225
+ if (params.entryId !== undefined)
226
+ stringParam(params, "entryId", id, true);
227
+ break;
228
+ case "set_runtime":
229
+ stringParam(params, "providerId", id);
230
+ stringParam(params, "modelId", id);
231
+ break;
232
+ case "run_command":
233
+ stringParam(params, "name", id);
234
+ if (!/^[a-z][a-z0-9-]*(?::[a-z][a-z0-9-]*)?$/.test(params.name))
235
+ throw new RpcProtocolError("INVALID_PARAMS", "run_command.name is invalid.", id);
236
+ if (params.args !== undefined && (typeof params.args !== "string" || params.args.length > RPC_MAX_PROMPT_LENGTH))
237
+ throw new RpcProtocolError("INVALID_PARAMS", "args must be a string of at most 1,000,000 characters.", id);
238
+ break;
239
+ case "set_default_provider":
240
+ case "set_default_model":
241
+ case "set_locale":
242
+ case "set_permission_mode":
243
+ stringParam(params, method === "set_default_provider"
244
+ ? "providerId"
245
+ : method === "set_default_model"
246
+ ? "modelId"
247
+ : method === "set_locale"
248
+ ? "locale"
249
+ : "permissionMode", id);
250
+ if (method === "set_locale" && params.locale !== "en" && params.locale !== "zh-CN")
251
+ throw new RpcProtocolError("INVALID_PARAMS", "locale must be en or zh-CN.", id);
252
+ if (method === "set_permission_mode" &&
253
+ params.permissionMode !== "ask" &&
254
+ params.permissionMode !== "allow" &&
255
+ params.permissionMode !== "deny")
256
+ throw new RpcProtocolError("INVALID_PARAMS", "permissionMode must be ask, allow, or deny.", id);
257
+ break;
258
+ case "configure_custom_provider":
259
+ for (const name of ["api", "baseUrl", "apiKey", "modelId"])
260
+ stringParam(params, name, id);
261
+ if (!["openai-responses", "openai-chat-completions", "anthropic-messages"].includes(params.api))
262
+ throw new RpcProtocolError("INVALID_PARAMS", "Unsupported custom Provider API.", id);
263
+ break;
264
+ case "set_thinking_level":
265
+ if (params.level !== undefined &&
266
+ params.level !== "low" &&
267
+ params.level !== "medium" &&
268
+ params.level !== "high" &&
269
+ params.level !== "max")
270
+ throw new RpcProtocolError("INVALID_PARAMS", "set_thinking_level.level must be a valid thinking level.", id);
271
+ break;
272
+ case "retry":
273
+ stringParam(params, "targetRequestId", id);
274
+ break;
275
+ case "login":
276
+ stringParam(params, "providerId", id);
277
+ stringParam(params, "apiKey", id);
278
+ if (params.modelId !== undefined)
279
+ stringParam(params, "modelId", id, true);
280
+ if (params.api !== undefined)
281
+ stringParam(params, "api", id, true);
282
+ break;
283
+ case "configure_mcp_server":
284
+ stringParam(params, "serverId", id);
285
+ stringParam(params, "scope", id);
286
+ if (!objectRecord(params.config))
287
+ throw new RpcProtocolError("INVALID_PARAMS", "config must be an object.", id);
288
+ break;
289
+ case "remove_mcp_server":
290
+ stringParam(params, "serverId", id);
291
+ if (params.scope !== undefined)
292
+ stringParam(params, "scope", id, true);
293
+ break;
294
+ case "set_plugin_enabled":
295
+ stringParam(params, "pluginId", id);
296
+ booleanParam(params, "enabled", id);
297
+ break;
298
+ case "set_compaction_enabled":
299
+ case "set_project_trust":
300
+ booleanParam(params, method === "set_compaction_enabled" ? "enabled" : "trusted", id);
301
+ break;
302
+ case "get_capabilities":
303
+ if (params.events !== undefined &&
304
+ (!Array.isArray(params.events) || !params.events.every((item) => typeof item === "string")))
305
+ throw new RpcProtocolError("INVALID_PARAMS", "get_capabilities.events must be a string array.", id);
306
+ break;
307
+ case "resume_events":
308
+ if (params.lastSequence !== undefined &&
309
+ (!Number.isSafeInteger(params.lastSequence) || params.lastSequence < 0))
310
+ throw new RpcProtocolError("INVALID_PARAMS", "resume_events.lastSequence must be a non-negative integer.", id);
311
+ break;
312
+ case "create_attachment":
313
+ stringParam(params, "name", id);
314
+ stringParam(params, "contentType", id);
315
+ attachmentDataParam(params, id);
316
+ if (!["image/png", "image/jpeg", "image/webp", "image/gif"].includes(params.contentType))
317
+ throw new RpcProtocolError("INVALID_PARAMS", "Attachment contentType is unsupported.", id);
318
+ break;
319
+ case "get_transcript":
320
+ if (params.pageToken !== undefined)
321
+ stringParam(params, "pageToken", id, true);
322
+ if (params.pageSize !== undefined &&
323
+ (!Number.isSafeInteger(params.pageSize) || params.pageSize < 1 || params.pageSize > 200))
324
+ throw new RpcProtocolError("INVALID_PARAMS", "pageSize must be an integer between 1 and 200.", id);
325
+ if (params.maxBytes !== undefined &&
326
+ (!Number.isSafeInteger(params.maxBytes) ||
327
+ params.maxBytes < 1024 ||
328
+ params.maxBytes > RPC_MAX_TRANSCRIPT_BYTES))
329
+ throw new RpcProtocolError("INVALID_PARAMS", `maxBytes must be between 1024 and ${RPC_MAX_TRANSCRIPT_BYTES}.`, id);
330
+ break;
331
+ case "approve_tool":
332
+ stringParam(params, "approvalId", id);
333
+ booleanParam(params, "approved", id);
334
+ break;
101
335
  }
336
+ return { version: RPC_PROTOCOL_VERSION, kind: "request", id, method, params };
102
337
  }
103
338
  export function parseRpcServerMessage(line) {
104
339
  const record = parseJsonObject(line);
@@ -106,22 +341,26 @@ export function parseRpcServerMessage(line) {
106
341
  if (record.kind === "event") {
107
342
  requiredId(record.requestId, "requestId");
108
343
  const event = objectRecord(record.event);
109
- if (!event || typeof event.type !== "string" || !RPC_EVENT_TYPES.has(event.type)) {
344
+ const type = event?.type;
345
+ if (typeof type !== "string" ||
346
+ (!LEGACY_EVENT_TYPES.has(type) && !EXTENDED_EVENT_TYPES.has(type)))
347
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC event must contain a typed event object.");
348
+ if (!event)
110
349
  throw new RpcProtocolError("INVALID_REQUEST", "RPC event must contain a typed event object.");
111
- }
350
+ if (record.sequence !== undefined && (!Number.isSafeInteger(record.sequence) || record.sequence < 0))
351
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC event sequence is invalid.");
352
+ assertEvent(event, type);
112
353
  return record;
113
354
  }
114
- if (record.kind !== "response") {
355
+ if (record.kind !== "response")
115
356
  throw new RpcProtocolError("INVALID_REQUEST", 'RPC server message kind must be "response" or "event".');
116
- }
117
357
  if (record.ok === false) {
118
358
  const error = objectRecord(record.error);
119
359
  if (!error ||
120
360
  typeof error.code !== "string" ||
121
361
  !RPC_ERROR_CODES.has(error.code) ||
122
- typeof error.message !== "string") {
362
+ typeof error.message !== "string")
123
363
  throw new RpcProtocolError("INVALID_REQUEST", "RPC error response has an invalid error object.");
124
- }
125
364
  if (record.id !== undefined)
126
365
  requiredId(record.id, "id");
127
366
  return record;
@@ -130,94 +369,307 @@ export function parseRpcServerMessage(line) {
130
369
  throw new RpcProtocolError("INVALID_REQUEST", "RPC response ok must be a boolean.");
131
370
  requiredId(record.id, "id");
132
371
  const result = objectRecord(record.result);
133
- if (!result) {
134
- throw new RpcProtocolError("INVALID_REQUEST", "RPC success response must contain a result object.");
135
- }
372
+ if (!result || typeof result.method !== "string" || !RPC_METHODS.includes(result.method))
373
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC success response has an unknown method.");
136
374
  assertSuccessResult(result);
137
375
  return record;
138
376
  }
139
377
  function assertSuccessResult(result) {
140
378
  switch (result.method) {
141
- case "prompt": {
142
- const message = objectRecord(result.message);
143
- if (!message ||
144
- message.role !== "assistant" ||
145
- !Array.isArray(message.content) ||
146
- !message.content.every(isAssistantContent) ||
147
- typeof message.provider !== "string" ||
148
- typeof message.model !== "string" ||
149
- !finiteNumber(message.timestamp) ||
150
- typeof message.stopReason !== "string" ||
151
- !ASSISTANT_STOP_REASONS.has(message.stopReason) ||
152
- !isUsage(message.usage) ||
153
- (message.stopReason === "error" || message.stopReason === "aborted"
154
- ? typeof message.errorMessage !== "string"
155
- : message.errorMessage !== undefined)) {
156
- throw new RpcProtocolError("INVALID_REQUEST", "RPC prompt response has an invalid message.");
157
- }
379
+ case "prompt":
380
+ case "retry":
381
+ assertAssistantMessage(result.message);
158
382
  return;
159
- }
160
383
  case "cancel":
161
- if (typeof result.cancelled !== "boolean") {
162
- throw new RpcProtocolError("INVALID_REQUEST", "RPC cancel response has an invalid result.");
163
- }
384
+ if (typeof result.cancelled !== "boolean")
385
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC cancel result is invalid.");
164
386
  return;
165
- case "get_state": {
166
- const state = objectRecord(result.state);
167
- if (!state ||
168
- typeof state.sessionId !== "string" ||
169
- state.sessionId.length === 0 ||
170
- typeof state.modelId !== "string" ||
171
- state.modelId.length === 0 ||
172
- typeof state.isStreaming !== "boolean" ||
173
- !Number.isInteger(state.messageCount) ||
174
- state.messageCount < 0) {
175
- throw new RpcProtocolError("INVALID_REQUEST", "RPC get_state response has an invalid state.");
387
+ case "get_state":
388
+ assertState(result.state);
389
+ return;
390
+ case "get_capabilities":
391
+ assertCapabilities(result);
392
+ return;
393
+ case "resume_events":
394
+ if (typeof result.snapshotRequired !== "boolean")
395
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC resume_events result is invalid.");
396
+ return;
397
+ case "get_operation":
398
+ assertOperationState(result.operation);
399
+ return;
400
+ case "create_attachment":
401
+ assertAttachmentInfo(result.attachment);
402
+ return;
403
+ case "get_product_state":
404
+ assertProductState(result.state);
405
+ return;
406
+ case "get_project_trust":
407
+ if (typeof result.trusted !== "boolean")
408
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC get_project_trust result is invalid.");
409
+ return;
410
+ case "list_sessions":
411
+ if (!Array.isArray(result.sessions))
412
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC list_sessions result is invalid.");
413
+ for (const session of result.sessions)
414
+ assertSessionInfo(session);
415
+ return;
416
+ case "new_session":
417
+ case "open_session":
418
+ case "rename_session":
419
+ case "branch_session":
420
+ assertSessionInfo(result.session);
421
+ return;
422
+ case "inspect_session":
423
+ if (!objectRecord(result.snapshot))
424
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC Session snapshot is invalid.");
425
+ return;
426
+ case "list_providers":
427
+ if (!Array.isArray(result.providers))
428
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC providers result is invalid.");
429
+ return;
430
+ case "list_context_files":
431
+ if (!Array.isArray(result.files))
432
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC context files result is invalid.");
433
+ return;
434
+ case "list_mcp_servers":
435
+ if (!Array.isArray(result.servers))
436
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC MCP result is invalid.");
437
+ return;
438
+ case "list_web_contributions":
439
+ {
440
+ const manifest = objectRecord(result.manifest);
441
+ if (!manifest || !validateWebManifest(manifest))
442
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC Web contribution manifest is invalid.");
176
443
  }
177
444
  return;
178
- }
179
- default:
180
- throw new RpcProtocolError("INVALID_REQUEST", "RPC success response has an unknown method.");
181
- }
182
- }
183
- function finiteNumber(value) {
184
- return typeof value === "number" && Number.isFinite(value);
185
- }
186
- function nonNegativeNumber(value) {
187
- return finiteNumber(value) && value >= 0;
188
- }
189
- function isAssistantContent(value) {
190
- const content = objectRecord(value);
191
- if (!content)
192
- return false;
193
- switch (content.type) {
194
- case "text":
195
- return typeof content.text === "string";
196
- case "thinking":
197
- return typeof content.thinking === "string";
198
- case "tool_call":
199
- return (typeof content.id === "string" &&
200
- typeof content.name === "string" &&
201
- objectRecord(content.arguments) !== undefined);
202
- default:
203
- return false;
204
- }
205
- }
206
- function isUsage(value) {
207
- const usage = objectRecord(value);
208
- const cost = objectRecord(usage?.cost);
209
- return Boolean(usage &&
210
- cost &&
211
- nonNegativeNumber(usage.input) &&
212
- nonNegativeNumber(usage.output) &&
213
- nonNegativeNumber(usage.cacheRead) &&
214
- nonNegativeNumber(usage.cacheWrite) &&
215
- nonNegativeNumber(usage.totalTokens) &&
216
- nonNegativeNumber(cost.input) &&
217
- nonNegativeNumber(cost.output) &&
218
- nonNegativeNumber(cost.cacheRead) &&
219
- nonNegativeNumber(cost.cacheWrite) &&
220
- nonNegativeNumber(cost.total));
445
+ case "list_commands":
446
+ if (!Array.isArray(result.commands))
447
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC commands result is invalid.");
448
+ for (const command of result.commands)
449
+ assertCommandInfo(command);
450
+ return;
451
+ case "run_command":
452
+ if (typeof result.command !== "string" || !result.command)
453
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC command result is invalid.");
454
+ if (result.action !== undefined)
455
+ assertCommandAction(result.action);
456
+ return;
457
+ case "configure_mcp_server":
458
+ case "reconnect_mcp_server":
459
+ if (!objectRecord(result.server))
460
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC MCP result is invalid.");
461
+ return;
462
+ case "login":
463
+ if (!objectRecord(result.provider))
464
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC login result is invalid.");
465
+ return;
466
+ case "set_project_trust":
467
+ if (typeof result.trusted !== "boolean")
468
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC trust result is invalid.");
469
+ return;
470
+ case "logout":
471
+ case "remove_mcp_server":
472
+ return;
473
+ case "get_settings":
474
+ if (!objectRecord(result.settings))
475
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC settings result is invalid.");
476
+ return;
477
+ case "set_default_provider":
478
+ case "set_default_model":
479
+ case "set_locale":
480
+ case "set_permission_mode":
481
+ case "configure_custom_provider":
482
+ return;
483
+ }
484
+ }
485
+ function assertCapabilities(result) {
486
+ if (!Array.isArray(result.methods) ||
487
+ !result.methods.every((method) => typeof method === "string" && RPC_METHODS.includes(method)) ||
488
+ !Array.isArray(result.events) ||
489
+ !result.events.every((event) => typeof event === "string" && EXTENDED_EVENT_NAMES.has(event)) ||
490
+ !Number.isSafeInteger(result.eventBufferSize) ||
491
+ result.eventBufferSize < 0)
492
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC get_capabilities result is invalid.");
493
+ }
494
+ function assertSessionInfo(value) {
495
+ const session = objectRecord(value);
496
+ if (!session || typeof session.id !== "string" || !session.id || typeof session.label !== "string")
497
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC Session result is invalid.");
498
+ if (session.modifiedAt !== undefined && !Number.isFinite(session.modifiedAt))
499
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC Session modifiedAt is invalid.");
500
+ }
501
+ function assertCommandInfo(value) {
502
+ const command = objectRecord(value);
503
+ if (!command ||
504
+ typeof command.name !== "string" ||
505
+ !command.name ||
506
+ typeof command.description !== "string" ||
507
+ (command.kind !== "command" && command.kind !== "skill"))
508
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC command info is invalid.");
509
+ }
510
+ function assertCommandAction(value) {
511
+ const action = objectRecord(value);
512
+ if (!action || typeof action.command !== "string" || !action.command || typeof action.args !== "string")
513
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC command action is invalid.");
514
+ }
515
+ function assertOperationState(value) {
516
+ const operation = objectRecord(value);
517
+ if (!operation ||
518
+ typeof operation.requestId !== "string" ||
519
+ !operation.requestId ||
520
+ typeof operation.kind !== "string" ||
521
+ !RPC_METHODS.includes(operation.kind) ||
522
+ typeof operation.status !== "string" ||
523
+ !["queued", "running", "completed", "failed", "cancelled", "crashed"].includes(operation.status))
524
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC operation state is invalid.");
525
+ if (operation.sessionId !== undefined && typeof operation.sessionId !== "string")
526
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC operation session ID is invalid.");
527
+ if (operation.message !== undefined)
528
+ assertAssistantMessage(operation.message);
529
+ if (operation.error !== undefined)
530
+ assertError(operation.error);
531
+ }
532
+ function assertAttachmentInfo(value) {
533
+ const attachment = objectRecord(value);
534
+ if (!attachment ||
535
+ typeof attachment.id !== "string" ||
536
+ !attachment.id ||
537
+ typeof attachment.name !== "string" ||
538
+ !attachment.name ||
539
+ typeof attachment.contentType !== "string" ||
540
+ !["image/png", "image/jpeg", "image/webp", "image/gif"].includes(attachment.contentType) ||
541
+ !Number.isSafeInteger(attachment.bytes) ||
542
+ attachment.bytes < 0)
543
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC attachment result is invalid.");
544
+ }
545
+ function assertProductState(value) {
546
+ const state = objectRecord(value);
547
+ if (!state || typeof state.projectTrusted !== "boolean")
548
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC product state is invalid.");
549
+ }
550
+ function assertError(value) {
551
+ const error = objectRecord(value);
552
+ if (!error ||
553
+ typeof error.code !== "string" ||
554
+ !RPC_ERROR_CODES.has(error.code) ||
555
+ typeof error.message !== "string")
556
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC error result is invalid.");
557
+ }
558
+ function assertEvent(event, type) {
559
+ if (type === "operation_update") {
560
+ assertOperationState(event.operation);
561
+ return;
562
+ }
563
+ if (type === "session_changed") {
564
+ if (event.session !== undefined)
565
+ assertSessionInfo(event.session);
566
+ return;
567
+ }
568
+ if (type === "snapshot_required")
569
+ return;
570
+ if (type === "tool_approval") {
571
+ if (typeof event.approvalId !== "string")
572
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC tool_approval event is invalid.");
573
+ return;
574
+ }
575
+ if (type === "product_audit") {
576
+ if (typeof event.action !== "string" ||
577
+ ![
578
+ "login",
579
+ "logout",
580
+ "set_project_trust",
581
+ "configure_mcp_server",
582
+ "remove_mcp_server",
583
+ "reconnect_mcp_server",
584
+ ].includes(event.action) ||
585
+ (event.target !== undefined && typeof event.target !== "string") ||
586
+ (event.projectTrusted !== undefined && typeof event.projectTrusted !== "boolean"))
587
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC product_audit event is invalid.");
588
+ return;
589
+ }
590
+ if (type === "tool_execution_start") {
591
+ if (typeof event.toolCallId !== "string" || typeof event.toolName !== "string" || !objectRecord(event.arguments))
592
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC tool event is invalid.");
593
+ return;
594
+ }
595
+ if (type === "tool_execution_end") {
596
+ if (typeof event.toolCallId !== "string" || typeof event.toolName !== "string" || !objectRecord(event.result))
597
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC tool event is invalid.");
598
+ return;
599
+ }
600
+ if (type === "message_start" || type === "message_end") {
601
+ if (!objectRecord(event.message))
602
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC message event is invalid.");
603
+ return;
604
+ }
605
+ if (type === "message_update") {
606
+ const update = objectRecord(event.event);
607
+ if (!update || typeof update.type !== "string")
608
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC message update event is invalid.");
609
+ return;
610
+ }
611
+ if (type === "turn_end") {
612
+ if (!objectRecord(event.message) || !Array.isArray(event.toolResults))
613
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC turn event is invalid.");
614
+ return;
615
+ }
616
+ if (type === "agent_end") {
617
+ if (!Array.isArray(event.messages))
618
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC agent event is invalid.");
619
+ return;
620
+ }
621
+ if (type === "compaction_start") {
622
+ if (event.reason !== "threshold" && event.reason !== "manual")
623
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC compaction event is invalid.");
624
+ return;
625
+ }
626
+ if (type === "compaction_end") {
627
+ if ((event.reason !== "threshold" && event.reason !== "manual") ||
628
+ typeof event.success !== "boolean" ||
629
+ (event.errorMessage !== undefined && typeof event.errorMessage !== "string"))
630
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC compaction event is invalid.");
631
+ return;
632
+ }
633
+ if (type === "queue_update") {
634
+ if (!Array.isArray(event.steering) || !event.steering.every((item) => typeof item === "string"))
635
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC queue event is invalid.");
636
+ return;
637
+ }
638
+ if (type === "tree_navigated") {
639
+ if (typeof event.oldLeafId !== "string" ||
640
+ typeof event.newLeafId !== "string" ||
641
+ typeof event.selectedEntryId !== "string" ||
642
+ typeof event.restoredEditorText !== "boolean")
643
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC tree event is invalid.");
644
+ return;
645
+ }
646
+ if (type === "usage_update" && !objectRecord(event.usage)) {
647
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC usage event is invalid.");
648
+ }
649
+ }
650
+ function assertState(value) {
651
+ const state = objectRecord(value);
652
+ if (!state ||
653
+ typeof state.sessionId !== "string" ||
654
+ !state.sessionId ||
655
+ typeof state.modelId !== "string" ||
656
+ !state.modelId ||
657
+ typeof state.isStreaming !== "boolean" ||
658
+ !Number.isInteger(state.messageCount) ||
659
+ state.messageCount < 0)
660
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC get_state response has an invalid state.");
661
+ }
662
+ function assertAssistantMessage(value) {
663
+ const message = objectRecord(value);
664
+ if (!message ||
665
+ message.role !== "assistant" ||
666
+ !Array.isArray(message.content) ||
667
+ typeof message.provider !== "string" ||
668
+ typeof message.model !== "string" ||
669
+ !Number.isFinite(message.timestamp) ||
670
+ typeof message.stopReason !== "string" ||
671
+ !ASSISTANT_STOP_REASONS.has(message.stopReason))
672
+ throw new RpcProtocolError("INVALID_REQUEST", "RPC prompt response has an invalid message.");
221
673
  }
222
674
  export function rpcErrorResponse(error) {
223
675
  return {