kennel 0.2.2 → 0.2.5

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 (237) hide show
  1. package/README.md +23 -13
  2. package/dist/cli/dispatch.js +16 -3
  3. package/dist/cli/src/cli/dispatch.js +16 -3
  4. package/dist/cli/src/cli/usage.js +1 -1
  5. package/dist/cli/src/core/command.js +1 -0
  6. package/dist/cli/src/core/init.js +5 -5
  7. package/dist/cli/src/plugins/external.d.ts +29 -3
  8. package/dist/cli/src/plugins/external.js +78 -24
  9. package/dist/cli/src/site/server-plugins.d.ts +2 -7
  10. package/dist/cli/src/site/viewer.js +1 -0
  11. package/dist/cli/usage.js +1 -1
  12. package/dist/core/command.js +1 -0
  13. package/dist/core/init.js +5 -5
  14. package/dist/core/runtime.js +357 -3207
  15. package/dist/package/preview.js +1232 -5113
  16. package/dist/plugins/external.d.ts +29 -3
  17. package/dist/plugins/external.js +78 -24
  18. package/dist/site/server-plugins.d.ts +2 -7
  19. package/dist/site/server-plugins.js +552 -10447
  20. package/dist/site/viewer.js +1 -0
  21. package/kernel/apps/web/package.json +1 -5
  22. package/kernel/apps/web/scripts/dev.mjs +53 -0
  23. package/kernel/apps/web/src/app.css +0 -3
  24. package/kernel/apps/web/src/main.tsx +0 -1
  25. package/kernel/apps/web/src/plugins.ts +0 -30
  26. package/kernel/apps/web/tsconfig.json +1 -2
  27. package/kernel/apps/web/vite.config.ts +31 -13
  28. package/kernel/packages/api/package.json +0 -4
  29. package/kernel/packages/api/src/server/folder-metadata-plugin.ts +13 -38
  30. package/kernel/packages/api/src/server/index.ts +0 -1
  31. package/kernel/packages/api/src/server/plugins.ts +49 -16
  32. package/kernel/packages/api/test/core.test.ts +13 -25
  33. package/kernel/packages/markdown/README.md +1 -1
  34. package/package.json +1 -1
  35. package/web/assets/{abnfDiagram-VRR7QNED-Bgfb1nEB.js → abnfDiagram-VRR7QNED-xd_g1uK3.js} +1 -1
  36. package/web/assets/app-CX20nNIa.js +2 -0
  37. package/web/assets/{app-options-D-RJiQ-X.js → app-options-CkPJE5ep.js} +1 -1
  38. package/web/assets/{app-view-header-BLvLq02T.js → app-view-header-CNk5KnA-.js} +1 -1
  39. package/web/assets/{arc-Dk_KI36B.js → arc-B0u5yBJA.js} +1 -1
  40. package/web/assets/{architectureDiagram-ZJ3FMSHR-NR_KhRCf.js → architectureDiagram-ZJ3FMSHR-DfxOAo8P.js} +1 -1
  41. package/web/assets/{ask-tray-TzeTcO6-.js → ask-tray-SscJecDY.js} +1 -1
  42. package/web/assets/{blockDiagram-677ZJIJ3-CkLkwx9C.js → blockDiagram-677ZJIJ3-Ci3Usxh6.js} +1 -1
  43. package/web/assets/{c4Diagram-LMCZKHZV-CFCUH8e_.js → c4Diagram-LMCZKHZV-BqgwIVgh.js} +1 -1
  44. package/web/assets/channel-X7WHyxxT.js +1 -0
  45. package/web/assets/{chunk-2Q5K7J3B-B_BPLWsW.js → chunk-2Q5K7J3B-CfX69l2U.js} +1 -1
  46. package/web/assets/{chunk-32BRIVSS-B1VB1hOy.js → chunk-32BRIVSS-CuFlzZkl.js} +1 -1
  47. package/web/assets/{chunk-5VM5RSS4-KFcYr8Co.js → chunk-5VM5RSS4-DidCMlJa.js} +1 -1
  48. package/web/assets/{chunk-EX3LRPZG-CpBX3kuK.js → chunk-EX3LRPZG-B5CDm1dS.js} +1 -1
  49. package/web/assets/{chunk-JWPE2WC7-BPSl40wG.js → chunk-JWPE2WC7-D5fGV_sH.js} +1 -1
  50. package/web/assets/{chunk-MOJQB5TN-D2RcYmoU.js → chunk-MOJQB5TN-ayhH5Q-H.js} +1 -1
  51. package/web/assets/{chunk-RYQCIY6F-m7Gyn-t3.js → chunk-RYQCIY6F-C4BfOOZn.js} +1 -1
  52. package/web/assets/{chunk-V7JOEXUC-TDvdopxS.js → chunk-V7JOEXUC-DpUEIM9V.js} +1 -1
  53. package/web/assets/{chunk-VR4S4FIN-DZTsG51a.js → chunk-VR4S4FIN-DoQuFFRh.js} +1 -1
  54. package/web/assets/{chunk-XXDRQBXY-Dp0--RE2.js → chunk-XXDRQBXY-CI9eiLwn.js} +1 -1
  55. package/web/assets/classDiagram-OUVF2IWQ-BjsLQ3dz.js +1 -0
  56. package/web/assets/classDiagram-v2-EOCWNBFH-BjsLQ3dz.js +1 -0
  57. package/web/assets/client-7OWw5kW2.js +6 -0
  58. package/web/assets/client-DYj_td4Q.js +17 -0
  59. package/web/assets/{client-j2kQmxsO.js → client-Dk-NBvJR.js} +4 -4
  60. package/web/assets/command-zkzH4hVz.js +38 -0
  61. package/web/assets/{copy-context-C0Uqsp-3.js → copy-context-D5oiWrYC.js} +1 -1
  62. package/web/assets/{cose-bilkent-JH36ORCC-CPu3PI8h.js → cose-bilkent-JH36ORCC-BHRk1mO3.js} +1 -1
  63. package/web/assets/{cynefin-VYW2F7L2-DWxftYAm.js → cynefin-VYW2F7L2-C1B09TRE.js} +1 -1
  64. package/web/assets/{cynefinDiagram-TSTJHNR4-DsmN2V-p.js → cynefinDiagram-TSTJHNR4-B27qXQbv.js} +1 -1
  65. package/web/assets/{dagre-VKFMJZFB-COEbApyY.js → dagre-VKFMJZFB-B1qEi32g.js} +1 -1
  66. package/web/assets/{diagram-FQU43EPY-0O9WGWKB.js → diagram-FQU43EPY-BMkkgADD.js} +1 -1
  67. package/web/assets/{diagram-G47NLZAW-CutEdMVh.js → diagram-G47NLZAW-Cb8_g1A5.js} +1 -1
  68. package/web/assets/{diagram-NH7WQ7WH-C9KZc3B2.js → diagram-NH7WQ7WH-B51wuc5m.js} +1 -1
  69. package/web/assets/{diagram-OA4YK3LP-D8kkPXbY.js → diagram-OA4YK3LP-xnsecbbI.js} +1 -1
  70. package/web/assets/{diagram-WEI45ONY-_YqiTaGP.js → diagram-WEI45ONY-DSZdyaAV.js} +1 -1
  71. package/web/assets/{document-Dgt5eZFj.js → document-Dc2dftTW.js} +3 -3
  72. package/web/assets/{ebnfDiagram-CCIWWBDH-JO-zQh6g.js → ebnfDiagram-CCIWWBDH-aTHmcUGy.js} +1 -1
  73. package/web/assets/{entities-C3wz7FCx.js → entities-CCUtpskY.js} +1 -1
  74. package/web/assets/{erDiagram-Q63AITRT-9UjQwJ4P.js → erDiagram-Q63AITRT-CUUPBcvo.js} +1 -1
  75. package/web/assets/{file-viewer-DZJ8nYnl.js → file-viewer-DJ3rsmef.js} +1 -1
  76. package/web/assets/{flowDiagram-23GEKE2U-Ca08tnYM.js → flowDiagram-23GEKE2U-aTQXx2Mh.js} +1 -1
  77. package/web/assets/{folder-image-BfGgxo7i.js → folder-image-Bnv43tzP.js} +1 -1
  78. package/web/assets/{folder-landing-qUKBCnG-.js → folder-landing-DCnzYXXY.js} +1 -1
  79. package/web/assets/{folder-list-BfFjv7rR.js → folder-list-DvVkVjiR.js} +1 -1
  80. package/web/assets/{folder-metadata-DCw8xzHk.js → folder-metadata-C9hMMzIH.js} +1 -1
  81. package/web/assets/{folder-mobile-bar-Ubz4babf.js → folder-mobile-bar-VoTL1GS0.js} +1 -1
  82. package/web/assets/folder-plugin-view-Cvd804ZU.js +6 -0
  83. package/web/assets/{ganttDiagram-NO4QXBWP-KnHzX5W3.js → ganttDiagram-NO4QXBWP-DiwdUp7u.js} +1 -1
  84. package/web/assets/{gitGraphDiagram-IHSO6WYX-Cm8woNtK.js → gitGraphDiagram-IHSO6WYX-BL2gG_IS.js} +1 -1
  85. package/web/assets/{index-CNyy98F8.js → index-CUTtMSyJ.js} +2 -2
  86. package/web/assets/index-CegvVQ1C.js +1 -0
  87. package/web/assets/index-Dwhf8F_U.css +1 -0
  88. package/web/assets/{infoDiagram-FWYZ7A6U-yyqmUtIb.js → infoDiagram-FWYZ7A6U-B3n0zZpt.js} +1 -1
  89. package/web/assets/{ishikawaDiagram-FXEZZL3T-BfvR_Zy4.js → ishikawaDiagram-FXEZZL3T-D7YytbEv.js} +1 -1
  90. package/web/assets/{journeyDiagram-5HDEW3XC-BKuw06HM.js → journeyDiagram-5HDEW3XC-BYwqEl3C.js} +1 -1
  91. package/web/assets/{kanban-definition-HUTT4EX6-n0010rmQ.js → kanban-definition-HUTT4EX6-BQHNJgXZ.js} +1 -1
  92. package/web/assets/{linear-C0d0lT8O.js → linear-BPiQCLNk.js} +1 -1
  93. package/web/assets/{mermaid.core-BDVbShyO.js → mermaid.core-CD-KvBjV.js} +4 -4
  94. package/web/assets/{metadata-KV0dpp4G.js → metadata-COJ7fZul.js} +1 -1
  95. package/web/assets/{mindmap-definition-LN4V7U3C--_0ks3GF.js → mindmap-definition-LN4V7U3C-C1L_gyoj.js} +1 -1
  96. package/web/assets/{pegDiagram-2B236MQR-CBoNIpKR.js → pegDiagram-2B236MQR-BDAfItqS.js} +1 -1
  97. package/web/assets/{pieDiagram-ENE6RG2P-MA5tkYh5.js → pieDiagram-ENE6RG2P-CkZYH3Vz.js} +1 -1
  98. package/web/assets/{popover-DBD7FF-W.js → popover-0oA2lLUV.js} +2 -2
  99. package/web/assets/{project-search-dialog-DM1IkSZu.js → project-search-dialog-B2oqMT6h.js} +1 -1
  100. package/web/assets/{quadrantDiagram-ABIIQ3AL-CWT1ryqF.js → quadrantDiagram-ABIIQ3AL-Dy8Al3YZ.js} +1 -1
  101. package/web/assets/{railroadDiagram-RFXS5EU6-ZiLB5FGi.js → railroadDiagram-RFXS5EU6-Dd9_yo7B.js} +1 -1
  102. package/web/assets/{requirementDiagram-TGXJPOKE-CQq9uneq.js → requirementDiagram-TGXJPOKE-DPhIUsbs.js} +1 -1
  103. package/web/assets/{sankeyDiagram-HTMAVEWB-qDG-0JqI.js → sankeyDiagram-HTMAVEWB-B2QkYtub.js} +1 -1
  104. package/web/assets/{search-DNrQA5fF.js → search-C1J0-xiB.js} +1 -1
  105. package/web/assets/select-CtXC_PLC.js +30 -0
  106. package/web/assets/{selection-popup-DmtTeRs2.js → selection-popup-qhlUFzGq.js} +1 -1
  107. package/web/assets/{sequenceDiagram-DBY2YBRQ-CiApurLO.js → sequenceDiagram-DBY2YBRQ-Bx7fcZDx.js} +1 -1
  108. package/web/assets/{sizeCapture-X5ZJPWSS-DZSR5QXm.js → sizeCapture-X5ZJPWSS-CIXIhl_A.js} +1 -1
  109. package/web/assets/{stateDiagram-2N3HPSRC-CjJJR9_z.js → stateDiagram-2N3HPSRC-DCrdAflB.js} +1 -1
  110. package/web/assets/stateDiagram-v2-6OUMAXLB-0KCFLYeQ.js +1 -0
  111. package/web/assets/{swimlanes-5IMT3BWC-CKmo1sg6.js → swimlanes-5IMT3BWC-DA2vc7iZ.js} +2 -2
  112. package/web/assets/swimlanesDiagram-G3AALYLV-CAw3AV84.js +8 -0
  113. package/web/assets/{timeline-definition-FHXFAJF6-D-NMwS3y.js → timeline-definition-FHXFAJF6-lKfJiV9V.js} +1 -1
  114. package/web/assets/{vennDiagram-L72KCM5P-CfL6LBWw.js → vennDiagram-L72KCM5P-DO1q2KzG.js} +1 -1
  115. package/web/assets/{view-context-gyDl_p2V.js → view-context-DXKM3-l1.js} +4 -4
  116. package/web/assets/{viewer-capabilities-Bpp8Uvcg.js → viewer-capabilities-Cig_xM9u.js} +1 -1
  117. package/web/assets/{wardleyDiagram-EHGQE667-DgldMxaj.js → wardleyDiagram-EHGQE667-Dal9LkuZ.js} +1 -1
  118. package/web/assets/{xychartDiagram-FW5EYKEG-CIoAIFX8.js → xychartDiagram-FW5EYKEG-B3dPLPII.js} +1 -1
  119. package/web/index.html +2 -2
  120. package/kernel/packages/api/test/partial-loading.test.ts +0 -43
  121. package/kernel/plugins/calendar/SKILL.md +0 -173
  122. package/kernel/plugins/calendar/eslint.config.js +0 -10
  123. package/kernel/plugins/calendar/package.json +0 -73
  124. package/kernel/plugins/calendar/schema.json +0 -137
  125. package/kernel/plugins/calendar/src/calendar.tsx +0 -328
  126. package/kernel/plugins/calendar/src/client.tsx +0 -139
  127. package/kernel/plugins/calendar/src/context.ts +0 -48
  128. package/kernel/plugins/calendar/src/copy-button.tsx +0 -66
  129. package/kernel/plugins/calendar/src/event-dialog.tsx +0 -270
  130. package/kernel/plugins/calendar/src/index.ts +0 -4
  131. package/kernel/plugins/calendar/src/manifest.ts +0 -7
  132. package/kernel/plugins/calendar/src/parse.ts +0 -610
  133. package/kernel/plugins/calendar/src/server.ts +0 -160
  134. package/kernel/plugins/calendar/src/utils.ts +0 -80
  135. package/kernel/plugins/calendar/src/views.tsx +0 -418
  136. package/kernel/plugins/calendar/test/context.test.mjs +0 -60
  137. package/kernel/plugins/calendar/test/package.test.mjs +0 -43
  138. package/kernel/plugins/calendar/test/parse.test.mjs +0 -392
  139. package/kernel/plugins/calendar/test/server.test.mjs +0 -126
  140. package/kernel/plugins/calendar/tsconfig.json +0 -17
  141. package/kernel/plugins/mail/SKILL.md +0 -97
  142. package/kernel/plugins/mail/eslint.config.js +0 -10
  143. package/kernel/plugins/mail/package.json +0 -79
  144. package/kernel/plugins/mail/src/api.ts +0 -359
  145. package/kernel/plugins/mail/src/bun-ffi.d.ts +0 -14
  146. package/kernel/plugins/mail/src/client.tsx +0 -14
  147. package/kernel/plugins/mail/src/flock.ts +0 -137
  148. package/kernel/plugins/mail/src/folders.ts +0 -37
  149. package/kernel/plugins/mail/src/history.ts +0 -485
  150. package/kernel/plugins/mail/src/index.ts +0 -3
  151. package/kernel/plugins/mail/src/mail-card.tsx +0 -123
  152. package/kernel/plugins/mail/src/mail-conversation.tsx +0 -153
  153. package/kernel/plugins/mail/src/mail-detail-page.tsx +0 -467
  154. package/kernel/plugins/mail/src/mail-hooks.ts +0 -252
  155. package/kernel/plugins/mail/src/mail-page.tsx +0 -109
  156. package/kernel/plugins/mail/src/mail-request.ts +0 -78
  157. package/kernel/plugins/mail/src/mail-send-box.tsx +0 -175
  158. package/kernel/plugins/mail/src/mailos.ts +0 -723
  159. package/kernel/plugins/mail/src/manifest.ts +0 -7
  160. package/kernel/plugins/mail/src/node.ts +0 -171
  161. package/kernel/plugins/mail/src/parse.ts +0 -139
  162. package/kernel/plugins/mail/src/server.ts +0 -125
  163. package/kernel/plugins/mail/src/types.ts +0 -10
  164. package/kernel/plugins/mail/src/viewer.tsx +0 -147
  165. package/kernel/plugins/mail/test/flock.test.mjs +0 -156
  166. package/kernel/plugins/mail/test/folders.test.mjs +0 -138
  167. package/kernel/plugins/mail/test/history.test.mjs +0 -460
  168. package/kernel/plugins/mail/test/mailos.test.mjs +0 -752
  169. package/kernel/plugins/mail/test/node.test.mjs +0 -207
  170. package/kernel/plugins/mail/test/package.test.mjs +0 -54
  171. package/kernel/plugins/mail/test/parse.test.mjs +0 -32
  172. package/kernel/plugins/mail/test/server.test.mjs +0 -116
  173. package/kernel/plugins/mail/test/viewer.test.mjs +0 -192
  174. package/kernel/plugins/mail/tsconfig.json +0 -17
  175. package/kernel/plugins/projects/SKILL.md +0 -73
  176. package/kernel/plugins/projects/eslint.config.js +0 -10
  177. package/kernel/plugins/projects/package.json +0 -70
  178. package/kernel/plugins/projects/src/client.tsx +0 -17
  179. package/kernel/plugins/projects/src/data/model.ts +0 -129
  180. package/kernel/plugins/projects/src/index.ts +0 -17
  181. package/kernel/plugins/projects/src/manifest.ts +0 -7
  182. package/kernel/plugins/projects/src/project-context.ts +0 -41
  183. package/kernel/plugins/projects/src/server.ts +0 -276
  184. package/kernel/plugins/projects/src/ui/project-card.tsx +0 -61
  185. package/kernel/plugins/projects/src/ui/projects-page.tsx +0 -102
  186. package/kernel/plugins/projects/test/package.test.mjs +0 -51
  187. package/kernel/plugins/projects/tsconfig.json +0 -17
  188. package/kernel/plugins/tasks/SKILL.md +0 -341
  189. package/kernel/plugins/tasks/eslint.config.js +0 -10
  190. package/kernel/plugins/tasks/package.json +0 -74
  191. package/kernel/plugins/tasks/schema.json +0 -939
  192. package/kernel/plugins/tasks/src/api.ts +0 -212
  193. package/kernel/plugins/tasks/src/client.tsx +0 -23
  194. package/kernel/plugins/tasks/src/data/parse.ts +0 -544
  195. package/kernel/plugins/tasks/src/data/task-id.ts +0 -56
  196. package/kernel/plugins/tasks/src/data/todo-model.ts +0 -795
  197. package/kernel/plugins/tasks/src/index.ts +0 -34
  198. package/kernel/plugins/tasks/src/manifest.ts +0 -7
  199. package/kernel/plugins/tasks/src/pages/task-detail.tsx +0 -48
  200. package/kernel/plugins/tasks/src/pages/task-list.tsx +0 -88
  201. package/kernel/plugins/tasks/src/server.ts +0 -447
  202. package/kernel/plugins/tasks/src/styles.css +0 -9
  203. package/kernel/plugins/tasks/src/ui/compact-todo-list.tsx +0 -372
  204. package/kernel/plugins/tasks/src/ui/error-details.tsx +0 -78
  205. package/kernel/plugins/tasks/src/ui/task-page.tsx +0 -392
  206. package/kernel/plugins/tasks/src/ui/todo-agent-filter.tsx +0 -36
  207. package/kernel/plugins/tasks/src/ui/todo-filter-bar.tsx +0 -66
  208. package/kernel/plugins/tasks/src/ui/todo-item.tsx +0 -494
  209. package/kernel/plugins/tasks/src/ui/todo-status-filter.tsx +0 -60
  210. package/kernel/plugins/tasks/src/ui/todo-tag-filter.tsx +0 -48
  211. package/kernel/plugins/tasks/src/ui/todo-warnings.tsx +0 -106
  212. package/kernel/plugins/tasks/test/api.test.mjs +0 -99
  213. package/kernel/plugins/tasks/test/folder-sources.test.mjs +0 -46
  214. package/kernel/plugins/tasks/test/package.test.mjs +0 -54
  215. package/kernel/plugins/tasks/test/parse.test.mjs +0 -225
  216. package/kernel/plugins/tasks/test/server.test.mjs +0 -386
  217. package/kernel/plugins/tasks/tsconfig.json +0 -17
  218. package/web/assets/app-DoGr2Zi7.js +0 -2
  219. package/web/assets/channel-uMEjV8qc.js +0 -1
  220. package/web/assets/classDiagram-OUVF2IWQ-fbZocVor.js +0 -1
  221. package/web/assets/classDiagram-v2-EOCWNBFH-fbZocVor.js +0 -1
  222. package/web/assets/client-C6Nxdfif.js +0 -2
  223. package/web/assets/client-CXYfBko5.js +0 -17
  224. package/web/assets/client-CoKtOq-X.js +0 -7
  225. package/web/assets/client-DyRQz5RU.js +0 -53
  226. package/web/assets/client-OY6HUzuD.js +0 -98
  227. package/web/assets/client-YOYWZIFi.js +0 -34
  228. package/web/assets/command-BugZBGXE.js +0 -38
  229. package/web/assets/folder-plugin-view-DsWR1zmQ.js +0 -6
  230. package/web/assets/index-BaRnbYRw.js +0 -1
  231. package/web/assets/index-BexmLxIP.css +0 -1
  232. package/web/assets/index-DDirZMgx.js +0 -1
  233. package/web/assets/note-card-DBfX6gW1.js +0 -6
  234. package/web/assets/select-D8cqNgcp.js +0 -30
  235. package/web/assets/stateDiagram-v2-6OUMAXLB-BpeGSCu9.js +0 -1
  236. package/web/assets/swimlanesDiagram-G3AALYLV-D9RjLKb9.js +0 -8
  237. package/web/assets/use-folder-filter-LQyXns5Q.js +0 -1
