kennel 0.2.3 → 0.2.6

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 (274) 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 +28 -2
  8. package/dist/cli/src/plugins/external.js +77 -23
  9. package/dist/cli/src/site/server-plugins.d.ts +4 -9
  10. package/dist/cli/src/site/viewer.js +1 -0
  11. package/dist/cli/usage.js +1 -1
  12. package/dist/core/api-client.js +576 -10317
  13. package/dist/core/command.js +1 -0
  14. package/dist/core/core-folders.js +2313 -12088
  15. package/dist/core/init.js +5 -5
  16. package/dist/core/runtime.js +8237 -20713
  17. package/dist/package/preview.js +19617 -33352
  18. package/dist/plugins/external.d.ts +28 -2
  19. package/dist/plugins/external.js +77 -23
  20. package/dist/site/server-plugins.d.ts +4 -9
  21. package/dist/site/server-plugins.js +557 -10452
  22. package/dist/site/viewer.js +1 -0
  23. package/kernel/apps/web/package.json +2 -6
  24. package/kernel/apps/web/scripts/dev.mjs +53 -0
  25. package/kernel/apps/web/src/app.css +0 -3
  26. package/kernel/apps/web/src/external-plugins.ts +1 -1
  27. package/kernel/apps/web/src/folder-filter-icons.tsx +1 -1
  28. package/kernel/apps/web/src/folder-plugin-view.tsx +1 -1
  29. package/kernel/apps/web/src/main.tsx +0 -1
  30. package/kernel/apps/web/src/plugins.ts +1 -31
  31. package/kernel/apps/web/tsconfig.json +1 -2
  32. package/kernel/apps/web/vite.config.ts +32 -14
  33. package/kernel/packages/agents/package.json +1 -1
  34. package/kernel/packages/agents/src/agent-card.tsx +1 -1
  35. package/kernel/packages/agents/src/client.tsx +1 -1
  36. package/kernel/packages/agents/src/manifest.ts +1 -1
  37. package/kernel/packages/agents/src/server.ts +1 -1
  38. package/kernel/packages/agents/src/viewer.tsx +1 -1
  39. package/kernel/packages/api/package.json +1 -5
  40. package/kernel/packages/api/src/server/acp-live-plugin.ts +1 -1
  41. package/kernel/packages/api/src/server/api/create-agent-file.ts +2 -2
  42. package/kernel/packages/api/src/server/api/document-edit.ts +2 -2
  43. package/kernel/packages/api/src/server/api/open-path.ts +2 -2
  44. package/kernel/packages/api/src/server/folder-metadata-plugin.ts +17 -42
  45. package/kernel/packages/api/src/server/index.ts +0 -1
  46. package/kernel/packages/api/src/server/plugins.ts +52 -19
  47. package/kernel/packages/api/src/shared/viewer-route.ts +1 -1
  48. package/kernel/packages/api/test/core.test.ts +14 -26
  49. package/kernel/packages/markdown/README.md +1 -1
  50. package/kernel/packages/notes/package.json +1 -1
  51. package/kernel/packages/notes/src/client.tsx +1 -1
  52. package/kernel/packages/notes/src/manifest.ts +1 -1
  53. package/kernel/packages/notes/src/server.ts +1 -1
  54. package/kernel/packages/plugins/SKILL.md +39 -0
  55. package/kernel/{plugins/mail → packages/plugins}/package.json +53 -28
  56. package/kernel/packages/plugins/src/index.ts +52 -0
  57. package/kernel/packages/plugins/src/page.ts +17 -0
  58. package/kernel/{plugins/projects → packages/plugins}/tsconfig.json +5 -1
  59. package/kernel/packages/plugins/tsup.config.ts +25 -0
  60. package/kernel/packages/ui/src/components/content-issues.tsx +1 -1
  61. package/kernel/packages/ui/tsconfig.json +1 -1
  62. package/package.json +2 -3
  63. package/web/assets/{abnfDiagram-VRR7QNED-Bgfb1nEB.js → abnfDiagram-VRR7QNED-xd_g1uK3.js} +1 -1
  64. package/web/assets/app-CX20nNIa.js +2 -0
  65. package/web/assets/{app-options-D-RJiQ-X.js → app-options-CkPJE5ep.js} +1 -1
  66. package/web/assets/{app-view-header-BLvLq02T.js → app-view-header-CNk5KnA-.js} +1 -1
  67. package/web/assets/{arc-Dk_KI36B.js → arc-B0u5yBJA.js} +1 -1
  68. package/web/assets/{architectureDiagram-ZJ3FMSHR-NR_KhRCf.js → architectureDiagram-ZJ3FMSHR-DfxOAo8P.js} +1 -1
  69. package/web/assets/{ask-tray-TzeTcO6-.js → ask-tray-SscJecDY.js} +1 -1
  70. package/web/assets/{blockDiagram-677ZJIJ3-CkLkwx9C.js → blockDiagram-677ZJIJ3-Ci3Usxh6.js} +1 -1
  71. package/web/assets/{c4Diagram-LMCZKHZV-CFCUH8e_.js → c4Diagram-LMCZKHZV-BqgwIVgh.js} +1 -1
  72. package/web/assets/channel-X7WHyxxT.js +1 -0
  73. package/web/assets/{chunk-2Q5K7J3B-B_BPLWsW.js → chunk-2Q5K7J3B-CfX69l2U.js} +1 -1
  74. package/web/assets/{chunk-32BRIVSS-B1VB1hOy.js → chunk-32BRIVSS-CuFlzZkl.js} +1 -1
  75. package/web/assets/{chunk-5VM5RSS4-KFcYr8Co.js → chunk-5VM5RSS4-DidCMlJa.js} +1 -1
  76. package/web/assets/{chunk-EX3LRPZG-CpBX3kuK.js → chunk-EX3LRPZG-B5CDm1dS.js} +1 -1
  77. package/web/assets/{chunk-JWPE2WC7-BPSl40wG.js → chunk-JWPE2WC7-D5fGV_sH.js} +1 -1
  78. package/web/assets/{chunk-MOJQB5TN-D2RcYmoU.js → chunk-MOJQB5TN-ayhH5Q-H.js} +1 -1
  79. package/web/assets/{chunk-RYQCIY6F-m7Gyn-t3.js → chunk-RYQCIY6F-C4BfOOZn.js} +1 -1
  80. package/web/assets/{chunk-V7JOEXUC-TDvdopxS.js → chunk-V7JOEXUC-DpUEIM9V.js} +1 -1
  81. package/web/assets/{chunk-VR4S4FIN-DZTsG51a.js → chunk-VR4S4FIN-DoQuFFRh.js} +1 -1
  82. package/web/assets/{chunk-XXDRQBXY-Dp0--RE2.js → chunk-XXDRQBXY-CI9eiLwn.js} +1 -1
  83. package/web/assets/classDiagram-OUVF2IWQ-BjsLQ3dz.js +1 -0
  84. package/web/assets/classDiagram-v2-EOCWNBFH-BjsLQ3dz.js +1 -0
  85. package/web/assets/client-7OWw5kW2.js +6 -0
  86. package/web/assets/client-DYj_td4Q.js +17 -0
  87. package/web/assets/{client-j2kQmxsO.js → client-Dk-NBvJR.js} +4 -4
  88. package/web/assets/command-zkzH4hVz.js +38 -0
  89. package/web/assets/{copy-context-C0Uqsp-3.js → copy-context-D5oiWrYC.js} +1 -1
  90. package/web/assets/{cose-bilkent-JH36ORCC-CPu3PI8h.js → cose-bilkent-JH36ORCC-BHRk1mO3.js} +1 -1
  91. package/web/assets/{cynefin-VYW2F7L2-DWxftYAm.js → cynefin-VYW2F7L2-C1B09TRE.js} +1 -1
  92. package/web/assets/{cynefinDiagram-TSTJHNR4-DsmN2V-p.js → cynefinDiagram-TSTJHNR4-B27qXQbv.js} +1 -1
  93. package/web/assets/{dagre-VKFMJZFB-COEbApyY.js → dagre-VKFMJZFB-B1qEi32g.js} +1 -1
  94. package/web/assets/{diagram-FQU43EPY-0O9WGWKB.js → diagram-FQU43EPY-BMkkgADD.js} +1 -1
  95. package/web/assets/{diagram-G47NLZAW-CutEdMVh.js → diagram-G47NLZAW-Cb8_g1A5.js} +1 -1
  96. package/web/assets/{diagram-NH7WQ7WH-C9KZc3B2.js → diagram-NH7WQ7WH-B51wuc5m.js} +1 -1
  97. package/web/assets/{diagram-OA4YK3LP-D8kkPXbY.js → diagram-OA4YK3LP-xnsecbbI.js} +1 -1
  98. package/web/assets/{diagram-WEI45ONY-_YqiTaGP.js → diagram-WEI45ONY-DSZdyaAV.js} +1 -1
  99. package/web/assets/{document-Dgt5eZFj.js → document-Dc2dftTW.js} +3 -3
  100. package/web/assets/{ebnfDiagram-CCIWWBDH-JO-zQh6g.js → ebnfDiagram-CCIWWBDH-aTHmcUGy.js} +1 -1
  101. package/web/assets/{entities-C3wz7FCx.js → entities-CCUtpskY.js} +1 -1
  102. package/web/assets/{erDiagram-Q63AITRT-9UjQwJ4P.js → erDiagram-Q63AITRT-CUUPBcvo.js} +1 -1
  103. package/web/assets/{file-viewer-DZJ8nYnl.js → file-viewer-DJ3rsmef.js} +1 -1
  104. package/web/assets/{flowDiagram-23GEKE2U-Ca08tnYM.js → flowDiagram-23GEKE2U-aTQXx2Mh.js} +1 -1
  105. package/web/assets/{folder-image-BfGgxo7i.js → folder-image-Bnv43tzP.js} +1 -1
  106. package/web/assets/{folder-landing-qUKBCnG-.js → folder-landing-DCnzYXXY.js} +1 -1
  107. package/web/assets/{folder-list-BfFjv7rR.js → folder-list-DvVkVjiR.js} +1 -1
  108. package/web/assets/{folder-metadata-DCw8xzHk.js → folder-metadata-C9hMMzIH.js} +1 -1
  109. package/web/assets/{folder-mobile-bar-Ubz4babf.js → folder-mobile-bar-VoTL1GS0.js} +1 -1
  110. package/web/assets/folder-plugin-view-Cvd804ZU.js +6 -0
  111. package/web/assets/{ganttDiagram-NO4QXBWP-KnHzX5W3.js → ganttDiagram-NO4QXBWP-DiwdUp7u.js} +1 -1
  112. package/web/assets/{gitGraphDiagram-IHSO6WYX-Cm8woNtK.js → gitGraphDiagram-IHSO6WYX-BL2gG_IS.js} +1 -1
  113. package/web/assets/{index-CNyy98F8.js → index-CUTtMSyJ.js} +2 -2
  114. package/web/assets/index-CegvVQ1C.js +1 -0
  115. package/web/assets/index-Dwhf8F_U.css +1 -0
  116. package/web/assets/{infoDiagram-FWYZ7A6U-yyqmUtIb.js → infoDiagram-FWYZ7A6U-B3n0zZpt.js} +1 -1
  117. package/web/assets/{ishikawaDiagram-FXEZZL3T-BfvR_Zy4.js → ishikawaDiagram-FXEZZL3T-D7YytbEv.js} +1 -1
  118. package/web/assets/{journeyDiagram-5HDEW3XC-BKuw06HM.js → journeyDiagram-5HDEW3XC-BYwqEl3C.js} +1 -1
  119. package/web/assets/{kanban-definition-HUTT4EX6-n0010rmQ.js → kanban-definition-HUTT4EX6-BQHNJgXZ.js} +1 -1
  120. package/web/assets/{linear-C0d0lT8O.js → linear-BPiQCLNk.js} +1 -1
  121. package/web/assets/{mermaid.core-BDVbShyO.js → mermaid.core-CD-KvBjV.js} +4 -4
  122. package/web/assets/{metadata-KV0dpp4G.js → metadata-COJ7fZul.js} +1 -1
  123. package/web/assets/{mindmap-definition-LN4V7U3C--_0ks3GF.js → mindmap-definition-LN4V7U3C-C1L_gyoj.js} +1 -1
  124. package/web/assets/{pegDiagram-2B236MQR-CBoNIpKR.js → pegDiagram-2B236MQR-BDAfItqS.js} +1 -1
  125. package/web/assets/{pieDiagram-ENE6RG2P-MA5tkYh5.js → pieDiagram-ENE6RG2P-CkZYH3Vz.js} +1 -1
  126. package/web/assets/{popover-DBD7FF-W.js → popover-0oA2lLUV.js} +2 -2
  127. package/web/assets/{project-search-dialog-DM1IkSZu.js → project-search-dialog-B2oqMT6h.js} +1 -1
  128. package/web/assets/{quadrantDiagram-ABIIQ3AL-CWT1ryqF.js → quadrantDiagram-ABIIQ3AL-Dy8Al3YZ.js} +1 -1
  129. package/web/assets/{railroadDiagram-RFXS5EU6-ZiLB5FGi.js → railroadDiagram-RFXS5EU6-Dd9_yo7B.js} +1 -1
  130. package/web/assets/{requirementDiagram-TGXJPOKE-CQq9uneq.js → requirementDiagram-TGXJPOKE-DPhIUsbs.js} +1 -1
  131. package/web/assets/{sankeyDiagram-HTMAVEWB-qDG-0JqI.js → sankeyDiagram-HTMAVEWB-B2QkYtub.js} +1 -1
  132. package/web/assets/{search-DNrQA5fF.js → search-C1J0-xiB.js} +1 -1
  133. package/web/assets/select-CtXC_PLC.js +30 -0
  134. package/web/assets/{selection-popup-DmtTeRs2.js → selection-popup-qhlUFzGq.js} +1 -1
  135. package/web/assets/{sequenceDiagram-DBY2YBRQ-CiApurLO.js → sequenceDiagram-DBY2YBRQ-Bx7fcZDx.js} +1 -1
  136. package/web/assets/{sizeCapture-X5ZJPWSS-DZSR5QXm.js → sizeCapture-X5ZJPWSS-CIXIhl_A.js} +1 -1
  137. package/web/assets/{stateDiagram-2N3HPSRC-CjJJR9_z.js → stateDiagram-2N3HPSRC-DCrdAflB.js} +1 -1
  138. package/web/assets/stateDiagram-v2-6OUMAXLB-0KCFLYeQ.js +1 -0
  139. package/web/assets/{swimlanes-5IMT3BWC-CKmo1sg6.js → swimlanes-5IMT3BWC-DA2vc7iZ.js} +2 -2
  140. package/web/assets/swimlanesDiagram-G3AALYLV-CAw3AV84.js +8 -0
  141. package/web/assets/{timeline-definition-FHXFAJF6-D-NMwS3y.js → timeline-definition-FHXFAJF6-lKfJiV9V.js} +1 -1
  142. package/web/assets/{vennDiagram-L72KCM5P-CfL6LBWw.js → vennDiagram-L72KCM5P-DO1q2KzG.js} +1 -1
  143. package/web/assets/{view-context-gyDl_p2V.js → view-context-DXKM3-l1.js} +4 -4
  144. package/web/assets/{viewer-capabilities-Bpp8Uvcg.js → viewer-capabilities-Cig_xM9u.js} +1 -1
  145. package/web/assets/{wardleyDiagram-EHGQE667-DgldMxaj.js → wardleyDiagram-EHGQE667-Dal9LkuZ.js} +1 -1
  146. package/web/assets/{xychartDiagram-FW5EYKEG-CIoAIFX8.js → xychartDiagram-FW5EYKEG-B3dPLPII.js} +1 -1
  147. package/web/index.html +2 -2
  148. package/kernel/packages/api/test/partial-loading.test.ts +0 -43
  149. package/kernel/packages/folder-plugin/package.json +0 -50
  150. package/kernel/packages/folder-plugin/src/index.ts +0 -15
  151. package/kernel/packages/folder-plugin/tsconfig.json +0 -17
  152. package/kernel/plugins/calendar/SKILL.md +0 -173
  153. package/kernel/plugins/calendar/eslint.config.js +0 -10
  154. package/kernel/plugins/calendar/package.json +0 -73
  155. package/kernel/plugins/calendar/schema.json +0 -137
  156. package/kernel/plugins/calendar/src/calendar.tsx +0 -328
  157. package/kernel/plugins/calendar/src/client.tsx +0 -139
  158. package/kernel/plugins/calendar/src/context.ts +0 -48
  159. package/kernel/plugins/calendar/src/copy-button.tsx +0 -66
  160. package/kernel/plugins/calendar/src/event-dialog.tsx +0 -270
  161. package/kernel/plugins/calendar/src/index.ts +0 -4
  162. package/kernel/plugins/calendar/src/manifest.ts +0 -7
  163. package/kernel/plugins/calendar/src/parse.ts +0 -610
  164. package/kernel/plugins/calendar/src/server.ts +0 -160
  165. package/kernel/plugins/calendar/src/utils.ts +0 -80
  166. package/kernel/plugins/calendar/src/views.tsx +0 -418
  167. package/kernel/plugins/calendar/test/context.test.mjs +0 -60
  168. package/kernel/plugins/calendar/test/package.test.mjs +0 -43
  169. package/kernel/plugins/calendar/test/parse.test.mjs +0 -392
  170. package/kernel/plugins/calendar/test/server.test.mjs +0 -126
  171. package/kernel/plugins/calendar/tsconfig.json +0 -17
  172. package/kernel/plugins/mail/SKILL.md +0 -97
  173. package/kernel/plugins/mail/eslint.config.js +0 -10
  174. package/kernel/plugins/mail/src/api.ts +0 -359
  175. package/kernel/plugins/mail/src/bun-ffi.d.ts +0 -14
  176. package/kernel/plugins/mail/src/client.tsx +0 -14
  177. package/kernel/plugins/mail/src/flock.ts +0 -137
  178. package/kernel/plugins/mail/src/folders.ts +0 -37
  179. package/kernel/plugins/mail/src/history.ts +0 -485
  180. package/kernel/plugins/mail/src/index.ts +0 -3
  181. package/kernel/plugins/mail/src/mail-card.tsx +0 -123
  182. package/kernel/plugins/mail/src/mail-conversation.tsx +0 -153
  183. package/kernel/plugins/mail/src/mail-detail-page.tsx +0 -467
  184. package/kernel/plugins/mail/src/mail-hooks.ts +0 -252
  185. package/kernel/plugins/mail/src/mail-page.tsx +0 -109
  186. package/kernel/plugins/mail/src/mail-request.ts +0 -78
  187. package/kernel/plugins/mail/src/mail-send-box.tsx +0 -175
  188. package/kernel/plugins/mail/src/mailos.ts +0 -723
  189. package/kernel/plugins/mail/src/manifest.ts +0 -7
  190. package/kernel/plugins/mail/src/node.ts +0 -171
  191. package/kernel/plugins/mail/src/parse.ts +0 -139
  192. package/kernel/plugins/mail/src/server.ts +0 -125
  193. package/kernel/plugins/mail/src/types.ts +0 -10
  194. package/kernel/plugins/mail/src/viewer.tsx +0 -147
  195. package/kernel/plugins/mail/test/flock.test.mjs +0 -156
  196. package/kernel/plugins/mail/test/folders.test.mjs +0 -138
  197. package/kernel/plugins/mail/test/history.test.mjs +0 -460
  198. package/kernel/plugins/mail/test/mailos.test.mjs +0 -752
  199. package/kernel/plugins/mail/test/node.test.mjs +0 -207
  200. package/kernel/plugins/mail/test/package.test.mjs +0 -54
  201. package/kernel/plugins/mail/test/parse.test.mjs +0 -32
  202. package/kernel/plugins/mail/test/server.test.mjs +0 -116
  203. package/kernel/plugins/mail/test/viewer.test.mjs +0 -192
  204. package/kernel/plugins/mail/tsconfig.json +0 -17
  205. package/kernel/plugins/projects/SKILL.md +0 -73
  206. package/kernel/plugins/projects/eslint.config.js +0 -10
  207. package/kernel/plugins/projects/package.json +0 -70
  208. package/kernel/plugins/projects/src/client.tsx +0 -17
  209. package/kernel/plugins/projects/src/data/model.ts +0 -129
  210. package/kernel/plugins/projects/src/index.ts +0 -17
  211. package/kernel/plugins/projects/src/manifest.ts +0 -7
  212. package/kernel/plugins/projects/src/project-context.ts +0 -41
  213. package/kernel/plugins/projects/src/server.ts +0 -276
  214. package/kernel/plugins/projects/src/ui/project-card.tsx +0 -61
  215. package/kernel/plugins/projects/src/ui/projects-page.tsx +0 -102
  216. package/kernel/plugins/projects/test/package.test.mjs +0 -51
  217. package/kernel/plugins/tasks/SKILL.md +0 -341
  218. package/kernel/plugins/tasks/eslint.config.js +0 -10
  219. package/kernel/plugins/tasks/package.json +0 -74
  220. package/kernel/plugins/tasks/schema.json +0 -939
  221. package/kernel/plugins/tasks/src/api.ts +0 -212
  222. package/kernel/plugins/tasks/src/client.tsx +0 -23
  223. package/kernel/plugins/tasks/src/data/parse.ts +0 -544
  224. package/kernel/plugins/tasks/src/data/task-id.ts +0 -56
  225. package/kernel/plugins/tasks/src/data/todo-model.ts +0 -795
  226. package/kernel/plugins/tasks/src/index.ts +0 -34
  227. package/kernel/plugins/tasks/src/manifest.ts +0 -7
  228. package/kernel/plugins/tasks/src/pages/task-detail.tsx +0 -48
  229. package/kernel/plugins/tasks/src/pages/task-list.tsx +0 -88
  230. package/kernel/plugins/tasks/src/server.ts +0 -447
  231. package/kernel/plugins/tasks/src/styles.css +0 -9
  232. package/kernel/plugins/tasks/src/ui/compact-todo-list.tsx +0 -372
  233. package/kernel/plugins/tasks/src/ui/error-details.tsx +0 -78
  234. package/kernel/plugins/tasks/src/ui/task-page.tsx +0 -392
  235. package/kernel/plugins/tasks/src/ui/todo-agent-filter.tsx +0 -36
  236. package/kernel/plugins/tasks/src/ui/todo-filter-bar.tsx +0 -66
  237. package/kernel/plugins/tasks/src/ui/todo-item.tsx +0 -494
  238. package/kernel/plugins/tasks/src/ui/todo-status-filter.tsx +0 -60
  239. package/kernel/plugins/tasks/src/ui/todo-tag-filter.tsx +0 -48
  240. package/kernel/plugins/tasks/src/ui/todo-warnings.tsx +0 -106
  241. package/kernel/plugins/tasks/test/api.test.mjs +0 -99
  242. package/kernel/plugins/tasks/test/folder-sources.test.mjs +0 -46
  243. package/kernel/plugins/tasks/test/package.test.mjs +0 -54
  244. package/kernel/plugins/tasks/test/parse.test.mjs +0 -225
  245. package/kernel/plugins/tasks/test/server.test.mjs +0 -386
  246. package/kernel/plugins/tasks/tsconfig.json +0 -17
  247. package/web/assets/app-DoGr2Zi7.js +0 -2
  248. package/web/assets/channel-uMEjV8qc.js +0 -1
  249. package/web/assets/classDiagram-OUVF2IWQ-fbZocVor.js +0 -1
  250. package/web/assets/classDiagram-v2-EOCWNBFH-fbZocVor.js +0 -1
  251. package/web/assets/client-C6Nxdfif.js +0 -2
  252. package/web/assets/client-CXYfBko5.js +0 -17
  253. package/web/assets/client-CoKtOq-X.js +0 -7
  254. package/web/assets/client-DyRQz5RU.js +0 -53
  255. package/web/assets/client-OY6HUzuD.js +0 -98
  256. package/web/assets/client-YOYWZIFi.js +0 -34
  257. package/web/assets/command-BugZBGXE.js +0 -38
  258. package/web/assets/folder-plugin-view-DsWR1zmQ.js +0 -6
  259. package/web/assets/index-BaRnbYRw.js +0 -1
  260. package/web/assets/index-BexmLxIP.css +0 -1
  261. package/web/assets/index-DDirZMgx.js +0 -1
  262. package/web/assets/note-card-DBfX6gW1.js +0 -6
  263. package/web/assets/select-D8cqNgcp.js +0 -30
  264. package/web/assets/stateDiagram-v2-6OUMAXLB-BpeGSCu9.js +0 -1
  265. package/web/assets/swimlanesDiagram-G3AALYLV-D9RjLKb9.js +0 -8
  266. package/web/assets/use-folder-filter-LQyXns5Q.js +0 -1
  267. /package/kernel/packages/{folder-plugin → plugins}/eslint.config.js +0 -0
  268. /package/kernel/packages/{folder-plugin → plugins}/src/client.ts +0 -0
  269. /package/kernel/packages/{folder-plugin → plugins}/src/endpoint.ts +0 -0
  270. /package/kernel/packages/{folder-plugin → plugins}/src/server.ts +0 -0
  271. /package/kernel/packages/{folder-plugin → plugins}/src/subpath.ts +0 -0
  272. /package/kernel/packages/{folder-plugin → plugins}/src/types.ts +0 -0
  273. /package/kernel/packages/{folder-plugin → plugins}/src/validation.ts +0 -0
  274. /package/kernel/packages/{folder-plugin → plugins}/test/contract.test.mjs +0 -0
