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.
- package/README.md +23 -13
- package/dist/cli/dispatch.js +16 -3
- package/dist/cli/src/cli/dispatch.js +16 -3
- package/dist/cli/src/cli/usage.js +1 -1
- package/dist/cli/src/core/command.js +1 -0
- package/dist/cli/src/core/init.js +5 -5
- package/dist/cli/src/plugins/external.d.ts +28 -2
- package/dist/cli/src/plugins/external.js +77 -23
- package/dist/cli/src/site/server-plugins.d.ts +4 -9
- package/dist/cli/src/site/viewer.js +1 -0
- package/dist/cli/usage.js +1 -1
- package/dist/core/api-client.js +576 -10317
- package/dist/core/command.js +1 -0
- package/dist/core/core-folders.js +2313 -12088
- package/dist/core/init.js +5 -5
- package/dist/core/runtime.js +8237 -20713
- package/dist/package/preview.js +19617 -33352
- package/dist/plugins/external.d.ts +28 -2
- package/dist/plugins/external.js +77 -23
- package/dist/site/server-plugins.d.ts +4 -9
- package/dist/site/server-plugins.js +557 -10452
- package/dist/site/viewer.js +1 -0
- package/kernel/apps/web/package.json +2 -6
- package/kernel/apps/web/scripts/dev.mjs +53 -0
- package/kernel/apps/web/src/app.css +0 -3
- package/kernel/apps/web/src/external-plugins.ts +1 -1
- package/kernel/apps/web/src/folder-filter-icons.tsx +1 -1
- package/kernel/apps/web/src/folder-plugin-view.tsx +1 -1
- package/kernel/apps/web/src/main.tsx +0 -1
- package/kernel/apps/web/src/plugins.ts +1 -31
- package/kernel/apps/web/tsconfig.json +1 -2
- package/kernel/apps/web/vite.config.ts +32 -14
- package/kernel/packages/agents/package.json +1 -1
- package/kernel/packages/agents/src/agent-card.tsx +1 -1
- package/kernel/packages/agents/src/client.tsx +1 -1
- package/kernel/packages/agents/src/manifest.ts +1 -1
- package/kernel/packages/agents/src/server.ts +1 -1
- package/kernel/packages/agents/src/viewer.tsx +1 -1
- package/kernel/packages/api/package.json +1 -5
- package/kernel/packages/api/src/server/acp-live-plugin.ts +1 -1
- package/kernel/packages/api/src/server/api/create-agent-file.ts +2 -2
- package/kernel/packages/api/src/server/api/document-edit.ts +2 -2
- package/kernel/packages/api/src/server/api/open-path.ts +2 -2
- package/kernel/packages/api/src/server/folder-metadata-plugin.ts +17 -42
- package/kernel/packages/api/src/server/index.ts +0 -1
- package/kernel/packages/api/src/server/plugins.ts +52 -19
- package/kernel/packages/api/src/shared/viewer-route.ts +1 -1
- package/kernel/packages/api/test/core.test.ts +14 -26
- package/kernel/packages/markdown/README.md +1 -1
- package/kernel/packages/notes/package.json +1 -1
- package/kernel/packages/notes/src/client.tsx +1 -1
- package/kernel/packages/notes/src/manifest.ts +1 -1
- package/kernel/packages/notes/src/server.ts +1 -1
- package/kernel/packages/plugins/SKILL.md +39 -0
- package/kernel/{plugins/mail → packages/plugins}/package.json +53 -28
- package/kernel/packages/plugins/src/index.ts +52 -0
- package/kernel/packages/plugins/src/page.ts +17 -0
- package/kernel/{plugins/projects → packages/plugins}/tsconfig.json +5 -1
- package/kernel/packages/plugins/tsup.config.ts +25 -0
- package/kernel/packages/ui/src/components/content-issues.tsx +1 -1
- package/kernel/packages/ui/tsconfig.json +1 -1
- package/package.json +2 -3
- package/web/assets/{abnfDiagram-VRR7QNED-Bgfb1nEB.js → abnfDiagram-VRR7QNED-xd_g1uK3.js} +1 -1
- package/web/assets/app-CX20nNIa.js +2 -0
- package/web/assets/{app-options-D-RJiQ-X.js → app-options-CkPJE5ep.js} +1 -1
- package/web/assets/{app-view-header-BLvLq02T.js → app-view-header-CNk5KnA-.js} +1 -1
- package/web/assets/{arc-Dk_KI36B.js → arc-B0u5yBJA.js} +1 -1
- package/web/assets/{architectureDiagram-ZJ3FMSHR-NR_KhRCf.js → architectureDiagram-ZJ3FMSHR-DfxOAo8P.js} +1 -1
- package/web/assets/{ask-tray-TzeTcO6-.js → ask-tray-SscJecDY.js} +1 -1
- package/web/assets/{blockDiagram-677ZJIJ3-CkLkwx9C.js → blockDiagram-677ZJIJ3-Ci3Usxh6.js} +1 -1
- package/web/assets/{c4Diagram-LMCZKHZV-CFCUH8e_.js → c4Diagram-LMCZKHZV-BqgwIVgh.js} +1 -1
- package/web/assets/channel-X7WHyxxT.js +1 -0
- package/web/assets/{chunk-2Q5K7J3B-B_BPLWsW.js → chunk-2Q5K7J3B-CfX69l2U.js} +1 -1
- package/web/assets/{chunk-32BRIVSS-B1VB1hOy.js → chunk-32BRIVSS-CuFlzZkl.js} +1 -1
- package/web/assets/{chunk-5VM5RSS4-KFcYr8Co.js → chunk-5VM5RSS4-DidCMlJa.js} +1 -1
- package/web/assets/{chunk-EX3LRPZG-CpBX3kuK.js → chunk-EX3LRPZG-B5CDm1dS.js} +1 -1
- package/web/assets/{chunk-JWPE2WC7-BPSl40wG.js → chunk-JWPE2WC7-D5fGV_sH.js} +1 -1
- package/web/assets/{chunk-MOJQB5TN-D2RcYmoU.js → chunk-MOJQB5TN-ayhH5Q-H.js} +1 -1
- package/web/assets/{chunk-RYQCIY6F-m7Gyn-t3.js → chunk-RYQCIY6F-C4BfOOZn.js} +1 -1
- package/web/assets/{chunk-V7JOEXUC-TDvdopxS.js → chunk-V7JOEXUC-DpUEIM9V.js} +1 -1
- package/web/assets/{chunk-VR4S4FIN-DZTsG51a.js → chunk-VR4S4FIN-DoQuFFRh.js} +1 -1
- package/web/assets/{chunk-XXDRQBXY-Dp0--RE2.js → chunk-XXDRQBXY-CI9eiLwn.js} +1 -1
- package/web/assets/classDiagram-OUVF2IWQ-BjsLQ3dz.js +1 -0
- package/web/assets/classDiagram-v2-EOCWNBFH-BjsLQ3dz.js +1 -0
- package/web/assets/client-7OWw5kW2.js +6 -0
- package/web/assets/client-DYj_td4Q.js +17 -0
- package/web/assets/{client-j2kQmxsO.js → client-Dk-NBvJR.js} +4 -4
- package/web/assets/command-zkzH4hVz.js +38 -0
- package/web/assets/{copy-context-C0Uqsp-3.js → copy-context-D5oiWrYC.js} +1 -1
- package/web/assets/{cose-bilkent-JH36ORCC-CPu3PI8h.js → cose-bilkent-JH36ORCC-BHRk1mO3.js} +1 -1
- package/web/assets/{cynefin-VYW2F7L2-DWxftYAm.js → cynefin-VYW2F7L2-C1B09TRE.js} +1 -1
- package/web/assets/{cynefinDiagram-TSTJHNR4-DsmN2V-p.js → cynefinDiagram-TSTJHNR4-B27qXQbv.js} +1 -1
- package/web/assets/{dagre-VKFMJZFB-COEbApyY.js → dagre-VKFMJZFB-B1qEi32g.js} +1 -1
- package/web/assets/{diagram-FQU43EPY-0O9WGWKB.js → diagram-FQU43EPY-BMkkgADD.js} +1 -1
- package/web/assets/{diagram-G47NLZAW-CutEdMVh.js → diagram-G47NLZAW-Cb8_g1A5.js} +1 -1
- package/web/assets/{diagram-NH7WQ7WH-C9KZc3B2.js → diagram-NH7WQ7WH-B51wuc5m.js} +1 -1
- package/web/assets/{diagram-OA4YK3LP-D8kkPXbY.js → diagram-OA4YK3LP-xnsecbbI.js} +1 -1
- package/web/assets/{diagram-WEI45ONY-_YqiTaGP.js → diagram-WEI45ONY-DSZdyaAV.js} +1 -1
- package/web/assets/{document-Dgt5eZFj.js → document-Dc2dftTW.js} +3 -3
- package/web/assets/{ebnfDiagram-CCIWWBDH-JO-zQh6g.js → ebnfDiagram-CCIWWBDH-aTHmcUGy.js} +1 -1
- package/web/assets/{entities-C3wz7FCx.js → entities-CCUtpskY.js} +1 -1
- package/web/assets/{erDiagram-Q63AITRT-9UjQwJ4P.js → erDiagram-Q63AITRT-CUUPBcvo.js} +1 -1
- package/web/assets/{file-viewer-DZJ8nYnl.js → file-viewer-DJ3rsmef.js} +1 -1
- package/web/assets/{flowDiagram-23GEKE2U-Ca08tnYM.js → flowDiagram-23GEKE2U-aTQXx2Mh.js} +1 -1
- package/web/assets/{folder-image-BfGgxo7i.js → folder-image-Bnv43tzP.js} +1 -1
- package/web/assets/{folder-landing-qUKBCnG-.js → folder-landing-DCnzYXXY.js} +1 -1
- package/web/assets/{folder-list-BfFjv7rR.js → folder-list-DvVkVjiR.js} +1 -1
- package/web/assets/{folder-metadata-DCw8xzHk.js → folder-metadata-C9hMMzIH.js} +1 -1
- package/web/assets/{folder-mobile-bar-Ubz4babf.js → folder-mobile-bar-VoTL1GS0.js} +1 -1
- package/web/assets/folder-plugin-view-Cvd804ZU.js +6 -0
- package/web/assets/{ganttDiagram-NO4QXBWP-KnHzX5W3.js → ganttDiagram-NO4QXBWP-DiwdUp7u.js} +1 -1
- package/web/assets/{gitGraphDiagram-IHSO6WYX-Cm8woNtK.js → gitGraphDiagram-IHSO6WYX-BL2gG_IS.js} +1 -1
- package/web/assets/{index-CNyy98F8.js → index-CUTtMSyJ.js} +2 -2
- package/web/assets/index-CegvVQ1C.js +1 -0
- package/web/assets/index-Dwhf8F_U.css +1 -0
- package/web/assets/{infoDiagram-FWYZ7A6U-yyqmUtIb.js → infoDiagram-FWYZ7A6U-B3n0zZpt.js} +1 -1
- package/web/assets/{ishikawaDiagram-FXEZZL3T-BfvR_Zy4.js → ishikawaDiagram-FXEZZL3T-D7YytbEv.js} +1 -1
- package/web/assets/{journeyDiagram-5HDEW3XC-BKuw06HM.js → journeyDiagram-5HDEW3XC-BYwqEl3C.js} +1 -1
- package/web/assets/{kanban-definition-HUTT4EX6-n0010rmQ.js → kanban-definition-HUTT4EX6-BQHNJgXZ.js} +1 -1
- package/web/assets/{linear-C0d0lT8O.js → linear-BPiQCLNk.js} +1 -1
- package/web/assets/{mermaid.core-BDVbShyO.js → mermaid.core-CD-KvBjV.js} +4 -4
- package/web/assets/{metadata-KV0dpp4G.js → metadata-COJ7fZul.js} +1 -1
- package/web/assets/{mindmap-definition-LN4V7U3C--_0ks3GF.js → mindmap-definition-LN4V7U3C-C1L_gyoj.js} +1 -1
- package/web/assets/{pegDiagram-2B236MQR-CBoNIpKR.js → pegDiagram-2B236MQR-BDAfItqS.js} +1 -1
- package/web/assets/{pieDiagram-ENE6RG2P-MA5tkYh5.js → pieDiagram-ENE6RG2P-CkZYH3Vz.js} +1 -1
- package/web/assets/{popover-DBD7FF-W.js → popover-0oA2lLUV.js} +2 -2
- package/web/assets/{project-search-dialog-DM1IkSZu.js → project-search-dialog-B2oqMT6h.js} +1 -1
- package/web/assets/{quadrantDiagram-ABIIQ3AL-CWT1ryqF.js → quadrantDiagram-ABIIQ3AL-Dy8Al3YZ.js} +1 -1
- package/web/assets/{railroadDiagram-RFXS5EU6-ZiLB5FGi.js → railroadDiagram-RFXS5EU6-Dd9_yo7B.js} +1 -1
- package/web/assets/{requirementDiagram-TGXJPOKE-CQq9uneq.js → requirementDiagram-TGXJPOKE-DPhIUsbs.js} +1 -1
- package/web/assets/{sankeyDiagram-HTMAVEWB-qDG-0JqI.js → sankeyDiagram-HTMAVEWB-B2QkYtub.js} +1 -1
- package/web/assets/{search-DNrQA5fF.js → search-C1J0-xiB.js} +1 -1
- package/web/assets/select-CtXC_PLC.js +30 -0
- package/web/assets/{selection-popup-DmtTeRs2.js → selection-popup-qhlUFzGq.js} +1 -1
- package/web/assets/{sequenceDiagram-DBY2YBRQ-CiApurLO.js → sequenceDiagram-DBY2YBRQ-Bx7fcZDx.js} +1 -1
- package/web/assets/{sizeCapture-X5ZJPWSS-DZSR5QXm.js → sizeCapture-X5ZJPWSS-CIXIhl_A.js} +1 -1
- package/web/assets/{stateDiagram-2N3HPSRC-CjJJR9_z.js → stateDiagram-2N3HPSRC-DCrdAflB.js} +1 -1
- package/web/assets/stateDiagram-v2-6OUMAXLB-0KCFLYeQ.js +1 -0
- package/web/assets/{swimlanes-5IMT3BWC-CKmo1sg6.js → swimlanes-5IMT3BWC-DA2vc7iZ.js} +2 -2
- package/web/assets/swimlanesDiagram-G3AALYLV-CAw3AV84.js +8 -0
- package/web/assets/{timeline-definition-FHXFAJF6-D-NMwS3y.js → timeline-definition-FHXFAJF6-lKfJiV9V.js} +1 -1
- package/web/assets/{vennDiagram-L72KCM5P-CfL6LBWw.js → vennDiagram-L72KCM5P-DO1q2KzG.js} +1 -1
- package/web/assets/{view-context-gyDl_p2V.js → view-context-DXKM3-l1.js} +4 -4
- package/web/assets/{viewer-capabilities-Bpp8Uvcg.js → viewer-capabilities-Cig_xM9u.js} +1 -1
- package/web/assets/{wardleyDiagram-EHGQE667-DgldMxaj.js → wardleyDiagram-EHGQE667-Dal9LkuZ.js} +1 -1
- package/web/assets/{xychartDiagram-FW5EYKEG-CIoAIFX8.js → xychartDiagram-FW5EYKEG-B3dPLPII.js} +1 -1
- package/web/index.html +2 -2
- package/kernel/packages/api/test/partial-loading.test.ts +0 -43
- package/kernel/packages/folder-plugin/package.json +0 -50
- package/kernel/packages/folder-plugin/src/index.ts +0 -15
- package/kernel/packages/folder-plugin/tsconfig.json +0 -17
- package/kernel/plugins/calendar/SKILL.md +0 -173
- package/kernel/plugins/calendar/eslint.config.js +0 -10
- package/kernel/plugins/calendar/package.json +0 -73
- package/kernel/plugins/calendar/schema.json +0 -137
- package/kernel/plugins/calendar/src/calendar.tsx +0 -328
- package/kernel/plugins/calendar/src/client.tsx +0 -139
- package/kernel/plugins/calendar/src/context.ts +0 -48
- package/kernel/plugins/calendar/src/copy-button.tsx +0 -66
- package/kernel/plugins/calendar/src/event-dialog.tsx +0 -270
- package/kernel/plugins/calendar/src/index.ts +0 -4
- package/kernel/plugins/calendar/src/manifest.ts +0 -7
- package/kernel/plugins/calendar/src/parse.ts +0 -610
- package/kernel/plugins/calendar/src/server.ts +0 -160
- package/kernel/plugins/calendar/src/utils.ts +0 -80
- package/kernel/plugins/calendar/src/views.tsx +0 -418
- package/kernel/plugins/calendar/test/context.test.mjs +0 -60
- package/kernel/plugins/calendar/test/package.test.mjs +0 -43
- package/kernel/plugins/calendar/test/parse.test.mjs +0 -392
- package/kernel/plugins/calendar/test/server.test.mjs +0 -126
- package/kernel/plugins/calendar/tsconfig.json +0 -17
- package/kernel/plugins/mail/SKILL.md +0 -97
- package/kernel/plugins/mail/eslint.config.js +0 -10
- package/kernel/plugins/mail/src/api.ts +0 -359
- package/kernel/plugins/mail/src/bun-ffi.d.ts +0 -14
- package/kernel/plugins/mail/src/client.tsx +0 -14
- package/kernel/plugins/mail/src/flock.ts +0 -137
- package/kernel/plugins/mail/src/folders.ts +0 -37
- package/kernel/plugins/mail/src/history.ts +0 -485
- package/kernel/plugins/mail/src/index.ts +0 -3
- package/kernel/plugins/mail/src/mail-card.tsx +0 -123
- package/kernel/plugins/mail/src/mail-conversation.tsx +0 -153
- package/kernel/plugins/mail/src/mail-detail-page.tsx +0 -467
- package/kernel/plugins/mail/src/mail-hooks.ts +0 -252
- package/kernel/plugins/mail/src/mail-page.tsx +0 -109
- package/kernel/plugins/mail/src/mail-request.ts +0 -78
- package/kernel/plugins/mail/src/mail-send-box.tsx +0 -175
- package/kernel/plugins/mail/src/mailos.ts +0 -723
- package/kernel/plugins/mail/src/manifest.ts +0 -7
- package/kernel/plugins/mail/src/node.ts +0 -171
- package/kernel/plugins/mail/src/parse.ts +0 -139
- package/kernel/plugins/mail/src/server.ts +0 -125
- package/kernel/plugins/mail/src/types.ts +0 -10
- package/kernel/plugins/mail/src/viewer.tsx +0 -147
- package/kernel/plugins/mail/test/flock.test.mjs +0 -156
- package/kernel/plugins/mail/test/folders.test.mjs +0 -138
- package/kernel/plugins/mail/test/history.test.mjs +0 -460
- package/kernel/plugins/mail/test/mailos.test.mjs +0 -752
- package/kernel/plugins/mail/test/node.test.mjs +0 -207
- package/kernel/plugins/mail/test/package.test.mjs +0 -54
- package/kernel/plugins/mail/test/parse.test.mjs +0 -32
- package/kernel/plugins/mail/test/server.test.mjs +0 -116
- package/kernel/plugins/mail/test/viewer.test.mjs +0 -192
- package/kernel/plugins/mail/tsconfig.json +0 -17
- package/kernel/plugins/projects/SKILL.md +0 -73
- package/kernel/plugins/projects/eslint.config.js +0 -10
- package/kernel/plugins/projects/package.json +0 -70
- package/kernel/plugins/projects/src/client.tsx +0 -17
- package/kernel/plugins/projects/src/data/model.ts +0 -129
- package/kernel/plugins/projects/src/index.ts +0 -17
- package/kernel/plugins/projects/src/manifest.ts +0 -7
- package/kernel/plugins/projects/src/project-context.ts +0 -41
- package/kernel/plugins/projects/src/server.ts +0 -276
- package/kernel/plugins/projects/src/ui/project-card.tsx +0 -61
- package/kernel/plugins/projects/src/ui/projects-page.tsx +0 -102
- package/kernel/plugins/projects/test/package.test.mjs +0 -51
- package/kernel/plugins/tasks/SKILL.md +0 -341
- package/kernel/plugins/tasks/eslint.config.js +0 -10
- package/kernel/plugins/tasks/package.json +0 -74
- package/kernel/plugins/tasks/schema.json +0 -939
- package/kernel/plugins/tasks/src/api.ts +0 -212
- package/kernel/plugins/tasks/src/client.tsx +0 -23
- package/kernel/plugins/tasks/src/data/parse.ts +0 -544
- package/kernel/plugins/tasks/src/data/task-id.ts +0 -56
- package/kernel/plugins/tasks/src/data/todo-model.ts +0 -795
- package/kernel/plugins/tasks/src/index.ts +0 -34
- package/kernel/plugins/tasks/src/manifest.ts +0 -7
- package/kernel/plugins/tasks/src/pages/task-detail.tsx +0 -48
- package/kernel/plugins/tasks/src/pages/task-list.tsx +0 -88
- package/kernel/plugins/tasks/src/server.ts +0 -447
- package/kernel/plugins/tasks/src/styles.css +0 -9
- package/kernel/plugins/tasks/src/ui/compact-todo-list.tsx +0 -372
- package/kernel/plugins/tasks/src/ui/error-details.tsx +0 -78
- package/kernel/plugins/tasks/src/ui/task-page.tsx +0 -392
- package/kernel/plugins/tasks/src/ui/todo-agent-filter.tsx +0 -36
- package/kernel/plugins/tasks/src/ui/todo-filter-bar.tsx +0 -66
- package/kernel/plugins/tasks/src/ui/todo-item.tsx +0 -494
- package/kernel/plugins/tasks/src/ui/todo-status-filter.tsx +0 -60
- package/kernel/plugins/tasks/src/ui/todo-tag-filter.tsx +0 -48
- package/kernel/plugins/tasks/src/ui/todo-warnings.tsx +0 -106
- package/kernel/plugins/tasks/test/api.test.mjs +0 -99
- package/kernel/plugins/tasks/test/folder-sources.test.mjs +0 -46
- package/kernel/plugins/tasks/test/package.test.mjs +0 -54
- package/kernel/plugins/tasks/test/parse.test.mjs +0 -225
- package/kernel/plugins/tasks/test/server.test.mjs +0 -386
- package/kernel/plugins/tasks/tsconfig.json +0 -17
- package/web/assets/app-DoGr2Zi7.js +0 -2
- package/web/assets/channel-uMEjV8qc.js +0 -1
- package/web/assets/classDiagram-OUVF2IWQ-fbZocVor.js +0 -1
- package/web/assets/classDiagram-v2-EOCWNBFH-fbZocVor.js +0 -1
- package/web/assets/client-C6Nxdfif.js +0 -2
- package/web/assets/client-CXYfBko5.js +0 -17
- package/web/assets/client-CoKtOq-X.js +0 -7
- package/web/assets/client-DyRQz5RU.js +0 -53
- package/web/assets/client-OY6HUzuD.js +0 -98
- package/web/assets/client-YOYWZIFi.js +0 -34
- package/web/assets/command-BugZBGXE.js +0 -38
- package/web/assets/folder-plugin-view-DsWR1zmQ.js +0 -6
- package/web/assets/index-BaRnbYRw.js +0 -1
- package/web/assets/index-BexmLxIP.css +0 -1
- package/web/assets/index-DDirZMgx.js +0 -1
- package/web/assets/note-card-DBfX6gW1.js +0 -6
- package/web/assets/select-D8cqNgcp.js +0 -30
- package/web/assets/stateDiagram-v2-6OUMAXLB-BpeGSCu9.js +0 -1
- package/web/assets/swimlanesDiagram-G3AALYLV-D9RjLKb9.js +0 -8
- package/web/assets/use-folder-filter-LQyXns5Q.js +0 -1
- /package/kernel/packages/{folder-plugin → plugins}/eslint.config.js +0 -0
- /package/kernel/packages/{folder-plugin → plugins}/src/client.ts +0 -0
- /package/kernel/packages/{folder-plugin → plugins}/src/endpoint.ts +0 -0
- /package/kernel/packages/{folder-plugin → plugins}/src/server.ts +0 -0
- /package/kernel/packages/{folder-plugin → plugins}/src/subpath.ts +0 -0
- /package/kernel/packages/{folder-plugin → plugins}/src/types.ts +0 -0
- /package/kernel/packages/{folder-plugin → plugins}/src/validation.ts +0 -0
- /package/kernel/packages/{folder-plugin → plugins}/test/contract.test.mjs +0 -0
|
@@ -1,22 +1,16 @@
|
|
|
1
|
-
import type { FolderPluginContext } from "
|
|
2
|
-
import type { FolderPluginServer } from "
|
|
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 {
|
|
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 =
|
|
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 "
|
|
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 "
|
|
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
|
|
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 "
|
|
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
|
|
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
|
|
258
|
-
|
|
259
|
-
|
|
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
|
|
271
|
-
|
|
272
|
-
|
|
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`,
|
|
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
|
-
"
|
|
42
|
+
"kennel-plugins": "workspace:*",
|
|
43
43
|
"@raggle-ai/ui": "workspace:*",
|
|
44
44
|
"@tanstack/react-query": "catalog:tanstack",
|
|
45
45
|
"lucide-react": "^0.562.0"
|
|
@@ -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": "
|
|
3
|
+
"name": "kennel-plugins",
|
|
4
4
|
"version": "0.1.0",
|
|
5
|
-
"description": "
|
|
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
|
|
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
|
-
"
|
|
18
|
+
"dist"
|
|
20
19
|
],
|
|
20
|
+
"sideEffects": false,
|
|
21
|
+
"prettier": "@raggle-ai/prettier-config",
|
|
21
22
|
"exports": {
|
|
22
|
-
".":
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
"./
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
"./
|
|
31
|
-
|
|
32
|
-
|
|
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
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
|
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
|
|
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
|
+
"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
|
-
"
|
|
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-
|
|
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};
|