kennel 0.2.2 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +29 -3
- package/dist/cli/src/plugins/external.js +78 -24
- package/dist/cli/src/site/server-plugins.d.ts +2 -7
- package/dist/cli/src/site/viewer.js +1 -0
- package/dist/cli/usage.js +1 -1
- package/dist/core/command.js +1 -0
- package/dist/core/init.js +5 -5
- package/dist/core/runtime.js +357 -3207
- package/dist/package/preview.js +1232 -5113
- package/dist/plugins/external.d.ts +29 -3
- package/dist/plugins/external.js +78 -24
- package/dist/site/server-plugins.d.ts +2 -7
- package/dist/site/server-plugins.js +552 -10447
- package/dist/site/viewer.js +1 -0
- package/kernel/apps/web/package.json +1 -5
- package/kernel/apps/web/scripts/dev.mjs +53 -0
- package/kernel/apps/web/src/app.css +0 -3
- package/kernel/apps/web/src/main.tsx +0 -1
- package/kernel/apps/web/src/plugins.ts +0 -30
- package/kernel/apps/web/tsconfig.json +1 -2
- package/kernel/apps/web/vite.config.ts +31 -13
- package/kernel/packages/api/package.json +0 -4
- package/kernel/packages/api/src/server/folder-metadata-plugin.ts +13 -38
- package/kernel/packages/api/src/server/index.ts +0 -1
- package/kernel/packages/api/src/server/plugins.ts +49 -16
- package/kernel/packages/api/test/core.test.ts +13 -25
- package/kernel/packages/markdown/README.md +1 -1
- package/package.json +1 -1
- 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/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/package.json +0 -79
- 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/projects/tsconfig.json +0 -17
- 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/README.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
Publishing, MCP generation, and knowledge-source commands for Kennel workspaces. The compact schema validator has moved to the private [`raggle-ai/kennel-compact`](https://github.com/raggle-ai/kennel-compact) repository.
|
|
4
4
|
|
|
5
|
+
## Local web development
|
|
6
|
+
|
|
7
|
+
Run `bun run web` from the repository root. The dev server uses the plugins
|
|
8
|
+
installed with `kennel plugin add` in your Kennel user configuration. It shares
|
|
9
|
+
the CLI's client registry and server/API bundling; it does not require a local
|
|
10
|
+
`plugins/` directory. Restart the dev server after installing a plugin.
|
|
11
|
+
|
|
5
12
|
## Usage
|
|
6
13
|
|
|
7
14
|
```bash
|
|
@@ -27,6 +34,7 @@ kennel serve /path/to/workspace
|
|
|
27
34
|
kennel dev /path/to/docs-site --config index.json
|
|
28
35
|
kennel init .
|
|
29
36
|
kennel plugin add https://github.com/example/kennel-transcripts-plugin.git#main
|
|
37
|
+
kennel plugin add https://github.com/raggle-ai/kennel-plugins.git --path plugins/calendar
|
|
30
38
|
kennel core-folders .
|
|
31
39
|
kennel mcp generate . --config index.json
|
|
32
40
|
kennel publish init cloudflare .
|
|
@@ -76,13 +84,14 @@ Entity search reads allowed local roots from
|
|
|
76
84
|
```
|
|
77
85
|
|
|
78
86
|
The same user config stores trusted external folder plugins added with
|
|
79
|
-
`kennel plugin add <git-repository-url[#ref]
|
|
80
|
-
ref, or `HEAD` with no fragment, to a full commit,
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
87
|
+
`kennel plugin add <git-repository-url[#ref]> [--path <subdirectory>]`. The
|
|
88
|
+
command pins the requested ref, or `HEAD` with no fragment, to a full commit,
|
|
89
|
+
selects the repository root or the requested subdirectory as the plugin package
|
|
90
|
+
root, validates package metadata and explicit client/server/manifest exports
|
|
91
|
+
plus optional API/CSS exports, builds the composed kernel in the XDG cache, and
|
|
92
|
+
only then atomically updates config. Installed plugin imports are derived from
|
|
93
|
+
package metadata, not from URL text. The transcripts plugin contract is package
|
|
94
|
+
`kennel-transcripts-plugin`, id `memos`, trigger `memos.json`.
|
|
86
95
|
|
|
87
96
|
When this file is absent, entity search allows only the workspace opened by
|
|
88
97
|
`knl`. Invalid config fails closed.
|
|
@@ -92,12 +101,13 @@ Suggested convention for agents: write generated HTML components to
|
|
|
92
101
|
.kennel/preview/<name>.html --watch` (reuses 5180), so preview items share one
|
|
93
102
|
well-known scratch folder across any AI client.
|
|
94
103
|
|
|
95
|
-
`kennel init` scaffolds starter content files for
|
|
96
|
-
the current folder (or the given path)
|
|
97
|
-
`
|
|
98
|
-
|
|
99
|
-
untouched; `--plugin <id>` scaffolds one plugin,
|
|
100
|
-
`--list` prints what would be created without
|
|
104
|
+
`kennel init` scaffolds starter content files for installed folder plugins into
|
|
105
|
+
the current folder (or the given path). The external Tasks and Calendar plugins
|
|
106
|
+
provide `todo.json` and `calendar.json` templates after they are installed from
|
|
107
|
+
`raggle-ai/kennel-plugins` with `kennel plugin add ... --path plugins/<id>`.
|
|
108
|
+
Existing files are left untouched; `--plugin <id>` scaffolds one plugin,
|
|
109
|
+
`--force` overwrites, and `--list` prints what would be created without
|
|
110
|
+
writing.
|
|
101
111
|
|
|
102
112
|
`kennel core-folders` lists schema-declared collections and their records using
|
|
103
113
|
the same metadata index as the UI. Titles, icons, counts, fields and validation
|
package/dist/cli/dispatch.js
CHANGED
|
@@ -13,10 +13,23 @@ export async function dispatch(argv) {
|
|
|
13
13
|
}
|
|
14
14
|
if (command === 'plugin' && args[0] === 'add') {
|
|
15
15
|
const url = args[1];
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
let directory;
|
|
17
|
+
for (let index = 2; index < args.length; index += 1) {
|
|
18
|
+
const arg = args[index];
|
|
19
|
+
if (arg === '--path' || arg === '--directory') {
|
|
20
|
+
directory = args[index + 1];
|
|
21
|
+
if (!directory)
|
|
22
|
+
throw new Error(`${arg} requires a plugin subdirectory`);
|
|
23
|
+
index += 1;
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
throw new Error('Usage: kennel plugin add <git-repository-url> [--path <subdirectory>]');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (!url)
|
|
30
|
+
throw new Error('Usage: kennel plugin add <git-repository-url> [--path <subdirectory>]');
|
|
18
31
|
const { installExternalPlugin } = await import('../plugins/external.js');
|
|
19
|
-
const plugin = await installExternalPlugin(url);
|
|
32
|
+
const plugin = await installExternalPlugin(url, { directory });
|
|
20
33
|
console.log(`Installed plugin ${plugin.id} from ${plugin.packageName} at ${plugin.commit}`);
|
|
21
34
|
return;
|
|
22
35
|
}
|
|
@@ -13,10 +13,23 @@ export async function dispatch(argv) {
|
|
|
13
13
|
}
|
|
14
14
|
if (command === 'plugin' && args[0] === 'add') {
|
|
15
15
|
const url = args[1];
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
let directory;
|
|
17
|
+
for (let index = 2; index < args.length; index += 1) {
|
|
18
|
+
const arg = args[index];
|
|
19
|
+
if (arg === '--path' || arg === '--directory') {
|
|
20
|
+
directory = args[index + 1];
|
|
21
|
+
if (!directory)
|
|
22
|
+
throw new Error(`${arg} requires a plugin subdirectory`);
|
|
23
|
+
index += 1;
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
throw new Error('Usage: kennel plugin add <git-repository-url> [--path <subdirectory>]');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
if (!url)
|
|
30
|
+
throw new Error('Usage: kennel plugin add <git-repository-url> [--path <subdirectory>]');
|
|
18
31
|
const { installExternalPlugin } = await import('../plugins/external.js');
|
|
19
|
-
const plugin = await installExternalPlugin(url);
|
|
32
|
+
const plugin = await installExternalPlugin(url, { directory });
|
|
20
33
|
console.log(`Installed plugin ${plugin.id} from ${plugin.packageName} at ${plugin.commit}`);
|
|
21
34
|
return;
|
|
22
35
|
}
|
|
@@ -2,7 +2,7 @@ export function usage() {
|
|
|
2
2
|
console.log(`Usage:
|
|
3
3
|
knl core [folder] [--host <host>] [--port <port>] [--api-only]
|
|
4
4
|
kennel init [path] [--plugin <id>] [--force] [--list]
|
|
5
|
-
kennel plugin add <git-repository-url>
|
|
5
|
+
kennel plugin add <git-repository-url> [--path <subdirectory>]
|
|
6
6
|
kennel core-folders [path] [--json]
|
|
7
7
|
kennel [folder] [--host <host>] [--port <port>] [--lan|--tailscale]
|
|
8
8
|
kennel pop|p <file|folder> [--open] [--watch] [--host <host>] [--port <port>] [--lan|--tailscale]
|
|
@@ -45,6 +45,7 @@ export async function core(args) {
|
|
|
45
45
|
throw new Error("Web assets missing; build the CLI or use --api-only");
|
|
46
46
|
process.env.KENNEL_KERNEL_KEY = kernel.key;
|
|
47
47
|
process.env.KENNEL_EXTERNAL_SERVER_ENTRIES = JSON.stringify(kernel.serverEntries);
|
|
48
|
+
process.env.KENNEL_EXTERNAL_API_ENTRIES = JSON.stringify(kernel.apiEntries);
|
|
48
49
|
const api = createKennelApi({
|
|
49
50
|
root,
|
|
50
51
|
host,
|
|
@@ -22,7 +22,7 @@ function parseArgs(args) {
|
|
|
22
22
|
else if (arg === '--plugin') {
|
|
23
23
|
const value = args[index + 1];
|
|
24
24
|
if (!value)
|
|
25
|
-
throw new Error('--plugin requires a plugin id
|
|
25
|
+
throw new Error('--plugin requires a plugin id');
|
|
26
26
|
options.plugin = value;
|
|
27
27
|
index += 1;
|
|
28
28
|
}
|
|
@@ -41,11 +41,11 @@ function initUsage() {
|
|
|
41
41
|
return `Usage:
|
|
42
42
|
kennel init [path] [--plugin <id>] [--force] [--list]
|
|
43
43
|
|
|
44
|
-
Scaffold starter content files for folder plugins
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
Scaffold starter content files for installed folder plugins into the given
|
|
45
|
+
folder (default: current directory). Existing files are left untouched unless
|
|
46
|
+
--force is passed.
|
|
47
47
|
|
|
48
|
-
--plugin <id> only scaffold one plugin
|
|
48
|
+
--plugin <id> only scaffold one plugin
|
|
49
49
|
--force overwrite existing starter files
|
|
50
50
|
--list show which files each plugin would create, without writing`;
|
|
51
51
|
}
|
|
@@ -4,7 +4,8 @@ export type ExternalPluginEntry = {
|
|
|
4
4
|
commit: string;
|
|
5
5
|
packageName: string;
|
|
6
6
|
id: string;
|
|
7
|
-
|
|
7
|
+
directory?: string;
|
|
8
|
+
trigger?: string;
|
|
8
9
|
entries: {
|
|
9
10
|
client: string;
|
|
10
11
|
clientSymbol: string;
|
|
@@ -12,13 +13,19 @@ export type ExternalPluginEntry = {
|
|
|
12
13
|
serverSymbol: string;
|
|
13
14
|
manifest: string;
|
|
14
15
|
manifestSymbol: string;
|
|
16
|
+
api?: string;
|
|
17
|
+
apiSymbol?: string;
|
|
15
18
|
css?: string;
|
|
16
19
|
};
|
|
17
20
|
};
|
|
18
21
|
export declare function kennelConfigPath(): string;
|
|
19
|
-
export declare function validateExternalPlugin(inputUrl: string, existing?: ExternalPluginEntry[]
|
|
22
|
+
export declare function validateExternalPlugin(inputUrl: string, existing?: ExternalPluginEntry[], options?: {
|
|
23
|
+
directory?: string;
|
|
24
|
+
}): Promise<ExternalPluginEntry>;
|
|
20
25
|
export declare function readExternalPlugins(): ExternalPluginEntry[];
|
|
21
|
-
export declare function installExternalPlugin(url: string
|
|
26
|
+
export declare function installExternalPlugin(url: string, options?: {
|
|
27
|
+
directory?: string;
|
|
28
|
+
}): Promise<ExternalPluginEntry>;
|
|
22
29
|
export declare function kernelKey(plugins?: ExternalPluginEntry[]): string;
|
|
23
30
|
export type ActiveKernel = {
|
|
24
31
|
buildIdentity: string;
|
|
@@ -32,5 +39,24 @@ export type ActiveKernel = {
|
|
|
32
39
|
symbol: string;
|
|
33
40
|
trigger?: string;
|
|
34
41
|
}>;
|
|
42
|
+
apiEntries: Array<{
|
|
43
|
+
id: string;
|
|
44
|
+
module: string;
|
|
45
|
+
symbol: string;
|
|
46
|
+
}>;
|
|
35
47
|
};
|
|
48
|
+
export declare function prepareExternalPluginModules(temp: string, target?: string, plugins?: ExternalPluginEntry[]): Promise<{
|
|
49
|
+
clientModule: string;
|
|
50
|
+
serverEntries: {
|
|
51
|
+
id: string;
|
|
52
|
+
module: string;
|
|
53
|
+
symbol: string;
|
|
54
|
+
trigger?: string;
|
|
55
|
+
}[];
|
|
56
|
+
apiEntries: {
|
|
57
|
+
id: string;
|
|
58
|
+
module: string;
|
|
59
|
+
symbol: string;
|
|
60
|
+
}[];
|
|
61
|
+
}>;
|
|
36
62
|
export declare function ensureKernel(plugins?: ExternalPluginEntry[]): Promise<ActiveKernel>;
|
|
@@ -15,10 +15,10 @@ import { pathToFileURL, fileURLToPath } from "node:url";
|
|
|
15
15
|
import { spawnSync } from "node:child_process";
|
|
16
16
|
const CONFIG_FILE = join("kennel", "config.json");
|
|
17
17
|
const VALID_ID = /^[a-z][a-z0-9-]*$/u;
|
|
18
|
-
const CORE_IDS = new Set(["agents", "
|
|
18
|
+
const CORE_IDS = new Set(["agents", "notes"]);
|
|
19
19
|
const KENNEL_KERNEL_SCHEMA = 2;
|
|
20
20
|
const BUILD_RUNTIME = `node-${process.versions.node}`;
|
|
21
|
-
const BUILD_IDENTITY = "kennel-external-kernel-
|
|
21
|
+
const BUILD_IDENTITY = "kennel-external-kernel-v3";
|
|
22
22
|
function xdgConfigHome() {
|
|
23
23
|
return process.env.XDG_CONFIG_HOME?.trim() || join(homedir(), ".config");
|
|
24
24
|
}
|
|
@@ -103,6 +103,19 @@ function sourceCheckout(url, commit) {
|
|
|
103
103
|
run("git", ["checkout", "--force", commit], { cwd: dir });
|
|
104
104
|
return realpathSync(dir);
|
|
105
105
|
}
|
|
106
|
+
function pluginRoot(repoRoot, directory) {
|
|
107
|
+
if (!directory)
|
|
108
|
+
return repoRoot;
|
|
109
|
+
if (isAbsolute(directory) || directory.includes("\0"))
|
|
110
|
+
throw new Error(`Unsafe plugin directory: ${directory}`);
|
|
111
|
+
const target = resolve(repoRoot, directory);
|
|
112
|
+
const rel = relative(repoRoot, target);
|
|
113
|
+
if (rel === "" || rel.startsWith("..") || isAbsolute(rel))
|
|
114
|
+
throw new Error(`Unsafe plugin directory: ${directory}`);
|
|
115
|
+
if (!existsSync(target) || !statSync(target).isDirectory())
|
|
116
|
+
throw new Error(`Missing plugin directory: ${directory}`);
|
|
117
|
+
return target;
|
|
118
|
+
}
|
|
106
119
|
function packageExportPath(exportsValue, key) {
|
|
107
120
|
if (!exportsValue || typeof exportsValue !== "object" || Array.isArray(exportsValue))
|
|
108
121
|
return undefined;
|
|
@@ -150,16 +163,12 @@ function internalSourceAliases(root = kernelSourceRoot()) {
|
|
|
150
163
|
const aliases = {};
|
|
151
164
|
for (const [name, path] of Object.entries({
|
|
152
165
|
"@raggle-ai/agents": "packages/agents/src",
|
|
153
|
-
"@raggle-ai/calendar": "plugins/calendar/src",
|
|
154
166
|
"@raggle-ai/folder-plugin": "packages/folder-plugin/src",
|
|
155
167
|
"@raggle-ai/kennel-api": "packages/api/src",
|
|
156
|
-
"@raggle-ai/mail": "plugins/mail/src",
|
|
157
168
|
"@raggle-ai/markdown": "packages/markdown/src",
|
|
158
169
|
"@raggle-ai/notes": "packages/notes/src",
|
|
159
|
-
"@raggle-ai/projects": "plugins/projects/src",
|
|
160
170
|
"@raggle-ai/schemas": "packages/schemas/src",
|
|
161
171
|
"@raggle-ai/session-finding": "packages/session-finding/src",
|
|
162
|
-
"@raggle-ai/tasks": "plugins/tasks/src",
|
|
163
172
|
"@raggle-ai/ui": "packages/ui/src",
|
|
164
173
|
"kennel-client": "packages/api-client/src",
|
|
165
174
|
})) {
|
|
@@ -188,7 +197,7 @@ function resolveAliasPath(target, suffix) {
|
|
|
188
197
|
}
|
|
189
198
|
function esbuildAliasPlugin(root = kernelSourceRoot()) {
|
|
190
199
|
const sourceAliases = internalSourceAliases(root);
|
|
191
|
-
const hostPackages = ["@raggle-ai/barkdown", "@raggle-ai/scout-ui", "@tanstack/react-query", "@tanstack/react-router", "lucide-react", "react", "react-dom", "react/jsx-runtime", "yaml", "lexical"];
|
|
200
|
+
const hostPackages = ["@raggle-ai/barkdown", "@raggle-ai/scout-ui", "@tanstack/react-query", "@tanstack/react-router", "date-fns", "effect", "lucide-react", "react", "react-dom", "react/jsx-runtime", "yaml", "lexical"];
|
|
192
201
|
return {
|
|
193
202
|
name: "kennel-host-resolution",
|
|
194
203
|
setup(build) {
|
|
@@ -241,9 +250,12 @@ async function validateImports(entry) {
|
|
|
241
250
|
const manifestOut = join(dir, "manifest.mjs");
|
|
242
251
|
const serverOut = join(dir, "server.mjs");
|
|
243
252
|
const clientOut = join(dir, "client.mjs");
|
|
253
|
+
const apiOut = join(dir, "api.mjs");
|
|
244
254
|
await bundleForImport(entry.entries.manifest, manifestOut, "browser");
|
|
245
255
|
await bundleForImport(entry.entries.server, serverOut, "node");
|
|
246
256
|
await bundleForImport(entry.entries.client, clientOut, "node");
|
|
257
|
+
if (entry.entries.api)
|
|
258
|
+
await bundleForImport(entry.entries.api, apiOut, "node");
|
|
247
259
|
const manifestModule = await import(__rewriteRelativeImportExtension(pathToFileURL(manifestOut).href));
|
|
248
260
|
const serverModule = await import(__rewriteRelativeImportExtension(pathToFileURL(serverOut).href));
|
|
249
261
|
const clientModule = await import(__rewriteRelativeImportExtension(pathToFileURL(clientOut).href));
|
|
@@ -260,15 +272,22 @@ async function validateImports(entry) {
|
|
|
260
272
|
throw new Error("client id mismatch");
|
|
261
273
|
if (typeof client.component !== "function")
|
|
262
274
|
throw new Error("client export missing component");
|
|
275
|
+
if (entry.entries.api && entry.entries.apiSymbol) {
|
|
276
|
+
const apiModule = await import(__rewriteRelativeImportExtension(pathToFileURL(apiOut).href));
|
|
277
|
+
if (typeof apiModule[entry.entries.apiSymbol] !== "function")
|
|
278
|
+
throw new Error("API export missing handler");
|
|
279
|
+
}
|
|
263
280
|
}
|
|
264
281
|
finally {
|
|
265
282
|
await rm(dir, { force: true, recursive: true });
|
|
266
283
|
}
|
|
267
284
|
}
|
|
268
|
-
export async function validateExternalPlugin(inputUrl, existing = []) {
|
|
285
|
+
export async function validateExternalPlugin(inputUrl, existing = [], options = {}) {
|
|
269
286
|
const { url, requestedRef } = splitRepositoryUrl(inputUrl);
|
|
270
287
|
const commit = resolveCommit(url, requestedRef);
|
|
271
|
-
const
|
|
288
|
+
const checkoutRoot = sourceCheckout(url, commit);
|
|
289
|
+
const directory = options.directory?.trim() || undefined;
|
|
290
|
+
const root = pluginRoot(checkoutRoot, directory);
|
|
272
291
|
const pkgPath = join(root, "package.json");
|
|
273
292
|
if (!existsSync(pkgPath))
|
|
274
293
|
throw new Error("Plugin repository has no package.json at its root");
|
|
@@ -277,8 +296,6 @@ export async function validateExternalPlugin(inputUrl, existing = []) {
|
|
|
277
296
|
const metadata = pkg.kennel?.plugin;
|
|
278
297
|
if (!metadata || typeof metadata !== "object")
|
|
279
298
|
throw new Error("package.json must define kennel.plugin metadata");
|
|
280
|
-
if (!metadata.exports || typeof metadata.exports !== "object")
|
|
281
|
-
throw new Error("kennel.plugin.exports is required");
|
|
282
299
|
const id = stringField(metadata.id, "plugin id");
|
|
283
300
|
if (!VALID_ID.test(id))
|
|
284
301
|
throw new Error(`Invalid plugin id: ${id}`);
|
|
@@ -286,14 +303,23 @@ export async function validateExternalPlugin(inputUrl, existing = []) {
|
|
|
286
303
|
throw new Error(`External plugin id collides with core plugin: ${id}`);
|
|
287
304
|
if (existing.some((plugin) => plugin.id === id))
|
|
288
305
|
throw new Error(`External plugin id is already installed: ${id}`);
|
|
289
|
-
const trigger = stringField(metadata.trigger, "trigger file");
|
|
290
|
-
if (trigger.includes("/") || trigger.includes("\\") || trigger === "." || trigger === "..")
|
|
306
|
+
const trigger = metadata.trigger === undefined ? undefined : stringField(metadata.trigger, "trigger file");
|
|
307
|
+
if (trigger && (trigger.includes("/") || trigger.includes("\\") || trigger === "." || trigger === ".."))
|
|
291
308
|
throw new Error(`Invalid trigger file: ${trigger}`);
|
|
292
309
|
const exportsValue = pkg.exports;
|
|
293
310
|
const client = safeRelativeFile(root, packageExportPath(exportsValue, "./client"), "./client package export");
|
|
294
311
|
const server = safeRelativeFile(root, packageExportPath(exportsValue, "./server"), "./server package export");
|
|
295
312
|
const manifest = safeRelativeFile(root, packageExportPath(exportsValue, "./manifest"), "./manifest package export");
|
|
296
|
-
const
|
|
313
|
+
const apiPath = packageExportPath(exportsValue, "./api");
|
|
314
|
+
const apiExport = apiPath
|
|
315
|
+
? safeRelativeFile(root, apiPath, "./api package export")
|
|
316
|
+
: undefined;
|
|
317
|
+
const apiSymbol = apiExport
|
|
318
|
+
? typeof metadata.exports?.apiSymbol === "string"
|
|
319
|
+
? metadata.exports.apiSymbol
|
|
320
|
+
: "default"
|
|
321
|
+
: undefined;
|
|
322
|
+
const cssValue = metadata.exports?.css;
|
|
297
323
|
const css = cssValue === undefined ? undefined : safeRelativeFile(root, cssValue, "css export path");
|
|
298
324
|
const entry = {
|
|
299
325
|
url,
|
|
@@ -301,14 +327,22 @@ export async function validateExternalPlugin(inputUrl, existing = []) {
|
|
|
301
327
|
commit,
|
|
302
328
|
packageName,
|
|
303
329
|
id,
|
|
304
|
-
|
|
330
|
+
...(directory ? { directory } : {}),
|
|
331
|
+
...(trigger ? { trigger } : {}),
|
|
305
332
|
entries: {
|
|
306
333
|
client,
|
|
307
|
-
clientSymbol:
|
|
334
|
+
clientSymbol: typeof metadata.exports?.clientSymbol === "string"
|
|
335
|
+
? metadata.exports.clientSymbol
|
|
336
|
+
: "default",
|
|
308
337
|
server,
|
|
309
|
-
serverSymbol:
|
|
338
|
+
serverSymbol: typeof metadata.exports?.serverSymbol === "string"
|
|
339
|
+
? metadata.exports.serverSymbol
|
|
340
|
+
: "default",
|
|
310
341
|
manifest,
|
|
311
|
-
manifestSymbol:
|
|
342
|
+
manifestSymbol: typeof metadata.exports?.manifestSymbol === "string"
|
|
343
|
+
? metadata.exports.manifestSymbol
|
|
344
|
+
: "default",
|
|
345
|
+
...(apiExport ? { api: apiExport, apiSymbol } : {}),
|
|
312
346
|
...(css ? { css } : {}),
|
|
313
347
|
},
|
|
314
348
|
};
|
|
@@ -319,13 +353,13 @@ export function readExternalPlugins() {
|
|
|
319
353
|
const config = readJson(kennelConfigPath());
|
|
320
354
|
return Array.isArray(config.externalPlugins) ? config.externalPlugins : [];
|
|
321
355
|
}
|
|
322
|
-
export async function installExternalPlugin(url) {
|
|
356
|
+
export async function installExternalPlugin(url, options = {}) {
|
|
323
357
|
const path = kennelConfigPath();
|
|
324
358
|
const config = readJson(path);
|
|
325
359
|
const externalPlugins = Array.isArray(config.externalPlugins) ? config.externalPlugins : [];
|
|
326
360
|
let entry;
|
|
327
361
|
try {
|
|
328
|
-
entry = await validateExternalPlugin(url, externalPlugins);
|
|
362
|
+
entry = await validateExternalPlugin(url, externalPlugins, options);
|
|
329
363
|
const nextPlugins = [...externalPlugins, entry];
|
|
330
364
|
await ensureKernel(nextPlugins);
|
|
331
365
|
writeJsonAtomic(path, { ...config, externalPlugins: nextPlugins });
|
|
@@ -349,6 +383,7 @@ export function kernelKey(plugins = readExternalPlugins()) {
|
|
|
349
383
|
requestedRef: plugin.requestedRef ?? null,
|
|
350
384
|
packageName: plugin.packageName,
|
|
351
385
|
id: plugin.id,
|
|
386
|
+
directory: plugin.directory ?? null,
|
|
352
387
|
commit: plugin.commit,
|
|
353
388
|
trigger: plugin.trigger,
|
|
354
389
|
entries: plugin.entries,
|
|
@@ -369,7 +404,9 @@ async function readKernelMarker(marker, key) {
|
|
|
369
404
|
kernel.key !== key ||
|
|
370
405
|
!existsSync(resolve(kernel.webRoot, "index.html")) ||
|
|
371
406
|
!Array.isArray(kernel.serverEntries) ||
|
|
372
|
-
kernel.serverEntries.some((entry) => !entry.id || !entry.module || !entry.symbol || !existsSync(entry.module))
|
|
407
|
+
kernel.serverEntries.some((entry) => !entry.id || !entry.module || !entry.symbol || !existsSync(entry.module)) ||
|
|
408
|
+
!Array.isArray(kernel.apiEntries) ||
|
|
409
|
+
kernel.apiEntries.some((entry) => !entry.id || !entry.module || !entry.symbol || !existsSync(entry.module)))
|
|
373
410
|
return undefined;
|
|
374
411
|
return kernel;
|
|
375
412
|
}
|
|
@@ -404,8 +441,7 @@ function moveIncompleteAside(target) {
|
|
|
404
441
|
renameSync(target, broken);
|
|
405
442
|
rmSync(broken, { force: true, recursive: true });
|
|
406
443
|
}
|
|
407
|
-
async function
|
|
408
|
-
const sourceRoot = kernelSourceRoot();
|
|
444
|
+
export async function prepareExternalPluginModules(temp, target = temp, plugins = readExternalPlugins()) {
|
|
409
445
|
const clientModule = join(temp, "external-plugins.tsx");
|
|
410
446
|
const serverDir = join(temp, "server");
|
|
411
447
|
mkdirSync(serverDir, { recursive: true });
|
|
@@ -414,16 +450,29 @@ async function buildKernelTemp(temp, target, key, plugins) {
|
|
|
414
450
|
const clientItems = plugins.map((plugin, index) => ` { ...manifest${index}, component: lazy(async () => ({ default: (await import(${JSON.stringify(plugin.entries.client)}))[${JSON.stringify(plugin.entries.clientSymbol)}].component })) }`).join(",\n");
|
|
415
451
|
await writeFile(clientModule, `import { lazy } from "react";\nimport type { FolderPluginClient } from "@raggle-ai/folder-plugin/client";\n${cssImports}\n${clientImports}\nexport const externalFolderPlugins: FolderPluginClient[] = [\n${clientItems}\n];\n`);
|
|
416
452
|
const serverEntries = [];
|
|
453
|
+
const apiEntries = [];
|
|
417
454
|
for (const plugin of plugins) {
|
|
418
455
|
const outfile = join(serverDir, `${plugin.id}.js`);
|
|
419
456
|
await bundleForImport(plugin.entries.server, outfile, "node");
|
|
420
457
|
serverEntries.push({ id: plugin.id, module: join(target, "server", `${plugin.id}.js`), symbol: plugin.entries.serverSymbol, trigger: plugin.trigger });
|
|
458
|
+
if (plugin.entries.api && plugin.entries.apiSymbol) {
|
|
459
|
+
const apiOutfile = join(serverDir, `${plugin.id}-api.js`);
|
|
460
|
+
await bundleForImport(plugin.entries.api, apiOutfile, "node");
|
|
461
|
+
apiEntries.push({ id: plugin.id, module: join(target, "server", `${plugin.id}-api.js`), symbol: plugin.entries.apiSymbol });
|
|
462
|
+
}
|
|
421
463
|
}
|
|
464
|
+
return { clientModule, serverEntries, apiEntries };
|
|
465
|
+
}
|
|
466
|
+
async function buildKernelTemp(temp, target, key, plugins) {
|
|
467
|
+
const sourceRoot = kernelSourceRoot();
|
|
468
|
+
const { clientModule, serverEntries, apiEntries } = await prepareExternalPluginModules(temp, target, plugins);
|
|
422
469
|
const vite = await import("vite");
|
|
423
470
|
const previousClientModule = process.env.KENNEL_EXTERNAL_CLIENT_MODULE;
|
|
424
471
|
const previousSourceRoot = process.env.KENNEL_KERNEL_SOURCE_ROOT;
|
|
472
|
+
const previousHostNodeModules = process.env.KENNEL_HOST_NODE_MODULES;
|
|
425
473
|
process.env.KENNEL_EXTERNAL_CLIENT_MODULE = clientModule;
|
|
426
474
|
process.env.KENNEL_KERNEL_SOURCE_ROOT = sourceRoot;
|
|
475
|
+
process.env.KENNEL_HOST_NODE_MODULES = resolve(cliRoot(), "node_modules");
|
|
427
476
|
try {
|
|
428
477
|
await vite.build({
|
|
429
478
|
configFile: resolve(sourceRoot, "apps/web/vite.config.ts"),
|
|
@@ -442,6 +491,10 @@ async function buildKernelTemp(temp, target, key, plugins) {
|
|
|
442
491
|
delete process.env.KENNEL_KERNEL_SOURCE_ROOT;
|
|
443
492
|
else
|
|
444
493
|
process.env.KENNEL_KERNEL_SOURCE_ROOT = previousSourceRoot;
|
|
494
|
+
if (previousHostNodeModules === undefined)
|
|
495
|
+
delete process.env.KENNEL_HOST_NODE_MODULES;
|
|
496
|
+
else
|
|
497
|
+
process.env.KENNEL_HOST_NODE_MODULES = previousHostNodeModules;
|
|
445
498
|
}
|
|
446
499
|
const kernel = {
|
|
447
500
|
buildIdentity: BUILD_IDENTITY,
|
|
@@ -450,6 +503,7 @@ async function buildKernelTemp(temp, target, key, plugins) {
|
|
|
450
503
|
key,
|
|
451
504
|
webRoot: join(target, "web"),
|
|
452
505
|
serverEntries,
|
|
506
|
+
apiEntries,
|
|
453
507
|
};
|
|
454
508
|
await writeFile(join(temp, "kernel.json"), JSON.stringify(kernel, null, 2));
|
|
455
509
|
return kernel;
|
|
@@ -457,7 +511,7 @@ async function buildKernelTemp(temp, target, key, plugins) {
|
|
|
457
511
|
export async function ensureKernel(plugins = readExternalPlugins()) {
|
|
458
512
|
if (plugins.length === 0) {
|
|
459
513
|
const webRoot = resolve(dirname(fileURLToPath(import.meta.url)), "../../web");
|
|
460
|
-
return { buildIdentity: BUILD_IDENTITY, schema: KENNEL_KERNEL_SCHEMA, runtime: BUILD_RUNTIME, key: "core", webRoot, serverEntries: [] };
|
|
514
|
+
return { buildIdentity: BUILD_IDENTITY, schema: KENNEL_KERNEL_SCHEMA, runtime: BUILD_RUNTIME, key: "core", webRoot, serverEntries: [], apiEntries: [] };
|
|
461
515
|
}
|
|
462
516
|
const key = kernelKey(plugins);
|
|
463
517
|
const target = kernelRoot(key);
|
|
@@ -18,13 +18,8 @@ export type { FolderPluginContext, FolderPluginData, FolderPluginDetection, Fold
|
|
|
18
18
|
export declare class FolderPluginFailure extends Error {
|
|
19
19
|
constructor(message: string);
|
|
20
20
|
}
|
|
21
|
-
export declare function handleMailApiRoutes(request: import("node:http").IncomingMessage, response: import("node:http").ServerResponse, context: {
|
|
22
|
-
authorizeFolder: (value: string | null) => string;
|
|
23
|
-
mailDir?: string;
|
|
24
|
-
watch: (folder: string) => void;
|
|
25
|
-
}): Promise<boolean>;
|
|
26
21
|
export declare function folderServerRegistry(options?: {
|
|
27
|
-
|
|
22
|
+
agentsHomeDir?: string;
|
|
28
23
|
}): Map<string, FolderPluginServer>;
|
|
29
24
|
export type FolderPluginScaffoldFile = {
|
|
30
25
|
plugin: string;
|
|
@@ -50,5 +45,5 @@ export type FolderPluginScaffoldResult = {
|
|
|
50
45
|
export declare function scaffoldFolderPlugins(folder: string, options?: {
|
|
51
46
|
force?: boolean;
|
|
52
47
|
write?: boolean;
|
|
53
|
-
|
|
48
|
+
agentsHomeDir?: string;
|
|
54
49
|
}): Promise<FolderPluginScaffoldResult>;
|
|
@@ -313,6 +313,7 @@ export async function viewer(input) {
|
|
|
313
313
|
}
|
|
314
314
|
process.env.KENNEL_KERNEL_KEY = kernel.key;
|
|
315
315
|
process.env.KENNEL_EXTERNAL_SERVER_ENTRIES = JSON.stringify(kernel.serverEntries);
|
|
316
|
+
process.env.KENNEL_EXTERNAL_API_ENTRIES = JSON.stringify(kernel.apiEntries);
|
|
316
317
|
const api = createKennelApi({
|
|
317
318
|
root: options.root,
|
|
318
319
|
host: options.host,
|
package/dist/cli/usage.js
CHANGED
|
@@ -2,7 +2,7 @@ export function usage() {
|
|
|
2
2
|
console.log(`Usage:
|
|
3
3
|
knl core [folder] [--host <host>] [--port <port>] [--api-only]
|
|
4
4
|
kennel init [path] [--plugin <id>] [--force] [--list]
|
|
5
|
-
kennel plugin add <git-repository-url>
|
|
5
|
+
kennel plugin add <git-repository-url> [--path <subdirectory>]
|
|
6
6
|
kennel core-folders [path] [--json]
|
|
7
7
|
kennel [folder] [--host <host>] [--port <port>] [--lan|--tailscale]
|
|
8
8
|
kennel pop|p <file|folder> [--open] [--watch] [--host <host>] [--port <port>] [--lan|--tailscale]
|
package/dist/core/command.js
CHANGED
|
@@ -45,6 +45,7 @@ export async function core(args) {
|
|
|
45
45
|
throw new Error("Web assets missing; build the CLI or use --api-only");
|
|
46
46
|
process.env.KENNEL_KERNEL_KEY = kernel.key;
|
|
47
47
|
process.env.KENNEL_EXTERNAL_SERVER_ENTRIES = JSON.stringify(kernel.serverEntries);
|
|
48
|
+
process.env.KENNEL_EXTERNAL_API_ENTRIES = JSON.stringify(kernel.apiEntries);
|
|
48
49
|
const api = createKennelApi({
|
|
49
50
|
root,
|
|
50
51
|
host,
|
package/dist/core/init.js
CHANGED
|
@@ -22,7 +22,7 @@ function parseArgs(args) {
|
|
|
22
22
|
else if (arg === '--plugin') {
|
|
23
23
|
const value = args[index + 1];
|
|
24
24
|
if (!value)
|
|
25
|
-
throw new Error('--plugin requires a plugin id
|
|
25
|
+
throw new Error('--plugin requires a plugin id');
|
|
26
26
|
options.plugin = value;
|
|
27
27
|
index += 1;
|
|
28
28
|
}
|
|
@@ -41,11 +41,11 @@ function initUsage() {
|
|
|
41
41
|
return `Usage:
|
|
42
42
|
kennel init [path] [--plugin <id>] [--force] [--list]
|
|
43
43
|
|
|
44
|
-
Scaffold starter content files for folder plugins
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
Scaffold starter content files for installed folder plugins into the given
|
|
45
|
+
folder (default: current directory). Existing files are left untouched unless
|
|
46
|
+
--force is passed.
|
|
47
47
|
|
|
48
|
-
--plugin <id> only scaffold one plugin
|
|
48
|
+
--plugin <id> only scaffold one plugin
|
|
49
49
|
--force overwrite existing starter files
|
|
50
50
|
--list show which files each plugin would create, without writing`;
|
|
51
51
|
}
|