@@ -1,22 +1,16 @@
1
- import type { FolderPluginContext } from "@raggle-ai/folder-plugin/server";
2
- import type { FolderPluginServer } from "@raggle-ai/folder-plugin/server";
3
- import type { MailCreatePluginOptions } from "@raggle-ai/mail/server";
1
+ import type { FolderPluginContext } from "kennel-plugins/server";
2
+ import type { FolderPluginServer } from "kennel-plugins/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
- import { FolderPluginFailure } from "@raggle-ai/folder-plugin/server";
11
- import { createMailPlugin } from "@raggle-ai/mail/server";
8
+ import { FolderPluginFailure } from "kennel-plugins/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;
@@ -33,7 +33,7 @@ const sectionTabs: Record<ViewerSection, FolderTab> = {
33
33
  skills: "skills",
34
34
  };
35
35
 
36
- import { folderPathId as encodeBase64Url } from "@raggle-ai/folder-plugin/client";
36
+ import { folderPathId as encodeBase64Url } from "kennel-plugins/client";
37
37
 
38
38
  function decodeBase64Url(value: string) {
39
39
  const padded = `${value}${"=".repeat((4 - (value.length % 4)) % 4)}`;
@@ -9,7 +9,7 @@ import {
9
9
  configuredFolderServerRegistry,
10
10
  scaffoldFolderPlugins,
11
11
  } from "../src/server/plugins";
12
- import type { FolderPluginServer } from "~/folder-plugin/server";
12
+ import type { FolderPluginServer } from "kennel-plugins/server";
13
13
  import { createCoreFolderIndex } from "@raggle-ai/schemas/node";
14
14
 
15
15
  const cleanup: (() => Promise<unknown>)[] = [];
@@ -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
 
@@ -39,7 +39,7 @@
39
39
  "publish:public:dry-run": "npm --@raggle-ai:registry=https://registry.npmjs.org publish --dry-run --access public --registry=https://registry.npmjs.org"
40
40
  },
