kennel 0.2.0 → 0.2.2

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 (872) hide show
  1. package/README.md +18 -5
  2. package/dist/cli/dispatch.js +9 -0
  3. package/dist/cli/src/automations/notifications.d.ts +40 -0
  4. package/dist/cli/src/automations/notifications.js +220 -0
  5. package/dist/cli/src/cli/dispatch.d.ts +1 -0
  6. package/dist/cli/src/cli/dispatch.js +125 -0
  7. package/dist/cli/src/cli/usage.d.ts +1 -0
  8. package/dist/cli/src/cli/usage.js +25 -0
  9. package/dist/cli/src/core/api-client.d.ts +13 -0
  10. package/dist/cli/src/core/api-client.js +1 -0
  11. package/dist/cli/src/core/command.d.ts +1 -0
  12. package/dist/cli/src/core/command.js +69 -0
  13. package/dist/cli/src/core/core-folders.d.ts +1 -0
  14. package/dist/cli/src/core/core-folders.js +42 -0
  15. package/dist/cli/src/core/init.d.ts +1 -0
  16. package/dist/cli/src/core/init.js +141 -0
  17. package/dist/cli/src/core/runtime.d.ts +14 -0
  18. package/dist/cli/src/core/runtime.js +1 -0
  19. package/dist/cli/src/deploy/cloudflare.d.ts +6 -0
  20. package/dist/cli/src/deploy/cloudflare.js +100 -0
  21. package/dist/cli/src/deploy/environment.d.ts +2 -0
  22. package/dist/cli/src/deploy/environment.js +47 -0
  23. package/dist/cli/src/deploy/smoke-tests.d.ts +4 -0
  24. package/dist/cli/src/deploy/smoke-tests.js +92 -0
  25. package/dist/cli/src/deploy/trigger-dev.d.ts +2 -0
  26. package/dist/cli/src/deploy/trigger-dev.js +255 -0
  27. package/dist/cli/src/deploy/vercel.d.ts +3 -0
  28. package/dist/cli/src/deploy/vercel.js +67 -0
  29. package/dist/cli/src/main.d.ts +1 -0
  30. package/dist/cli/src/main.js +9 -0
  31. package/dist/cli/src/mcp/agent-tools.d.ts +8 -0
  32. package/dist/cli/src/mcp/agent-tools.js +247 -0
  33. package/dist/cli/src/mcp/config.d.ts +25 -0
  34. package/dist/cli/src/mcp/config.js +185 -0
  35. package/dist/cli/src/mcp/function-source.d.ts +7 -0
  36. package/dist/cli/src/mcp/function-source.js +42 -0
  37. package/dist/cli/src/mcp/generate.d.ts +1 -0
  38. package/dist/cli/src/mcp/generate.js +47 -0
  39. package/dist/cli/src/mcp/install-page.d.ts +12 -0
  40. package/dist/cli/src/mcp/install-page.js +5 -0
  41. package/dist/cli/src/notifications/email-worker.d.ts +8 -0
  42. package/dist/cli/src/notifications/email-worker.js +137 -0
  43. package/dist/cli/src/package/mcp-data.d.ts +1 -0
  44. package/dist/cli/src/package/mcp-data.js +1 -0
  45. package/dist/cli/src/package/mcp-email-worker.d.ts +1 -0
  46. package/dist/cli/src/package/mcp-email-worker.js +1 -0
  47. package/dist/cli/src/package/mcp-http.d.ts +1 -0
  48. package/dist/cli/src/package/mcp-http.js +1 -0
  49. package/dist/cli/src/package/mcp-stdio.d.ts +1 -0
  50. package/dist/cli/src/package/mcp-stdio.js +1 -0
  51. package/dist/cli/src/package/mcp.d.ts +1 -0
  52. package/dist/cli/src/package/mcp.js +1 -0
  53. package/dist/cli/src/package/preview.d.ts +9 -0
  54. package/dist/cli/src/package/preview.js +1 -0
  55. package/dist/cli/src/plugins/external.d.ts +36 -0
  56. package/dist/cli/src/plugins/external.js +503 -0
  57. package/dist/cli/src/publish/cloudflare-init.d.ts +12 -0
  58. package/dist/cli/src/publish/cloudflare-init.js +101 -0
  59. package/dist/cli/src/publish/config.d.ts +28 -0
  60. package/dist/cli/src/publish/config.js +178 -0
  61. package/dist/cli/src/publish/options.d.ts +13 -0
  62. package/dist/cli/src/publish/options.js +78 -0
  63. package/dist/cli/src/publish/vercel-init.d.ts +9 -0
  64. package/dist/cli/src/publish/vercel-init.js +52 -0
  65. package/dist/cli/src/shared/json.d.ts +4 -0
  66. package/dist/cli/src/shared/json.js +56 -0
  67. package/dist/cli/src/shared/object.d.ts +2 -0
  68. package/dist/cli/src/shared/object.js +3 -0
  69. package/dist/cli/src/shared/package-manager.d.ts +11 -0
  70. package/dist/cli/src/shared/package-manager.js +39 -0
  71. package/dist/cli/src/shared/path.d.ts +4 -0
  72. package/dist/cli/src/shared/path.js +40 -0
  73. package/dist/cli/src/shared/process.d.ts +7 -0
  74. package/dist/cli/src/shared/process.js +12 -0
  75. package/dist/cli/src/shared/project-config.d.ts +2 -0
  76. package/dist/cli/src/shared/project-config.js +26 -0
  77. package/dist/cli/src/site/dev.d.ts +10 -0
  78. package/dist/cli/src/site/dev.js +126 -0
  79. package/dist/cli/src/site/extension.d.ts +8 -0
  80. package/dist/cli/src/site/extension.js +113 -0
  81. package/dist/cli/src/site/folder-icons.d.ts +46 -0
  82. package/dist/cli/src/site/folder-icons.js +86 -0
  83. package/dist/cli/src/site/hot-viewer.d.ts +2 -0
  84. package/dist/cli/src/site/hot-viewer.js +231 -0
  85. package/dist/cli/src/site/kinds.d.ts +1 -0
  86. package/dist/cli/src/site/kinds.js +1 -0
  87. package/dist/cli/src/site/mail.d.ts +1 -0
  88. package/dist/cli/src/site/mail.js +10 -0
  89. package/dist/cli/src/site/renderers.d.ts +61 -0
  90. package/dist/cli/src/site/renderers.js +219 -0
  91. package/dist/cli/src/site/server-plugins.d.ts +54 -0
  92. package/dist/cli/src/site/server-plugins.js +1 -0
  93. package/dist/cli/src/site/viewer.d.ts +36 -0
  94. package/dist/cli/src/site/viewer.js +352 -0
  95. package/dist/cli/src/site/vitepress.d.ts +1 -0
  96. package/dist/cli/src/site/vitepress.js +1 -0
  97. package/dist/cli/usage.js +1 -0
  98. package/dist/core/api-client.js +75 -44
  99. package/dist/core/command.js +6 -3
  100. package/dist/core/core-folders.js +38280 -33
  101. package/dist/core/init.js +59 -4
  102. package/dist/core/runtime.js +57163 -41853
  103. package/dist/package/preview.js +40589 -17894
  104. package/dist/plugins/external.d.ts +36 -0
  105. package/dist/plugins/external.js +503 -0
  106. package/dist/site/server-plugins.js +394 -59
  107. package/dist/site/viewer.js +18 -5
  108. package/kernel/apps/web/.env.example +11 -0
  109. package/kernel/apps/web/components.json +20 -0
  110. package/kernel/apps/web/eslint.config.mjs +60 -0
  111. package/kernel/apps/web/index.html +17 -0
  112. package/kernel/apps/web/package.json +79 -0
  113. package/kernel/apps/web/public/favicon.svg +6 -0
  114. package/kernel/apps/web/public/providers/claude.svg +1 -0
  115. package/kernel/apps/web/public/providers/codex.svg +1 -0
  116. package/kernel/apps/web/public/providers/cursor.svg +1 -0
  117. package/kernel/apps/web/public/providers/opencode.svg +1 -0
  118. package/kernel/apps/web/public/providers/pi.svg +1 -0
  119. package/kernel/apps/web/server/acp/index.ts +1 -0
  120. package/kernel/apps/web/server/acp/live-agent-connection.ts +1 -0
  121. package/kernel/apps/web/server/acp/process-manager.ts +1 -0
  122. package/kernel/apps/web/server/acp/registry.ts +1 -0
  123. package/kernel/apps/web/server/acp/sdk.ts +1 -0
  124. package/kernel/apps/web/server/acp/transport.ts +1 -0
  125. package/kernel/apps/web/server/acp/types.ts +1 -0
  126. package/kernel/apps/web/server/acp-live-plugin.ts +30 -0
  127. package/kernel/apps/web/server/api/document-edit.ts +1 -0
  128. package/kernel/apps/web/server/api/open-path.ts +1 -0
  129. package/kernel/apps/web/server/core-plugin.ts +49 -0
  130. package/kernel/apps/web/server/folder-favicon.ts +1 -0
  131. package/kernel/apps/web/server/folder-icons.ts +1 -0
  132. package/kernel/apps/web/server/folder-metadata-plugin.ts +31 -0
  133. package/kernel/apps/web/server/plugins.ts +1 -0
  134. package/kernel/apps/web/server/preview-kinds.ts +1 -0
  135. package/kernel/apps/web/src/ai-input.tsx +62 -0
  136. package/kernel/apps/web/src/annotations.tsx +430 -0
  137. package/kernel/apps/web/src/api/client.ts +3 -0
  138. package/kernel/apps/web/src/api/errors.ts +1 -0
  139. package/kernel/apps/web/src/api/events.ts +42 -0
  140. package/kernel/apps/web/src/app.css +332 -0
  141. package/kernel/apps/web/src/app.tsx +667 -0
  142. package/kernel/apps/web/src/ask-draft.ts +164 -0
  143. package/kernel/apps/web/src/ask-tray.tsx +256 -0
  144. package/kernel/apps/web/src/comment-editor.tsx +93 -0
  145. package/kernel/apps/web/src/comment-form.tsx +162 -0
  146. package/kernel/apps/web/src/copy-path.ts +18 -0
  147. package/kernel/apps/web/src/deferred-ask-tray.tsx +20 -0
  148. package/kernel/apps/web/src/document-url.ts +46 -0
  149. package/kernel/apps/web/src/documents-url.ts +23 -0
  150. package/kernel/apps/web/src/dropped-folder.ts +64 -0
  151. package/kernel/apps/web/src/external-plugins.ts +3 -0
  152. package/kernel/apps/web/src/file-viewer.tsx +171 -0
  153. package/kernel/apps/web/src/folder-filter-icons.tsx +39 -0
  154. package/kernel/apps/web/src/folder-metadata.ts +76 -0
  155. package/kernel/apps/web/src/folder-plugin-view.tsx +87 -0
  156. package/kernel/apps/web/src/folder-query-cache.ts +66 -0
  157. package/kernel/apps/web/src/host-adapters.ts +209 -0
  158. package/kernel/apps/web/src/host-bridge.ts +214 -0
  159. package/kernel/apps/web/src/lib/entity-folder.ts +2 -0
  160. package/kernel/apps/web/src/linked-session-header.tsx +43 -0
  161. package/kernel/apps/web/src/live-session-controls.tsx +326 -0
  162. package/kernel/apps/web/src/local-source.ts +32 -0
  163. package/kernel/apps/web/src/main.tsx +24 -0
  164. package/kernel/apps/web/src/markdown-page.tsx +444 -0
  165. package/kernel/apps/web/src/notes-page.tsx +103 -0
  166. package/kernel/apps/web/src/plugins.ts +53 -0
  167. package/kernel/apps/web/src/project-search-dialog.tsx +257 -0
  168. package/kernel/apps/web/src/project-search.ts +18 -0
  169. package/kernel/apps/web/src/query-client.ts +4 -0
  170. package/kernel/apps/web/src/rehype-source-lines.ts +22 -0
  171. package/kernel/apps/web/src/routes/document.tsx +1 -0
  172. package/kernel/apps/web/src/routes/entities.tsx +277 -0
  173. package/kernel/apps/web/src/routes/search.tsx +60 -0
  174. package/kernel/apps/web/src/selection-context.ts +68 -0
  175. package/kernel/apps/web/src/selection-input.tsx +58 -0
  176. package/kernel/apps/web/src/selection-popup.tsx +155 -0
  177. package/kernel/apps/web/src/session-transcript-page.tsx +152 -0
  178. package/kernel/apps/web/src/use-annotations.ts +162 -0
  179. package/kernel/apps/web/src/use-ask-ai.ts +26 -0
  180. package/kernel/apps/web/src/use-ask-draft.ts +27 -0
  181. package/kernel/apps/web/src/use-document.ts +37 -0
  182. package/kernel/apps/web/src/use-folder-notes.ts +49 -0
  183. package/kernel/apps/web/src/use-linked-session.ts +33 -0
  184. package/kernel/apps/web/src/view-context.tsx +69 -0
  185. package/kernel/apps/web/src/view-header.tsx +66 -0
  186. package/kernel/apps/web/src/viewer-capabilities.ts +33 -0
  187. package/kernel/apps/web/src/viewer-route.ts +1 -0
  188. package/kernel/apps/web/src/viewport-height.ts +33 -0
  189. package/kernel/apps/web/tsconfig.json +24 -0
  190. package/kernel/apps/web/vite.config.ts +252 -0
  191. package/kernel/packages/agents/eslint.config.js +10 -0
  192. package/kernel/packages/agents/package.json +75 -0
  193. package/kernel/packages/agents/src/agent-card.tsx +334 -0
  194. package/kernel/packages/agents/src/client.tsx +13 -0
  195. package/kernel/packages/agents/src/index.ts +18 -0
  196. package/kernel/packages/agents/src/manifest.ts +7 -0
  197. package/kernel/packages/agents/src/node.ts +447 -0
  198. package/kernel/packages/agents/src/profiles.ts +137 -0
  199. package/kernel/packages/agents/src/resolve.ts +69 -0
  200. package/kernel/packages/agents/src/server.ts +60 -0
  201. package/kernel/packages/agents/src/types.ts +82 -0
  202. package/kernel/packages/agents/src/viewer.tsx +370 -0
  203. package/kernel/packages/agents/test/profiles.test.mjs +88 -0
  204. package/kernel/packages/agents/test/resolve.test.mjs +729 -0
  205. package/kernel/packages/agents/tsconfig.json +17 -0
  206. package/kernel/packages/api/README.md +73 -0
  207. package/kernel/packages/api/openapi.json +3368 -0
  208. package/kernel/packages/api/package.json +41 -0
  209. package/kernel/packages/api/src/client/errors.ts +1 -0
  210. package/kernel/packages/api/src/client/index.ts +2 -0
  211. package/kernel/packages/api/src/contracts/schemas.ts +277 -0
  212. package/kernel/packages/api/src/contracts.ts +20 -0
  213. package/kernel/packages/api/src/index.ts +34 -0
  214. package/kernel/packages/api/src/server/acp/index.ts +35 -0
  215. package/kernel/packages/api/src/server/acp/live-agent-connection.ts +44 -0
  216. package/kernel/packages/api/src/server/acp/process-manager.ts +291 -0
  217. package/kernel/packages/api/src/server/acp/registry.ts +140 -0
  218. package/kernel/packages/api/src/server/acp/sdk.ts +15 -0
  219. package/kernel/packages/api/src/server/acp/transport.ts +115 -0
  220. package/kernel/packages/api/src/server/acp/types.ts +89 -0
  221. package/kernel/packages/api/src/server/acp-live-plugin.ts +423 -0
  222. package/kernel/packages/api/src/server/api/create-agent-file.ts +46 -0
  223. package/kernel/packages/api/src/server/api/document-edit.ts +125 -0
  224. package/kernel/packages/api/src/server/api/open-path.ts +40 -0
  225. package/kernel/packages/api/src/server/contracts.ts +85 -0
  226. package/kernel/packages/api/src/server/entity-folder.ts +353 -0
  227. package/kernel/packages/api/src/server/folder-favicon.ts +17 -0
  228. package/kernel/packages/api/src/server/folder-icons.ts +113 -0
  229. package/kernel/packages/api/src/server/folder-metadata-plugin.ts +1758 -0
  230. package/kernel/packages/api/src/server/host.ts +21 -0
  231. package/kernel/packages/api/src/server/index.ts +197 -0
  232. package/kernel/packages/api/src/server/linked-folder-discovery.ts +158 -0
  233. package/kernel/packages/api/src/server/plugins.ts +205 -0
  234. package/kernel/packages/api/src/server/project-discovery.ts +69 -0
  235. package/kernel/packages/api/src/server/watcher.ts +46 -0
  236. package/kernel/packages/api/src/shared/selection.ts +16 -0
  237. package/kernel/packages/api/src/shared/viewer-route.ts +200 -0
  238. package/kernel/packages/api/test/agents-loading.test.ts +94 -0
  239. package/kernel/packages/api/test/core.test.ts +364 -0
  240. package/kernel/packages/api/test/entity-folder.test.ts +131 -0
  241. package/kernel/packages/api/test/linked-folder-discovery.test.ts +78 -0
  242. package/kernel/packages/api/test/media-endpoint.test.ts +83 -0
  243. package/kernel/packages/api/test/partial-loading.test.ts +43 -0
  244. package/kernel/packages/api/test/project-discovery.test.ts +44 -0
  245. package/kernel/packages/api/tsconfig.json +11 -0
  246. package/kernel/packages/api-client/README.md +72 -0
  247. package/kernel/packages/api-client/package.json +26 -0
  248. package/kernel/packages/api-client/scripts/generate.ts +68 -0
  249. package/kernel/packages/api-client/src/errors.ts +59 -0
  250. package/kernel/packages/api-client/src/generated.d.ts +1248 -0
  251. package/kernel/packages/api-client/src/index.ts +206 -0
  252. package/kernel/packages/api-client/src/responses.ts +19 -0
  253. package/kernel/packages/api-client/test/client.test.ts +143 -0
  254. package/kernel/packages/api-client/tsconfig.json +12 -0
  255. package/kernel/packages/folder-plugin/eslint.config.js +10 -0
  256. package/kernel/packages/folder-plugin/package.json +50 -0
  257. package/kernel/packages/folder-plugin/src/client.ts +73 -0
  258. package/kernel/packages/folder-plugin/src/endpoint.ts +273 -0
  259. package/kernel/packages/folder-plugin/src/index.ts +15 -0
  260. package/kernel/packages/folder-plugin/src/server.ts +78 -0
  261. package/kernel/packages/folder-plugin/src/subpath.ts +34 -0
  262. package/kernel/packages/folder-plugin/src/types.ts +86 -0
  263. package/kernel/packages/folder-plugin/src/validation.ts +56 -0
  264. package/kernel/packages/folder-plugin/test/contract.test.mjs +133 -0
  265. package/kernel/packages/folder-plugin/tsconfig.json +17 -0
  266. package/kernel/packages/kinds/package.json +24 -0
  267. package/kernel/packages/kinds/src/kinds.ts +172 -0
  268. package/kernel/packages/markdown/README.md +40 -0
  269. package/kernel/packages/markdown/explorer.css +1 -0
  270. package/kernel/packages/markdown/package.json +30 -0
  271. package/kernel/packages/markdown/src/documents.ts +1 -0
  272. package/kernel/packages/markdown/src/explorer.ts +1 -0
  273. package/kernel/packages/markdown/src/index.ts +2 -0
  274. package/kernel/packages/markdown/src/metadata.ts +63 -0
  275. package/kernel/packages/markdown/src/node.ts +1 -0
  276. package/kernel/packages/markdown/styles.css +1 -0
  277. package/kernel/packages/notes/SKILL.md +19 -0
  278. package/kernel/packages/notes/eslint.config.js +10 -0
  279. package/kernel/packages/notes/package.json +72 -0
  280. package/kernel/packages/notes/src/client.tsx +12 -0
  281. package/kernel/packages/notes/src/data/ai-input.ts +58 -0
  282. package/kernel/packages/notes/src/data/api.ts +40 -0
  283. package/kernel/packages/notes/src/data/parse.ts +15 -0
  284. package/kernel/packages/notes/src/data/routing.ts +33 -0
  285. package/kernel/packages/notes/src/data/use-folder-notes.ts +49 -0
  286. package/kernel/packages/notes/src/index.ts +2 -0
  287. package/kernel/packages/notes/src/manifest.ts +6 -0
  288. package/kernel/packages/notes/src/pages/notes-page.tsx +79 -0
  289. package/kernel/packages/notes/src/pages/single-note-page.tsx +57 -0
  290. package/kernel/packages/notes/src/server.ts +88 -0
  291. package/kernel/packages/notes/src/ui/ai-composer-controls.tsx +70 -0
  292. package/kernel/packages/notes/src/ui/folder-notes-list.tsx +140 -0
  293. package/kernel/packages/notes/tsconfig.json +16 -0
  294. package/kernel/packages/schemas/ICON-POLICY.md +43 -0
  295. package/kernel/packages/schemas/SKILL.md +185 -0
  296. package/kernel/packages/schemas/eslint.config.js +10 -0
  297. package/kernel/packages/schemas/package.json +81 -0
  298. package/kernel/packages/schemas/src/client.tsx +137 -0
  299. package/kernel/packages/schemas/src/data/config-file.ts +37 -0
  300. package/kernel/packages/schemas/src/data/contract.ts +174 -0
  301. package/kernel/packages/schemas/src/data/favicon.ts +218 -0
  302. package/kernel/packages/schemas/src/data/fields.ts +96 -0
  303. package/kernel/packages/schemas/src/data/icon-image.ts +53 -0
  304. package/kernel/packages/schemas/src/data/icon.ts +97 -0
  305. package/kernel/packages/schemas/src/data/load.ts +161 -0
  306. package/kernel/packages/schemas/src/data/params.ts +103 -0
  307. package/kernel/packages/schemas/src/data/query.ts +33 -0
  308. package/kernel/packages/schemas/src/data/sort.ts +50 -0
  309. package/kernel/packages/schemas/src/data/workspace.ts +101 -0
  310. package/kernel/packages/schemas/src/index.ts +22 -0
  311. package/kernel/packages/schemas/src/manifest.ts +4 -0
  312. package/kernel/packages/schemas/src/node.ts +384 -0
  313. package/kernel/packages/schemas/src/pages/collection.tsx +252 -0
  314. package/kernel/packages/schemas/src/server.ts +208 -0
  315. package/kernel/packages/schemas/src/ui/schema-entity-list.tsx +124 -0
  316. package/kernel/packages/schemas/src/ui/schema-filters.tsx +186 -0
  317. package/kernel/packages/schemas/src/ui/schema-search.tsx +35 -0
  318. package/kernel/packages/schemas/src/ui/use-query-param-filter-setting.tsx +15 -0
  319. package/kernel/packages/schemas/test/contract.test.mjs +26 -0
  320. package/kernel/packages/schemas/test/fields.test.mjs +187 -0
  321. package/kernel/packages/schemas/test/load.test.mjs +12 -0
  322. package/kernel/packages/schemas/test/node.test.mjs +412 -0
  323. package/kernel/packages/schemas/test/query.test.mjs +134 -0
  324. package/kernel/packages/schemas/test/workspace.test.mjs +86 -0
  325. package/kernel/packages/schemas/tsconfig.json +17 -0
  326. package/kernel/packages/session-finding/package.json +33 -0
  327. package/kernel/packages/session-finding/src/index.ts +120 -0
  328. package/kernel/packages/session-finding/test/list-sessions.test.mjs +139 -0
  329. package/kernel/packages/session-finding/tsconfig.json +12 -0
  330. package/kernel/packages/ui/LICENSE +21 -0
  331. package/kernel/packages/ui/components.json +20 -0
  332. package/kernel/packages/ui/eslint.config.js +8 -0
  333. package/kernel/packages/ui/package.json +106 -0
  334. package/kernel/packages/ui/src/chat/file-link.ts +178 -0
  335. package/kernel/packages/ui/src/chat/index.ts +18 -0
  336. package/kernel/packages/ui/src/chat/transcript.tsx +348 -0
  337. package/kernel/packages/ui/src/chat/turns.ts +76 -0
  338. package/kernel/packages/ui/src/chat/types.ts +23 -0
  339. package/kernel/packages/ui/src/chat/use-overflowing.ts +56 -0
  340. package/kernel/packages/ui/src/components/accordion.tsx +74 -0
  341. package/kernel/packages/ui/src/components/alert-dialog.tsx +164 -0
  342. package/kernel/packages/ui/src/components/alert.tsx +68 -0
  343. package/kernel/packages/ui/src/components/app-breadcrumbs.tsx +170 -0
  344. package/kernel/packages/ui/src/components/app-header.tsx +125 -0
  345. package/kernel/packages/ui/src/components/app-options.tsx +87 -0
  346. package/kernel/packages/ui/src/components/app-view-header.tsx +34 -0
  347. package/kernel/packages/ui/src/components/aspect-ratio.tsx +11 -0
  348. package/kernel/packages/ui/src/components/avatar.tsx +53 -0
  349. package/kernel/packages/ui/src/components/badge.tsx +47 -0
  350. package/kernel/packages/ui/src/components/base-dialog.tsx +3 -0
  351. package/kernel/packages/ui/src/components/base-tabs.tsx +63 -0
  352. package/kernel/packages/ui/src/components/breadcrumb.tsx +110 -0
  353. package/kernel/packages/ui/src/components/button-group.tsx +86 -0
  354. package/kernel/packages/ui/src/components/button.tsx +65 -0
  355. package/kernel/packages/ui/src/components/calendar.tsx +240 -0
  356. package/kernel/packages/ui/src/components/card.tsx +95 -0
  357. package/kernel/packages/ui/src/components/carousel.tsx +240 -0
  358. package/kernel/packages/ui/src/components/chart.tsx +375 -0
  359. package/kernel/packages/ui/src/components/checkbox.tsx +39 -0
  360. package/kernel/packages/ui/src/components/collapsible.tsx +33 -0
  361. package/kernel/packages/ui/src/components/collection-icon.tsx +28 -0
  362. package/kernel/packages/ui/src/components/command.tsx +205 -0
  363. package/kernel/packages/ui/src/components/content-issues.tsx +63 -0
  364. package/kernel/packages/ui/src/components/context-menu.tsx +298 -0
  365. package/kernel/packages/ui/src/components/copy-context.tsx +134 -0
  366. package/kernel/packages/ui/src/components/dialog.tsx +157 -0
  367. package/kernel/packages/ui/src/components/drawer.tsx +162 -0
  368. package/kernel/packages/ui/src/components/dropdown-menu.tsx +303 -0
  369. package/kernel/packages/ui/src/components/empty.tsx +108 -0
  370. package/kernel/packages/ui/src/components/field.tsx +260 -0
  371. package/kernel/packages/ui/src/components/file-preview.tsx +152 -0
  372. package/kernel/packages/ui/src/components/file-renderer.tsx +466 -0
  373. package/kernel/packages/ui/src/components/filter-chip-panel.tsx +157 -0
  374. package/kernel/packages/ui/src/components/filter-select.tsx +127 -0
  375. package/kernel/packages/ui/src/components/folder-activity.tsx +646 -0
  376. package/kernel/packages/ui/src/components/folder-file-list.tsx +58 -0
  377. package/kernel/packages/ui/src/components/folder-filter-bar.tsx +191 -0
  378. package/kernel/packages/ui/src/components/folder-image.tsx +18 -0
  379. package/kernel/packages/ui/src/components/folder-landing.tsx +70 -0
  380. package/kernel/packages/ui/src/components/folder-list.tsx +140 -0
  381. package/kernel/packages/ui/src/components/folder-metadata.tsx +107 -0
  382. package/kernel/packages/ui/src/components/folder-mobile-bar.tsx +60 -0
  383. package/kernel/packages/ui/src/components/folder-project-list.tsx +133 -0
  384. package/kernel/packages/ui/src/components/folder-session-list.tsx +113 -0
  385. package/kernel/packages/ui/src/components/folder-session-page.tsx +126 -0
  386. package/kernel/packages/ui/src/components/folder-sidebar.tsx +52 -0
  387. package/kernel/packages/ui/src/components/folder-skill-list.tsx +62 -0
  388. package/kernel/packages/ui/src/components/folder-tabs.tsx +156 -0
  389. package/kernel/packages/ui/src/components/form.tsx +167 -0
  390. package/kernel/packages/ui/src/components/hover-card.tsx +52 -0
  391. package/kernel/packages/ui/src/components/icons.tsx +34 -0
  392. package/kernel/packages/ui/src/components/input-group.tsx +184 -0
  393. package/kernel/packages/ui/src/components/input-otp.tsx +90 -0
  394. package/kernel/packages/ui/src/components/input.tsx +29 -0
  395. package/kernel/packages/ui/src/components/item.tsx +195 -0
  396. package/kernel/packages/ui/src/components/kbd.tsx +32 -0
  397. package/kernel/packages/ui/src/components/label.tsx +27 -0
  398. package/kernel/packages/ui/src/components/link.tsx +45 -0
  399. package/kernel/packages/ui/src/components/live-tool-call.tsx +193 -0
  400. package/kernel/packages/ui/src/components/menubar.tsx +323 -0
  401. package/kernel/packages/ui/src/components/navigation-menu.tsx +210 -0
  402. package/kernel/packages/ui/src/components/note-card.tsx +149 -0
  403. package/kernel/packages/ui/src/components/pagination.tsx +128 -0
  404. package/kernel/packages/ui/src/components/popover.tsx +56 -0
  405. package/kernel/packages/ui/src/components/progress.tsx +31 -0
  406. package/kernel/packages/ui/src/components/radio-group.tsx +54 -0
  407. package/kernel/packages/ui/src/components/scroll-area.tsx +61 -0
  408. package/kernel/packages/ui/src/components/select.tsx +219 -0
  409. package/kernel/packages/ui/src/components/separator.tsx +30 -0
  410. package/kernel/packages/ui/src/components/session-icon.tsx +124 -0
  411. package/kernel/packages/ui/src/components/sheet.tsx +157 -0
  412. package/kernel/packages/ui/src/components/sidebar.tsx +789 -0
  413. package/kernel/packages/ui/src/components/skeleton.tsx +13 -0
  414. package/kernel/packages/ui/src/components/slider.tsx +73 -0
  415. package/kernel/packages/ui/src/components/sonner.tsx +41 -0
  416. package/kernel/packages/ui/src/components/spinner.tsx +16 -0
  417. package/kernel/packages/ui/src/components/switch.tsx +40 -0
  418. package/kernel/packages/ui/src/components/table.tsx +120 -0
  419. package/kernel/packages/ui/src/components/tabs.tsx +78 -0
  420. package/kernel/packages/ui/src/components/textarea.tsx +25 -0
  421. package/kernel/packages/ui/src/components/toggle-group.tsx +87 -0
  422. package/kernel/packages/ui/src/components/toggle.tsx +48 -0
  423. package/kernel/packages/ui/src/components/tooltip.tsx +71 -0
  424. package/kernel/packages/ui/src/components/viewer-options.tsx +166 -0
  425. package/kernel/packages/ui/src/hooks/use-folder-filter.ts +103 -0
  426. package/kernel/packages/ui/src/hooks/use-mobile.ts +19 -0
  427. package/kernel/packages/ui/src/index.ts +13 -0
  428. package/kernel/packages/ui/src/lib/document-extensions.ts +83 -0
  429. package/kernel/packages/ui/src/lib/folder-activity.ts +143 -0
  430. package/kernel/packages/ui/src/lib/folder-filter.ts +284 -0
  431. package/kernel/packages/ui/src/lib/live-tool-call.tsx +109 -0
  432. package/kernel/packages/ui/src/lib/media-urls.ts +176 -0
  433. package/kernel/packages/ui/src/lib/obsidian-links.ts +120 -0
  434. package/kernel/packages/ui/src/lib/source-components.tsx +65 -0
  435. package/kernel/packages/ui/src/lib/utils.tsx +7 -0
  436. package/kernel/packages/ui/src/pages/entity-detail-page.tsx +82 -0
  437. package/kernel/packages/ui/src/pages/entity-list-page.tsx +50 -0
  438. package/kernel/packages/ui/src/pages/entity-page.tsx +69 -0
  439. package/kernel/packages/ui/src/styles/folder-activity.css +2151 -0
  440. package/kernel/packages/ui/test/copy-context.test.mjs +48 -0
  441. package/kernel/packages/ui/test/folder-filter.test.mjs +484 -0
  442. package/kernel/packages/ui/tsconfig.json +15 -0
  443. package/kernel/plugins/calendar/SKILL.md +173 -0
  444. package/kernel/plugins/calendar/eslint.config.js +10 -0
  445. package/kernel/plugins/calendar/package.json +73 -0
  446. package/kernel/plugins/calendar/schema.json +137 -0
  447. package/kernel/plugins/calendar/src/calendar.tsx +328 -0
  448. package/kernel/plugins/calendar/src/client.tsx +139 -0
  449. package/kernel/plugins/calendar/src/context.ts +48 -0
  450. package/kernel/plugins/calendar/src/copy-button.tsx +66 -0
  451. package/kernel/plugins/calendar/src/event-dialog.tsx +270 -0
  452. package/kernel/plugins/calendar/src/index.ts +4 -0
  453. package/kernel/plugins/calendar/src/manifest.ts +7 -0
  454. package/kernel/plugins/calendar/src/parse.ts +610 -0
  455. package/kernel/plugins/calendar/src/server.ts +160 -0
  456. package/kernel/plugins/calendar/src/utils.ts +80 -0
  457. package/kernel/plugins/calendar/src/views.tsx +418 -0
  458. package/kernel/plugins/calendar/test/context.test.mjs +60 -0
  459. package/kernel/plugins/calendar/test/package.test.mjs +43 -0
  460. package/kernel/plugins/calendar/test/parse.test.mjs +392 -0
  461. package/kernel/plugins/calendar/test/server.test.mjs +126 -0
  462. package/kernel/plugins/calendar/tsconfig.json +17 -0
  463. package/kernel/plugins/mail/SKILL.md +97 -0
  464. package/kernel/plugins/mail/eslint.config.js +10 -0
  465. package/kernel/plugins/mail/package.json +79 -0
  466. package/kernel/plugins/mail/src/api.ts +359 -0
  467. package/kernel/plugins/mail/src/bun-ffi.d.ts +14 -0
  468. package/kernel/plugins/mail/src/client.tsx +14 -0
  469. package/kernel/plugins/mail/src/flock.ts +137 -0
  470. package/kernel/plugins/mail/src/folders.ts +37 -0
  471. package/kernel/plugins/mail/src/history.ts +485 -0
  472. package/kernel/plugins/mail/src/index.ts +3 -0
  473. package/kernel/plugins/mail/src/mail-card.tsx +123 -0
  474. package/kernel/plugins/mail/src/mail-conversation.tsx +153 -0
  475. package/kernel/plugins/mail/src/mail-detail-page.tsx +467 -0
  476. package/kernel/plugins/mail/src/mail-hooks.ts +252 -0
  477. package/kernel/plugins/mail/src/mail-page.tsx +109 -0
  478. package/kernel/plugins/mail/src/mail-request.ts +78 -0
  479. package/kernel/plugins/mail/src/mail-send-box.tsx +175 -0
  480. package/kernel/plugins/mail/src/mailos.ts +723 -0
  481. package/kernel/plugins/mail/src/manifest.ts +7 -0
  482. package/kernel/plugins/mail/src/node.ts +171 -0
  483. package/kernel/plugins/mail/src/parse.ts +139 -0
  484. package/kernel/plugins/mail/src/server.ts +125 -0
  485. package/kernel/plugins/mail/src/types.ts +10 -0
  486. package/kernel/plugins/mail/src/viewer.tsx +147 -0
  487. package/kernel/plugins/mail/test/flock.test.mjs +156 -0
  488. package/kernel/plugins/mail/test/folders.test.mjs +138 -0
  489. package/kernel/plugins/mail/test/history.test.mjs +460 -0
  490. package/kernel/plugins/mail/test/mailos.test.mjs +752 -0
  491. package/kernel/plugins/mail/test/node.test.mjs +207 -0
  492. package/kernel/plugins/mail/test/package.test.mjs +54 -0
  493. package/kernel/plugins/mail/test/parse.test.mjs +32 -0
  494. package/kernel/plugins/mail/test/server.test.mjs +116 -0
  495. package/kernel/plugins/mail/test/viewer.test.mjs +192 -0
  496. package/kernel/plugins/mail/tsconfig.json +17 -0
  497. package/kernel/plugins/projects/SKILL.md +73 -0
  498. package/kernel/plugins/projects/eslint.config.js +10 -0
  499. package/kernel/plugins/projects/package.json +70 -0
  500. package/kernel/plugins/projects/src/client.tsx +17 -0
  501. package/kernel/plugins/projects/src/data/model.ts +129 -0
  502. package/kernel/plugins/projects/src/index.ts +17 -0
  503. package/kernel/plugins/projects/src/manifest.ts +7 -0
  504. package/kernel/plugins/projects/src/project-context.ts +41 -0
  505. package/kernel/plugins/projects/src/server.ts +276 -0
  506. package/kernel/plugins/projects/src/ui/project-card.tsx +61 -0
  507. package/kernel/plugins/projects/src/ui/projects-page.tsx +102 -0
  508. package/kernel/plugins/projects/test/package.test.mjs +51 -0
  509. package/kernel/plugins/projects/tsconfig.json +17 -0
  510. package/kernel/plugins/tasks/SKILL.md +341 -0
  511. package/kernel/plugins/tasks/eslint.config.js +10 -0
  512. package/kernel/plugins/tasks/package.json +74 -0
  513. package/kernel/plugins/tasks/schema.json +939 -0
  514. package/kernel/plugins/tasks/src/api.ts +212 -0
  515. package/kernel/plugins/tasks/src/client.tsx +23 -0
  516. package/kernel/plugins/tasks/src/data/parse.ts +544 -0
  517. package/kernel/plugins/tasks/src/data/task-id.ts +56 -0
  518. package/kernel/plugins/tasks/src/data/todo-model.ts +795 -0
  519. package/kernel/plugins/tasks/src/index.ts +34 -0
  520. package/kernel/plugins/tasks/src/manifest.ts +7 -0
  521. package/kernel/plugins/tasks/src/pages/task-detail.tsx +48 -0
  522. package/kernel/plugins/tasks/src/pages/task-list.tsx +88 -0
  523. package/kernel/plugins/tasks/src/server.ts +447 -0
  524. package/kernel/plugins/tasks/src/styles.css +9 -0
  525. package/kernel/plugins/tasks/src/ui/compact-todo-list.tsx +372 -0
  526. package/kernel/plugins/tasks/src/ui/error-details.tsx +78 -0
  527. package/kernel/plugins/tasks/src/ui/task-page.tsx +392 -0
  528. package/kernel/plugins/tasks/src/ui/todo-agent-filter.tsx +36 -0
  529. package/kernel/plugins/tasks/src/ui/todo-filter-bar.tsx +66 -0
  530. package/kernel/plugins/tasks/src/ui/todo-item.tsx +494 -0
  531. package/kernel/plugins/tasks/src/ui/todo-status-filter.tsx +60 -0
  532. package/kernel/plugins/tasks/src/ui/todo-tag-filter.tsx +48 -0
  533. package/kernel/plugins/tasks/src/ui/todo-warnings.tsx +106 -0
  534. package/kernel/plugins/tasks/test/api.test.mjs +99 -0
  535. package/kernel/plugins/tasks/test/folder-sources.test.mjs +46 -0
  536. package/kernel/plugins/tasks/test/package.test.mjs +54 -0
  537. package/kernel/plugins/tasks/test/parse.test.mjs +225 -0
  538. package/kernel/plugins/tasks/test/server.test.mjs +386 -0
  539. package/kernel/plugins/tasks/tsconfig.json +17 -0
  540. package/node_modules/@agentclientprotocol/sdk/LICENSE +191 -0
  541. package/node_modules/@agentclientprotocol/sdk/README.md +70 -0
  542. package/node_modules/@agentclientprotocol/sdk/dist/acp.d.ts +1835 -0
  543. package/node_modules/@agentclientprotocol/sdk/dist/acp.js +1885 -0
  544. package/node_modules/@agentclientprotocol/sdk/dist/acp.js.map +1 -0
  545. package/node_modules/@agentclientprotocol/sdk/dist/acp.test.d.ts +1 -0
  546. package/node_modules/@agentclientprotocol/sdk/dist/acp.test.js +5036 -0
  547. package/node_modules/@agentclientprotocol/sdk/dist/acp.test.js.map +1 -0
  548. package/node_modules/@agentclientprotocol/sdk/dist/connection.d.ts +82 -0
  549. package/node_modules/@agentclientprotocol/sdk/dist/connection.js +428 -0
  550. package/node_modules/@agentclientprotocol/sdk/dist/connection.js.map +1 -0
  551. package/node_modules/@agentclientprotocol/sdk/dist/connection.test.d.ts +1 -0
  552. package/node_modules/@agentclientprotocol/sdk/dist/connection.test.js +470 -0
  553. package/node_modules/@agentclientprotocol/sdk/dist/connection.test.js.map +1 -0
  554. package/node_modules/@agentclientprotocol/sdk/dist/cookie-store.d.ts +26 -0
  555. package/node_modules/@agentclientprotocol/sdk/dist/cookie-store.js +96 -0
  556. package/node_modules/@agentclientprotocol/sdk/dist/cookie-store.js.map +1 -0
  557. package/node_modules/@agentclientprotocol/sdk/dist/cookie-store.test.d.ts +1 -0
  558. package/node_modules/@agentclientprotocol/sdk/dist/cookie-store.test.js +77 -0
  559. package/node_modules/@agentclientprotocol/sdk/dist/cookie-store.test.js.map +1 -0
  560. package/node_modules/@agentclientprotocol/sdk/dist/examples/agent.d.ts +2 -0
  561. package/node_modules/@agentclientprotocol/sdk/dist/examples/agent.js +232 -0
  562. package/node_modules/@agentclientprotocol/sdk/dist/examples/agent.js.map +1 -0
  563. package/node_modules/@agentclientprotocol/sdk/dist/examples/client.d.ts +2 -0
  564. package/node_modules/@agentclientprotocol/sdk/dist/examples/client.js +132 -0
  565. package/node_modules/@agentclientprotocol/sdk/dist/examples/client.js.map +1 -0
  566. package/node_modules/@agentclientprotocol/sdk/dist/examples/dual-version-agent.d.ts +9 -0
  567. package/node_modules/@agentclientprotocol/sdk/dist/examples/dual-version-agent.js +221 -0
  568. package/node_modules/@agentclientprotocol/sdk/dist/examples/dual-version-agent.js.map +1 -0
  569. package/node_modules/@agentclientprotocol/sdk/dist/examples/http-client.d.ts +2 -0
  570. package/node_modules/@agentclientprotocol/sdk/dist/examples/http-client.js +86 -0
  571. package/node_modules/@agentclientprotocol/sdk/dist/examples/http-client.js.map +1 -0
  572. package/node_modules/@agentclientprotocol/sdk/dist/examples/http-server.d.ts +2 -0
  573. package/node_modules/@agentclientprotocol/sdk/dist/examples/http-server.js +112 -0
  574. package/node_modules/@agentclientprotocol/sdk/dist/examples/http-server.js.map +1 -0
  575. package/node_modules/@agentclientprotocol/sdk/dist/examples/ws-client.d.ts +2 -0
  576. package/node_modules/@agentclientprotocol/sdk/dist/examples/ws-client.js +88 -0
  577. package/node_modules/@agentclientprotocol/sdk/dist/examples/ws-client.js.map +1 -0
  578. package/node_modules/@agentclientprotocol/sdk/dist/http-stream.d.ts +33 -0
  579. package/node_modules/@agentclientprotocol/sdk/dist/http-stream.js +435 -0
  580. package/node_modules/@agentclientprotocol/sdk/dist/http-stream.js.map +1 -0
  581. package/node_modules/@agentclientprotocol/sdk/dist/http-stream.test.d.ts +1 -0
  582. package/node_modules/@agentclientprotocol/sdk/dist/http-stream.test.js +1380 -0
  583. package/node_modules/@agentclientprotocol/sdk/dist/http-stream.test.js.map +1 -0
  584. package/node_modules/@agentclientprotocol/sdk/dist/jsonrpc.d.ts +603 -0
  585. package/node_modules/@agentclientprotocol/sdk/dist/jsonrpc.js +1064 -0
  586. package/node_modules/@agentclientprotocol/sdk/dist/jsonrpc.js.map +1 -0
  587. package/node_modules/@agentclientprotocol/sdk/dist/jsonrpc.test.d.ts +1 -0
  588. package/node_modules/@agentclientprotocol/sdk/dist/jsonrpc.test.js +851 -0
  589. package/node_modules/@agentclientprotocol/sdk/dist/jsonrpc.test.js.map +1 -0
  590. package/node_modules/@agentclientprotocol/sdk/dist/line-buffer.d.ts +22 -0
  591. package/node_modules/@agentclientprotocol/sdk/dist/line-buffer.js +64 -0
  592. package/node_modules/@agentclientprotocol/sdk/dist/line-buffer.js.map +1 -0
  593. package/node_modules/@agentclientprotocol/sdk/dist/line-buffer.test.d.ts +1 -0
  594. package/node_modules/@agentclientprotocol/sdk/dist/line-buffer.test.js +45 -0
  595. package/node_modules/@agentclientprotocol/sdk/dist/line-buffer.test.js.map +1 -0
  596. package/node_modules/@agentclientprotocol/sdk/dist/node-adapter.d.ts +17 -0
  597. package/node_modules/@agentclientprotocol/sdk/dist/node-adapter.js +426 -0
  598. package/node_modules/@agentclientprotocol/sdk/dist/node-adapter.js.map +1 -0
  599. package/node_modules/@agentclientprotocol/sdk/dist/node-adapter.test.d.ts +1 -0
  600. package/node_modules/@agentclientprotocol/sdk/dist/node-adapter.test.js +499 -0
  601. package/node_modules/@agentclientprotocol/sdk/dist/node-adapter.test.js.map +1 -0
  602. package/node_modules/@agentclientprotocol/sdk/dist/protocol-router.d.ts +37 -0
  603. package/node_modules/@agentclientprotocol/sdk/dist/protocol-router.js +474 -0
  604. package/node_modules/@agentclientprotocol/sdk/dist/protocol-router.js.map +1 -0
  605. package/node_modules/@agentclientprotocol/sdk/dist/protocol-router.test.d.ts +1 -0
  606. package/node_modules/@agentclientprotocol/sdk/dist/protocol-router.test.js +535 -0
  607. package/node_modules/@agentclientprotocol/sdk/dist/protocol-router.test.js.map +1 -0
  608. package/node_modules/@agentclientprotocol/sdk/dist/protocol.d.ts +11 -0
  609. package/node_modules/@agentclientprotocol/sdk/dist/protocol.js +57 -0
  610. package/node_modules/@agentclientprotocol/sdk/dist/protocol.js.map +1 -0
  611. package/node_modules/@agentclientprotocol/sdk/dist/protocol.test.d.ts +1 -0
  612. package/node_modules/@agentclientprotocol/sdk/dist/protocol.test.js +73 -0
  613. package/node_modules/@agentclientprotocol/sdk/dist/protocol.test.js.map +1 -0
  614. package/node_modules/@agentclientprotocol/sdk/dist/schema/guards.gen.d.ts +199 -0
  615. package/node_modules/@agentclientprotocol/sdk/dist/schema/guards.gen.js +211 -0
  616. package/node_modules/@agentclientprotocol/sdk/dist/schema/guards.gen.js.map +1 -0
  617. package/node_modules/@agentclientprotocol/sdk/dist/schema/index.d.ts +51 -0
  618. package/node_modules/@agentclientprotocol/sdk/dist/schema/index.js +52 -0
  619. package/node_modules/@agentclientprotocol/sdk/dist/schema/index.js.map +1 -0
  620. package/node_modules/@agentclientprotocol/sdk/dist/schema/types.gen.d.ts +6118 -0
  621. package/node_modules/@agentclientprotocol/sdk/dist/schema/types.gen.js +3 -0
  622. package/node_modules/@agentclientprotocol/sdk/dist/schema/types.gen.js.map +1 -0
  623. package/node_modules/@agentclientprotocol/sdk/dist/schema/zod.gen.d.ts +14160 -0
  624. package/node_modules/@agentclientprotocol/sdk/dist/schema/zod.gen.js +3066 -0
  625. package/node_modules/@agentclientprotocol/sdk/dist/schema/zod.gen.js.map +1 -0
  626. package/node_modules/@agentclientprotocol/sdk/dist/schema-deserialize.d.ts +30 -0
  627. package/node_modules/@agentclientprotocol/sdk/dist/schema-deserialize.js +98 -0
  628. package/node_modules/@agentclientprotocol/sdk/dist/schema-deserialize.js.map +1 -0
  629. package/node_modules/@agentclientprotocol/sdk/dist/schema-deserialize.test.d.ts +1 -0
  630. package/node_modules/@agentclientprotocol/sdk/dist/schema-deserialize.test.js +93 -0
  631. package/node_modules/@agentclientprotocol/sdk/dist/schema-deserialize.test.js.map +1 -0
  632. package/node_modules/@agentclientprotocol/sdk/dist/server-permission.test.d.ts +1 -0
  633. package/node_modules/@agentclientprotocol/sdk/dist/server-permission.test.js +261 -0
  634. package/node_modules/@agentclientprotocol/sdk/dist/server-permission.test.js.map +1 -0
  635. package/node_modules/@agentclientprotocol/sdk/dist/server-session-sse.test.d.ts +1 -0
  636. package/node_modules/@agentclientprotocol/sdk/dist/server-session-sse.test.js +490 -0
  637. package/node_modules/@agentclientprotocol/sdk/dist/server-session-sse.test.js.map +1 -0
  638. package/node_modules/@agentclientprotocol/sdk/dist/server-sse.d.ts +2 -0
  639. package/node_modules/@agentclientprotocol/sdk/dist/server-sse.js +104 -0
  640. package/node_modules/@agentclientprotocol/sdk/dist/server-sse.js.map +1 -0
  641. package/node_modules/@agentclientprotocol/sdk/dist/server-sse.test.d.ts +1 -0
  642. package/node_modules/@agentclientprotocol/sdk/dist/server-sse.test.js +52 -0
  643. package/node_modules/@agentclientprotocol/sdk/dist/server-sse.test.js.map +1 -0
  644. package/node_modules/@agentclientprotocol/sdk/dist/server-websocket-upgrade.test.d.ts +1 -0
  645. package/node_modules/@agentclientprotocol/sdk/dist/server-websocket-upgrade.test.js +946 -0
  646. package/node_modules/@agentclientprotocol/sdk/dist/server-websocket-upgrade.test.js.map +1 -0
  647. package/node_modules/@agentclientprotocol/sdk/dist/server.d.ts +81 -0
  648. package/node_modules/@agentclientprotocol/sdk/dist/server.js +380 -0
  649. package/node_modules/@agentclientprotocol/sdk/dist/server.js.map +1 -0
  650. package/node_modules/@agentclientprotocol/sdk/dist/server.test.d.ts +1 -0
  651. package/node_modules/@agentclientprotocol/sdk/dist/server.test.js +1082 -0
  652. package/node_modules/@agentclientprotocol/sdk/dist/server.test.js.map +1 -0
  653. package/node_modules/@agentclientprotocol/sdk/dist/sse.d.ts +4 -0
  654. package/node_modules/@agentclientprotocol/sdk/dist/sse.js +91 -0
  655. package/node_modules/@agentclientprotocol/sdk/dist/sse.js.map +1 -0
  656. package/node_modules/@agentclientprotocol/sdk/dist/sse.test.d.ts +1 -0
  657. package/node_modules/@agentclientprotocol/sdk/dist/sse.test.js +126 -0
  658. package/node_modules/@agentclientprotocol/sdk/dist/sse.test.js.map +1 -0
  659. package/node_modules/@agentclientprotocol/sdk/dist/stream.d.ts +35 -0
  660. package/node_modules/@agentclientprotocol/sdk/dist/stream.js +106 -0
  661. package/node_modules/@agentclientprotocol/sdk/dist/stream.js.map +1 -0
  662. package/node_modules/@agentclientprotocol/sdk/dist/stream.test.d.ts +1 -0
  663. package/node_modules/@agentclientprotocol/sdk/dist/stream.test.js +206 -0
  664. package/node_modules/@agentclientprotocol/sdk/dist/stream.test.js.map +1 -0
  665. package/node_modules/@agentclientprotocol/sdk/dist/test-support/streams.d.ts +8 -0
  666. package/node_modules/@agentclientprotocol/sdk/dist/test-support/streams.js +51 -0
  667. package/node_modules/@agentclientprotocol/sdk/dist/test-support/streams.js.map +1 -0
  668. package/node_modules/@agentclientprotocol/sdk/dist/test-support/test-agent.d.ts +24 -0
  669. package/node_modules/@agentclientprotocol/sdk/dist/test-support/test-agent.js +163 -0
  670. package/node_modules/@agentclientprotocol/sdk/dist/test-support/test-agent.js.map +1 -0
  671. package/node_modules/@agentclientprotocol/sdk/dist/test-support/test-http-server.d.ts +9 -0
  672. package/node_modules/@agentclientprotocol/sdk/dist/test-support/test-http-server.js +74 -0
  673. package/node_modules/@agentclientprotocol/sdk/dist/test-support/test-http-server.js.map +1 -0
  674. package/node_modules/@agentclientprotocol/sdk/dist/v2/acp.d.ts +806 -0
  675. package/node_modules/@agentclientprotocol/sdk/dist/v2/acp.js +1183 -0
  676. package/node_modules/@agentclientprotocol/sdk/dist/v2/acp.js.map +1 -0
  677. package/node_modules/@agentclientprotocol/sdk/dist/v2/acp.test.d.ts +1 -0
  678. package/node_modules/@agentclientprotocol/sdk/dist/v2/acp.test.js +512 -0
  679. package/node_modules/@agentclientprotocol/sdk/dist/v2/acp.test.js.map +1 -0
  680. package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/guards.gen.d.ts +954 -0
  681. package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/guards.gen.js +1035 -0
  682. package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/guards.gen.js.map +1 -0
  683. package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/index.d.ts +42 -0
  684. package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/index.js +43 -0
  685. package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/index.js.map +1 -0
  686. package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/types.gen.d.ts +6146 -0
  687. package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/types.gen.js +3 -0
  688. package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/types.gen.js.map +1 -0
  689. package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/zod.gen.d.ts +30552 -0
  690. package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/zod.gen.js +3204 -0
  691. package/node_modules/@agentclientprotocol/sdk/dist/v2/schema/zod.gen.js.map +1 -0
  692. package/node_modules/@agentclientprotocol/sdk/dist/ws-server.d.ts +14 -0
  693. package/node_modules/@agentclientprotocol/sdk/dist/ws-server.js +358 -0
  694. package/node_modules/@agentclientprotocol/sdk/dist/ws-server.js.map +1 -0
  695. package/node_modules/@agentclientprotocol/sdk/dist/ws-stream.d.ts +54 -0
  696. package/node_modules/@agentclientprotocol/sdk/dist/ws-stream.js +246 -0
  697. package/node_modules/@agentclientprotocol/sdk/dist/ws-stream.js.map +1 -0
  698. package/node_modules/@agentclientprotocol/sdk/dist/ws-stream.test.d.ts +1 -0
  699. package/node_modules/@agentclientprotocol/sdk/dist/ws-stream.test.js +833 -0
  700. package/node_modules/@agentclientprotocol/sdk/dist/ws-stream.test.js.map +1 -0
  701. package/node_modules/@agentclientprotocol/sdk/dist/ws-utils.d.ts +13 -0
  702. package/node_modules/@agentclientprotocol/sdk/dist/ws-utils.js +78 -0
  703. package/node_modules/@agentclientprotocol/sdk/dist/ws-utils.js.map +1 -0
  704. package/node_modules/@agentclientprotocol/sdk/dist/ws-utils.test.d.ts +1 -0
  705. package/node_modules/@agentclientprotocol/sdk/dist/ws-utils.test.js +42 -0
  706. package/node_modules/@agentclientprotocol/sdk/dist/ws-utils.test.js.map +1 -0
  707. package/node_modules/@agentclientprotocol/sdk/package.json +105 -0
  708. package/node_modules/@agentclientprotocol/sdk/schema/schema.json +8819 -0
  709. package/node_modules/@agentclientprotocol/sdk/schema/v2/schema.unstable.json +10098 -0
  710. package/package.json +52 -6
  711. package/web/assets/{abnfDiagram-VRR7QNED-Nfq-O04D.js → abnfDiagram-VRR7QNED-Bgfb1nEB.js} +1 -1
  712. package/web/assets/app-DoGr2Zi7.js +2 -0
  713. package/web/assets/app-options-D-RJiQ-X.js +25 -0
  714. package/web/assets/app-view-header-BLvLq02T.js +1 -0
  715. package/web/assets/arc-Dk_KI36B.js +1 -0
  716. package/web/assets/{architectureDiagram-ZJ3FMSHR-qhRwPNcQ.js → architectureDiagram-ZJ3FMSHR-NR_KhRCf.js} +1 -1
  717. package/web/assets/ask-tray-TzeTcO6-.js +14 -0
  718. package/web/assets/{blockDiagram-677ZJIJ3-C56P3bGu.js → blockDiagram-677ZJIJ3-CkLkwx9C.js} +1 -1
  719. package/web/assets/button-C6arH7zt.js +1 -0
  720. package/web/assets/{c4Diagram-LMCZKHZV-Ey1M72zD.js → c4Diagram-LMCZKHZV-CFCUH8e_.js} +1 -1
  721. package/web/assets/channel-uMEjV8qc.js +1 -0
  722. package/web/assets/{chunk-2Q5K7J3B-a6isk9VU.js → chunk-2Q5K7J3B-B_BPLWsW.js} +1 -1
  723. package/web/assets/{chunk-32BRIVSS-uy4kdSLL.js → chunk-32BRIVSS-B1VB1hOy.js} +1 -1
  724. package/web/assets/{chunk-5VM5RSS4-oj2sBFd7.js → chunk-5VM5RSS4-KFcYr8Co.js} +1 -1
  725. package/web/assets/{chunk-EX3LRPZG-Bzl1ukAi.js → chunk-EX3LRPZG-CpBX3kuK.js} +3 -3
  726. package/web/assets/{chunk-JWPE2WC7-sUph7I_t.js → chunk-JWPE2WC7-BPSl40wG.js} +1 -1
  727. package/web/assets/{chunk-MOJQB5TN-C0ERSuVK.js → chunk-MOJQB5TN-D2RcYmoU.js} +1 -1
  728. package/web/assets/{chunk-RYQCIY6F-Dyw1Hfwp.js → chunk-RYQCIY6F-m7Gyn-t3.js} +1 -1
  729. package/web/assets/{chunk-V7JOEXUC-DnSz22rb.js → chunk-V7JOEXUC-TDvdopxS.js} +1 -1
  730. package/web/assets/{chunk-VR4S4FIN-Bp2SNel7.js → chunk-VR4S4FIN-DZTsG51a.js} +1 -1
  731. package/web/assets/{chunk-XXDRQBXY-Dqtar746.js → chunk-XXDRQBXY-Dp0--RE2.js} +1 -1
  732. package/web/assets/classDiagram-OUVF2IWQ-fbZocVor.js +1 -0
  733. package/web/assets/classDiagram-v2-EOCWNBFH-fbZocVor.js +1 -0
  734. package/web/assets/client-C6Nxdfif.js +2 -0
  735. package/web/assets/client-CXYfBko5.js +17 -0
  736. package/web/assets/client-CoKtOq-X.js +7 -0
  737. package/web/assets/client-DyRQz5RU.js +53 -0
  738. package/web/assets/client-OY6HUzuD.js +98 -0
  739. package/web/assets/client-YOYWZIFi.js +34 -0
  740. package/web/assets/client-j2kQmxsO.js +22 -0
  741. package/web/assets/command-BugZBGXE.js +38 -0
  742. package/web/assets/copy-context-C0Uqsp-3.js +1 -0
  743. package/web/assets/{cose-bilkent-JH36ORCC-Dx1VqMjj.js → cose-bilkent-JH36ORCC-CPu3PI8h.js} +1 -1
  744. package/web/assets/{cynefin-VYW2F7L2-SjhCWmIV.js → cynefin-VYW2F7L2-DWxftYAm.js} +1 -1
  745. package/web/assets/{cynefinDiagram-TSTJHNR4-Dvqz2594.js → cynefinDiagram-TSTJHNR4-DsmN2V-p.js} +1 -1
  746. package/web/assets/{dagre-VKFMJZFB-Ju2m2qXt.js → dagre-VKFMJZFB-COEbApyY.js} +1 -1
  747. package/web/assets/{diagram-FQU43EPY-DsHKTt0k.js → diagram-FQU43EPY-0O9WGWKB.js} +1 -1
  748. package/web/assets/{diagram-G47NLZAW-DWHAcLkJ.js → diagram-G47NLZAW-CutEdMVh.js} +1 -1
  749. package/web/assets/{diagram-NH7WQ7WH-uUMz46ZD.js → diagram-NH7WQ7WH-C9KZc3B2.js} +1 -1
  750. package/web/assets/{diagram-OA4YK3LP-BRjVzjdp.js → diagram-OA4YK3LP-D8kkPXbY.js} +1 -1
  751. package/web/assets/{diagram-WEI45ONY-Cb-FhBpQ.js → diagram-WEI45ONY-_YqiTaGP.js} +1 -1
  752. package/web/assets/document-Dgt5eZFj.js +19 -0
  753. package/web/assets/{ebnfDiagram-CCIWWBDH-IhhxX3IB.js → ebnfDiagram-CCIWWBDH-JO-zQh6g.js} +1 -1
  754. package/web/assets/{entities-DUnx74kH.js → entities-C3wz7FCx.js} +12 -12
  755. package/web/assets/{erDiagram-Q63AITRT-D1frgeWf.js → erDiagram-Q63AITRT-9UjQwJ4P.js} +1 -1
  756. package/web/assets/file-viewer-DZJ8nYnl.js +1 -0
  757. package/web/assets/{flowDiagram-23GEKE2U-BiPPM-FY.js → flowDiagram-23GEKE2U-Ca08tnYM.js} +5 -5
  758. package/web/assets/folder-image-BfGgxo7i.js +1 -0
  759. package/web/assets/folder-landing-qUKBCnG-.js +54 -0
  760. package/web/assets/folder-list-BfFjv7rR.js +1 -0
  761. package/web/assets/folder-metadata-DCw8xzHk.js +2 -0
  762. package/web/assets/folder-mobile-bar-Ubz4babf.js +1 -0
  763. package/web/assets/folder-plugin-view-DsWR1zmQ.js +6 -0
  764. package/web/assets/{ganttDiagram-NO4QXBWP-CmEOlHD7.js → ganttDiagram-NO4QXBWP-KnHzX5W3.js} +1 -1
  765. package/web/assets/{gitGraphDiagram-IHSO6WYX-tTjcpZpU.js → gitGraphDiagram-IHSO6WYX-Cm8woNtK.js} +1 -1
  766. package/web/assets/index-BaRnbYRw.js +1 -0
  767. package/web/assets/index-BexmLxIP.css +1 -0
  768. package/web/assets/index-Bp9DidgD.js +1 -0
  769. package/web/assets/{index-eL1k96k8.js → index-CCXE8zc9.js} +1 -1
  770. package/web/assets/index-CNyy98F8.js +2 -0
  771. package/web/assets/{index-DmrKjrlM.js → index-CXhBn-ar.js} +1 -1
  772. package/web/assets/index-DDirZMgx.js +1 -0
  773. package/web/assets/{infoDiagram-FWYZ7A6U-Ok2sdbc1.js → infoDiagram-FWYZ7A6U-yyqmUtIb.js} +1 -1
  774. package/web/assets/{ishikawaDiagram-FXEZZL3T-kPnM5psX.js → ishikawaDiagram-FXEZZL3T-BfvR_Zy4.js} +4 -4
  775. package/web/assets/{journeyDiagram-5HDEW3XC-BkoT0-45.js → journeyDiagram-5HDEW3XC-BKuw06HM.js} +1 -1
  776. package/web/assets/{kanban-definition-HUTT4EX6-xnm_eFoU.js → kanban-definition-HUTT4EX6-n0010rmQ.js} +8 -8
  777. package/web/assets/{linear-CLZpgLH-.js → linear-C0d0lT8O.js} +1 -1
  778. package/web/assets/linked-session-header-BkEweU0Z.js +3 -0
  779. package/web/assets/{markdown-njUwQKsR.js → markdown-Bw9RgUGR.js} +9 -9
  780. package/web/assets/{mermaid.core-Bvxj3RoN.js → mermaid.core-BDVbShyO.js} +6 -6
  781. package/web/assets/metadata-KV0dpp4G.js +1 -0
  782. package/web/assets/{mindmap-definition-LN4V7U3C-42Uoox79.js → mindmap-definition-LN4V7U3C--_0ks3GF.js} +1 -1
  783. package/web/assets/note-card-DBfX6gW1.js +6 -0
  784. package/web/assets/{pegDiagram-2B236MQR-B-GZCw3w.js → pegDiagram-2B236MQR-CBoNIpKR.js} +1 -1
  785. package/web/assets/{pieDiagram-ENE6RG2P-DRmmssIB.js → pieDiagram-ENE6RG2P-MA5tkYh5.js} +3 -3
  786. package/web/assets/popover-DBD7FF-W.js +9 -0
  787. package/web/assets/{project-search-dialog-B730oZ1S.js → project-search-dialog-DM1IkSZu.js} +6 -6
  788. package/web/assets/{quadrantDiagram-ABIIQ3AL-BfhVQ7V9.js → quadrantDiagram-ABIIQ3AL-CWT1ryqF.js} +1 -1
  789. package/web/assets/{railroadDiagram-RFXS5EU6-DxKx7XRp.js → railroadDiagram-RFXS5EU6-ZiLB5FGi.js} +1 -1
  790. package/web/assets/{react-DZzLHL-l.js → react-B9jn2M18.js} +2 -2
  791. package/web/assets/{requirementDiagram-TGXJPOKE-NUzj9fw1.js → requirementDiagram-TGXJPOKE-CQq9uneq.js} +1 -1
  792. package/web/assets/{sankeyDiagram-HTMAVEWB-Cy9OMnl-.js → sankeyDiagram-HTMAVEWB-qDG-0JqI.js} +1 -1
  793. package/web/assets/search-DNrQA5fF.js +2 -0
  794. package/web/assets/select-D8cqNgcp.js +30 -0
  795. package/web/assets/selection-popup-DmtTeRs2.js +7 -0
  796. package/web/assets/{sequenceDiagram-DBY2YBRQ-CBNE9mzn.js → sequenceDiagram-DBY2YBRQ-CiApurLO.js} +1 -1
  797. package/web/assets/{sizeCapture-X5ZJPWSS-S4HhfX0n.js → sizeCapture-X5ZJPWSS-DZSR5QXm.js} +1 -1
  798. package/web/assets/stateDiagram-2N3HPSRC-CjJJR9_z.js +1 -0
  799. package/web/assets/stateDiagram-v2-6OUMAXLB-BpeGSCu9.js +1 -0
  800. package/web/assets/{swimlanes-5IMT3BWC-DJ2aLWal.js → swimlanes-5IMT3BWC-CKmo1sg6.js} +2 -2
  801. package/web/assets/swimlanesDiagram-G3AALYLV-D9RjLKb9.js +8 -0
  802. package/web/assets/tanstack-YzX_Mi37.js +3 -0
  803. package/web/assets/{timeline-definition-FHXFAJF6-vFDUVPCX.js → timeline-definition-FHXFAJF6-D-NMwS3y.js} +1 -1
  804. package/web/assets/{use-folder-filter-BbTUlXgG.js → use-folder-filter-LQyXns5Q.js} +1 -1
  805. package/web/assets/{utils-CwHGE3BB.js → utils-DCaHk0Gm.js} +1 -1
  806. package/web/assets/{vennDiagram-L72KCM5P-AsnhK2zW.js → vennDiagram-L72KCM5P-CfL6LBWw.js} +1 -1
  807. package/web/assets/view-context-gyDl_p2V.js +229 -0
  808. package/web/assets/viewer-capabilities-Bpp8Uvcg.js +1 -0
  809. package/web/assets/{wardleyDiagram-EHGQE667-Cj1wFbNV.js → wardleyDiagram-EHGQE667-DgldMxaj.js} +1 -1
  810. package/web/assets/{xychartDiagram-FW5EYKEG-Bbvnutsm.js → xychartDiagram-FW5EYKEG-CIoAIFX8.js} +1 -1
  811. package/web/favicon.svg +6 -0
  812. package/web/index.html +5 -4
  813. package/web/assets/app-CPSmsokP.js +0 -2
  814. package/web/assets/app-options-XEWvevsz.js +0 -25
  815. package/web/assets/app-view-header-BKZ90ToF.js +0 -1
  816. package/web/assets/arc-DbpbZvCt.js +0 -1
  817. package/web/assets/arrow-left-CFeHb-Z1.js +0 -1
  818. package/web/assets/ask-tray-D2YHtbPj.js +0 -14
  819. package/web/assets/button-BJ7z-ZA7.js +0 -1
  820. package/web/assets/calendar-days-DWh2XMO2.js +0 -1
  821. package/web/assets/channel-dSRp_qTo.js +0 -1
  822. package/web/assets/chevron-down-C5oRtqbX.js +0 -1
  823. package/web/assets/chevron-right-CsPtvh8C.js +0 -1
  824. package/web/assets/chevron-up-DjpU6Pyv.js +0 -1
  825. package/web/assets/classDiagram-OUVF2IWQ-B7B2zLzM.js +0 -1
  826. package/web/assets/classDiagram-v2-EOCWNBFH-B7B2zLzM.js +0 -1
  827. package/web/assets/client-CAudjYV9.js +0 -34
  828. package/web/assets/client-Dn9-_Gm_.js +0 -14
  829. package/web/assets/client-Dxrf2tyq.js +0 -102
  830. package/web/assets/client-aFI2M4pE.js +0 -53
  831. package/web/assets/collection-icon-TbOVyORG.js +0 -1
  832. package/web/assets/collection-page-Du6FKkuU.js +0 -10
  833. package/web/assets/command-C_g5E1Wx.js +0 -38
  834. package/web/assets/copy-Ikmr6Iq2.js +0 -1
  835. package/web/assets/copy-context-Cl1TE2PJ.js +0 -1
  836. package/web/assets/document-DcjNSJCk.js +0 -2
  837. package/web/assets/external-link-BXmSXqqF.js +0 -1
  838. package/web/assets/file-renderer-BRZTrYx8.js +0 -19
  839. package/web/assets/file-text-CiiSsCDq.js +0 -1
  840. package/web/assets/file-viewer-C1wAeVDK.js +0 -1
  841. package/web/assets/folder-image-AXBrHUcU.js +0 -1
  842. package/web/assets/folder-landing-BhRg7hwn.js +0 -54
  843. package/web/assets/folder-list-rIdszVde.js +0 -1
  844. package/web/assets/folder-metadata-puTC5QqJ.js +0 -2
  845. package/web/assets/folder-mobile-bar-DjjRQo3T.js +0 -1
  846. package/web/assets/folder-plugin-view-BU_kzR8j.js +0 -6
  847. package/web/assets/index-DS2Wmd9I.css +0 -1
  848. package/web/assets/index-DgqzSeIR.js +0 -1
  849. package/web/assets/index-DnlTDqaa.js +0 -1
  850. package/web/assets/index-DztTMDFz.js +0 -2
  851. package/web/assets/index-kY75qc96.js +0 -1
  852. package/web/assets/index-p38i_yyY.js +0 -1
  853. package/web/assets/link-2-BWKA6t--.js +0 -1
  854. package/web/assets/link-DC_1Z6Yy.js +0 -11
  855. package/web/assets/linked-session-header-DJYWZ_-q.js +0 -3
  856. package/web/assets/mail-2rCdIFul.js +0 -1
  857. package/web/assets/markdown-title-dncAYYiP.js +0 -131
  858. package/web/assets/notes-page-DIW6rgJp.js +0 -10
  859. package/web/assets/pencil-8cobiSSq.js +0 -1
  860. package/web/assets/plus-BHV2wJr7.js +0 -1
  861. package/web/assets/popover-Cmmgj-MJ.js +0 -9
  862. package/web/assets/search-CvlYUkN6.js +0 -2
  863. package/web/assets/select-1SvaKQsS.js +0 -30
  864. package/web/assets/selection-popup-ntjycEVh.js +0 -7
  865. package/web/assets/sparkles-CBhGREdc.js +0 -1
  866. package/web/assets/stateDiagram-2N3HPSRC-BEw1Mheu.js +0 -1
  867. package/web/assets/stateDiagram-v2-6OUMAXLB-BHtjl1iD.js +0 -1
  868. package/web/assets/swimlanesDiagram-G3AALYLV-Z362aroZ.js +0 -8
  869. package/web/assets/tanstack-CD46mJkU.js +0 -1
  870. package/web/assets/view-context-D-fh9AbH.js +0 -81
  871. package/web/assets/viewer-capabilities-CROIaoqh.js +0 -1
  872. package/web/assets/x-BUeE--I4.js +0 -1