@@ -313,6 +313,7 @@ export async function viewer(input) {
313
313
  }
314
314
  process.env.KENNEL_KERNEL_KEY = kernel.key;
315
315
  process.env.KENNEL_EXTERNAL_SERVER_ENTRIES = JSON.stringify(kernel.serverEntries);
316
+ process.env.KENNEL_EXTERNAL_API_ENTRIES = JSON.stringify(kernel.apiEntries);
316
317
  const api = createKennelApi({
317
318
  root: options.root,
318
319
  host: options.host,
@@ -6,7 +6,7 @@
6
6
  "prettier": "@raggle-ai/prettier-config",
7
7
  "scripts": {
8
8
  "build": "node scripts/build.mjs",
9
- "dev": "vite dev",
9
+ "dev": "node scripts/dev.mjs",
10
10
  "typecheck": "tsc --noEmit",
11
11
  "format": "prettier . --check --cache --cache-location .cache/.prettiercache --ignore-path ../../.prettierignore",
12
12
  "format:fix": "prettier . --write --cache --cache-location .cache/.prettiercache --ignore-path ../../.prettierignore",
@@ -23,19 +23,15 @@
23
23
  "@lexical/react": "0.49.0",
24
24
  "@lexical/rich-text": "0.49.0",
25
25
  "@raggle-ai/agents": "workspace:*",
26
- "@raggle-ai/calendar": "workspace:*",
27
26
  "@raggle-ai/folder-plugin": "workspace:*",
28
27
  "@raggle-ai/kennel-api": "workspace:*",
29
28
  "@raggle-ai/kennel-preview": "workspace:*",
30
29
  "@raggle-ai/local": "0.14.0",
31
- "@raggle-ai/mail": "workspace:*",
32
30
  "@raggle-ai/markdown": "workspace:*",
33
31
  "@raggle-ai/notes": "workspace:*",
34
- "@raggle-ai/projects": "workspace:*",
35
32
  "@raggle-ai/schemas": "workspace:*",
36
33
  "@raggle-ai/scout-ui": "0.1.3",
37
34
  "@raggle-ai/session-finding": "workspace:*",
38
- "@raggle-ai/tasks": "workspace:*",
39
35
  "@raggle-ai/ui": "workspace:*",
40
36
  "@tanstack/react-query": "catalog:tanstack",
41
37
  "@tanstack/react-router": "catalog:tanstack",
@@ -0,0 +1,53 @@
1
+ import { spawn } from "node:child_process"
2
+ import { mkdtemp, rm } from "node:fs/promises"
3
+ import { tmpdir } from "node:os"
4
+ import { dirname, join, resolve } from "node:path"
5
+ import { fileURLToPath } from "node:url"
6
+
7
+ import {
8
+ prepareExternalPluginModules,
9
+ readExternalPlugins,
10
+ } from "../../../cli/src/plugins/external.ts"
11
+
12
+ const workspace = resolve(import.meta.dirname, "../../..")
13
+ const temp = await mkdtemp(join(tmpdir(), "kennel-web-dev-"))
14
+ try {
15
+ const plugins = readExternalPlugins()
16
+ const modules = await prepareExternalPluginModules(temp, temp, plugins)
17
+ const args = process.argv.slice(2).filter((arg) => arg !== "--")
18
+ const child = spawn(
19
+ process.execPath,
20
+ [
21
+ resolve(
22
+ dirname(fileURLToPath(import.meta.resolve("vite/package.json"))),
23
+ "bin/vite.js",
24
+ ),
25
+ "dev",
26
+ ...args,
27
+ ],
28
+ {
29
+ cwd: resolve(workspace, "apps/web"),
30
+ stdio: "inherit",
31
+ env: {
32
+ ...process.env,
33
+ KENNEL_KERNEL_SOURCE_ROOT: workspace,
34
+ KENNEL_HOST_NODE_MODULES: resolve(workspace, "cli/node_modules"),
35
+ KENNEL_EXTERNAL_CLIENT_MODULE: modules.clientModule,
36
+ KENNEL_EXTERNAL_SERVER_ENTRIES: JSON.stringify(modules.serverEntries),
37
+ KENNEL_EXTERNAL_API_ENTRIES: JSON.stringify(modules.apiEntries),
38
+ KENNEL_EXTERNAL_SOURCE_ROOTS: JSON.stringify(
39
+ plugins.map((plugin) => dirname(plugin.entries.client)),
40
+ ),
41
+ },
42
+ },
43
+ )
44
+ for (const signal of ["SIGINT", "SIGTERM"]) {
45
+ process.on(signal, () => child.kill(signal))
46
+ }
47
+ process.exitCode = await new Promise((resolve, reject) => {
48
+ child.once("error", reject)
49
+ child.once("exit", (code) => resolve(code ?? 1))
50
+ })
51
+ } finally {
52
+ await rm(temp, { recursive: true, force: true })
53
+ }
@@ -1,9 +1,6 @@
1
1
  @import "tailwindcss";
2
2
  @source "../../../packages/agents/src";
3
3
  @source "../../../packages/ui/src";
4
- @source "../../../plugins/calendar/src";
5
- @source "../../../plugins/mail/src";
6
- @source "../../../plugins/tasks/src";
7
4
  @source "./";
8
5
 
9
6
  @theme {
@@ -1,7 +1,6 @@
1
1
  import "@raggle-ai/markdown/styles.css"
2
2
  import "@raggle-ai/markdown/explorer.css"
3
3
  import "@raggle-ai/ui/folder-activity.css"
4
- import "@raggle-ai/tasks/todo-model/styles.css"
5
4
  import "./app.css"
6
5
 
7
6
  import { StrictMode } from "react"
@@ -3,27 +3,10 @@ import { externalFolderPlugins } from "@/external-plugins"
3
3
 
4
4
  import type { FolderPluginClient } from "@raggle-ai/folder-plugin/client"
5
5
  import { agentsManifest } from "@raggle-ai/agents/manifest"
6
- import { calendarManifest } from "@raggle-ai/calendar/manifest"
7
- import { mailManifest } from "@raggle-ai/mail/manifest"
8
- import { projectsManifest } from "@raggle-ai/projects/manifest"
9
- import { tasksManifest } from "@raggle-ai/tasks/manifest"
10
6
 
11
7
  // Keep navigation metadata cheap. Import only the selected plugin's UI;
12
8
  // never construct an import path from an untrusted URL segment.
13
9
  export const folderPlugins: FolderPluginClient[] = [
14
- {
15
- ...calendarManifest,
16
- component: lazy(async () => ({
17
- default: (await import("@raggle-ai/calendar/client")).calendarClient
18
- .component,
19
- })),
20
- },
21
- {
22
- ...mailManifest,
23
- component: lazy(async () => ({
24
- default: (await import("@raggle-ai/mail/client")).mailClient.component,
25
- })),
26
- },
27
10
  {
28
11
  ...agentsManifest,
29
12
  component: lazy(async () => ({
@@ -31,19 +14,6 @@ export const folderPlugins: FolderPluginClient[] = [
31
14
  .component,
32
15
  })),
33
16
  },
34
- {
35
- ...tasksManifest,
36
- component: lazy(async () => ({
37
- default: (await import("@raggle-ai/tasks/client")).tasksClient.component,
38
- })),
39
- },
40
- {
41
- ...projectsManifest,
42
- component: lazy(async () => ({
43
- default: (await import("@raggle-ai/projects/client")).projectsClient
44
- .component,
45
- })),
46
- },
47
17
  ...externalFolderPlugins,
48
18
  ]
49
19
 
@@ -6,8 +6,7 @@
6
6
  "src/**/*.ts",
7
7
  "src/**/*.tsx",
8
8
  "test/**/*.test.ts",
9
- "vite.config.ts",
10
- "../../plugins/mail/src/bun-ffi.d.ts"
9
+ "vite.config.ts"
11
10
  ],
12
11
  "compilerOptions": {
13
12
  "baseUrl": ".",
@@ -15,17 +15,32 @@ const workspace = resolve(
15
15
  process.env.KENNEL_KERNEL_SOURCE_ROOT || resolve(root, "../.."),
16
16
  )
17
17
  const require = createRequire(import.meta.url)
18
+ const hostNodeModules = process.env.KENNEL_HOST_NODE_MODULES
19
+ const packageNameOf = (name: string) => {
20
+ const [scopeOrName, packageName] = name.split("/")
21
+ return name.startsWith("@") && packageName
22
+ ? `${scopeOrName}/${packageName}`
23
+ : (scopeOrName ?? name)
24
+ }
25
+ const hostPackagePath = (name: string, entry = "package.json") =>
26
+ hostNodeModules
27
+ ? resolve(hostNodeModules, packageNameOf(name), entry)
28
+ : undefined
18
29
  const packageDir = (name: string): string | undefined => {
30
+ const hostPath = hostPackagePath(name)
31
+ if (hostPath && existsSync(hostPath)) return dirname(hostPath)
19
32
  try {
20
- const packageName = name.startsWith("@")
21
- ? name.split("/").slice(0, 2).join("/")
22
- : name.split("/")[0]
33
+ const packageName = packageNameOf(name)
23
34
  return dirname(require.resolve(`${packageName}/package.json`))
24
35
  } catch {
25
36
  return undefined
26
37
  }
27
38
  }
28
39
  const packageEntry = (name: string): string | undefined => {
40
+ const packageName = packageNameOf(name)
41
+ const entry = name.slice(packageName.length).replace(/^\//, "")
42
+ const hostPath = hostPackagePath(name, entry)
43
+ if (hostPath && existsSync(hostPath)) return hostPath
29
44
  try {
30
45
  return require.resolve(name)
31
46
  } catch {
@@ -59,22 +74,21 @@ const resolveBarkdown = (): string | undefined => {
59
74
  const barkdown = resolveBarkdown()
60
75
  const internalPackages: Array<[RegExp, string]> = [
61
76
  [/^@raggle-ai\/agents(\/.*)?$/, "packages/agents/src"],
62
- [/^@raggle-ai\/calendar(\/.*)?$/, "plugins/calendar/src"],
63
77
  [/^@raggle-ai\/folder-plugin(\/.*)?$/, "packages/folder-plugin/src"],
64
78
  [/^@raggle-ai\/kennel-api(\/.*)?$/, "packages/api/src"],
65
- [/^@raggle-ai\/mail(\/.*)?$/, "plugins/mail/src"],
66
79
  [/^@raggle-ai\/markdown(\/.*)?$/, "packages/markdown/src"],
67
80
  [/^@raggle-ai\/notes(\/.*)?$/, "packages/notes/src"],
68
- [/^@raggle-ai\/projects(\/.*)?$/, "plugins/projects/src"],
69
81
  [/^@raggle-ai\/schemas(\/.*)?$/, "packages/schemas/src"],
70
82
  [/^@raggle-ai\/session-finding(\/.*)?$/, "packages/session-finding/src"],
71
- [/^@raggle-ai\/tasks(\/.*)?$/, "plugins/tasks/src"],
72
83
  [/^@raggle-ai\/ui(\/.*)?$/, "packages/ui/src"],
73
84
  [/^kennel-client(\/.*)?$/, "packages/api-client/src"],
74
85
  ]
75
86
  const hostPackageNames = [
87
+ "@raggle-ai/barkdown",
76
88
  "@tanstack/react-query",
77
89
  "@tanstack/react-router",
90
+ "date-fns",
91
+ "effect",
78
92
  "lucide-react",
79
93
  "react",
80
94
  "react-dom",
@@ -95,6 +109,14 @@ const hostPackageAliases = hostPackageNames.flatMap((name) => {
95
109
  const hostPackageRoots = hostPackageNames
96
110
  .map(packageDir)
97
111
  .filter((path): path is string => Boolean(path))
112
+ const externalSourceRoots: string[] = JSON.parse(
113
+ process.env.KENNEL_EXTERNAL_SOURCE_ROOTS || "[]",
114
+ )
115
+ const externalClientModule = process.env.KENNEL_EXTERNAL_CLIENT_MODULE
116
+ const externalRoots = [
117
+ ...externalSourceRoots,
118
+ ...(externalClientModule ? [dirname(externalClientModule)] : []),
119
+ ]
98
120
  const aliases: AliasOptions = [
99
121
  ...(process.env.KENNEL_EXTERNAL_CLIENT_MODULE
100
122
  ? [
@@ -114,10 +136,6 @@ const aliases: AliasOptions = [
114
136
  find: /^@raggle-ai\/markdown\/explorer\.css$/,
115
137
  replacement: resolve(workspace, "packages/markdown/explorer.css"),
116
138
  },
117
- {
118
- find: /^@raggle-ai\/tasks\/todo-model\/styles\.css$/,
119
- replacement: resolve(workspace, "plugins/tasks/src/styles.css"),
120
- },
121
139
  {
122
140
  find: /^@raggle-ai\/ui\/folder-activity\.css$/,
123
141
  replacement: resolve(
@@ -230,8 +248,8 @@ export default defineConfig({
230
248
  ],
231
249
  fs: {
232
250
  allow: barkdown
233
- ? [workspace, barkdown, ...hostPackageRoots]
234
- : [workspace, ...hostPackageRoots],
251
+ ? [workspace, barkdown, ...hostPackageRoots, ...externalRoots]
252
+ : [workspace, ...hostPackageRoots, ...externalRoots],
235
253
  },
236
254
  // Warm the biggest cold-transform graphs (measured ~1–5 s each on first
237
255
  // request, stacking into the long first load / first HMR after a server
@@ -19,17 +19,13 @@
19
19
  "dependencies": {
20
20
  "@agentclientprotocol/sdk": "^1.3.0",
21
21
  "@raggle-ai/agents": "workspace:*",
22
- "@raggle-ai/calendar": "workspace:*",
23
22
  "@raggle-ai/folder-plugin": "workspace:*",
24
23
  "@raggle-ai/kennel-kinds": "workspace:*",
25
24
  "@raggle-ai/local": "0.14.0",
26
- "@raggle-ai/mail": "workspace:*",
27
25
  "@raggle-ai/markdown": "workspace:*",
28
26
  "@raggle-ai/notes": "workspace:*",
29
- "@raggle-ai/projects": "workspace:*",
30
27
  "@raggle-ai/schemas": "workspace:*",
31
28
  "@raggle-ai/session-finding": "workspace:*",
32
- "@raggle-ai/tasks": "workspace:*",
33
29
  "@raggle-ai/ui": "workspace:*",
34
30
  "yaml": "^2.9.0",
35
31
  "zod": "catalog:"
@@ -22,15 +22,12 @@ import { parse as parseYaml } from "yaml";
22
22
 
23
23
  import type { FolderPluginServer } from "@raggle-ai/folder-plugin/server";
24
24
  import type { LocalMarkdownFileSummary, LocalProject } from "@raggle-ai/local";
25
- import type { MailApiContext, MailPreviewer } from "@raggle-ai/mail/api";
26
25
  import type { FolderSkill } from "@raggle-ai/ui/lib/folder-activity";
27
26
  import { runApiRoute } from "@raggle-ai/folder-plugin/endpoint";
28
27
  import { FolderPluginFailure } from "@raggle-ai/folder-plugin/server";
29
28
  import { folderWorkspace } from "@raggle-ai/schemas/workspace";
30
29
  import { createSchemaCollectionServer } from "@raggle-ai/schemas/server";
31
30
  import local from "@raggle-ai/local";
32
- import { handleMailApiRoutes } from "@raggle-ai/mail/api";
33
- import { handleTasksApiRoutes } from "@raggle-ai/tasks/api";
34
31
  import {
35
32
  listFolderSessions,
36
33
  readSessionTranscript,
@@ -45,6 +42,7 @@ import { folderIcon, workspaceBreadcrumbIcons } from "./folder-icons.js";
45
42
  import { faviconService } from "@raggle-ai/schemas/favicon";
46
43
  import {
47
44
  configuredFolderServerRegistry,
45
+ externalApiHandlers,
48
46
  folderServerRegistryAsync,
49
47
  type FolderPluginRegistryConfig,
50
48
  } from "./plugins.js";
@@ -137,17 +135,6 @@ export type FolderMetadataPluginOptions = {
137
135
  restrictToRoot?: boolean;
138
136
  root: string;
139
137
  sessionFinding?: SessionFinding;
140
- mailPreviewer?: MailPreviewer;
141
- /**
142
- * Inject a MailOS service (tests only). Defaults to a real subprocess
143
- * service resolved from PATH.
144
- */
145
- mailos?: MailApiContext["mailos"];
146
- /**
147
- * Override MailOS mail directory. Intended for tests.
148
- * Defaults to ~/.email/drafts.
149
- */
150
- mailDir?: string;
151
138
  /** Override the home directory used for Agent global files. Intended for tests. */
152
139
  agentsHomeDir?: string;
153
140
  /** Override isolated linked-project discovery, for tests. */
@@ -774,7 +761,7 @@ function pluginConfigWarnings(
774
761
  const ids = unique([...config.plugins.disable, ...config.plugins.order]);
775
762
  return ids
776
763
  .filter((id) => !registry.has(id))
777
- .map((id) => `unknown plugin id "${id}" — not bundled in this build`);
764
+ .map((id) => `unknown plugin id "${id}" — not installed in this build`);
778
765
  }
779
766
 
780
767
  async function pluginAvailability(
@@ -824,9 +811,6 @@ export function createFolderApi({
824
811
  restrictToRoot = false,
825
812
  root,
826
813
  sessionFinding,
827
- mailPreviewer,
828
- mailDir,
829
- mailos,
830
814
  agentsHomeDir,
831
815
  linkedFolderLoader,
832
816
  remoteAccess = false,
@@ -839,10 +823,9 @@ export function createFolderApi({
839
823
  readSessionTranscript,
840
824
  };
841
825
  const basePlugins = folderServerRegistryAsync({
842
- mailDir,
843
- previewer: mailPreviewer,
844
826
  agentsHomeDir,
845
827
  });
828
+ const baseExternalApiHandlers = externalApiHandlers();
846
829
  const assetFiles = new Map<
847
830
  string,
848
831
  { mediaType: IconAsset["mediaType"]; path: string }
@@ -1447,24 +1430,16 @@ export function createFolderApi({
1447
1430
  }
1448
1431
  return;
1449
1432
  }
1450
- if (
1451
- await handleMailApiRoutes(request, response, {
1452
- authorizeFolder: (value) => folderPath(value, root, lockedRoot),
1453
- mailDir,
1454
- mailos,
1455
- mailPreviewer,
1456
- watch,
1457
- })
1458
- )
1459
- return;
1460
- if (
1461
- await handleTasksApiRoutes(request, response, {
1462
- authorizeFolder: (value) => folderPath(value, root, lockedRoot),
1463
- readOnly: remote,
1464
- watch,
1465
- })
1466
- )
1467
- return;
1433
+ for (const handler of await baseExternalApiHandlers) {
1434
+ if (
1435
+ await handler(request, response, {
1436
+ authorizeFolder: (value) => folderPath(value, root, lockedRoot),
1437
+ readOnly: remote,
1438
+ watch,
1439
+ })
1440
+ )
1441
+ return;
1442
+ }
1468
1443
  if (url.pathname === "/api/create-agent-file") {
1469
1444
  if (remote) {
1470
1445
  response.writeHead(403, {
@@ -50,7 +50,6 @@ export function createKennelApi(options: KennelApiOptions) {
50
50
  },
51
51
  };
52
52
  const folder = createFolderApi({
53
- mailDir: process.env.KENNEL_MAIL_DIR || undefined,
54
53
  ...options,
55
54
  remoteAccess: remote,
56
55
  });
@@ -1,22 +1,16 @@
1
1
  import type { FolderPluginContext } from "@raggle-ai/folder-plugin/server";
2
2
  import type { FolderPluginServer } from "@raggle-ai/folder-plugin/server";
3
- import type { MailCreatePluginOptions } from "@raggle-ai/mail/server";
4
3
  import { pathToFileURL } from "node:url";
5
4
  import { existsSync } from "node:fs";
6
5
  import { mkdir, stat, writeFile } from "node:fs/promises";
7
6
  import { dirname, relative, resolve, sep } from "node:path";
8
7
  import { createAgentsPlugin } from "@raggle-ai/agents/server";
9
- import { createCalendarPlugin } from "@raggle-ai/calendar/server";
10
8
  import { FolderPluginFailure } from "@raggle-ai/folder-plugin/server";
11
- import { createMailPlugin } from "@raggle-ai/mail/server";
12
9
  import { createNotesPlugin } from "@raggle-ai/notes/server";
13
- import { createProjectsPlugin } from "@raggle-ai/projects/server";
14
- import { createTasksPlugin } from "@raggle-ai/tasks/server";
15
10
 
16
11
  export { FolderPluginFailure };
17
- export { handleMailApiRoutes } from "@raggle-ai/mail/api";
18
12
 
19
- export type FolderServerRegistryOptions = MailCreatePluginOptions & {
13
+ export type FolderServerRegistryOptions = {
20
14
  /** Override the home directory used for Agent global files. Intended for tests. */
21
15
  agentsHomeDir?: string;
22
16
  };
@@ -49,23 +43,15 @@ export function configuredFolderServerRegistry(
49
43
  return new Map(ids.map((id) => [id, registry.get(id)!]));
50
44
  }
51
45
 
52
- /**
53
- * Explicit server-only plugin registry. Mail preview execution and the mail
54
- * directory are injected here so the host and tests can keep their existing
55
- * seams while the plugin owns its folder authorization.
56
- */
46
+ /** Core server plugins. Installed plugins are loaded separately. */
57
47
  export function createFolderServerPlugins(
58
48
  options: FolderServerRegistryOptions = {},
59
49
  ): FolderPluginServer[] {
60
50
  return [
61
- createCalendarPlugin(),
62
- createMailPlugin(options),
63
51
  createAgentsPlugin({
64
52
  homeDir: options.agentsHomeDir,
65
53
  }),
66
54
  createNotesPlugin(),
67
- createTasksPlugin(),
68
- createProjectsPlugin(),
69
55
  ];
70
56
  }
71
57
 
@@ -84,6 +70,22 @@ type ExternalServerEntry = {
84
70
  trigger?: string;
85
71
  };
86
72
 
73
+ export type ExternalApiHandler = (
74
+ request: import("node:http").IncomingMessage,
75
+ response: import("node:http").ServerResponse,
76
+ context: {
77
+ authorizeFolder: (value: string | null) => string;
78
+ readOnly: boolean;
79
+ watch: (folder: string) => void;
80
+ },
81
+ ) => Promise<boolean>;
82
+
83
+ export type ExternalApiEntry = {
84
+ id: string;
85
+ module: string;
86
+ symbol: string;
87
+ };
88
+
87
89
  function externalServerEntries(): ExternalServerEntry[] {
88
90
  const source = process.env.KENNEL_EXTERNAL_SERVER_ENTRIES;
89
91
  if (!source) return [];
@@ -143,6 +145,37 @@ export async function folderServerRegistryAsync(
143
145
  return registry;
144
146
  }
145
147
 
148
+ function externalApiEntries(): ExternalApiEntry[] {
149
+ const source = process.env.KENNEL_EXTERNAL_API_ENTRIES;
150
+ if (!source) return [];
151
+ const value = JSON.parse(source) as unknown;
152
+ if (!Array.isArray(value)) throw new Error("Invalid external plugin API config");
153
+ return value.map((entry) => {
154
+ if (!entry || typeof entry !== "object" || Array.isArray(entry))
155
+ throw new Error("Invalid external plugin API config");
156
+ const item = entry as Partial<ExternalApiEntry>;
157
+ if (
158
+ typeof item.id !== "string" ||
159
+ typeof item.module !== "string" ||
160
+ typeof item.symbol !== "string"
161
+ )
162
+ throw new Error("Invalid external plugin API config");
163
+ return { id: item.id, module: item.module, symbol: item.symbol };
164
+ });
165
+ }
166
+
167
+ export async function externalApiHandlers(): Promise<ExternalApiHandler[]> {
168
+ const handlers: ExternalApiHandler[] = [];
169
+ for (const entry of externalApiEntries()) {
170
+ const imported = await import(pathToFileURL(entry.module).href);
171
+ const handler = imported[entry.symbol];
172
+ if (typeof handler !== "function")
173
+ throw new Error(`External plugin ${entry.id} did not export API handler ${entry.symbol}`);
174
+ handlers.push(handler as ExternalApiHandler);
175
+ }
176
+ return handlers;
177
+ }
178
+
146
179
  export type FolderPluginScaffoldFile = {
147
180
  plugin: string;
148
181
  path: string;
@@ -187,7 +187,7 @@ function plugin(id: string): FolderPluginServer {
187
187
  };
188
188
  }
189
189
 
190
- test("plugin registry config disables and orders only bundled plugins", () => {
190
+ test("plugin registry config disables and orders only registered plugins", () => {
191
191
  const calendar = plugin("calendar");
192
192
  const tasks = plugin("tasks");
193
193
  const projects = plugin("projects");
@@ -226,7 +226,9 @@ test("folder kennel.json filters plugin metadata and direct plugin routes", asyn
226
226
  metadata.plugins.items.map((item: { id: string }) => item.id),
227
227
  ).not.toContain("tasks");
228
228
  expect(metadata.plugins.configWarnings).toEqual([
229
- 'unknown plugin id "ghost" — not bundled in this build',
229
+ 'unknown plugin id "tasks" — not installed in this build',
230
+ 'unknown plugin id "ghost" — not installed in this build',
231
+ 'unknown plugin id "projects" — not installed in this build',
230
232
  ]);
231
233
 
232
234
  const direct = await fetch(
@@ -246,31 +248,22 @@ test("nearest malformed kennel.json falls back to default plugins", async () =>
246
248
  expect(metadata.plugins.configWarnings).toEqual([]);
247
249
  expect(
248
250
  metadata.plugins.items.map((item: { id: string }) => item.id),
249
- ).toContain("tasks");
251
+ ).not.toContain("tasks");
250
252
  });
251
253
 
252
- test("scaffold writes every plugin's starter file once and skips existing", async () => {
254
+ test("scaffold has no core starter files without external plugins", async () => {
253
255
  const root = await mkdtemp(join(tmpdir(), "kennel-init-"));
254
256
  cleanup.push(() => rm(root, { recursive: true, force: true }));
255
257
 
256
258
  const first = await scaffoldFolderPlugins(root);
257
- expect(first.created.map((f) => f.path).sort()).toEqual([
258
- "calendar.json",
259
- "todo.json",
260
- ]);
261
-
262
- const second = await scaffoldFolderPlugins(root);
263
- expect(second.created).toEqual([]);
264
- expect(second.skipped.map((f) => f.path).sort()).toEqual([
265
- "calendar.json",
266
- "todo.json",
267
- ]);
259
+ expect(first.created).toEqual([]);
260
+ expect(first.skipped).toEqual([]);
261
+ expect(first.supported).toEqual([]);
268
262
 
269
263
  const forced = await scaffoldFolderPlugins(root, { force: true });
270
- expect(forced.created.map((f) => f.path).sort()).toEqual([
271
- "calendar.json",
272
- "todo.json",
273
- ]);
264
+ expect(forced.created).toEqual([]);
265
+ expect(forced.skipped).toEqual([]);
266
+ expect(forced.supported).toEqual([]);
274
267
  });
275
268
 
276
269
  test("scaffold write:false reports supported files without creating them", async () => {
@@ -280,12 +273,7 @@ test("scaffold write:false reports supported files without creating them", async
280
273
  const result = await scaffoldFolderPlugins(root, { write: false });
281
274
  expect(result.created).toEqual([]);
282
275
  expect(result.skipped).toEqual([]);
283
- expect(result.supported).toEqual(
284
- expect.arrayContaining([
285
- expect.objectContaining({ id: "calendar", files: ["calendar.json"] }),
286
- expect.objectContaining({ id: "tasks", files: ["todo.json"] }),
287
- ]),
288
- );
276
+ expect(result.supported).toEqual([]);
289
277
  });
290
278
 
291
279
  test("workspace discovery surfaces declared schema core folders with titles", async () => {
@@ -2,7 +2,7 @@
2
2
 
3
3
  Internal BarackDown re-export consumed by every Kennel package that renders
4
4
  Markdown (`packages/ui`, `packages/agents`, `packages/api`, `packages/dist`,
5
- `packages/core-components`, `plugins/mail`, `cli`, and `apps/web`). The
5
+ `packages/core-components`, external plugins, `cli`, and `apps/web`). The
6
6
  purpose of this tiny package is to be the single place where Kennel decides
7
7
  which BarkDown implementation it uses.
8
8
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kennel",
3
- "version": "0.2.2",
3
+ "version": "0.2.5",
4
4
  "description": "Open-source pop-up previews for AI output: markdown, HTML artifacts, email, images, code, tables, notes, and calendars, from the terminal or your agent session.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1 +1 @@
1
- import{g as p,r as u,d as a}from"./chunk-MOJQB5TN-D2RcYmoU.js";import{p as f}from"./chunk-JWPE2WC7-BPSl40wG.js";import{_ as n,l as o}from"./mermaid.core-BDVbShyO.js";import{b as c,M as d}from"./cynefin-VYW2F7L2-DWxftYAm.js";import"./index-CNyy98F8.js";import"./react-B9jn2M18.js";import"./markdown-Bw9RgUGR.js";var v=c().RailroadAbnf.parser.LangiumParser,i=n(e=>{const r=e.alternatives.map(g);return r.length===1?r[0]:{type:"choice",alternatives:r}},"transformAlternation"),g=n(e=>{const r=e.elements.map(y);return r.length===1?r[0]:{type:"sequence",elements:r}},"transformConcatenation"),b=n(e=>{if(e.includes("*")){const[t,s]=e.split("*"),l=t?parseInt(t,10):0,m=s?parseInt(s,10):1/0;return{min:l,max:m}}const r=parseInt(e,10);return{min:r,max:r}},"parseRepeat"),y=n(e=>{const r=A(e.primary);if(!e.repeat)return r;const{min:t,max:s}=b(e.repeat);return t===0&&s===1?{type:"optional",element:r}:{type:"repetition",element:r,min:t,max:s}},"transformElement"),A=n(e=>{switch(e.$type){case"AbnfStringLiteral":return{type:"terminal",value:e.value};case"AbnfNumVal":return{type:"terminal",value:e.value};case"AbnfRuleName":return{type:"nonterminal",name:e.name};case"AbnfGroup":return i(e.element);case"AbnfOptionalGroup":return{type:"optional",element:i(e.element)};default:throw new Error(`Unsupported ABNF primary node: ${e.$type}`)}},"transformPrimary"),P=n(e=>({name:e.name,definition:i(e.definition)}),"transformRule"),h=n(e=>{f(e,a),e.title&&a.setTitle(e.title),e.rules.map(r=>a.addRule(P(r)))},"populateDb"),R={parse:n(e=>{a.clear(),o.debug("[ABNF Parser] Starting Langium parse");const r=v.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new d(r);const t=r.value;o.debug("[ABNF Parser] Parsed rules:",t.rules.length),h(t),o.debug("[ABNF Parser] Parse complete")},"parse"),parser:{yy:a}},I={parser:R,db:a,renderer:u,styles:p};export{I as diagram};
1
+ import{g as p,r as u,d as a}from"./chunk-MOJQB5TN-ayhH5Q-H.js";import{p as f}from"./chunk-JWPE2WC7-D5fGV_sH.js";import{_ as n,l as o}from"./mermaid.core-CD-KvBjV.js";import{b as c,M as d}from"./cynefin-VYW2F7L2-C1B09TRE.js";import"./index-CUTtMSyJ.js";import"./react-B9jn2M18.js";import"./markdown-Bw9RgUGR.js";var v=c().RailroadAbnf.parser.LangiumParser,i=n(e=>{const r=e.alternatives.map(g);return r.length===1?r[0]:{type:"choice",alternatives:r}},"transformAlternation"),g=n(e=>{const r=e.elements.map(y);return r.length===1?r[0]:{type:"sequence",elements:r}},"transformConcatenation"),b=n(e=>{if(e.includes("*")){const[t,s]=e.split("*"),l=t?parseInt(t,10):0,m=s?parseInt(s,10):1/0;return{min:l,max:m}}const r=parseInt(e,10);return{min:r,max:r}},"parseRepeat"),y=n(e=>{const r=A(e.primary);if(!e.repeat)return r;const{min:t,max:s}=b(e.repeat);return t===0&&s===1?{type:"optional",element:r}:{type:"repetition",element:r,min:t,max:s}},"transformElement"),A=n(e=>{switch(e.$type){case"AbnfStringLiteral":return{type:"terminal",value:e.value};case"AbnfNumVal":return{type:"terminal",value:e.value};case"AbnfRuleName":return{type:"nonterminal",name:e.name};case"AbnfGroup":return i(e.element);case"AbnfOptionalGroup":return{type:"optional",element:i(e.element)};default:throw new Error(`Unsupported ABNF primary node: ${e.$type}`)}},"transformPrimary"),P=n(e=>({name:e.name,definition:i(e.definition)}),"transformRule"),h=n(e=>{f(e,a),e.title&&a.setTitle(e.title),e.rules.map(r=>a.addRule(P(r)))},"populateDb"),R={parse:n(e=>{a.clear(),o.debug("[ABNF Parser] Starting Langium parse");const r=v.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new d(r);const t=r.value;o.debug("[ABNF Parser] Parsed rules:",t.rules.length),h(t),o.debug("[ABNF Parser] Parse complete")},"parse"),parser:{yy:a}},I={parser:R,db:a,renderer:u,styles:p};export{I as diagram};