41
41
  "dependencies": {
42
- "@raggle-ai/folder-plugin": "workspace:*",
42
+ "kennel-plugins": "workspace:*",
43
43
  "@raggle-ai/ui": "workspace:*",
44
44
  "@tanstack/react-query": "catalog:tanstack",
45
45
  "lucide-react": "^0.562.0"
@@ -1,4 +1,4 @@
1
- import type { FolderPluginClient } from "@raggle-ai/folder-plugin/client"
1
+ import type { FolderPluginClient } from "kennel-plugins/client"
2
2
 
3
3
  import { notesManifest } from "./manifest.ts"
4
4
  import { NotesPage } from "./pages/notes-page.tsx"
@@ -1,4 +1,4 @@
1
- import type { FolderPluginManifest } from "@raggle-ai/folder-plugin"
1
+ import type { FolderPluginManifest } from "kennel-plugins"
2
2
 
3
3
  export const notesManifest = {
4
4
  id: "notes",
@@ -6,7 +6,7 @@ import type {
6
6
  FolderPluginData,
7
7
  FolderPluginDetection,
8
8
  FolderPluginServer,
9
- } from "@raggle-ai/folder-plugin/server"
9
+ } from "kennel-plugins/server"
10
10
 
11
11
  import { notesManifest } from "./manifest.ts"
12
12
 
@@ -0,0 +1,39 @@
1
+ ---
2
+ name: kennel-plugins
3
+ description: Install, register, or build a trusted Kennel folder plugin. Use for `knl plugin add`, external plugin kernels, plugin tabs, or deciding where plugin code belongs.
4
+ ---
5
+
6
+ # Kennel Plugin Management
7
+
8
+ ## Ownership
9
+
10
+ Keep each concern in its owner:
11
+
12
+ | Concern | Location |
13
+ | ----------------------------------------------------------- | -------------------------------------- |
14
+ | Plugin contract and public client/server types | `packages/plugins` (`kennel-plugins`) |
15
+ | Generic reusable viewer UI | `packages/ui` |
16
+ | Folder metadata API and server registry | `packages/api` |
17
+ | Browser route and static external-plugin registry | `apps/web` |
18
+ | Install, pin, cache, validate, and compose external plugins | `cli/src/plugins/external.ts` |
19
+ | Built-in Agents and Notes feature code | `packages/agents` and `packages/notes` |
20
+ | External plugin feature code | Its own repository |
21
+
22
+ Keep new plugin feature code in its own repository. Add to `packages/plugins` only when every plugin needs a contract change. Add to `packages/ui` only when every viewer can use the UI component.
23
+
24
+ ## External plugin install
25
+
26
+ 1. Inspect the plugin `package.json`, `src/manifest.ts`, `src/client.tsx`, and `src/server.ts`.
27
+ 2. Require `package.json > kennel.plugin` with a unique non-core `id`. The conventional `./manifest`, `./client`, `./server`, and optional `./api` entries must default-export their values. Add `trigger` only when a file can make an otherwise unavailable plugin visible.
28
+ 3. Keep the manifest id and package id equal. The client and server must spread or otherwise return that manifest id.
29
+ 4. Ensure the repository TypeScript config works outside the Kennel workspace. Do not require unpublished workspace config files during kernel bundling.
30
+ 5. Install with `knl plugin add <git-url>`. It pins the resolved commit, validates exports, stores source in `~/.cache/kennel/plugins/sources/`, records the plugin in `~/.config/kennel/config.json`, and composes a static kernel in `~/.cache/kennel/kernels/`.
31
+ 6. Use `knl view <folder>` after installation. External plugins require the composed static viewer; a plain Vite hot viewer cannot show their tabs.
32
+
33
+ ## Change workflow
34
+
35
+ - Start with the smallest plugin repository change. Do not copy plugin feature code into Kennel.
36
+ - Change `packages/plugins`, `packages/api`, `apps/web`, and `cli` only when the plugin contract or trusted-kernel behavior needs it.
37
+ - Keep plugin ids stable. Do not use core ids: `agents`, `calendar`, `mail`, `notes`, `projects`, or `tasks`.
38
+ - Verify a real install in an isolated `XDG_CONFIG_HOME` and `XDG_CACHE_HOME` first. Then verify the tab and its selected route in the composed viewer.
39
+ - A CLI behavior change requires a new `cli/package.json` version. The publish workflow releases it after merge to `main`.
@@ -1,58 +1,82 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
- "name": "@raggle-ai/mail",
3
+ "name": "kennel-plugins",
4
4
  "version": "0.1.0",
5
- "description": "Mail folder plugin: parse and view MailOS local email drafts for Kennel folders.",
5
+ "description": "Small shared contract for trusted folder view plugins in the Kennel web viewer.",
6
6
  "type": "module",
7
7
  "license": "MIT",
8
- "prettier": "@raggle-ai/prettier-config",
9
8
  "repository": {
10
9
  "type": "git",
11
10
  "url": "git+https://github.com/raggle-ai/kennel.git",
12
- "directory": "plugins/mail"
11
+ "directory": "packages/plugins"
13
12
  },
14
13
  "publishConfig": {
15
14
  "registry": "https://registry.npmjs.org",
16
15
  "access": "public"
17
16
  },
18
17
  "files": [
19
- "src"
18
+ "dist"
20
19
  ],
20
+ "sideEffects": false,
21
+ "prettier": "@raggle-ai/prettier-config",
21
22
  "exports": {
22
- ".": "./src/index.ts",
23
- "./api": "./src/api.ts",
24
- "./client": "./src/client.tsx",
25
- "./folders": "./src/folders.ts",
26
- "./history": "./src/history.ts",
27
- "./mailos": "./src/mailos.ts",
28
- "./manifest": "./src/manifest.ts",
29
- "./node": "./src/node.ts",
30
- "./parse": "./src/parse.ts",
31
- "./server": "./src/server.ts",
32
- "./viewer": "./src/viewer.tsx"
23
+ ".": {
24
+ "types": "./dist/index.d.ts",
25
+ "import": "./dist/index.js"
26
+ },
27
+ "./client": {
28
+ "types": "./dist/client.d.ts",
29
+ "import": "./dist/client.js"
30
+ },
31
+ "./endpoint": {
32
+ "types": "./dist/endpoint.d.ts",
33
+ "import": "./dist/endpoint.js"
34
+ },
35
+ "./page": {
36
+ "types": "./dist/page.d.ts",
37
+ "import": "./dist/page.js"
38
+ },
39
+ "./server": {
40
+ "types": "./dist/server.d.ts",
41
+ "import": "./dist/server.js"
42
+ },
43
+ "./subpath": {
44
+ "types": "./dist/subpath.d.ts",
45
+ "import": "./dist/subpath.js"
46
+ },
47
+ "./types": {
48
+ "types": "./dist/types.d.ts",
49
+ "import": "./dist/types.js"
50
+ },
51
+ "./validation": {
52
+ "types": "./dist/validation.d.ts",
53
+ "import": "./dist/validation.js"
54
+ }
33
55
  },
34
56
  "scripts": {
57
+ "build": "tsup",
58
+ "prepack": "bun run build",
35
59
  "test": "bun test test/*.test.mjs",
36
60
  "typecheck": "tsc --noEmit",
37
61
  "format": "prettier . --check --cache --cache-location .cache/.prettiercache --ignore-path ../../.prettierignore",
38
62
  "format:fix": "prettier . --write --cache --cache-location .cache/.prettiercache --ignore-path ../../.prettierignore",
39
63
  "lint": "eslint . --cache --cache-location .cache/.eslintcache",
40
64
  "lint:fix": "eslint . --fix --cache --cache-location .cache/.eslintcache",
41
- "clean": "git clean -xdf dist node_modules .cache .turbo/cache",
42
- "pack:check": "npm pack --dry-run",
43
- "publish:public:dry-run": "npm --@raggle-ai:registry=https://registry.npmjs.org publish --dry-run --access public --registry=https://registry.npmjs.org"
65
+ "clean": "git clean -xdf dist node_modules .cache .turbo/cache"
44
66
  },
45
67
  "dependencies": {
46
- "@raggle-ai/folder-plugin": "workspace:*",
47
- "@raggle-ai/markdown": "workspace:*",
48
- "@raggle-ai/ui": "workspace:*",
49
- "@tanstack/react-query": "catalog:tanstack",
50
- "koffi": "^3.3.1",
68
+ "class-variance-authority": "^0.7.1",
69
+ "clsx": "^2.1.1",
70
+ "cmdk": "^1.1.1",
51
71
  "lucide-react": "^0.562.0",
52
- "yaml": "^2.9.0"
72
+ "next-themes": "^0.4.6",
73
+ "radix-ui": "^1.6.7",
74
+ "sonner": "^2.0.7",
75
+ "tailwind-merge": "^3.4.0"
53
76
  },
54
77
  "peerDependencies": {
55
- "react": ">=18.3.0"
78
+ "react": ">=18.3.0",
79
+ "react-dom": ">=18.3.0"
56
80
  },
57
81
  "devDependencies": {
58
82
  "@eslint/compat": "catalog:eslint",
@@ -62,9 +86,10 @@
62
86
  "@raggle-ai/eslint-config": "workspace:*",
63
87
  "@raggle-ai/prettier-config": "workspace:*",
64
88
  "@raggle-ai/tsconfig": "workspace:*",
89
+ "@raggle-ai/ui": "workspace:*",
90
+ "kennel-client": "workspace:*",
65
91
  "@types/node": "catalog:",
66
92
  "@types/react": "catalog:react19",
67
- "@types/react-dom": "catalog:react19",
68
93
  "eslint": "catalog:eslint",
69
94
  "eslint-plugin-unused-imports": "catalog:eslint",
70
95
  "prettier": "catalog:prettier",
@@ -72,7 +97,7 @@
72
97
  "prettier-plugin-merge": "catalog:prettier",
73
98
  "prettier-plugin-tailwindcss": "catalog:prettier",
74
99
  "react": "catalog:react19",
75
- "react-dom": "catalog:react19",
100
+ "tsup": "8.5.1",
76
101
  "typescript": "catalog:",
77
102
  "typescript-eslint": "catalog:eslint"
78
103
  }
@@ -0,0 +1,52 @@
1
+ // The complete public surface for external folder plugins. Plugins should
2
+ // import this module only; it deliberately exposes selected shared UI, not
3
+ // the underlying @raggle-ai/ui package.
4
+ export {
5
+ CopyContextButton,
6
+ FilePreview,
7
+ FilePreviewList,
8
+ FolderFilterBar,
9
+ PluginPage,
10
+ PluginPageError,
11
+ PluginPageStatus,
12
+ useFolderFilter,
13
+ } from "./page.ts"
14
+ export { folderPathId } from "./client.ts"
15
+ export {
16
+ apiError,
17
+ ApiError,
18
+ jsonError,
19
+ jsonResponse,
20
+ parseJsonBody,
21
+ readBoundedBody,
22
+ runApiRoute,
23
+ sameOrigin,
24
+ } from "./endpoint.ts"
25
+ export { FolderPluginFailure } from "./server.ts"
26
+ export { isPluginPayloadError } from "./types.ts"
27
+ export type {
28
+ FolderPluginDataset,
29
+ FolderPluginDetection,
30
+ FolderPluginId,
31
+ FolderPluginManifest,
32
+ FolderPluginPayload,
33
+ FolderPluginPayloadError,
34
+ } from "./types.ts"
35
+ export type {
36
+ FolderPluginClient,
37
+ FolderPluginHostActions,
38
+ FolderPluginViewProps,
39
+ } from "./client.ts"
40
+ export type { ApiErrorCode, ApiRouteHandle, ApiRouteSpec } from "./endpoint.ts"
41
+ export type {
42
+ FolderPluginContext,
43
+ FolderPluginData,
44
+ FolderPluginInitFile,
45
+ FolderPluginInitResult,
46
+ FolderPluginServer,
47
+ } from "./server.ts"
48
+ export type {
49
+ FolderFilterChoice,
50
+ FolderFilterMode,
51
+ FolderSelection,
52
+ } from "./page.ts"
@@ -0,0 +1,17 @@
1
+ export {
2
+ EntityError as PluginPageError,
3
+ EntityPage as PluginPage,
4
+ EntityStatus as PluginPageStatus,
5
+ } from "@raggle-ai/ui/pages/entity-page"
6
+ export { CopyContextButton } from "@raggle-ai/ui/components/copy-context"
7
+ export {
8
+ FilePreview,
9
+ FilePreviewList,
10
+ } from "@raggle-ai/ui/components/file-preview"
11
+ export { FolderFilterBar } from "@raggle-ai/ui/components/folder-filter-bar"
12
+ export { useFolderFilter } from "@raggle-ai/ui/hooks/use-folder-filter"
13
+ export type {
14
+ FolderFilterChoice,
15
+ FolderFilterMode,
16
+ FolderSelection,
17
+ } from "@raggle-ai/ui/lib/folder-filter"
@@ -9,7 +9,11 @@
9
9
  "allowImportingTsExtensions": true,
10
10
  // local copy: bun doesn't read paths inherited via `extends`
11
11
  "paths": {
12
- "~/*": ["${configDir}/../../packages/*/src"]
12
+ "~/*": ["${configDir}/../../packages/*/src"],
13
+ "kennel-plugins": ["./src/index.ts"],
14
+ "kennel-plugins/*": ["./src/*"],
15
+ "@raggle-ai/ui/*": ["../ui/src/*"],
16
+ "kennel-client": ["../api-client/src/index.ts"]
13
17
  }
14
18
  },
