kennel 0.2.1 → 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,723 @@
1
+ import { execFile as execFileCb } from "node:child_process"
2
+ import { constants } from "node:fs"
3
+ import { access, realpath } from "node:fs/promises"
4
+ import { homedir } from "node:os"
5
+ import { delimiter, isAbsolute, resolve as resolvePath, sep } from "node:path"
6
+ import { promisify } from "node:util"
7
+
8
+ /**
9
+ * Injectable subprocess runner. Production uses `execFile`; tests inject a
10
+ * fake that records exact arguments and controls output/errors. The options
11
+ * mirror execFile's accepted shape so the real and fake implementations can
12
+ * share one signature.
13
+ */
14
+ export type ExecFileLike = (
15
+ file: string,
16
+ args: string[],
17
+ options: {
18
+ cwd: string
19
+ timeout: number
20
+ maxBuffer: number
21
+ windowsHide?: boolean
22
+ signal?: AbortSignal
23
+ },
24
+ ) => Promise<{ stdout: string; stderr: string }>
25
+
26
+ const defaultExecFileLike = promisify(execFileCb) as ExecFileLike
27
+
28
+ /**
29
+ * Failure code for a MailOS command. `timeout` when the child was killed by
30
+ * the deadline, `not-found` when the CLI reported the target missing,
31
+ * `aborted` when the caller cancelled (e.g. client disconnect), `failed` for
32
+ * every other non-zero exit.
33
+ */
34
+ export type MailosCommandFailure =
35
+ "timeout" | "not-found" | "aborted" | "failed"
36
+
37
+ export class MailosCommandError extends Error {
38
+ readonly code: MailosCommandFailure
39
+ readonly timedOut: boolean
40
+ readonly aborted: boolean
41
+ readonly exitCode: number | null
42
+
43
+ constructor(
44
+ code: MailosCommandFailure,
45
+ message: string,
46
+ details: {
47
+ exitCode?: number | null
48
+ timedOut?: boolean
49
+ aborted?: boolean
50
+ } = {},
51
+ ) {
52
+ super(message)
53
+ this.name = "MailosCommandError"
54
+ this.code = code
55
+ this.timedOut = details.timedOut ?? code === "timeout"
56
+ this.aborted = details.aborted ?? code === "aborted"
57
+ this.exitCode = details.exitCode ?? null
58
+ }
59
+ }
60
+
61
+ function classifyExecError(error: unknown): MailosCommandError {
62
+ if (error instanceof MailosCommandError) return error
63
+ if (!(error instanceof Error)) {
64
+ return new MailosCommandError("failed", "MailOS command failed")
65
+ }
66
+ if (error.name === "AbortError") {
67
+ return new MailosCommandError("aborted", "MailOS command cancelled")
68
+ }
69
+ const execError = error as Error & {
70
+ code?: string | number
71
+ killed?: boolean
72
+ }
73
+ if (execError.killed) {
74
+ return new MailosCommandError("timeout", "MailOS command timed out", {
75
+ timedOut: true,
76
+ exitCode: typeof execError.code === "number" ? execError.code : null,
77
+ })
78
+ }
79
+ return new MailosCommandError("failed", "MailOS command failed to complete", {
80
+ exitCode: typeof execError.code === "number" ? execError.code : null,
81
+ })
82
+ }
83
+
84
+ /**
85
+ * Central subprocess lifecycle: a hard timeout kills the child, an optional
86
+ * AbortSignal (client disconnect) cancels it, and errors are converted into
87
+ * redacted `MailosCommandError` values that never carry command output
88
+ * (credentials or message bodies cannot leak into error messages or logs).
89
+ */
90
+ export async function runMailos(
91
+ execFile: ExecFileLike,
92
+ mailosBin: string,
93
+ args: string[],
94
+ options: {
95
+ cwd: string
96
+ timeoutMs: number
97
+ maxBufferBytes?: number
98
+ signal?: AbortSignal
99
+ },
100
+ ): Promise<{ stdout: string; stderr: string }> {
101
+ if (options.signal?.aborted) {
102
+ throw new MailosCommandError("aborted", "MailOS command cancelled")
103
+ }
104
+ try {
105
+ return await execFile(mailosBin, args, {
106
+ cwd: options.cwd,
107
+ timeout: options.timeoutMs,
108
+ maxBuffer: options.maxBufferBytes ?? 10 * 1024 * 1024,
109
+ windowsHide: true,
110
+ signal: options.signal,
111
+ })
112
+ } catch (error) {
113
+ const classified = classifyExecError(error)
114
+ if (options.signal?.aborted && classified.code !== "aborted") {
115
+ throw new MailosCommandError("aborted", "MailOS command cancelled")
116
+ }
117
+ throw classified
118
+ }
119
+ }
120
+
121
+ export type MailosServiceOptions = {
122
+ execFile?: ExecFileLike
123
+ mailosBin?: string
124
+ /** Test seam: MailOS's global draft dir (defaults to ~/.email/drafts). */
125
+ globalDraftDir?: string
126
+ }
127
+
128
+ export type MailosIdentity = {
129
+ from: string | null
130
+ name: string | null
131
+ /** False when the CLI could not resolve an identity (caller may hide the row). */
132
+ ok: boolean
133
+ }
134
+
135
+ export type ConversationMessage = {
136
+ body: string
137
+ date: string | null
138
+ from: string | null
139
+ id: string
140
+ subject: string | null
141
+ to: string | null
142
+ }
143
+
144
+ export type ConversationOutcome =
145
+ "empty" | "ok" | "partial" | "not-found" | "timeout"
146
+
147
+ export type ConversationResult = {
148
+ items: ConversationMessage[]
149
+ missing: string[]
150
+ outcome: ConversationOutcome
151
+ }
152
+
153
+ export type SendPreviewResult = {
154
+ dryRun: true
155
+ output: string
156
+ revision: string
157
+ }
158
+
159
+ export type SendResult = {
160
+ dryRun: false
161
+ output: string
162
+ }
163
+
164
+ export type SendFailureReason =
165
+ | "revision-match"
166
+ | "contract"
167
+ | "command"
168
+ | "invalid-draft"
169
+ | "unsupported-draft-dir"
170
+
171
+ export class MailSendFailure extends Error {
172
+ readonly reason: SendFailureReason
173
+
174
+ constructor(reason: SendFailureReason, message: string) {
175
+ super(message)
176
+ this.name = "MailSendFailure"
177
+ this.reason = reason
178
+ }
179
+ }
180
+
181
+ async function isExecutable(path: string) {
182
+ try {
183
+ await access(path, constants.X_OK)
184
+ return true
185
+ } catch {
186
+ return false
187
+ }
188
+ }
189
+
190
+ function pathIsWithin(child: string, parent: string) {
191
+ const rel = child.startsWith(parent) ? child.slice(parent.length) : null
192
+ if (!rel) return false
193
+ return rel === "" || rel.startsWith(sep)
194
+ }
195
+
196
+ /**
197
+ * Resolve the MailOS binary, refusing to pick a binary that lives inside the
198
+ * working folder so drafts cannot point commands at an attacker-controlled
199
+ * executable.
200
+ */
201
+ export async function resolveMailosBinary({
202
+ cwd,
203
+ }: {
204
+ cwd: string
205
+ }): Promise<string> {
206
+ const preferred = resolvePath(homedir(), ".local", "bin", "mailos")
207
+ if (await isExecutable(preferred)) return preferred
208
+
209
+ const pathEnv = process.env.PATH ?? ""
210
+ for (const dir of pathEnv.split(delimiter)) {
211
+ const trimmed = dir.trim()
212
+ if (!trimmed) continue
213
+ if (!isAbsolute(trimmed)) continue
214
+
215
+ const candidate = resolvePath(trimmed, "mailos")
216
+ if (!isAbsolute(candidate)) continue
217
+ if (pathIsWithin(candidate, cwd)) continue
218
+
219
+ if (await isExecutable(candidate)) return candidate
220
+ }
221
+
222
+ throw new Error(
223
+ "MailOS binary not found. Expected ~/.local/bin/mailos or an absolute PATH entry.",
224
+ )
225
+ }
226
+
227
+ /**
228
+ * Bounded per-(folder, id) in-flight and success cache. The scope key embeds
229
+ * the working folder so caches never cross account/folder scope, in-flight
230
+ * reads are deduplicated, and successful reads are held for the conversation
231
+ * window instead of re-invoking the CLI on every detail view.
232
+ *
233
+ * Cancellation is subscriber-scoped: each caller's AbortSignal is registered
234
+ * on the shared in-flight entry; one canceled consumer only removes its own
235
+ * subscription, and the shared child is aborted only when the *last*
236
+ * subscriber cancels. A canceled consumer therefore never kills a concurrent
237
+ * consumer of the same (cwd, id), while a fully-disconnected request still
238
+ * stops its children.
239
+ */
240
+ type ConversationMessageCacheEntry = {
241
+ message: ConversationMessage
242
+ at: number
243
+ }
244
+
245
+ type ConversationInFlight = {
246
+ promise: Promise<ConversationMessage>
247
+ controller: AbortController
248
+ signals: Map<AbortSignal, () => void>
249
+ }
250
+
251
+ type ConversationCache = {
252
+ inFlight: Map<string, ConversationInFlight>
253
+ success: Map<string, ConversationMessageCacheEntry>
254
+ }
255
+
256
+ const conversationCache: ConversationCache = {
257
+ inFlight: new Map(),
258
+ success: new Map(),
259
+ }
260
+
261
+ export const conversationLimits = {
262
+ maxReferences: 12,
263
+ // MailOS `read` is an IMAP/notmuch operation; real-world successful reads
264
+ // are measured at 22-26s, so the per-read cap sits above that envelope
265
+ // (60s) while the whole conversation view stays bounded at 75s. There is
266
+ // deliberately no retry loop: slow-but-successful reads must not be
267
+ // classified as failures.
268
+ perReadTimeoutMs: 60_000,
269
+ totalBudgetMs: 75_000,
270
+ concurrency: 3,
271
+ successCacheSize: 40,
272
+ // Successful reads are only reused within the conversation window; after
273
+ // this the CLI is re-invoked so actions (send/archive/delete) never stay
274
+ // masked by a stale server-side copy.
275
+ successTtlMs: 60_000,
276
+ } as const
277
+
278
+ export function resetConversationCache() {
279
+ conversationCache.inFlight.clear()
280
+ conversationCache.success.clear()
281
+ }
282
+
283
+ function scopeKey(cwd: string, id: string) {
284
+ return `${cwd}\u0000${id}`
285
+ }
286
+
287
+ function parseConversationMarkdown(
288
+ id: string,
289
+ output: string,
290
+ ): ConversationMessage {
291
+ const subject = /^#\s+(.+)$/m.exec(output)?.[1]?.trim() ?? null
292
+ const from =
293
+ /^\*\*From:\*\*\s+(.+?)(?:\s{2,}|$)/m.exec(output)?.[1]?.trim() ?? null
294
+ const to =
295
+ /^\*\*To:\*\*\s+(.+?)(?:\s{2,}|$)/m.exec(output)?.[1]?.trim() ?? null
296
+ const date =
297
+ /^\*\*Date:\*\*\s+(.+?)(?:\s{2,}|$)/m.exec(output)?.[1]?.trim() ?? null
298
+ const separator = output.indexOf("\n---\n")
299
+ const body = (separator >= 0 ? output.slice(separator + 5) : output).trim()
300
+ return { body, date, from, id, subject, to }
301
+ }
302
+
303
+ /**
304
+ * Structured, account-scoped MailOS access. Every command is an explicit
305
+ * fixed template over a canonical draft identity; nothing from the client is
306
+ * ever formatted into the command line. Identity/conversation/send/archive
307
+ * live here instead of the web plugin so the basic draft reader (`node.ts`)
308
+ * never needs the CLI.
309
+ */
310
+ export type SendDraftOptions = {
311
+ /**
312
+ * The exact draft directory the client authorized (its mailDir). MailOS
313
+ * resolves draft ids against the global ~/.email/drafts by default; passing
314
+ * this makes send/preview target the file already read by list/detail,
315
+ * never a same-named draft elsewhere.
316
+ */
317
+ draftDir: string
318
+ signal?: AbortSignal
319
+ }
320
+
321
+ /** Internal parameter shape: the draft dir may be absent until validated. */
322
+ type SendDraftParams = {
323
+ draftDir?: string
324
+ signal?: AbortSignal
325
+ }
326
+
327
+ function requireDraftDir(draftDir: string | undefined) {
328
+ if (!draftDir || !isAbsolute(draftDir)) {
329
+ throw new MailSendFailure(
330
+ "invalid-draft",
331
+ "A send draft directory (the authorized mailDir) is required",
332
+ )
333
+ }
334
+ return draftDir
335
+ }
336
+
337
+ function sameCanonicalDir(left: string, right: string) {
338
+ const canonical = async (value: string) =>
339
+ realpath(value).catch(() => resolvePath(value))
340
+ return Promise.all([canonical(left), canonical(right)]).then(
341
+ ([leftReal, rightReal]) => leftReal === rightReal,
342
+ )
343
+ }
344
+
345
+ /** The single directory `mailos drafts archive <id>` can address. */
346
+ export function mailosGlobalDraftDir() {
347
+ return resolvePath(homedir(), ".email", "drafts")
348
+ }
349
+
350
+ export function createMailosService(options: MailosServiceOptions = {}) {
351
+ const execFile = options.execFile ?? defaultExecFileLike
352
+ const mailosBin = options.mailosBin
353
+ const globalDraftDir = options.globalDraftDir
354
+
355
+ async function binary(cwd: string) {
356
+ if (mailosBin) {
357
+ if (!isAbsolute(mailosBin)) {
358
+ throw new Error("mailosBin must be an absolute path")
359
+ }
360
+ if (pathIsWithin(mailosBin, cwd)) {
361
+ throw new Error("mailosBin cannot live inside the working folder")
362
+ }
363
+ return mailosBin
364
+ }
365
+ return resolveMailosBinary({ cwd })
366
+ }
367
+
368
+ function normalizeIdentityValue(value: string | null): string | null {
369
+ return value && value !== "(not set)" ? value : null
370
+ }
371
+
372
+ async function identity(cwd: string): Promise<MailosIdentity> {
373
+ try {
374
+ const bin = await binary(cwd)
375
+ const { stdout, stderr } = await runMailos(execFile, bin, ["whoami"], {
376
+ cwd,
377
+ timeoutMs: 15_000,
378
+ })
379
+ const output = [stdout, stderr].filter(Boolean).join("\n")
380
+ const from = normalizeIdentityValue(
381
+ /^Effective From:[ \t]*([^\r\n]+)$/im.exec(output)?.[1]?.trim() ?? null,
382
+ )
383
+ const name = normalizeIdentityValue(
384
+ /^From Name:[ \t]*([^\r\n]+)$/im.exec(output)?.[1]?.trim() ?? null,
385
+ )
386
+ return { from, name, ok: Boolean(from ?? name) }
387
+ } catch {
388
+ // Sender resolution is best-effort lazy enrichment; never fail the row.
389
+ return { from: null, name: null, ok: false }
390
+ }
391
+ }
392
+
393
+ /**
394
+ * Resolved markdown signature for a folder, or null when the folder has no
395
+ * signature configured (or the CLI cannot resolve one). Best-effort exactly
396
+ * like `identity`: a failing or empty `mailos sig` never fails the draft
397
+ * preview, it just leaves the signature section empty.
398
+ */
399
+ async function signature(
400
+ folder: string,
401
+ signal?: AbortSignal,
402
+ ): Promise<string | null> {
403
+ try {
404
+ const bin = await binary(folder)
405
+ const { stdout } = await runMailos(execFile, bin, ["sig", folder], {
406
+ cwd: folder,
407
+ timeoutMs: 15_000,
408
+ signal,
409
+ })
410
+ const output = stdout.trim()
411
+ if (!output) return null
412
+ if (output.includes("(no signature configured)")) return null
413
+ if (output.includes("(signature is empty)")) return null
414
+ return output
415
+ } catch {
416
+ return null
417
+ }
418
+ }
419
+
420
+ async function readMessage(
421
+ cwd: string,
422
+ id: string,
423
+ signal?: AbortSignal,
424
+ ): Promise<ConversationMessage> {
425
+ const bin = await binary(cwd)
426
+ const { stdout } = await runMailos(
427
+ execFile,
428
+ bin,
429
+ ["read", id, "--markdown"],
430
+ {
431
+ cwd,
432
+ timeoutMs: conversationLimits.perReadTimeoutMs,
433
+ signal,
434
+ },
435
+ )
436
+ return parseConversationMarkdown(id, stdout)
437
+ }
438
+
439
+ function cachedRead(
440
+ cwd: string,
441
+ id: string,
442
+ signal?: AbortSignal,
443
+ ): Promise<ConversationMessage> {
444
+ const key = scopeKey(cwd, id)
445
+ const cached = conversationCache.success.get(key)
446
+ if (cached) {
447
+ if (Date.now() - cached.at < conversationLimits.successTtlMs) {
448
+ return Promise.resolve(cached.message)
449
+ }
450
+ conversationCache.success.delete(key)
451
+ }
452
+
453
+ let entry = conversationCache.inFlight.get(key)
454
+ if (!entry) {
455
+ const controller = new AbortController()
456
+ const started = readMessage(cwd, id, controller.signal)
457
+ const created: ConversationInFlight = {
458
+ promise: started,
459
+ controller,
460
+ signals: new Map(),
461
+ }
462
+ entry = created
463
+ conversationCache.inFlight.set(key, created)
464
+ void started
465
+ .then((message) => {
466
+ const success = conversationCache.success
467
+ if (success.size >= conversationLimits.successCacheSize) {
468
+ success.delete(success.keys().next().value as string)
469
+ }
470
+ success.set(key, { message, at: Date.now() })
471
+ })
472
+ .catch(() => {
473
+ // The failure is delivered to `started` consumers; only the cache
474
+ // bookkeeping chain observes it here and must swallow it.
475
+ })
476
+ .finally(() => {
477
+ conversationCache.inFlight.delete(key)
478
+ for (const [subscriber, onAbort] of created.signals) {
479
+ subscriber.removeEventListener("abort", onAbort)
480
+ }
481
+ })
482
+ }
483
+ const active = entry
484
+ if (signal) {
485
+ const onAbort = () => {
486
+ active.signals.delete(signal)
487
+ // Last subscriber cancel kills the shared child; any remaining
488
+ // subscriber keeps it alive and still receives the result.
489
+ if (active.signals.size === 0) active.controller.abort()
490
+ }
491
+ active.signals.set(signal, onAbort)
492
+ if (signal.aborted) onAbort()
493
+ else signal.addEventListener("abort", onAbort, { once: true })
494
+ }
495
+ // The shared child runs on its own controller. Each caller's own abort
496
+ // only races their individual wait: the caller stops waiting (their
497
+ // request rejects as aborted) while the shared child keeps running for
498
+ // any remaining subscribers — production requests therefore reuse the
499
+ // in-flight read AND still stop on client disconnect.
500
+ if (!signal) return active.promise
501
+ return new Promise<ConversationMessage>((resolveOuter, rejectOuter) => {
502
+ let settled = false
503
+ const settleRace = (value: ConversationMessage | Error) => {
504
+ if (settled) return
505
+ settled = true
506
+ signal.removeEventListener("abort", onCallerAbort)
507
+ if (value instanceof Error) rejectOuter(value)
508
+ else resolveOuter(value)
509
+ }
510
+ const onCallerAbort = () =>
511
+ settleRace(
512
+ new MailosCommandError("aborted", "MailOS command cancelled"),
513
+ )
514
+ active.promise.then(
515
+ (message) => settleRace(message),
516
+ (error: unknown) =>
517
+ settleRace(error instanceof Error ? error : new Error(String(error))),
518
+ )
519
+ signal.addEventListener("abort", onCallerAbort, { once: true })
520
+ if (signal.aborted) onCallerAbort()
521
+ })
522
+ }
523
+
524
+ async function conversation(
525
+ cwd: string,
526
+ references: string[],
527
+ signal?: AbortSignal,
528
+ ): Promise<ConversationResult> {
529
+ const ids = [
530
+ ...new Set(
531
+ references
532
+ .map((candidate) => candidate.trim())
533
+ .filter((candidate) => Boolean(candidate) && !/\s/.test(candidate)),
534
+ ),
535
+ ].slice(0, conversationLimits.maxReferences)
536
+
537
+ const items: ConversationMessage[] = []
538
+ const missing: string[] = []
539
+ if (!ids.length) return { items, missing, outcome: "empty" }
540
+
541
+ const deadline = Date.now() + conversationLimits.totalBudgetMs
542
+ let timedOut = false
543
+ const queued = ids.map((id) => ({ id, started: false, done: false }))
544
+ let nextIndex = 0
545
+
546
+ const worker = async () => {
547
+ while (nextIndex < queued.length) {
548
+ const slot = queued[nextIndex]
549
+ if (!slot) break
550
+ nextIndex += 1
551
+ slot.started = true
552
+ try {
553
+ const message = await cachedRead(cwd, slot.id, signal)
554
+ if (!items.some((item) => item.id === message.id)) {
555
+ items.push(message)
556
+ }
557
+ } catch (error) {
558
+ if (error instanceof MailosCommandError) {
559
+ if (error.timedOut) timedOut = true
560
+ if (error.aborted) throw error
561
+ }
562
+ missing.push(slot.id)
563
+ }
564
+ if (Date.now() >= deadline) {
565
+ timedOut = true
566
+ break
567
+ }
568
+ }
569
+ }
570
+
571
+ const workers = Array.from(
572
+ { length: Math.min(conversationLimits.concurrency, ids.length) },
573
+ () => worker(),
574
+ )
575
+ await Promise.all(workers)
576
+
577
+ if (timedOut) return { items, missing, outcome: "timeout" }
578
+ if (!items.length && missing.length === ids.length) {
579
+ return { items, missing, outcome: "not-found" }
580
+ }
581
+ if (missing.length > 0) return { items, missing, outcome: "partial" }
582
+ return { items, missing, outcome: "ok" }
583
+ }
584
+
585
+ async function sendPreview(
586
+ cwd: string,
587
+ id: string,
588
+ options: SendDraftParams = {},
589
+ ): Promise<SendPreviewResult> {
590
+ const draftDir = requireDraftDir(options.draftDir)
591
+ const bin = await binary(cwd)
592
+ const args = ["send", "draft", id, "--draft-dir", draftDir, "--preview"]
593
+ const { stdout, stderr } = await runMailos(execFile, bin, args, {
594
+ cwd,
595
+ timeoutMs: 30_000,
596
+ signal: options.signal,
597
+ })
598
+ const output = [stdout, stderr].filter(Boolean).join("\n")
599
+ const revision = /^Revision:\s*([a-f0-9]{64})\s*$/im.exec(output)?.[1]
600
+ if (!revision) {
601
+ throw new MailSendFailure(
602
+ "invalid-draft",
603
+ "MailOS did not return a revision; the draft is not sendable.",
604
+ )
605
+ }
606
+ return { dryRun: true, output, revision }
607
+ }
608
+
609
+ async function confirmSend(
610
+ cwd: string,
611
+ id: string,
612
+ revision: string,
613
+ options: SendDraftParams = {},
614
+ ): Promise<SendResult> {
615
+ if (!/^[a-f0-9]{64}$/i.test(revision)) {
616
+ throw new MailSendFailure("revision-match", "Invalid draft revision")
617
+ }
618
+ const draftDir = requireDraftDir(options.draftDir)
619
+ const bin = await binary(cwd)
620
+ const args = [
621
+ "send",
622
+ "draft",
623
+ id,
624
+ "--draft-dir",
625
+ draftDir,
626
+ "--draft-revision",
627
+ revision,
628
+ "--delete-after=false",
629
+ ]
630
+ const { stdout, stderr } = await runMailos(execFile, bin, args, {
631
+ cwd,
632
+ timeoutMs: 60_000,
633
+ signal: options.signal,
634
+ })
635
+ const output = [stdout, stderr].filter(Boolean).join("\n")
636
+ // MailOS refuses a single draft whose bytes changed after the preview
637
+ // (send.go prints `❌ Draft <base> changed after preview` and errors the
638
+ // run). Surface that retryable conflict as a revision conflict, not as a
639
+ // generic command failure.
640
+ if (/\n?\s*❌\s*Draft\s+\S+\s+changed after preview/.test(output)) {
641
+ throw new MailSendFailure(
642
+ "revision-match",
643
+ "Draft changed after preview; refresh and preview again before sending",
644
+ )
645
+ }
646
+ const contract = validateSendContract(output)
647
+ if (!contract.ok) {
648
+ throw new MailSendFailure("contract", contract.reason)
649
+ }
650
+ return { dryRun: false, output }
651
+ }
652
+
653
+ async function archive(
654
+ cwd: string,
655
+ id: string,
656
+ options: SendDraftParams = {},
657
+ ): Promise<void> {
658
+ const draftDir = requireDraftDir(options.draftDir)
659
+ // `mailos drafts archive <id>` resolves ids ONLY against the global
660
+ // ~/.email/drafts directory (drafts.go `localDraftPath` ->
661
+ // `globalDraftDir`); it has no --draft-dir flag. A custom mailDir would
662
+ // silently mutate a same-named file (or fail) in the home drafts folder,
663
+ // so a non-canonical target is rejected here, before any spawn.
664
+ if (
665
+ !(await sameCanonicalDir(
666
+ draftDir,
667
+ globalDraftDir ?? mailosGlobalDraftDir(),
668
+ ))
669
+ ) {
670
+ throw new MailSendFailure(
671
+ "unsupported-draft-dir",
672
+ "MailOS drafts archive can only address the default ~/.email/drafts folder; this draft lives elsewhere. Delete it or archive it directly with mailos.",
673
+ )
674
+ }
675
+ const bin = await binary(cwd)
676
+ await runMailos(execFile, bin, ["drafts", "archive", id], {
677
+ cwd,
678
+ timeoutMs: 30_000,
679
+ signal: options.signal,
680
+ })
681
+ }
682
+
683
+ return {
684
+ identity,
685
+ signature,
686
+ conversation,
687
+ sendPreview,
688
+ confirmSend,
689
+ archive,
690
+ }
691
+ }
692
+
693
+ export type MailosService = ReturnType<typeof createMailosService>
694
+
695
+ /**
696
+ * MailOS exits successfully even when a bulk run skipped or failed drafts, so
697
+ * a non-zero exit alone cannot prove delivery. Validate the printed contract:
698
+ * no failure/skip markers, a summary claiming at least one sent draft, and no
699
+ * recorded errors.
700
+ */
701
+ export function validateSendContract(
702
+ output: string,
703
+ ): { ok: true } | { ok: false; reason: string } {
704
+ const markers = /^\s*(❌|⏭️)/m.exec(output)
705
+ if (markers) {
706
+ return { ok: false, reason: "MailOS reported a failed or skipped draft" }
707
+ }
708
+ if (output.includes("No draft files found to send")) {
709
+ return { ok: false, reason: "MailOS did not find the draft to send" }
710
+ }
711
+ const errors = /^\s*❌\s*Errors:\s*(\d+)/m.exec(output)
712
+ if (errors?.[1] && Number(errors[1]) > 0) {
713
+ return {
714
+ ok: false,
715
+ reason: `MailOS reported ${errors[1]} send error(s)`,
716
+ }
717
+ }
718
+ const sent = /^\s*✅\s*(?:Sent|Previewed|Would send):\s*(\d+)/m.exec(output)
719
+ if (!sent || Number(sent[1]) < 1) {
720
+ return { ok: false, reason: "MailOS did not confirm the draft was sent" }
721
+ }
722
+ return { ok: true }
723
+ }