@@ -0,0 +1,1380 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { ClientSideConnection, PROTOCOL_VERSION, agent as createAgentApp, client as createClientApp, methods, } from "./acp.js";
3
+ import { MemoryAcpCookieStore, createHttpStream } from "./http-stream.js";
4
+ import { EVENT_STREAM_MIME_TYPE, HEADER_CONNECTION_ID, HEADER_SESSION_ID, JSON_MIME_TYPE, } from "./protocol.js";
5
+ import { serializeSseEvent } from "./sse.js";
6
+ import { createTestAgentApp } from "./test-support/test-agent.js";
7
+ import { startTestServer } from "./test-support/test-http-server.js";
8
+ const initializeRequest = {
9
+ jsonrpc: "2.0",
10
+ id: 0,
11
+ method: "initialize",
12
+ params: {
13
+ protocolVersion: PROTOCOL_VERSION,
14
+ clientCapabilities: {},
15
+ },
16
+ };
17
+ const initializeResponse = {
18
+ jsonrpc: "2.0",
19
+ id: 0,
20
+ result: {
21
+ protocolVersion: PROTOCOL_VERSION,
22
+ agentCapabilities: {
23
+ loadSession: false,
24
+ },
25
+ },
26
+ };
27
+ const sessionNewResponse = {
28
+ jsonrpc: "2.0",
29
+ id: 1,
30
+ result: {
31
+ sessionId: "session-1",
32
+ },
33
+ };
34
+ const sessionNewRequest = {
35
+ jsonrpc: "2.0",
36
+ id: 1,
37
+ method: "session/new",
38
+ params: {
39
+ cwd: "/tmp",
40
+ mcpServers: [],
41
+ },
42
+ };
43
+ const promptRequest = {
44
+ jsonrpc: "2.0",
45
+ id: 2,
46
+ method: "session/prompt",
47
+ params: {
48
+ sessionId: "session-1",
49
+ prompt: [{ type: "text", text: "Hello" }],
50
+ },
51
+ };
52
+ const loadSessionRequest = {
53
+ jsonrpc: "2.0",
54
+ id: 3,
55
+ method: "session/load",
56
+ params: {
57
+ cwd: "/tmp",
58
+ mcpServers: [],
59
+ sessionId: "existing-session",
60
+ },
61
+ };
62
+ const permissionRequest = {
63
+ jsonrpc: "2.0",
64
+ id: 99,
65
+ method: "session/request_permission",
66
+ params: {
67
+ sessionId: "session-1",
68
+ toolCall: {
69
+ toolCallId: "permission-tool",
70
+ title: "Permission tool",
71
+ },
72
+ options: [
73
+ {
74
+ kind: "allow_once",
75
+ name: "Allow once",
76
+ optionId: "allow",
77
+ },
78
+ ],
79
+ },
80
+ };
81
+ const permissionResponse = {
82
+ jsonrpc: "2.0",
83
+ id: 99,
84
+ result: {
85
+ outcome: {
86
+ outcome: "selected",
87
+ optionId: "allow",
88
+ },
89
+ },
90
+ };
91
+ const connectionScopedServerRequest = {
92
+ jsonrpc: "2.0",
93
+ id: 99,
94
+ method: "connection/example",
95
+ params: {},
96
+ };
97
+ describe("createHttpStream", () => {
98
+ it("posts initialize with custom headers, opens connection SSE, and emits the initialize response", async () => {
99
+ const controlledFetch = createControlledFetch();
100
+ const stream = createHttpStream("https://agent.example/acp", {
101
+ fetch: controlledFetch.fetch,
102
+ headers: {
103
+ Authorization: "Bearer token",
104
+ "X-Test-Header": "phase-5",
105
+ },
106
+ });
107
+ const writer = stream.writable.getWriter();
108
+ const reader = stream.readable.getReader();
109
+ try {
110
+ await writer.write(initializeRequest);
111
+ expect(await readMessage(reader)).toEqual(initializeResponse);
112
+ expect(controlledFetch.requests).toHaveLength(2);
113
+ const initializePost = requestAt(controlledFetch.requests, 0);
114
+ expect(initializePost.url).toBe("https://agent.example/acp");
115
+ expect(initializePost.method).toBe("POST");
116
+ expect(initializePost.headers.get("Authorization")).toBe("Bearer token");
117
+ expect(initializePost.headers.get("X-Test-Header")).toBe("phase-5");
118
+ expect(initializePost.headers.get("Content-Type")).toBe(JSON_MIME_TYPE);
119
+ expect(initializePost.headers.get(HEADER_CONNECTION_ID)).toBeNull();
120
+ expect(JSON.parse(initializePost.body)).toEqual(initializeRequest);
121
+ const connectionGet = requestAt(controlledFetch.requests, 1);
122
+ expect(connectionGet.method).toBe("GET");
123
+ expect(connectionGet.headers.get("Authorization")).toBe("Bearer token");
124
+ expect(connectionGet.headers.get("Accept")).toBe(EVENT_STREAM_MIME_TYPE);
125
+ expect(connectionGet.headers.get(HEADER_CONNECTION_ID)).toBe("connection-1");
126
+ expect(connectionGet.headers.get(HEADER_SESSION_ID)).toBeNull();
127
+ }
128
+ finally {
129
+ reader.releaseLock();
130
+ writer.releaseLock();
131
+ await stream.writable.close();
132
+ }
133
+ });
134
+ it("errors and clears local resources when initialize POST fails", async () => {
135
+ const clearSpy = vi.spyOn(MemoryAcpCookieStore.prototype, "clear");
136
+ const controlledFetch = createControlledFetch({
137
+ initializeCookies: ["transport=alpha; Path=/"],
138
+ initializeStatus: 401,
139
+ initializeBody: "expired",
140
+ });
141
+ const stream = createHttpStream("https://agent.example/acp", {
142
+ fetch: controlledFetch.fetch,
143
+ });
144
+ const writer = stream.writable.getWriter();
145
+ const reader = stream.readable.getReader();
146
+ try {
147
+ await expect(writer.write(initializeRequest)).rejects.toThrow("ACP initialize failed: 401");
148
+ expect(controlledFetch.requests).toHaveLength(1);
149
+ await flushMicrotasks();
150
+ expect(clearSpy).toHaveBeenCalledTimes(1);
151
+ await expect(reader.read()).rejects.toThrow("ACP initialize failed");
152
+ }
153
+ finally {
154
+ clearSpy.mockRestore();
155
+ reader.releaseLock();
156
+ writer.releaseLock();
157
+ await closeStream(stream);
158
+ }
159
+ });
160
+ it("aborts and deletes late initialize connections when canceled during initialize POST", async () => {
161
+ const clearSpy = vi.spyOn(MemoryAcpCookieStore.prototype, "clear");
162
+ const initializeResponseDeferred = createDeferred();
163
+ const requests = [];
164
+ const fetch = async (_input, init) => {
165
+ const method = init?.method ?? "GET";
166
+ const headers = new Headers(init?.headers);
167
+ requests.push({
168
+ method,
169
+ headers,
170
+ signal: init?.signal,
171
+ });
172
+ if (method === "POST" && !headers.has(HEADER_CONNECTION_ID)) {
173
+ return await initializeResponseDeferred.promise;
174
+ }
175
+ if (method === "DELETE") {
176
+ return new Response(null, { status: 202 });
177
+ }
178
+ throw new Error(`Unexpected ${method} request`);
179
+ };
180
+ const stream = createHttpStream("https://agent.example/acp", { fetch });
181
+ const writer = stream.writable.getWriter();
182
+ try {
183
+ const write = writer.write(initializeRequest);
184
+ await flushMicrotasks();
185
+ expect(requests).toHaveLength(1);
186
+ expect(requests[0].signal?.aborted).toBe(false);
187
+ stream.readable.cancel().catch(() => undefined);
188
+ await flushMicrotasks();
189
+ expect(requests[0].signal?.aborted).toBe(true);
190
+ initializeResponseDeferred.resolve(jsonResponse(initializeResponse, 200, {
191
+ [HEADER_CONNECTION_ID]: "connection-1",
192
+ ...setCookieResponseHeaders(["transport=alpha; Path=/"]),
193
+ }));
194
+ await expect(write).rejects.toThrow("ACP HTTP stream is closed");
195
+ expect(requests).toHaveLength(2);
196
+ expect(requests[1].method).toBe("DELETE");
197
+ expect(requests[1].headers.get(HEADER_CONNECTION_ID)).toBe("connection-1");
198
+ expect(requests[1].headers.get("Cookie")).toBe("transport=alpha");
199
+ expect(clearSpy).toHaveBeenCalledTimes(2);
200
+ }
201
+ finally {
202
+ clearSpy.mockRestore();
203
+ writer.releaseLock();
204
+ await closeStream(stream);
205
+ }
206
+ });
207
+ it("deletes the initialized connection when the initialize body is not a response", async () => {
208
+ const clearSpy = vi.spyOn(MemoryAcpCookieStore.prototype, "clear");
209
+ const controlledFetch = createControlledFetch({
210
+ initializeCookies: ["transport=alpha; Path=/"],
211
+ initializeResponse: {
212
+ jsonrpc: "2.0",
213
+ id: 0,
214
+ method: "session/new",
215
+ params: {},
216
+ },
217
+ });
218
+ const stream = createHttpStream("https://agent.example/acp", {
219
+ fetch: controlledFetch.fetch,
220
+ });
221
+ const writer = stream.writable.getWriter();
222
+ const reader = stream.readable.getReader();
223
+ try {
224
+ await expect(writer.write(initializeRequest)).rejects.toThrow("ACP initialize response was not a JSON-RPC response");
225
+ const deleteRequest = requestAt(controlledFetch.requests, 1);
226
+ expect(deleteRequest.method).toBe("DELETE");
227
+ expect(deleteRequest.headers.get(HEADER_CONNECTION_ID)).toBe("connection-1");
228
+ expect(deleteRequest.headers.get("Cookie")).toBe("transport=alpha");
229
+ expect(controlledFetch.sseRequests).toHaveLength(0);
230
+ await flushMicrotasks();
231
+ expect(clearSpy).toHaveBeenCalledTimes(1);
232
+ await expect(reader.read()).rejects.toThrow("ACP initialize response was not a JSON-RPC response");
233
+ }
234
+ finally {
235
+ clearSpy.mockRestore();
236
+ reader.releaseLock();
237
+ writer.releaseLock();
238
+ await closeStream(stream);
239
+ }
240
+ });
241
+ it("deletes the initialized connection when the initialize response id does not match", async () => {
242
+ const clearSpy = vi.spyOn(MemoryAcpCookieStore.prototype, "clear");
243
+ const controlledFetch = createControlledFetch({
244
+ initializeCookies: ["transport=alpha; Path=/"],
245
+ initializeResponse: {
246
+ ...initializeResponse,
247
+ id: 999,
248
+ },
249
+ });
250
+ const stream = createHttpStream("https://agent.example/acp", {
251
+ fetch: controlledFetch.fetch,
252
+ });
253
+ const writer = stream.writable.getWriter();
254
+ const reader = stream.readable.getReader();
255
+ try {
256
+ await expect(writer.write(initializeRequest)).rejects.toThrow("ACP initialize response id did not match initialize request");
257
+ const deleteRequest = requestAt(controlledFetch.requests, 1);
258
+ expect(deleteRequest.method).toBe("DELETE");
259
+ expect(deleteRequest.headers.get(HEADER_CONNECTION_ID)).toBe("connection-1");
260
+ expect(deleteRequest.headers.get("Cookie")).toBe("transport=alpha");
261
+ expect(controlledFetch.sseRequests).toHaveLength(0);
262
+ await flushMicrotasks();
263
+ expect(clearSpy).toHaveBeenCalledTimes(1);
264
+ await expect(reader.read()).rejects.toThrow("ACP initialize response id did not match initialize request");
265
+ }
266
+ finally {
267
+ clearSpy.mockRestore();
268
+ reader.releaseLock();
269
+ writer.releaseLock();
270
+ await closeStream(stream);
271
+ }
272
+ });
273
+ it("opens session SSE after session creation and includes the session header on session-scoped POSTs", async () => {
274
+ const controlledFetch = createControlledFetch();
275
+ const stream = createHttpStream("https://agent.example/acp", {
276
+ fetch: controlledFetch.fetch,
277
+ });
278
+ const writer = stream.writable.getWriter();
279
+ const reader = stream.readable.getReader();
280
+ try {
281
+ await writer.write(initializeRequest);
282
+ await readMessage(reader);
283
+ await controlledFetch.sendSse(0, sessionNewResponse);
284
+ expect(await readMessage(reader)).toEqual(sessionNewResponse);
285
+ expect(controlledFetch.requests).toHaveLength(3);
286
+ const sessionGet = requestAt(controlledFetch.requests, 2);
287
+ expect(sessionGet.method).toBe("GET");
288
+ expect(sessionGet.headers.get(HEADER_CONNECTION_ID)).toBe("connection-1");
289
+ expect(sessionGet.headers.get(HEADER_SESSION_ID)).toBe("session-1");
290
+ await writer.write(promptRequest);
291
+ const promptPost = requestAt(controlledFetch.requests, 3);
292
+ expect(promptPost.method).toBe("POST");
293
+ expect(promptPost.headers.get(HEADER_CONNECTION_ID)).toBe("connection-1");
294
+ expect(promptPost.headers.get(HEADER_SESSION_ID)).toBe("session-1");
295
+ expect(JSON.parse(promptPost.body)).toEqual(promptRequest);
296
+ }
297
+ finally {
298
+ reader.releaseLock();
299
+ writer.releaseLock();
300
+ await stream.writable.close();
301
+ }
302
+ });
303
+ it("rejects JSON-RPC batches received over SSE before dispatch", async () => {
304
+ const controlledFetch = createControlledFetch();
305
+ const stream = createHttpStream("https://agent.example/acp", {
306
+ fetch: controlledFetch.fetch,
307
+ });
308
+ const writer = stream.writable.getWriter();
309
+ const reader = stream.readable.getReader();
310
+ try {
311
+ await writer.write(initializeRequest);
312
+ await readMessage(reader);
313
+ await controlledFetch.sendSse(0, sessionNewResponse);
314
+ await readMessage(reader);
315
+ await controlledFetch.sendSse(1, [
316
+ permissionRequest,
317
+ ]);
318
+ await expect(reader.read()).rejects.toThrow("ACP HTTP transport does not support JSON-RPC batch messages");
319
+ }
320
+ finally {
321
+ reader.releaseLock();
322
+ writer.releaseLock();
323
+ await closeStream(stream);
324
+ }
325
+ });
326
+ it("rejects outbound JSON-RPC batches before POSTing them", async () => {
327
+ const controlledFetch = createControlledFetch();
328
+ const stream = createHttpStream("https://agent.example/acp", {
329
+ fetch: controlledFetch.fetch,
330
+ });
331
+ const writer = stream.writable.getWriter();
332
+ const reader = stream.readable.getReader();
333
+ try {
334
+ await writer.write(initializeRequest);
335
+ await readMessage(reader);
336
+ await expect(writer.write([sessionNewRequest])).rejects.toThrow("ACP HTTP transport does not support JSON-RPC batch messages");
337
+ expect(controlledFetch.requests).toHaveLength(2);
338
+ }
339
+ finally {
340
+ await reader.cancel().catch(() => undefined);
341
+ reader.releaseLock();
342
+ writer.releaseLock();
343
+ await closeStream(stream);
344
+ }
345
+ });
346
+ it("errors the stream when the connection SSE closes cleanly", async () => {
347
+ const controlledFetch = createControlledFetch();
348
+ const stream = createHttpStream("https://agent.example/acp", {
349
+ fetch: controlledFetch.fetch,
350
+ });
351
+ const writer = stream.writable.getWriter();
352
+ const reader = stream.readable.getReader();
353
+ try {
354
+ await writer.write(initializeRequest);
355
+ await readMessage(reader);
356
+ await controlledFetch.closeSse(0);
357
+ await expect(reader.read()).rejects.toThrow("ACP connection SSE stream closed");
358
+ }
359
+ finally {
360
+ reader.releaseLock();
361
+ writer.releaseLock();
362
+ await closeStream(stream);
363
+ }
364
+ });
365
+ it("waits for a reopened session SSE before posting session-scoped messages", async () => {
366
+ const reopenedSessionSseResponse = createDeferred();
367
+ const controlledFetch = createControlledFetch({
368
+ sseResponseDelays: new Map([[2, reopenedSessionSseResponse.promise]]),
369
+ });
370
+ const stream = createHttpStream("https://agent.example/acp", {
371
+ fetch: controlledFetch.fetch,
372
+ });
373
+ const writer = stream.writable.getWriter();
374
+ const reader = stream.readable.getReader();
375
+ try {
376
+ await writer.write(initializeRequest);
377
+ await readMessage(reader);
378
+ await controlledFetch.sendSse(0, sessionNewResponse);
379
+ await readMessage(reader);
380
+ await controlledFetch.closeSse(1);
381
+ await flushMicrotasks();
382
+ const promptWrite = writer.write(promptRequest);
383
+ await flushMicrotasks();
384
+ const reopenedSessionGet = requestAt(controlledFetch.requests, 3);
385
+ expect(reopenedSessionGet.method).toBe("GET");
386
+ expect(reopenedSessionGet.headers.get(HEADER_CONNECTION_ID)).toBe("connection-1");
387
+ expect(reopenedSessionGet.headers.get(HEADER_SESSION_ID)).toBe("session-1");
388
+ expect(controlledFetch.requests).toHaveLength(4);
389
+ reopenedSessionSseResponse.resolve();
390
+ await promptWrite;
391
+ const promptPost = requestAt(controlledFetch.requests, 4);
392
+ expect(promptPost.method).toBe("POST");
393
+ expect(promptPost.headers.get(HEADER_SESSION_ID)).toBe("session-1");
394
+ }
395
+ finally {
396
+ reader.releaseLock();
397
+ writer.releaseLock();
398
+ await closeStream(stream);
399
+ }
400
+ });
401
+ it("errors the stream when a session SSE closes with a pending request", async () => {
402
+ const controlledFetch = createControlledFetch();
403
+ const stream = createHttpStream("https://agent.example/acp", {
404
+ fetch: controlledFetch.fetch,
405
+ });
406
+ const writer = stream.writable.getWriter();
407
+ const reader = stream.readable.getReader();
408
+ try {
409
+ await writer.write(initializeRequest);
410
+ await readMessage(reader);
411
+ await controlledFetch.sendSse(0, sessionNewResponse);
412
+ await readMessage(reader);
413
+ await writer.write(promptRequest);
414
+ await controlledFetch.closeSse(1);
415
+ await expect(reader.read()).rejects.toThrow("ACP session SSE stream closed");
416
+ }
417
+ finally {
418
+ reader.releaseLock();
419
+ writer.releaseLock();
420
+ await closeStream(stream);
421
+ }
422
+ });
423
+ it("opens session SSE before posting session/load for an existing session", async () => {
424
+ const controlledFetch = createControlledFetch();
425
+ const stream = createHttpStream("https://agent.example/acp", {
426
+ fetch: controlledFetch.fetch,
427
+ });
428
+ const writer = stream.writable.getWriter();
429
+ const reader = stream.readable.getReader();
430
+ try {
431
+ await writer.write(initializeRequest);
432
+ await readMessage(reader);
433
+ await writer.write(loadSessionRequest);
434
+ const sessionGet = requestAt(controlledFetch.requests, 2);
435
+ const loadPost = requestAt(controlledFetch.requests, 3);
436
+ expect(sessionGet.method).toBe("GET");
437
+ expect(sessionGet.headers.get(HEADER_CONNECTION_ID)).toBe("connection-1");
438
+ expect(sessionGet.headers.get(HEADER_SESSION_ID)).toBe("existing-session");
439
+ expect(loadPost.method).toBe("POST");
440
+ expect(loadPost.headers.get(HEADER_CONNECTION_ID)).toBe("connection-1");
441
+ expect(loadPost.headers.get(HEADER_SESSION_ID)).toBe("existing-session");
442
+ }
443
+ finally {
444
+ reader.releaseLock();
445
+ writer.releaseLock();
446
+ await stream.writable.close();
447
+ }
448
+ });
449
+ it("includes the session header only on responses to session-scoped server requests", async () => {
450
+ const controlledFetch = createControlledFetch();
451
+ const stream = createHttpStream("https://agent.example/acp", {
452
+ fetch: controlledFetch.fetch,
453
+ });
454
+ const writer = stream.writable.getWriter();
455
+ const reader = stream.readable.getReader();
456
+ try {
457
+ await writer.write(initializeRequest);
458
+ await readMessage(reader);
459
+ await controlledFetch.sendSse(0, sessionNewResponse);
460
+ await readMessage(reader);
461
+ await controlledFetch.sendSse(1, permissionRequest);
462
+ await readMessage(reader);
463
+ await writer.write(permissionResponse);
464
+ const responsePost = requestAt(controlledFetch.requests, 3);
465
+ expect(responsePost.method).toBe("POST");
466
+ expect(responsePost.headers.get(HEADER_CONNECTION_ID)).toBe("connection-1");
467
+ expect(responsePost.headers.get(HEADER_SESSION_ID)).toBe("session-1");
468
+ expect(JSON.parse(responsePost.body)).toEqual(permissionResponse);
469
+ await controlledFetch.sendSse(0, connectionScopedServerRequest);
470
+ await readMessage(reader);
471
+ await writer.write(permissionResponse);
472
+ const connectionResponsePost = requestAt(controlledFetch.requests, 4);
473
+ expect(connectionResponsePost.method).toBe("POST");
474
+ expect(connectionResponsePost.headers.get(HEADER_CONNECTION_ID)).toBe("connection-1");
475
+ expect(connectionResponsePost.headers.get(HEADER_SESSION_ID)).toBeNull();
476
+ expect(JSON.parse(connectionResponsePost.body)).toEqual(permissionResponse);
477
+ }
478
+ finally {
479
+ reader.releaseLock();
480
+ writer.releaseLock();
481
+ await stream.writable.close();
482
+ }
483
+ });
484
+ it("propagates cookies across initialize, SSE, session POST, and DELETE", async () => {
485
+ const controlledFetch = createControlledFetch({
486
+ initializeCookies: ["transport=alpha; Path=/"],
487
+ getCookies: ["route=bravo; Path=/"],
488
+ });
489
+ const stream = createHttpStream("https://agent.example/acp", {
490
+ fetch: controlledFetch.fetch,
491
+ headers: {
492
+ Cookie: "caller=custom; transport=caller",
493
+ },
494
+ });
495
+ const writer = stream.writable.getWriter();
496
+ const reader = stream.readable.getReader();
497
+ try {
498
+ await writer.write(initializeRequest);
499
+ await readMessage(reader);
500
+ await controlledFetch.sendSse(0, sessionNewResponse);
501
+ await readMessage(reader);
502
+ await writer.write(promptRequest);
503
+ await writer.close();
504
+ expect(requestAt(controlledFetch.requests, 0).credentials).toBe("include");
505
+ expect(requestAt(controlledFetch.requests, 0).headers.get("Cookie")).toBe("caller=custom; transport=caller");
506
+ expect(requestAt(controlledFetch.requests, 1).headers.get("Cookie")).toBe("transport=caller; caller=custom");
507
+ expect(requestAt(controlledFetch.requests, 2).headers.get("Cookie")).toBe("transport=caller; route=bravo; caller=custom");
508
+ expect(requestAt(controlledFetch.requests, 3).headers.get("Cookie")).toBe("transport=caller; route=bravo; caller=custom");
509
+ expect(requestAt(controlledFetch.requests, 4).headers.get("Cookie")).toBe("transport=caller; route=bravo; caller=custom");
510
+ expect(controlledFetch.requests.map((request) => request.credentials)).toEqual(["include", "include", "include", "include", "include"]);
511
+ }
512
+ finally {
513
+ reader.releaseLock();
514
+ writer.releaseLock();
515
+ }
516
+ });
517
+ it("omits managed cookies when cookie handling is disabled", async () => {
518
+ const controlledFetch = createControlledFetch({
519
+ initializeCookies: ["transport=alpha; Path=/"],
520
+ });
521
+ const stream = createHttpStream("https://agent.example/acp", {
522
+ fetch: controlledFetch.fetch,
523
+ cookies: "omit",
524
+ });
525
+ const writer = stream.writable.getWriter();
526
+ const reader = stream.readable.getReader();
527
+ try {
528
+ await writer.write(initializeRequest);
529
+ await readMessage(reader);
530
+ expect(requestAt(controlledFetch.requests, 0).credentials).toBe("omit");
531
+ expect(requestAt(controlledFetch.requests, 1).credentials).toBe("omit");
532
+ expect(requestAt(controlledFetch.requests, 1).headers.get("Cookie")).toBeNull();
533
+ }
534
+ finally {
535
+ reader.releaseLock();
536
+ writer.releaseLock();
537
+ await stream.writable.close();
538
+ }
539
+ });
540
+ it("clears SDK-owned ephemeral cookies when the stream errors", async () => {
541
+ const clearSpy = vi.spyOn(MemoryAcpCookieStore.prototype, "clear");
542
+ const controlledFetch = createControlledFetch({
543
+ initializeCookies: ["transport=alpha; Path=/"],
544
+ getStatus: 500,
545
+ });
546
+ const stream = createHttpStream("https://agent.example/acp", {
547
+ fetch: controlledFetch.fetch,
548
+ });
549
+ const writer = stream.writable.getWriter();
550
+ const reader = stream.readable.getReader();
551
+ try {
552
+ await writer.write(initializeRequest);
553
+ expect(await readMessage(reader)).toEqual(initializeResponse);
554
+ await expect(reader.read()).rejects.toThrow("ACP SSE connection failed");
555
+ expect(clearSpy).toHaveBeenCalledTimes(1);
556
+ }
557
+ finally {
558
+ clearSpy.mockRestore();
559
+ reader.releaseLock();
560
+ writer.releaseLock();
561
+ await stream.writable.close();
562
+ }
563
+ });
564
+ it("preserves caller-owned cookies when the stream errors", async () => {
565
+ const cookieStore = new MemoryAcpCookieStore();
566
+ const clearSpy = vi.spyOn(cookieStore, "clear");
567
+ const firstFetch = createControlledFetch({
568
+ initializeCookies: ["transport=alpha; Path=/"],
569
+ getStatus: 500,
570
+ });
571
+ const firstStream = createHttpStream("https://agent.example/acp", {
572
+ fetch: firstFetch.fetch,
573
+ cookieStore,
574
+ });
575
+ const firstWriter = firstStream.writable.getWriter();
576
+ const firstReader = firstStream.readable.getReader();
577
+ try {
578
+ await firstWriter.write(initializeRequest);
579
+ expect(await readMessage(firstReader)).toEqual(initializeResponse);
580
+ await expect(firstReader.read()).rejects.toThrow("ACP SSE connection failed");
581
+ expect(clearSpy).not.toHaveBeenCalled();
582
+ }
583
+ finally {
584
+ clearSpy.mockRestore();
585
+ firstReader.releaseLock();
586
+ firstWriter.releaseLock();
587
+ await firstStream.writable.close();
588
+ }
589
+ const secondFetch = createControlledFetch();
590
+ const secondStream = createHttpStream("https://agent.example/acp", {
591
+ fetch: secondFetch.fetch,
592
+ cookieStore,
593
+ });
594
+ const secondWriter = secondStream.writable.getWriter();
595
+ const secondReader = secondStream.readable.getReader();
596
+ try {
597
+ await secondWriter.write(initializeRequest);
598
+ await readMessage(secondReader);
599
+ expect(requestAt(secondFetch.requests, 0).headers.get("Cookie")).toBe("transport=alpha");
600
+ }
601
+ finally {
602
+ secondReader.releaseLock();
603
+ secondWriter.releaseLock();
604
+ await secondStream.writable.close();
605
+ }
606
+ });
607
+ it("preserves caller-owned cookies across separate stream instances", async () => {
608
+ const cookieStore = new MemoryAcpCookieStore();
609
+ const firstFetch = createControlledFetch({
610
+ initializeCookies: ["transport=alpha; Path=/"],
611
+ });
612
+ const firstStream = createHttpStream("https://agent.example/acp", {
613
+ fetch: firstFetch.fetch,
614
+ cookieStore,
615
+ });
616
+ const firstWriter = firstStream.writable.getWriter();
617
+ const firstReader = firstStream.readable.getReader();
618
+ try {
619
+ await firstWriter.write(initializeRequest);
620
+ await readMessage(firstReader);
621
+ await firstWriter.close();
622
+ }
623
+ finally {
624
+ firstReader.releaseLock();
625
+ firstWriter.releaseLock();
626
+ }
627
+ const secondFetch = createControlledFetch();
628
+ const secondStream = createHttpStream("https://agent.example/acp", {
629
+ fetch: secondFetch.fetch,
630
+ cookieStore,
631
+ });
632
+ const secondWriter = secondStream.writable.getWriter();
633
+ const secondReader = secondStream.readable.getReader();
634
+ try {
635
+ await secondWriter.write(initializeRequest);
636
+ await readMessage(secondReader);
637
+ expect(requestAt(secondFetch.requests, 0).headers.get("Cookie")).toBe("transport=alpha");
638
+ }
639
+ finally {
640
+ secondReader.releaseLock();
641
+ secondWriter.releaseLock();
642
+ await secondStream.writable.close();
643
+ }
644
+ });
645
+ it("clears SDK-owned ephemeral cookies when the stream closes", async () => {
646
+ const firstFetch = createControlledFetch({
647
+ initializeCookies: ["transport=alpha; Path=/"],
648
+ });
649
+ const firstStream = createHttpStream("https://agent.example/acp", {
650
+ fetch: firstFetch.fetch,
651
+ });
652
+ const firstWriter = firstStream.writable.getWriter();
653
+ const firstReader = firstStream.readable.getReader();
654
+ try {
655
+ await firstWriter.write(initializeRequest);
656
+ await readMessage(firstReader);
657
+ await firstWriter.close();
658
+ }
659
+ finally {
660
+ firstReader.releaseLock();
661
+ firstWriter.releaseLock();
662
+ }
663
+ const secondFetch = createControlledFetch();
664
+ const secondStream = createHttpStream("https://agent.example/acp", {
665
+ fetch: secondFetch.fetch,
666
+ });
667
+ const secondWriter = secondStream.writable.getWriter();
668
+ const secondReader = secondStream.readable.getReader();
669
+ try {
670
+ await secondWriter.write(initializeRequest);
671
+ await readMessage(secondReader);
672
+ expect(requestAt(secondFetch.requests, 0).headers.get("Cookie")).toBeNull();
673
+ }
674
+ finally {
675
+ secondReader.releaseLock();
676
+ secondWriter.releaseLock();
677
+ await secondStream.writable.close();
678
+ }
679
+ });
680
+ it("lets caller Cookie headers override caller-owned store values", async () => {
681
+ const cookieStore = new MemoryAcpCookieStore();
682
+ cookieStore.store(headersWithSetCookie(["transport=alpha", "route=bravo"]));
683
+ const controlledFetch = createControlledFetch();
684
+ const stream = createHttpStream("https://agent.example/acp", {
685
+ fetch: controlledFetch.fetch,
686
+ cookieStore,
687
+ headers: {
688
+ Cookie: "route=caller; caller=custom",
689
+ },
690
+ });
691
+ const writer = stream.writable.getWriter();
692
+ const reader = stream.readable.getReader();
693
+ try {
694
+ await writer.write(initializeRequest);
695
+ await readMessage(reader);
696
+ expect(requestAt(controlledFetch.requests, 0).headers.get("Cookie")).toBe("transport=alpha; route=caller; caller=custom");
697
+ }
698
+ finally {
699
+ reader.releaseLock();
700
+ writer.releaseLock();
701
+ await stream.writable.close();
702
+ }
703
+ });
704
+ it("sends DELETE and aborts SSE requests when closed", async () => {
705
+ const controlledFetch = createControlledFetch();
706
+ const stream = createHttpStream("https://agent.example/acp", {
707
+ fetch: controlledFetch.fetch,
708
+ });
709
+ const writer = stream.writable.getWriter();
710
+ const reader = stream.readable.getReader();
711
+ try {
712
+ await writer.write(initializeRequest);
713
+ await readMessage(reader);
714
+ await writer.close();
715
+ const deleteRequest = requestAt(controlledFetch.requests, 2);
716
+ expect(deleteRequest.method).toBe("DELETE");
717
+ expect(deleteRequest.headers.get(HEADER_CONNECTION_ID)).toBe("connection-1");
718
+ expect(sseAt(controlledFetch.sseRequests, 0).signal.aborted).toBe(true);
719
+ }
720
+ finally {
721
+ reader.releaseLock();
722
+ writer.releaseLock();
723
+ }
724
+ });
725
+ it("aborts active SSE requests before awaiting DELETE on close", async () => {
726
+ const deleteStarted = createDeferred();
727
+ const allowDelete = createDeferred();
728
+ let sseSignal;
729
+ const fetch = async (_input, init) => {
730
+ const method = init?.method ?? "GET";
731
+ const headers = new Headers(init?.headers);
732
+ if (method === "POST" && !headers.has(HEADER_CONNECTION_ID)) {
733
+ return jsonResponse(initializeResponse, 200, {
734
+ [HEADER_CONNECTION_ID]: "connection-1",
735
+ });
736
+ }
737
+ if (method === "GET") {
738
+ sseSignal = init?.signal;
739
+ return sseResponse(sseSignal);
740
+ }
741
+ if (method === "DELETE") {
742
+ deleteStarted.resolve();
743
+ await allowDelete.promise;
744
+ return new Response(null, { status: 202 });
745
+ }
746
+ throw new Error(`Unexpected ${method} request`);
747
+ };
748
+ const stream = createHttpStream("https://agent.example/acp", { fetch });
749
+ const writer = stream.writable.getWriter();
750
+ const reader = stream.readable.getReader();
751
+ let closePromise;
752
+ try {
753
+ await writer.write(initializeRequest);
754
+ await readMessage(reader);
755
+ closePromise = writer.close();
756
+ await deleteStarted.promise;
757
+ expect(sseSignal?.aborted).toBe(true);
758
+ allowDelete.resolve();
759
+ await closePromise;
760
+ }
761
+ finally {
762
+ allowDelete.resolve();
763
+ reader.releaseLock();
764
+ writer.releaseLock();
765
+ await closePromise?.catch(() => undefined);
766
+ await closeStream(stream);
767
+ }
768
+ });
769
+ it("aborts in-flight connected POSTs when closed", async () => {
770
+ const connectedPostAborted = createDeferred();
771
+ const requests = [];
772
+ const fetch = async (input, init) => {
773
+ const method = init?.method ?? "GET";
774
+ const headers = new Headers(init?.headers);
775
+ const signal = init?.signal;
776
+ requests.push({
777
+ url: String(input),
778
+ method,
779
+ headers,
780
+ body: bodyToString(init?.body),
781
+ credentials: init?.credentials,
782
+ signal,
783
+ });
784
+ if (method === "POST" && !headers.has(HEADER_CONNECTION_ID)) {
785
+ return jsonResponse(initializeResponse, 200, {
786
+ [HEADER_CONNECTION_ID]: "connection-1",
787
+ });
788
+ }
789
+ if (method === "GET") {
790
+ return sseResponse(signal);
791
+ }
792
+ if (method === "POST" && headers.has(HEADER_CONNECTION_ID)) {
793
+ return await new Promise((_resolve, reject) => {
794
+ signal?.addEventListener("abort", () => {
795
+ connectedPostAborted.resolve();
796
+ reject(new Error("connected POST aborted"));
797
+ }, { once: true });
798
+ });
799
+ }
800
+ if (method === "DELETE") {
801
+ return new Response(null, { status: 202 });
802
+ }
803
+ throw new Error(`Unexpected ${method} request`);
804
+ };
805
+ const stream = createHttpStream("https://agent.example/acp", { fetch });
806
+ const writer = stream.writable.getWriter();
807
+ const reader = stream.readable.getReader();
808
+ try {
809
+ await writer.write(initializeRequest);
810
+ await readMessage(reader);
811
+ const write = writer.write(sessionNewRequest);
812
+ await flushMicrotasks();
813
+ const postRequest = requestAt(requests, 2);
814
+ expect(postRequest.method).toBe("POST");
815
+ expect(postRequest.headers.get(HEADER_CONNECTION_ID)).toBe("connection-1");
816
+ expect(postRequest.signal?.aborted).toBe(false);
817
+ const cancel = reader.cancel();
818
+ await connectedPostAborted.promise;
819
+ expect(postRequest.signal?.aborted).toBe(true);
820
+ await expect(write).rejects.toThrow("connected POST aborted");
821
+ await cancel;
822
+ const deleteRequest = requestAt(requests, 3);
823
+ expect(deleteRequest.method).toBe("DELETE");
824
+ expect(deleteRequest.headers.get(HEADER_CONNECTION_ID)).toBe("connection-1");
825
+ }
826
+ finally {
827
+ writer.releaseLock();
828
+ await closeStream(stream);
829
+ }
830
+ });
831
+ it("errors and tears down local resources when connected POST fails", async () => {
832
+ const clearSpy = vi.spyOn(MemoryAcpCookieStore.prototype, "clear");
833
+ const controlledFetch = createControlledFetch({
834
+ initializeCookies: ["transport=alpha; Path=/"],
835
+ postStatus: 401,
836
+ postBody: "expired",
837
+ });
838
+ const stream = createHttpStream("https://agent.example/acp", {
839
+ fetch: controlledFetch.fetch,
840
+ });
841
+ const writer = stream.writable.getWriter();
842
+ const reader = stream.readable.getReader();
843
+ try {
844
+ await writer.write(initializeRequest);
845
+ await readMessage(reader);
846
+ await expect(writer.write(sessionNewRequest)).rejects.toThrow("ACP POST failed: 401");
847
+ const deleteRequest = requestAt(controlledFetch.requests, 3);
848
+ expect(deleteRequest.method).toBe("DELETE");
849
+ expect(deleteRequest.headers.get(HEADER_CONNECTION_ID)).toBe("connection-1");
850
+ expect(deleteRequest.headers.get("Cookie")).toBe("transport=alpha");
851
+ await flushMicrotasks();
852
+ expect(sseAt(controlledFetch.sseRequests, 0).signal.aborted).toBe(true);
853
+ expect(clearSpy).toHaveBeenCalledTimes(1);
854
+ await expect(reader.read()).rejects.toThrow("ACP POST failed");
855
+ }
856
+ finally {
857
+ clearSpy.mockRestore();
858
+ reader.releaseLock();
859
+ writer.releaseLock();
860
+ await closeStream(stream);
861
+ }
862
+ });
863
+ it("cleans up local resources when DELETE rejects during close", async () => {
864
+ const clearSpy = vi.spyOn(MemoryAcpCookieStore.prototype, "clear");
865
+ const controlledFetch = createControlledFetch({
866
+ initializeCookies: ["transport=alpha; Path=/"],
867
+ deleteError: new Error("Network dropped"),
868
+ });
869
+ const stream = createHttpStream("https://agent.example/acp", {
870
+ fetch: controlledFetch.fetch,
871
+ });
872
+ const writer = stream.writable.getWriter();
873
+ const reader = stream.readable.getReader();
874
+ try {
875
+ await writer.write(initializeRequest);
876
+ await readMessage(reader);
877
+ await expect(writer.close()).rejects.toThrow("Network dropped");
878
+ expect(sseAt(controlledFetch.sseRequests, 0).signal.aborted).toBe(true);
879
+ expect(clearSpy).toHaveBeenCalledTimes(1);
880
+ expect((await reader.read()).done).toBe(true);
881
+ }
882
+ finally {
883
+ clearSpy.mockRestore();
884
+ reader.releaseLock();
885
+ writer.releaseLock();
886
+ await closeStream(stream);
887
+ }
888
+ });
889
+ it("propagates DELETE failures from readable cancel", async () => {
890
+ const controlledFetch = createControlledFetch({
891
+ deleteError: new Error("Network dropped"),
892
+ });
893
+ const stream = createHttpStream("https://agent.example/acp", {
894
+ fetch: controlledFetch.fetch,
895
+ });
896
+ const writer = stream.writable.getWriter();
897
+ const reader = stream.readable.getReader();
898
+ try {
899
+ await writer.write(initializeRequest);
900
+ await readMessage(reader);
901
+ await expect(reader.cancel()).rejects.toThrow("Network dropped");
902
+ expect(sseAt(controlledFetch.sseRequests, 0).signal.aborted).toBe(true);
903
+ }
904
+ finally {
905
+ reader.releaseLock();
906
+ writer.releaseLock();
907
+ await closeStream(stream);
908
+ }
909
+ });
910
+ it("runs initialize, newSession, and prompt through ClientSideConnection", async () => {
911
+ const updates = [];
912
+ const server = await startTestServer(() => createTestAgentApp({ chunkCount: 2 }));
913
+ const stream = createHttpStream(server.url);
914
+ const conn = new ClientSideConnection(() => createTestClient({ updates }), stream);
915
+ try {
916
+ expect(await conn.initialize({
917
+ protocolVersion: PROTOCOL_VERSION,
918
+ clientCapabilities: {},
919
+ })).toMatchObject({
920
+ protocolVersion: PROTOCOL_VERSION,
921
+ agentCapabilities: { loadSession: false },
922
+ });
923
+ const session = await conn.newSession({ cwd: "/tmp", mcpServers: [] });
924
+ expect(session.sessionId).toMatch(/^[0-9a-f-]{36}$/);
925
+ await expect(conn.prompt({
926
+ sessionId: session.sessionId,
927
+ prompt: [{ type: "text", text: "Hello" }],
928
+ })).resolves.toEqual({ stopReason: "end_turn" });
929
+ expect(updates).toHaveLength(2);
930
+ expect(updates).toMatchObject([
931
+ {
932
+ sessionId: session.sessionId,
933
+ update: {
934
+ sessionUpdate: "agent_message_chunk",
935
+ content: { text: "chunk-1" },
936
+ },
937
+ },
938
+ {
939
+ sessionId: session.sessionId,
940
+ update: {
941
+ sessionUpdate: "agent_message_chunk",
942
+ content: { text: "chunk-2" },
943
+ },
944
+ },
945
+ ]);
946
+ }
947
+ finally {
948
+ await closeStream(stream);
949
+ await server.close();
950
+ }
951
+ });
952
+ it("runs initialize, newSession, and prompt through a client app", async () => {
953
+ const updates = [];
954
+ const server = await startTestServer(() => createTestAgentApp({ chunkCount: 2 }));
955
+ const stream = createHttpStream(server.url);
956
+ try {
957
+ const result = await createClientApp({ name: "http-app-client" })
958
+ .onNotification(methods.client.session.update, (c) => {
959
+ updates.push(c.params);
960
+ })
961
+ .connectWith(stream, async (agent) => {
962
+ const initialized = await agent.request(methods.agent.initialize, {
963
+ protocolVersion: PROTOCOL_VERSION,
964
+ clientCapabilities: {},
965
+ });
966
+ const session = await agent.request(methods.agent.session.new, {
967
+ cwd: "/tmp",
968
+ mcpServers: [],
969
+ });
970
+ const prompt = await agent.request(methods.agent.session.prompt, {
971
+ sessionId: session.sessionId,
972
+ prompt: [{ type: "text", text: "Hello" }],
973
+ });
974
+ return { initialized, prompt, session };
975
+ });
976
+ expect(result.initialized).toMatchObject({
977
+ protocolVersion: PROTOCOL_VERSION,
978
+ agentCapabilities: { loadSession: false },
979
+ });
980
+ expect(result.session.sessionId).toMatch(/^[0-9a-f-]{36}$/);
981
+ expect(result.prompt).toEqual({ stopReason: "end_turn" });
982
+ expect(updates).toMatchObject([
983
+ {
984
+ sessionId: result.session.sessionId,
985
+ update: {
986
+ sessionUpdate: "agent_message_chunk",
987
+ content: { text: "chunk-1" },
988
+ },
989
+ },
990
+ {
991
+ sessionId: result.session.sessionId,
992
+ update: {
993
+ sessionUpdate: "agent_message_chunk",
994
+ content: { text: "chunk-2" },
995
+ },
996
+ },
997
+ ]);
998
+ }
999
+ finally {
1000
+ await closeStream(stream);
1001
+ await server.close();
1002
+ }
1003
+ });
1004
+ it("round-trips permission requests through ClientSideConnection", async () => {
1005
+ const updates = [];
1006
+ const permissionRequests = [];
1007
+ const server = await startTestServer(() => createTestAgentApp({ enablePermission: true }));
1008
+ const stream = createHttpStream(server.url);
1009
+ const conn = new ClientSideConnection(() => createTestClient({ updates, permissionRequests }), stream);
1010
+ try {
1011
+ await conn.initialize({
1012
+ protocolVersion: PROTOCOL_VERSION,
1013
+ clientCapabilities: {},
1014
+ });
1015
+ const session = await conn.newSession({ cwd: "/tmp", mcpServers: [] });
1016
+ await expect(conn.prompt({
1017
+ sessionId: session.sessionId,
1018
+ prompt: [{ type: "text", text: "Hello" }],
1019
+ })).resolves.toEqual({ stopReason: "end_turn" });
1020
+ expect(permissionRequests).toHaveLength(1);
1021
+ expect(permissionRequests[0]).toMatchObject({
1022
+ sessionId: session.sessionId,
1023
+ toolCall: {
1024
+ toolCallId: "permission-tool",
1025
+ title: "Permission tool",
1026
+ },
1027
+ });
1028
+ expect(updates).toEqual(expect.arrayContaining([
1029
+ expect.objectContaining({
1030
+ sessionId: session.sessionId,
1031
+ update: expect.objectContaining({
1032
+ sessionUpdate: "agent_message_chunk",
1033
+ content: expect.objectContaining({
1034
+ text: "permission-selected-allow",
1035
+ }),
1036
+ }),
1037
+ }),
1038
+ ]));
1039
+ }
1040
+ finally {
1041
+ await closeStream(stream);
1042
+ await server.close();
1043
+ }
1044
+ });
1045
+ it("loads durable sessions after an HTTP reconnect", async () => {
1046
+ const durableSessions = new Map();
1047
+ const connectionIds = [];
1048
+ const fetch = recordInitializeConnectionIds(connectionIds);
1049
+ const server = await startTestServer(() => createDurableSessionAgent(durableSessions));
1050
+ try {
1051
+ const firstUpdates = [];
1052
+ const firstStream = createHttpStream(server.url, { fetch });
1053
+ const firstConn = new ClientSideConnection(() => createTestClient({ updates: firstUpdates }), firstStream);
1054
+ const initialized = await firstConn.initialize({
1055
+ protocolVersion: PROTOCOL_VERSION,
1056
+ clientCapabilities: {},
1057
+ });
1058
+ expect(initialized.agentCapabilities?.loadSession).toBe(true);
1059
+ const session = await firstConn.newSession({
1060
+ cwd: "/tmp",
1061
+ mcpServers: [],
1062
+ });
1063
+ await expect(firstConn.prompt({
1064
+ sessionId: session.sessionId,
1065
+ prompt: [{ type: "text", text: "Remember this" }],
1066
+ })).resolves.toEqual({ stopReason: "end_turn" });
1067
+ await waitForUpdates(firstUpdates, 1);
1068
+ await closeStream(firstStream);
1069
+ expect(durableSessions.has(session.sessionId)).toBe(true);
1070
+ const secondUpdates = [];
1071
+ const secondStream = createHttpStream(server.url, { fetch });
1072
+ const secondConn = new ClientSideConnection(() => createTestClient({ updates: secondUpdates }), secondStream);
1073
+ const reinitialized = await secondConn.initialize({
1074
+ protocolVersion: PROTOCOL_VERSION,
1075
+ clientCapabilities: {},
1076
+ });
1077
+ expect(reinitialized.agentCapabilities?.loadSession).toBe(true);
1078
+ // Production agents must authorize session/load against the authenticated
1079
+ // principal. This SDK transport test omits auth because there is no
1080
+ // generic auth layer in the SDK.
1081
+ await expect(secondConn.loadSession({
1082
+ sessionId: session.sessionId,
1083
+ cwd: "/tmp",
1084
+ mcpServers: [],
1085
+ })).resolves.toEqual({});
1086
+ await waitForUpdates(secondUpdates, firstUpdates.length);
1087
+ await closeStream(secondStream);
1088
+ expect(connectionIds).toHaveLength(2);
1089
+ expect(connectionIds[0]).not.toBe(connectionIds[1]);
1090
+ expect(secondUpdates).toEqual(firstUpdates);
1091
+ }
1092
+ finally {
1093
+ await server.close();
1094
+ }
1095
+ });
1096
+ it("keeps multiple sessions isolated through the SDK client abstraction", async () => {
1097
+ const updates = [];
1098
+ const server = await startTestServer();
1099
+ const stream = createHttpStream(server.url);
1100
+ const conn = new ClientSideConnection(() => createTestClient({ updates }), stream);
1101
+ try {
1102
+ await conn.initialize({
1103
+ protocolVersion: PROTOCOL_VERSION,
1104
+ clientCapabilities: {},
1105
+ });
1106
+ const firstSession = await conn.newSession({
1107
+ cwd: "/tmp",
1108
+ mcpServers: [],
1109
+ });
1110
+ const secondSession = await conn.newSession({
1111
+ cwd: "/tmp/other",
1112
+ mcpServers: [],
1113
+ });
1114
+ await Promise.all([
1115
+ conn.prompt({
1116
+ sessionId: firstSession.sessionId,
1117
+ prompt: [{ type: "text", text: "First" }],
1118
+ }),
1119
+ conn.prompt({
1120
+ sessionId: secondSession.sessionId,
1121
+ prompt: [{ type: "text", text: "Second" }],
1122
+ }),
1123
+ ]);
1124
+ expect(updates).toEqual(expect.arrayContaining([
1125
+ expect.objectContaining({ sessionId: firstSession.sessionId }),
1126
+ expect.objectContaining({ sessionId: secondSession.sessionId }),
1127
+ ]));
1128
+ expect(updates.filter((update) => update.sessionId === firstSession.sessionId)).toHaveLength(1);
1129
+ expect(updates.filter((update) => update.sessionId === secondSession.sessionId)).toHaveLength(1);
1130
+ }
1131
+ finally {
1132
+ await closeStream(stream);
1133
+ await server.close();
1134
+ }
1135
+ });
1136
+ });
1137
+ function createDurableSessionAgent(sessions) {
1138
+ return createAgentApp({ name: "durable-session-agent" })
1139
+ .onRequest(methods.agent.initialize, () => ({
1140
+ protocolVersion: PROTOCOL_VERSION,
1141
+ agentCapabilities: {
1142
+ loadSession: true,
1143
+ },
1144
+ }))
1145
+ .onRequest(methods.agent.session.new, (c) => {
1146
+ const sessionId = globalThis.crypto.randomUUID();
1147
+ sessions.set(sessionId, {
1148
+ cwd: c.params.cwd,
1149
+ history: [],
1150
+ });
1151
+ return { sessionId };
1152
+ })
1153
+ .onRequest(methods.agent.session.load, async (c) => {
1154
+ const session = sessions.get(c.params.sessionId);
1155
+ if (!session) {
1156
+ throw new Error(`Unknown durable session: ${c.params.sessionId}`);
1157
+ }
1158
+ for (const update of session.history) {
1159
+ await c.client.notify(methods.client.session.update, update);
1160
+ }
1161
+ return {};
1162
+ })
1163
+ .onRequest(methods.agent.session.prompt, async (c) => {
1164
+ const session = sessions.get(c.params.sessionId);
1165
+ if (!session) {
1166
+ throw new Error(`Unknown durable session: ${c.params.sessionId}`);
1167
+ }
1168
+ const update = {
1169
+ sessionId: c.params.sessionId,
1170
+ update: {
1171
+ sessionUpdate: "agent_message_chunk",
1172
+ content: {
1173
+ type: "text",
1174
+ text: `durable-history:${session.cwd}`,
1175
+ },
1176
+ },
1177
+ };
1178
+ session.history.push(update);
1179
+ await c.client.notify(methods.client.session.update, update);
1180
+ return { stopReason: "end_turn" };
1181
+ })
1182
+ .onRequest(methods.agent.authenticate, () => ({}))
1183
+ .onNotification(methods.agent.session.cancel, () => { });
1184
+ }
1185
+ function recordInitializeConnectionIds(connectionIds) {
1186
+ return async (input, init) => {
1187
+ const response = await globalThis.fetch(input, init);
1188
+ const headers = new Headers(init?.headers);
1189
+ if (init?.method === "POST" && !headers.has(HEADER_CONNECTION_ID)) {
1190
+ const connectionId = response.headers.get(HEADER_CONNECTION_ID);
1191
+ if (connectionId) {
1192
+ connectionIds.push(connectionId);
1193
+ }
1194
+ }
1195
+ return response;
1196
+ };
1197
+ }
1198
+ function createControlledFetch(options = {}) {
1199
+ const requests = [];
1200
+ const sseRequests = [];
1201
+ const encoder = new TextEncoder();
1202
+ return {
1203
+ requests,
1204
+ sseRequests,
1205
+ fetch: async (input, init) => {
1206
+ const method = init?.method ?? "GET";
1207
+ const headers = new Headers(init?.headers);
1208
+ requests.push({
1209
+ url: String(input),
1210
+ method,
1211
+ headers,
1212
+ body: bodyToString(init?.body),
1213
+ credentials: init?.credentials,
1214
+ signal: init?.signal,
1215
+ });
1216
+ if (method === "POST" && !headers.has(HEADER_CONNECTION_ID)) {
1217
+ const status = options.initializeStatus ?? 200;
1218
+ if (status !== 200) {
1219
+ return new Response(options.initializeBody ?? null, {
1220
+ status,
1221
+ headers: setCookieResponseHeaders(options.initializeCookies),
1222
+ });
1223
+ }
1224
+ return jsonResponse(options.initializeResponse ?? initializeResponse, 200, {
1225
+ [HEADER_CONNECTION_ID]: "connection-1",
1226
+ ...setCookieResponseHeaders(options.initializeCookies),
1227
+ });
1228
+ }
1229
+ if (method === "DELETE" && options.deleteError) {
1230
+ throw options.deleteError;
1231
+ }
1232
+ if (method === "POST" &&
1233
+ headers.has(HEADER_CONNECTION_ID) &&
1234
+ options.postStatus !== undefined) {
1235
+ return new Response(options.postBody ?? null, {
1236
+ status: options.postStatus,
1237
+ });
1238
+ }
1239
+ if (method === "POST" || method === "DELETE") {
1240
+ return new Response(null, { status: 202 });
1241
+ }
1242
+ if (method === "GET") {
1243
+ const status = options.getStatus ?? 200;
1244
+ if (status !== 200) {
1245
+ return new Response("SSE failed", {
1246
+ status,
1247
+ headers: setCookieResponseHeaders(options.getCookies),
1248
+ });
1249
+ }
1250
+ const sseIndex = sseRequests.length;
1251
+ await options.sseResponseDelays?.get(sseIndex);
1252
+ const stream = new TransformStream();
1253
+ const writer = stream.writable.getWriter();
1254
+ const signal = init?.signal;
1255
+ if (signal) {
1256
+ signal.addEventListener("abort", () => {
1257
+ void writer.close().catch(() => undefined);
1258
+ });
1259
+ }
1260
+ sseRequests.push({
1261
+ signal: signal ?? new AbortController().signal,
1262
+ writer,
1263
+ });
1264
+ return new Response(stream.readable, {
1265
+ status: 200,
1266
+ headers: {
1267
+ "Content-Type": EVENT_STREAM_MIME_TYPE,
1268
+ ...setCookieResponseHeaders(options.getCookies),
1269
+ },
1270
+ });
1271
+ }
1272
+ return new Response("Unexpected method", { status: 405 });
1273
+ },
1274
+ sendSse: async (index, message) => {
1275
+ await sseAt(sseRequests, index).writer.write(encoder.encode(serializeSseEvent(message)));
1276
+ },
1277
+ closeSse: async (index) => {
1278
+ await sseAt(sseRequests, index).writer.close();
1279
+ },
1280
+ };
1281
+ }
1282
+ function createTestClient(state) {
1283
+ return {
1284
+ requestPermission: (params) => {
1285
+ state.permissionRequests?.push(params);
1286
+ return Promise.resolve({
1287
+ outcome: {
1288
+ outcome: "selected",
1289
+ optionId: "allow",
1290
+ },
1291
+ });
1292
+ },
1293
+ sessionUpdate: (params) => {
1294
+ state.updates.push(params);
1295
+ return Promise.resolve();
1296
+ },
1297
+ };
1298
+ }
1299
+ async function closeStream(stream) {
1300
+ await stream.writable.close().catch(() => undefined);
1301
+ }
1302
+ async function flushMicrotasks() {
1303
+ await Promise.resolve();
1304
+ await Promise.resolve();
1305
+ }
1306
+ function createDeferred() {
1307
+ let resolve = () => { };
1308
+ let reject = () => { };
1309
+ const promise = new Promise((resolvePromise, rejectPromise) => {
1310
+ resolve = resolvePromise;
1311
+ reject = rejectPromise;
1312
+ });
1313
+ return { promise, resolve, reject };
1314
+ }
1315
+ async function readMessage(reader) {
1316
+ const result = await reader.read();
1317
+ if (result.done || Array.isArray(result.value)) {
1318
+ throw new Error("Expected an individual message");
1319
+ }
1320
+ return result.value;
1321
+ }
1322
+ async function waitForUpdates(updates, count) {
1323
+ const deadline = Date.now() + 1_000;
1324
+ while (updates.length < count) {
1325
+ if (Date.now() > deadline) {
1326
+ throw new Error(`Timed out waiting for ${count} session updates`);
1327
+ }
1328
+ await new Promise((resolve) => setTimeout(resolve, 1));
1329
+ }
1330
+ }
1331
+ function requestAt(requests, index) {
1332
+ const request = requests[index];
1333
+ if (!request) {
1334
+ throw new Error(`Expected request at index ${index}`);
1335
+ }
1336
+ return request;
1337
+ }
1338
+ function sseAt(requests, index) {
1339
+ const request = requests[index];
1340
+ if (!request) {
1341
+ throw new Error(`Expected SSE request at index ${index}`);
1342
+ }
1343
+ return request;
1344
+ }
1345
+ function bodyToString(body) {
1346
+ return typeof body === "string" ? body : "";
1347
+ }
1348
+ function jsonResponse(body, status, headers) {
1349
+ return new Response(JSON.stringify(body), {
1350
+ status,
1351
+ headers: {
1352
+ "Content-Type": JSON_MIME_TYPE,
1353
+ ...headers,
1354
+ },
1355
+ });
1356
+ }
1357
+ function sseResponse(signal) {
1358
+ const stream = new TransformStream();
1359
+ const writer = stream.writable.getWriter();
1360
+ signal?.addEventListener("abort", () => {
1361
+ void writer.close().catch(() => undefined);
1362
+ });
1363
+ return new Response(stream.readable, {
1364
+ status: 200,
1365
+ headers: {
1366
+ "Content-Type": EVENT_STREAM_MIME_TYPE,
1367
+ },
1368
+ });
1369
+ }
1370
+ function headersWithSetCookie(values) {
1371
+ const headers = new Headers();
1372
+ Object.defineProperty(headers, "getSetCookie", {
1373
+ value: () => values,
1374
+ });
1375
+ return headers;
1376
+ }
1377
+ function setCookieResponseHeaders(cookies) {
1378
+ return cookies ? { "Set-Cookie": cookies.join(", ") } : {};
1379
+ }
1380
+ //# sourceMappingURL=http-stream.test.js.map