15
19
  "include": ["src"],
@@ -0,0 +1,25 @@
1
+ import { defineConfig } from "tsup"
2
+
3
+ export default defineConfig({
4
+ entry: [
5
+ "src/index.ts",
6
+ "src/client.ts",
7
+ "src/endpoint.ts",
8
+ "src/page.ts",
9
+ "src/server.ts",
10
+ "src/subpath.ts",
11
+ "src/types.ts",
12
+ "src/validation.ts",
13
+ ],
14
+ format: ["esm"],
15
+ target: "es2022",
16
+ platform: "neutral",
17
+ clean: true,
18
+ esbuildOptions(options) {
19
+ options.jsx = "automatic"
20
+ },
21
+ splitting: true,
22
+ dts: { resolve: [/^@raggle-ai\/ui(?:\/|$)/, /^kennel-client(?:\/|$)/] },
23
+ noExternal: [/^@raggle-ai\/ui(?:\/|$)/, /^kennel-client(?:\/|$)/],
24
+ external: ["react", "react-dom", "react/jsx-runtime"],
25
+ })
@@ -2,7 +2,7 @@ import type { ReactNode } from "react"
2
2
 
3
3
  /**
4
4
  * One precise content problem, structurally identical to
5
- * `ContentIssue` from `@raggle-ai/folder-plugin` (kept local so the ui
5
+ * `ContentIssue` from `kennel-plugins` (kept local so the ui
6
6
  * package does not depend on the plugin contract's runtime).
7
7
  */
8
8
  export type ContentIssue = {
@@ -6,7 +6,7 @@
6
6
  "lib": ["dom", "dom.iterable", "esnext"],
7
7
  "jsx": "preserve",
8
8
  "baseUrl": ".",
9
- // Packages whose sources ui compile reach folder-plugin entries that
9
+ // Packages whose sources ui compile reach kennel-plugins entries that
10
10
  // import sibling files with .ts extensions (Bundler resolution, noEmit).
11
11
  "allowImportingTsExtensions": true
12
12
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kennel",
3
- "version": "0.2.3",
3
+ "version": "0.2.6",
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",
@@ -67,7 +67,6 @@
67
67
  "@lexical/rich-text": "0.49.0",
68
68
  "@libsql/client": "^0.17.3",
69
69
  "@raggle-ai/barkdown": "0.6.1",
70
- "@raggle-ai/folder-plugin": "^0.1.0",
71
70
  "@raggle-ai/kennel-knowledge": "^0.1.0",
72
71
  "@raggle-ai/kennel-mcp": "^0.1.8",
73
72
  "@raggle-ai/kennel-preview": "^0.1.0",
@@ -116,7 +115,7 @@
116
115
  "zod": "^4.3.6"
117
116
  },
118
117
  "devDependencies": {
119
- "@raggle-ai/folder-plugin": "^0.1.0",
118
+ "kennel-plugins": "0.1.0",
120
119
  "@types/node": "^22.13.4",
121
120
  "typescript": "^5.9.3"
122
121
  },
@@ -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};
@@ -0,0 +1,2 @@
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/ask-tray-SscJecDY.js","assets/react-B9jn2M18.js","assets/markdown-Bw9RgUGR.js","assets/view-context-DXKM3-l1.js","assets/index-CUTtMSyJ.js","assets/index-Dwhf8F_U.css","assets/tanstack-YzX_Mi37.js","assets/button-C6arH7zt.js","assets/utils-DCaHk0Gm.js","assets/folder-plugin-view-Cvd804ZU.js","assets/command-zkzH4hVz.js","assets/index-CCXE8zc9.js","assets/index-CegvVQ1C.js","assets/popover-0oA2lLUV.js","assets/folder-image-Bnv43tzP.js","assets/viewer-capabilities-Cig_xM9u.js","assets/entities-CCUtpskY.js","assets/search-C1J0-xiB.js","assets/search-BOHZTLC-.css","assets/folder-landing-DCnzYXXY.js","assets/folder-metadata-C9hMMzIH.js","assets/copy-context-D5oiWrYC.js","assets/index-Bp9DidgD.js","assets/app-options-CkPJE5ep.js","assets/index-CXhBn-ar.js","assets/folder-list-DvVkVjiR.js","assets/folder-activity-Cv1X2ezj.js","assets/folder-mobile-bar-VoTL1GS0.js","assets/app-view-header-CNk5KnA-.js","assets/file-viewer-DJ3rsmef.js","assets/metadata-COJ7fZul.js","assets/project-search-dialog-B2oqMT6h.js","assets/client-Dk-NBvJR.js","assets/select-CtXC_PLC.js","assets/client-7OWw5kW2.js"])))=>i.map(i=>d[i]);
2
+ import{_ as g,i as ne,f as T,c as re,e as ae,p as S,l as je,g as Re,r as _e,b as be}from"./index-CUTtMSyJ.js";import{c as s,j as r}from"./react-B9jn2M18.js";import{m as x,c as f}from"./tanstack-YzX_Mi37.js";import{b as ke,c as Ee,q as Ie,L as Te,T as Se,v as Q,V as De,i as se,s as ie,a as M,t as ce,g as Ae,h as Oe,j as E,k as F,m as Fe}from"./view-context-DXKM3-l1.js";function N(e){const t=new TextEncoder().encode(e);let o="";for(const c of t)o+=String.fromCharCode(c);return btoa(o).replaceAll("+","-").replaceAll("/","_").replaceAll("=","")}function Le(e){const t=new URL(e,window.location.origin),o=t.pathname.split("/").filter(Boolean),c=o.indexOf("folder"),d=c>=0?o[c+1]:void 0;let i=t.searchParams.get("folder")??void 0;if(!i&&d){const l=d.replaceAll("-","+").replaceAll("_","/"),a=l.padEnd(Math.ceil(l.length/4)*4,"="),u=atob(a),m=Uint8Array.from(u,j=>j.charCodeAt(0));i=new TextDecoder().decode(m)}return{folder:i}}function xt(e,t){return`/folder/${N(e)}/${t}`}function jt(e,t){return`/folder/${N(e)}/document/${N(t)}`}async function Ne(e,t,o={}){const c=new URL(e,window.location.origin),d=new URL("/api/metadata",window.location.origin),i=c.pathname.split("/").filter(Boolean),l=i[0]==="folder"?i[1]:void 0,a=c.searchParams.get("folder");if(a)d.searchParams.set("path",a);else if(l){const m=l.replaceAll("-","+").replaceAll("_","/"),j=m.padEnd(Math.ceil(m.length/4)*4,"="),y=atob(j),C=Uint8Array.from(y,V=>V.charCodeAt(0));d.searchParams.set("path",new TextDecoder().decode(C))}d.searchParams.set("part",t),o.notesScope&&d.searchParams.set("notesScope",o.notesScope);const u=await fetch(d,{headers:o.headers,signal:o.signal});if(!u.ok)throw new Error(await u.text());return await u.json()}function Ce(e,t=!0){const o=s.useRef(!1),c=Le(e).folder,d=c?N(c):"none",i=m=>({enabled:t&&!!c,gcTime:5*6e4,queryFn:({signal:j})=>{const y=m==="linked"&&o.current;return y&&(o.current=!1),Ne(e,"notes",{headers:y?{"x-kennel-retry-linked":"1"}:void 0,notesScope:m,signal:j})},queryKey:["folder",d,"notes",m],staleTime:15e3}),l=x.useQuery(i("local")),a=x.useQuery(i("linked")),u=s.useMemo(()=>l.data||a.data?[...l.data?.files.items??[],...a.data?.files.items??[]]:void 0,[l.data,a.data]);return{local:l,linked:a,files:u,retryLinked:()=>{o.current=!0,a.refetch()}}}const Ve=s.lazy(async()=>({default:(await g(async()=>{const{AskTray:e}=await import("./ask-tray-SscJecDY.js");return{AskTray:e}},__vite__mapDeps([0,1,2,3,4,5,6,7,8]))).AskTray}));function $e({folder:e}){const{enabled:t}=ke(),{draft:o}=Ee(e);return!t&&!o.comments.length&&!o.attachments.length?null:r.jsx(s.Suspense,{fallback:null,children:r.jsx(Ve,{folder:e})})}function Ke(e){const t=e.slice(e.lastIndexOf(".")).toLowerCase();if(t===".htm"||t===".html")return"html";if(t===".md"||t===".markdown")return"markdown";if(t===".text"||t===".txt")return"text"}async function le(e,t=""){const o=[];for await(const c of e.values()){const d=t?`${t}/${c.name}`:c.name;if(c.kind==="directory"){o.push(...await le(c,d));continue}const i=Ke(c.name);if(!i)continue;const l=await c.getFile();o.push({path:d,content:await l.text(),kind:i})}return o}async function qe(e){const t=await le(e);return t.sort((o,c)=>o.path.localeCompare(c.path)),{root:e.name,documents:t}}async function He(e){for(const t of e){if(t.kind!=="file")continue;const o=t.getAsFileSystemHandle;if(!o)throw new Error("This browser cannot read dropped folders.");const c=await o.call(t);if(c?.kind==="directory")return c}throw new Error("Drop one folder to open it.")}const Qe="kennel-folder-query-cache",z="queries",U=1,Me=10080*60*1e3;function ze(){return new Promise((e,t)=>{const o=indexedDB.open(Qe,U);o.onupgradeneeded=()=>{o.result.createObjectStore(z)},o.onerror=()=>t(o.error),o.onsuccess=()=>e(o.result)})}async function de(e,t){const o=await ze();return new Promise((c,d)=>{const i=o.transaction(z,e),l=t(i.objectStore(z));l.onerror=()=>d(l.error),l.onsuccess=()=>c(l.result),i.oncomplete=()=>o.close(),i.onerror=()=>{o.close(),d(i.error)}})}async function ee(e){const t=await de("readonly",o=>o.get(JSON.stringify(e))).catch(()=>{});if(t?.version===U&&!(Date.now()-t.savedAt>Me))return t.data}async function te(e,t){t&&await de("readwrite",o=>o.put({data:t,savedAt:Date.now(),version:U},JSON.stringify(e))).catch(()=>{})}const ue=s.lazy(async()=>({default:(await g(async()=>{const{FolderPluginPage:e}=await import("./folder-plugin-view-Cvd804ZU.js").then(t=>t.f);return{FolderPluginPage:e}},__vite__mapDeps([9,1,2,6,3,4,5,7,8,10,11,12,13,14,15]))).FolderPluginPage})),Be=s.lazy(async()=>({default:(await g(async()=>{const{EntitySearchPage:e}=await import("./entities-CCUtpskY.js");return{EntitySearchPage:e}},__vite__mapDeps([16,1,2,6,3,4,5]))).EntitySearchPage})),Ue=s.lazy(async()=>({default:(await g(async()=>{const{ProjectSearchPage:e}=await import("./search-C1J0-xiB.js");return{ProjectSearchPage:e}},__vite__mapDeps([17,1,2,6,3,4,5,18]))).ProjectSearchPage}));function I(){return r.jsx("p",{role:"status",className:"text-muted-foreground p-4 text-sm",children:"Loading page…"})}const D=f.createRootRoute({component:f.Outlet}),oe=s.lazy(async()=>({default:(await g(()=>import("./folder-landing-DCnzYXXY.js"),__vite__mapDeps([19,1,2,3,4,5,6,7,8,20,21,11,12,14,22,23,24,25,26]))).FolderLanding})),Ye=s.lazy(async()=>({default:(await g(()=>import("./folder-mobile-bar-VoTL1GS0.js"),__vite__mapDeps([27,1,2,23,3,4,5,6,21,7,8,11,24,14,28,13]))).FolderMobileBar})),Je=s.lazy(async()=>({default:(await g(()=>import("./file-viewer-DJ3rsmef.js"),__vite__mapDeps([29,1,2,3,4,5,6,30]))).FileViewer})),We=s.lazy(async()=>({default:(await g(()=>import("./project-search-dialog-B2oqMT6h.js"),__vite__mapDeps([31,1,2,6,3,4,5,10,11,8,12]))).ProjectSearchDialog})),Ge=s.lazy(async()=>{const e=await g(()=>import("./client-Dk-NBvJR.js"),__vite__mapDeps([32,1,2,6,23,3,4,5,21,7,8,11,24,14,28,13,33,22,25]));return{default:function(){const o=f.useLocation(),c=`${window.location.origin}${o.href}`;return r.jsx(e.CollectionPage,{href:c,request:(d,i,l)=>M.metadata(d,i,l),subscribeApiEvent:ie,parseRoute:S,collectionHref:ae,documentHref:re,folderHref:B,homeHref:d=>T(d,"notes"),openFolder:d=>{M.openPath(d).catch(i=>ce.error(i instanceof Error?i.message:"Could not open the default app."))}})}}}),Xe=s.lazy(async()=>({default:(await g(()=>import("./client-7OWw5kW2.js"),__vite__mapDeps([34,1,2,3,4,5,6,7,8,21,26]))).NotesPage})),Ze=f.createRoute({getParentRoute:()=>D,path:"/",component:fe}),b=f.createRoute({getParentRoute:()=>D,path:"folder/$folderId",component:fe}),et=f.createRoute({getParentRoute:()=>b,path:"skills"}),tt=f.createRoute({getParentRoute:()=>b,path:"views/$pluginId",component:ue}),ot=f.createRoute({getParentRoute:()=>b,path:"views/$pluginId/$subpath",component:ue}),nt=f.createRoute({getParentRoute:()=>b,path:"collections/$collectionId",component:()=>r.jsx(s.Suspense,{fallback:r.jsx("p",{role:"status",children:"Loading collection…"}),children:r.jsx(Ge,{})})}),rt=f.createRoute({getParentRoute:()=>b,path:"notes",component:Xe}),at=f.createRoute({getParentRoute:()=>b,path:"projects"}),st=f.createRoute({getParentRoute:()=>D,path:"entities",component:Be}),it=f.createRoute({getParentRoute:()=>D,path:"search",component:Ue}),ct=D.addChildren([Ze,st,it,b.addChildren([rt,nt,et,tt,ot,at])]),lt=f.createRouter({routeTree:ct});function dt(){const e=S(window.location.href).folder;return e?T(e,"notes"):"/"}function B(e){return T(e,"notes")}function ut(e){const t=S(window.location.href).folder;return t?re(t,e):e}function ft(e){const t=S(window.location.href).folder;return t?e==="files"?T(t,"notes"):T(t,e):"/"}function pt(e){const t=S(window.location.href).folder;return t?be(t,e):"/"}function mt({href:e,...t}){return!e?.startsWith("/")||ne(e)?r.jsx("a",{href:e,...t}):r.jsx(f.Link,{to:e,...t})}function ht(){return r.jsx(x.QueryClientProvider,{client:Ie,children:r.jsxs(Te,{component:mt,children:[r.jsx(s.Suspense,{fallback:r.jsx(I,{}),children:r.jsx(f.RouterProvider,{router:lt})}),r.jsx(Se,{})]})})}const L={discovery:Number.POSITIVE_INFINITY,identity:Number.POSITIVE_INFINITY,plugins:Number.POSITIVE_INFINITY,skills:15e3};function P(e,t){return["folder",e,t]}function fe(){const e=f.useLocation(),t=`${window.location.origin}${e.href}`,o=Q(t);return r.jsx(De,{kind:"folder",folder:se(t)?void 0:o.folder,children:r.jsx(yt,{})})}function yt(){const e=Ae(),t=je(window.location.href);t&&window.history.replaceState(null,"",t);const o=x.useQueryClient(),c=f.useNavigate(),d=f.useLocation(),i=`${window.location.origin}${d.href}`,l=se(i),a=Q(i),u=a.folder?Re(a.folder):"none",[m,j]=s.useState(()=>window.matchMedia("(max-width: 767px)").matches),[y,C]=s.useState(),[V,$]=s.useState(!1),[Y,J]=s.useState(!1),[pe,me]=s.useState(!1),W=pe&&!a.document,A=s.useRef(0),k=!l&&!y,R=k&&!!a.folder,he=P(u,"identity"),ye=P(u,"discovery");Oe(i,k);const ge=s.useMemo(()=>y?{read:async()=>y}:l?{read:E.read}:{...E},[y,l]),v=x.useQuery({enabled:!!R,gcTime:Number.POSITIVE_INFINITY,queryFn:({signal:n})=>F(i,"identity",{signal:n}),queryKey:he,staleTime:L.identity}),h=x.useQuery({enabled:!!(R&&a.section==="projects"),gcTime:Number.POSITIVE_INFINITY,queryFn:({signal:n})=>F(i,"discovery",{signal:n}),queryKey:ye,staleTime:L.discovery}),G=x.useQuery({enabled:!!R,gcTime:Number.POSITIVE_INFINITY,queryFn:({signal:n})=>F(i,"plugins",{signal:n}),queryKey:P(u,"plugins"),staleTime:L.plugins}),X=Ce(i,R&&a.section==="notes"),Z=x.useQuery({enabled:!!(R&&a.section==="skills"),gcTime:5*6e4,queryFn:({signal:n})=>F(i,"skills",{signal:n}),queryKey:P(u,"skills"),staleTime:L.skills}),_=s.useMemo(()=>{if(v.data)return{assets:{...h.data?.assets,...v.data.assets},files:{items:X.files??[]},folder:v.data.folder,iconAssetKey:v.data.iconAssetKey,plugins:G.data?.plugins??{items:[]},projects:h.data?.projects??{items:[]},workspace:e.workspace??h.data?.workspace,sessions:{items:[]},skills:Z.data?.skills??{items:[]}}},[h.data,v.data,X.files,G.data,Z.data,e.workspace]),K=v.error??(a.section==="projects"?h.error:void 0)??void 0,we=K?K instanceof Error?K.message:"Could not load folder activity.":"",ve=(_?.folder??y?.root??a.folder??"Kennel").replace(/\/+$/,"").split("/").pop()??"Kennel",Pe=_?.iconAssetKey?_.assets[_.iconAssetKey]:void 0;s.useEffect(()=>{const n=window.matchMedia("(max-width: 767px)"),p=()=>j(n.matches);return n.addEventListener("change",p),()=>n.removeEventListener("change",p)},[]),s.useEffect(()=>ie("kennel:metadata-changed",()=>{o.invalidateQueries({queryKey:["folder",u]})}),[u,o]),s.useEffect(()=>Fe("kennel:linked-folders-changed",a.folder,()=>{for(const n of[["notes","linked"],["plugins"]])o.invalidateQueries({queryKey:["folder",u,...n]},{cancelRefetch:!1})}),[u,a.folder,o]),s.useEffect(()=>{if(!R)return;const n=P(u,"identity"),p=P(u,"discovery");ee(n).then(w=>{w&&!o.getQueryData(n)&&o.setQueryData(n,w)}),ee(p).then(w=>{w&&!o.getQueryData(p)&&o.setQueryData(p,w)})},[u,R,o]),s.useEffect(()=>{te(P(u,"identity"),v.data)},[u,v.data]),s.useEffect(()=>{te(P(u,"discovery"),h.data)},[h.data,u]);const xe=n=>{const p=new URL(n,window.location.origin);Q(p.href),c({to:`${p.pathname}${p.search}`})},q=a.view||a.collectionId||a.section==="notes"?r.jsx(s.Suspense,{fallback:r.jsx(I,{}),children:r.jsx(f.Outlet,{})}):a.section==="projects"&&!h.data&&(h.isPending||h.error)?r.jsx("div",{className:"p-4",role:h.error?"alert":"status",children:h.error?r.jsxs(r.Fragment,{children:["Projects could not load."," ",r.jsx("button",{onClick:()=>{h.refetch()},children:"Retry projects"})]}):"Loading projects…"}):null,O=!!a.collectionId,H={data:_,collectionId:a.collectionId,collectionHref:n=>a.folder?ae(a.folder,n):"/",documentHref:ut,error:we,folder:a.folder,folderHref:B,onFindProject:()=>J(!0),onOpenFolder:()=>{E.openRoot?.()},onOpenPath:n=>{M.openPath(n).catch(p=>ce.error(p instanceof Error?p.message:"Could not open the default app."))},pluginHref:pt,tab:_e(a),tabHref:ft,view:a.view};return r.jsxs("div",{className:"folder-drop-zone","data-mobile-landing":k&&m?"true":void 0,onClickCapture:n=>{if(n.defaultPrevented||n.button!==0||n.metaKey||n.ctrlKey||n.shiftKey||n.altKey||!(n.target instanceof Element))return;const w=n.target.closest("a[href]")?.getAttribute("href");if(w?.startsWith("/folder/")&&!ne(w)){n.preventDefault(),xe(w);return}},onDragEnter:n=>{l||[...n.dataTransfer.items].some(p=>p.kind==="file")&&(n.preventDefault(),A.current+=1,$(!0))},onDragLeave:()=>{A.current-=1,A.current<=0&&$(!1)},onDragOver:n=>{l||(n.preventDefault(),n.dataTransfer.dropEffect="copy")},onDrop:n=>{l||(n.preventDefault(),A.current=0,$(!1),He(n.dataTransfer.items).then(qe).then(p=>{window.history.replaceState(null,"",window.location.pathname),C(p)}))},children:[O?null:r.jsx(s.Suspense,{fallback:null,children:r.jsx(Ye,{canOpen:!l&&!y,homeHref:dt(),icon:Pe,name:ve,folder:_?.folder??a.folder,folderHref:B,collectionHref:H.collectionHref,workspace:e.workspace??_?.workspace,onOpen:()=>{if(m){me(!0);return}E.openRoot?.()},onOpenFolder:()=>{E.openRoot?.()}})}),k&&O?r.jsx(s.Suspense,{fallback:r.jsx(I,{}),children:q}):null,k&&!O&&!m?r.jsx(s.Suspense,{fallback:r.jsx(I,{}),children:r.jsx(oe,{...H,children:q})}):null,k&&!O&&m?r.jsx("div",{className:"mobile-landing-content",children:r.jsx(s.Suspense,{fallback:r.jsx(I,{}),children:r.jsx(oe,{...H,children:q})})}):null,W?r.jsx(s.Suspense,{fallback:null,children:r.jsx(Je,{source:ge})}):null,a.folder&&!W?r.jsx($e,{folder:a.folder},a.folder):null,V?r.jsx("div",{className:"folder-drop-overlay",children:"Drop folder to open"}):null,Y?r.jsx(s.Suspense,{fallback:null,children:r.jsx(We,{open:Y,onOpenChange:J})}):null]})}const Rt=Object.freeze(Object.defineProperty({__proto__:null,App:ht},Symbol.toStringTag,{value:"Module"}));export{xt as a,jt as b,Rt as c,N as f,Le as p,Ce as u};