kennel 0.2.3 → 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 +28 -2
- package/dist/cli/src/plugins/external.js +75 -21
- 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 +28 -2
- package/dist/plugins/external.js +75 -21
- 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/dist/site/viewer.js
CHANGED
|
@@ -313,6 +313,7 @@ export async function viewer(input) {
|
|
|
313
313
|
}
|
|
314
314
|
process.env.KENNEL_KERNEL_KEY = kernel.key;
|
|
315
315
|
process.env.KENNEL_EXTERNAL_SERVER_ENTRIES = JSON.stringify(kernel.serverEntries);
|
|
316
|
+
process.env.KENNEL_EXTERNAL_API_ENTRIES = JSON.stringify(kernel.apiEntries);
|
|
316
317
|
const api = createKennelApi({
|
|
317
318
|
root: options.root,
|
|
318
319
|
host: options.host,
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"prettier": "@raggle-ai/prettier-config",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"build": "node scripts/build.mjs",
|
|
9
|
-
"dev": "
|
|
9
|
+
"dev": "node scripts/dev.mjs",
|
|
10
10
|
"typecheck": "tsc --noEmit",
|
|
11
11
|
"format": "prettier . --check --cache --cache-location .cache/.prettiercache --ignore-path ../../.prettierignore",
|
|
12
12
|
"format:fix": "prettier . --write --cache --cache-location .cache/.prettiercache --ignore-path ../../.prettierignore",
|
|
@@ -23,19 +23,15 @@
|
|
|
23
23
|
"@lexical/react": "0.49.0",
|
|
24
24
|
"@lexical/rich-text": "0.49.0",
|
|
25
25
|
"@raggle-ai/agents": "workspace:*",
|
|
26
|
-
"@raggle-ai/calendar": "workspace:*",
|
|
27
26
|
"@raggle-ai/folder-plugin": "workspace:*",
|
|
28
27
|
"@raggle-ai/kennel-api": "workspace:*",
|
|
29
28
|
"@raggle-ai/kennel-preview": "workspace:*",
|
|
30
29
|
"@raggle-ai/local": "0.14.0",
|
|
31
|
-
"@raggle-ai/mail": "workspace:*",
|
|
32
30
|
"@raggle-ai/markdown": "workspace:*",
|
|
33
31
|
"@raggle-ai/notes": "workspace:*",
|
|
34
|
-
"@raggle-ai/projects": "workspace:*",
|
|
35
32
|
"@raggle-ai/schemas": "workspace:*",
|
|
36
33
|
"@raggle-ai/scout-ui": "0.1.3",
|
|
37
34
|
"@raggle-ai/session-finding": "workspace:*",
|
|
38
|
-
"@raggle-ai/tasks": "workspace:*",
|
|
39
35
|
"@raggle-ai/ui": "workspace:*",
|
|
40
36
|
"@tanstack/react-query": "catalog:tanstack",
|
|
41
37
|
"@tanstack/react-router": "catalog:tanstack",
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { spawn } from "node:child_process"
|
|
2
|
+
import { mkdtemp, rm } from "node:fs/promises"
|
|
3
|
+
import { tmpdir } from "node:os"
|
|
4
|
+
import { dirname, join, resolve } from "node:path"
|
|
5
|
+
import { fileURLToPath } from "node:url"
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
prepareExternalPluginModules,
|
|
9
|
+
readExternalPlugins,
|
|
10
|
+
} from "../../../cli/src/plugins/external.ts"
|
|
11
|
+
|
|
12
|
+
const workspace = resolve(import.meta.dirname, "../../..")
|
|
13
|
+
const temp = await mkdtemp(join(tmpdir(), "kennel-web-dev-"))
|
|
14
|
+
try {
|
|
15
|
+
const plugins = readExternalPlugins()
|
|
16
|
+
const modules = await prepareExternalPluginModules(temp, temp, plugins)
|
|
17
|
+
const args = process.argv.slice(2).filter((arg) => arg !== "--")
|
|
18
|
+
const child = spawn(
|
|
19
|
+
process.execPath,
|
|
20
|
+
[
|
|
21
|
+
resolve(
|
|
22
|
+
dirname(fileURLToPath(import.meta.resolve("vite/package.json"))),
|
|
23
|
+
"bin/vite.js",
|
|
24
|
+
),
|
|
25
|
+
"dev",
|
|
26
|
+
...args,
|
|
27
|
+
],
|
|
28
|
+
{
|
|
29
|
+
cwd: resolve(workspace, "apps/web"),
|
|
30
|
+
stdio: "inherit",
|
|
31
|
+
env: {
|
|
32
|
+
...process.env,
|
|
33
|
+
KENNEL_KERNEL_SOURCE_ROOT: workspace,
|
|
34
|
+
KENNEL_HOST_NODE_MODULES: resolve(workspace, "cli/node_modules"),
|
|
35
|
+
KENNEL_EXTERNAL_CLIENT_MODULE: modules.clientModule,
|
|
36
|
+
KENNEL_EXTERNAL_SERVER_ENTRIES: JSON.stringify(modules.serverEntries),
|
|
37
|
+
KENNEL_EXTERNAL_API_ENTRIES: JSON.stringify(modules.apiEntries),
|
|
38
|
+
KENNEL_EXTERNAL_SOURCE_ROOTS: JSON.stringify(
|
|
39
|
+
plugins.map((plugin) => dirname(plugin.entries.client)),
|
|
40
|
+
),
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
)
|
|
44
|
+
for (const signal of ["SIGINT", "SIGTERM"]) {
|
|
45
|
+
process.on(signal, () => child.kill(signal))
|
|
46
|
+
}
|
|
47
|
+
process.exitCode = await new Promise((resolve, reject) => {
|
|
48
|
+
child.once("error", reject)
|
|
49
|
+
child.once("exit", (code) => resolve(code ?? 1))
|
|
50
|
+
})
|
|
51
|
+
} finally {
|
|
52
|
+
await rm(temp, { recursive: true, force: true })
|
|
53
|
+
}
|
|
@@ -3,27 +3,10 @@ import { externalFolderPlugins } from "@/external-plugins"
|
|
|
3
3
|
|
|
4
4
|
import type { FolderPluginClient } from "@raggle-ai/folder-plugin/client"
|
|
5
5
|
import { agentsManifest } from "@raggle-ai/agents/manifest"
|
|
6
|
-
import { calendarManifest } from "@raggle-ai/calendar/manifest"
|
|
7
|
-
import { mailManifest } from "@raggle-ai/mail/manifest"
|
|
8
|
-
import { projectsManifest } from "@raggle-ai/projects/manifest"
|
|
9
|
-
import { tasksManifest } from "@raggle-ai/tasks/manifest"
|
|
10
6
|
|
|
11
7
|
// Keep navigation metadata cheap. Import only the selected plugin's UI;
|
|
12
8
|
// never construct an import path from an untrusted URL segment.
|
|
13
9
|
export const folderPlugins: FolderPluginClient[] = [
|
|
14
|
-
{
|
|
15
|
-
...calendarManifest,
|
|
16
|
-
component: lazy(async () => ({
|
|
17
|
-
default: (await import("@raggle-ai/calendar/client")).calendarClient
|
|
18
|
-
.component,
|
|
19
|
-
})),
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
...mailManifest,
|
|
23
|
-
component: lazy(async () => ({
|
|
24
|
-
default: (await import("@raggle-ai/mail/client")).mailClient.component,
|
|
25
|
-
})),
|
|
26
|
-
},
|
|
27
10
|
{
|
|
28
11
|
...agentsManifest,
|
|
29
12
|
component: lazy(async () => ({
|
|
@@ -31,19 +14,6 @@ export const folderPlugins: FolderPluginClient[] = [
|
|
|
31
14
|
.component,
|
|
32
15
|
})),
|
|
33
16
|
},
|
|
34
|
-
{
|
|
35
|
-
...tasksManifest,
|
|
36
|
-
component: lazy(async () => ({
|
|
37
|
-
default: (await import("@raggle-ai/tasks/client")).tasksClient.component,
|
|
38
|
-
})),
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
...projectsManifest,
|
|
42
|
-
component: lazy(async () => ({
|
|
43
|
-
default: (await import("@raggle-ai/projects/client")).projectsClient
|
|
44
|
-
.component,
|
|
45
|
-
})),
|
|
46
|
-
},
|
|
47
17
|
...externalFolderPlugins,
|
|
48
18
|
]
|
|
49
19
|
|
|
@@ -15,17 +15,32 @@ const workspace = resolve(
|
|
|
15
15
|
process.env.KENNEL_KERNEL_SOURCE_ROOT || resolve(root, "../.."),
|
|
16
16
|
)
|
|
17
17
|
const require = createRequire(import.meta.url)
|
|
18
|
+
const hostNodeModules = process.env.KENNEL_HOST_NODE_MODULES
|
|
19
|
+
const packageNameOf = (name: string) => {
|
|
20
|
+
const [scopeOrName, packageName] = name.split("/")
|
|
21
|
+
return name.startsWith("@") && packageName
|
|
22
|
+
? `${scopeOrName}/${packageName}`
|
|
23
|
+
: (scopeOrName ?? name)
|
|
24
|
+
}
|
|
25
|
+
const hostPackagePath = (name: string, entry = "package.json") =>
|
|
26
|
+
hostNodeModules
|
|
27
|
+
? resolve(hostNodeModules, packageNameOf(name), entry)
|
|
28
|
+
: undefined
|
|
18
29
|
const packageDir = (name: string): string | undefined => {
|
|
30
|
+
const hostPath = hostPackagePath(name)
|
|
31
|
+
if (hostPath && existsSync(hostPath)) return dirname(hostPath)
|
|
19
32
|
try {
|
|
20
|
-
const packageName = name
|
|
21
|
-
? name.split("/").slice(0, 2).join("/")
|
|
22
|
-
: name.split("/")[0]
|
|
33
|
+
const packageName = packageNameOf(name)
|
|
23
34
|
return dirname(require.resolve(`${packageName}/package.json`))
|
|
24
35
|
} catch {
|
|
25
36
|
return undefined
|
|
26
37
|
}
|
|
27
38
|
}
|
|
28
39
|
const packageEntry = (name: string): string | undefined => {
|
|
40
|
+
const packageName = packageNameOf(name)
|
|
41
|
+
const entry = name.slice(packageName.length).replace(/^\//, "")
|
|
42
|
+
const hostPath = hostPackagePath(name, entry)
|
|
43
|
+
if (hostPath && existsSync(hostPath)) return hostPath
|
|
29
44
|
try {
|
|
30
45
|
return require.resolve(name)
|
|
31
46
|
} catch {
|
|
@@ -59,22 +74,21 @@ const resolveBarkdown = (): string | undefined => {
|
|
|
59
74
|
const barkdown = resolveBarkdown()
|
|
60
75
|
const internalPackages: Array<[RegExp, string]> = [
|
|
61
76
|
[/^@raggle-ai\/agents(\/.*)?$/, "packages/agents/src"],
|
|
62
|
-
[/^@raggle-ai\/calendar(\/.*)?$/, "plugins/calendar/src"],
|
|
63
77
|
[/^@raggle-ai\/folder-plugin(\/.*)?$/, "packages/folder-plugin/src"],
|
|
64
78
|
[/^@raggle-ai\/kennel-api(\/.*)?$/, "packages/api/src"],
|
|
65
|
-
[/^@raggle-ai\/mail(\/.*)?$/, "plugins/mail/src"],
|
|
66
79
|
[/^@raggle-ai\/markdown(\/.*)?$/, "packages/markdown/src"],
|
|
67
80
|
[/^@raggle-ai\/notes(\/.*)?$/, "packages/notes/src"],
|
|
68
|
-
[/^@raggle-ai\/projects(\/.*)?$/, "plugins/projects/src"],
|
|
69
81
|
[/^@raggle-ai\/schemas(\/.*)?$/, "packages/schemas/src"],
|
|
70
82
|
[/^@raggle-ai\/session-finding(\/.*)?$/, "packages/session-finding/src"],
|
|
71
|
-
[/^@raggle-ai\/tasks(\/.*)?$/, "plugins/tasks/src"],
|
|
72
83
|
[/^@raggle-ai\/ui(\/.*)?$/, "packages/ui/src"],
|
|
73
84
|
[/^kennel-client(\/.*)?$/, "packages/api-client/src"],
|
|
74
85
|
]
|
|
75
86
|
const hostPackageNames = [
|
|
87
|
+
"@raggle-ai/barkdown",
|
|
76
88
|
"@tanstack/react-query",
|
|
77
89
|
"@tanstack/react-router",
|
|
90
|
+
"date-fns",
|
|
91
|
+
"effect",
|
|
78
92
|
"lucide-react",
|
|
79
93
|
"react",
|
|
80
94
|
"react-dom",
|
|
@@ -95,6 +109,14 @@ const hostPackageAliases = hostPackageNames.flatMap((name) => {
|
|
|
95
109
|
const hostPackageRoots = hostPackageNames
|
|
96
110
|
.map(packageDir)
|
|
97
111
|
.filter((path): path is string => Boolean(path))
|
|
112
|
+
const externalSourceRoots: string[] = JSON.parse(
|
|
113
|
+
process.env.KENNEL_EXTERNAL_SOURCE_ROOTS || "[]",
|
|
114
|
+
)
|
|
115
|
+
const externalClientModule = process.env.KENNEL_EXTERNAL_CLIENT_MODULE
|
|
116
|
+
const externalRoots = [
|
|
117
|
+
...externalSourceRoots,
|
|
118
|
+
...(externalClientModule ? [dirname(externalClientModule)] : []),
|
|
119
|
+
]
|
|
98
120
|
const aliases: AliasOptions = [
|
|
99
121
|
...(process.env.KENNEL_EXTERNAL_CLIENT_MODULE
|
|
100
122
|
? [
|
|
@@ -114,10 +136,6 @@ const aliases: AliasOptions = [
|
|
|
114
136
|
find: /^@raggle-ai\/markdown\/explorer\.css$/,
|
|
115
137
|
replacement: resolve(workspace, "packages/markdown/explorer.css"),
|
|
116
138
|
},
|
|
117
|
-
{
|
|
118
|
-
find: /^@raggle-ai\/tasks\/todo-model\/styles\.css$/,
|
|
119
|
-
replacement: resolve(workspace, "plugins/tasks/src/styles.css"),
|
|
120
|
-
},
|
|
121
139
|
{
|
|
122
140
|
find: /^@raggle-ai\/ui\/folder-activity\.css$/,
|
|
123
141
|
replacement: resolve(
|
|
@@ -230,8 +248,8 @@ export default defineConfig({
|
|
|
230
248
|
],
|
|
231
249
|
fs: {
|
|
232
250
|
allow: barkdown
|
|
233
|
-
? [workspace, barkdown, ...hostPackageRoots]
|
|
234
|
-
: [workspace, ...hostPackageRoots],
|
|
251
|
+
? [workspace, barkdown, ...hostPackageRoots, ...externalRoots]
|
|
252
|
+
: [workspace, ...hostPackageRoots, ...externalRoots],
|
|
235
253
|
},
|
|
236
254
|
// Warm the biggest cold-transform graphs (measured ~1–5 s each on first
|
|
237
255
|
// request, stacking into the long first load / first HMR after a server
|
|
@@ -19,17 +19,13 @@
|
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"@agentclientprotocol/sdk": "^1.3.0",
|
|
21
21
|
"@raggle-ai/agents": "workspace:*",
|
|
22
|
-
"@raggle-ai/calendar": "workspace:*",
|
|
23
22
|
"@raggle-ai/folder-plugin": "workspace:*",
|
|
24
23
|
"@raggle-ai/kennel-kinds": "workspace:*",
|
|
25
24
|
"@raggle-ai/local": "0.14.0",
|
|
26
|
-
"@raggle-ai/mail": "workspace:*",
|
|
27
25
|
"@raggle-ai/markdown": "workspace:*",
|
|
28
26
|
"@raggle-ai/notes": "workspace:*",
|
|
29
|
-
"@raggle-ai/projects": "workspace:*",
|
|
30
27
|
"@raggle-ai/schemas": "workspace:*",
|
|
31
28
|
"@raggle-ai/session-finding": "workspace:*",
|
|
32
|
-
"@raggle-ai/tasks": "workspace:*",
|
|
33
29
|
"@raggle-ai/ui": "workspace:*",
|
|
34
30
|
"yaml": "^2.9.0",
|
|
35
31
|
"zod": "catalog:"
|
|
@@ -22,15 +22,12 @@ import { parse as parseYaml } from "yaml";
|
|
|
22
22
|
|
|
23
23
|
import type { FolderPluginServer } from "@raggle-ai/folder-plugin/server";
|
|
24
24
|
import type { LocalMarkdownFileSummary, LocalProject } from "@raggle-ai/local";
|
|
25
|
-
import type { MailApiContext, MailPreviewer } from "@raggle-ai/mail/api";
|
|
26
25
|
import type { FolderSkill } from "@raggle-ai/ui/lib/folder-activity";
|
|
27
26
|
import { runApiRoute } from "@raggle-ai/folder-plugin/endpoint";
|
|
28
27
|
import { FolderPluginFailure } from "@raggle-ai/folder-plugin/server";
|
|
29
28
|
import { folderWorkspace } from "@raggle-ai/schemas/workspace";
|
|
30
29
|
import { createSchemaCollectionServer } from "@raggle-ai/schemas/server";
|
|
31
30
|
import local from "@raggle-ai/local";
|
|
32
|
-
import { handleMailApiRoutes } from "@raggle-ai/mail/api";
|
|
33
|
-
import { handleTasksApiRoutes } from "@raggle-ai/tasks/api";
|
|
34
31
|
import {
|
|
35
32
|
listFolderSessions,
|
|
36
33
|
readSessionTranscript,
|
|
@@ -45,6 +42,7 @@ import { folderIcon, workspaceBreadcrumbIcons } from "./folder-icons.js";
|
|
|
45
42
|
import { faviconService } from "@raggle-ai/schemas/favicon";
|
|
46
43
|
import {
|
|
47
44
|
configuredFolderServerRegistry,
|
|
45
|
+
externalApiHandlers,
|
|
48
46
|
folderServerRegistryAsync,
|
|
49
47
|
type FolderPluginRegistryConfig,
|
|
50
48
|
} from "./plugins.js";
|
|
@@ -137,17 +135,6 @@ export type FolderMetadataPluginOptions = {
|
|
|
137
135
|
restrictToRoot?: boolean;
|
|
138
136
|
root: string;
|
|
139
137
|
sessionFinding?: SessionFinding;
|
|
140
|
-
mailPreviewer?: MailPreviewer;
|
|
141
|
-
/**
|
|
142
|
-
* Inject a MailOS service (tests only). Defaults to a real subprocess
|
|
143
|
-
* service resolved from PATH.
|
|
144
|
-
*/
|
|
145
|
-
mailos?: MailApiContext["mailos"];
|
|
146
|
-
/**
|
|
147
|
-
* Override MailOS mail directory. Intended for tests.
|
|
148
|
-
* Defaults to ~/.email/drafts.
|
|
149
|
-
*/
|
|
150
|
-
mailDir?: string;
|
|
151
138
|
/** Override the home directory used for Agent global files. Intended for tests. */
|
|
152
139
|
agentsHomeDir?: string;
|
|
153
140
|
/** Override isolated linked-project discovery, for tests. */
|
|
@@ -774,7 +761,7 @@ function pluginConfigWarnings(
|
|
|
774
761
|
const ids = unique([...config.plugins.disable, ...config.plugins.order]);
|
|
775
762
|
return ids
|
|
776
763
|
.filter((id) => !registry.has(id))
|
|
777
|
-
.map((id) => `unknown plugin id "${id}" — not
|
|
764
|
+
.map((id) => `unknown plugin id "${id}" — not installed in this build`);
|
|
778
765
|
}
|
|
779
766
|
|
|
780
767
|
async function pluginAvailability(
|
|
@@ -824,9 +811,6 @@ export function createFolderApi({
|
|
|
824
811
|
restrictToRoot = false,
|
|
825
812
|
root,
|
|
826
813
|
sessionFinding,
|
|
827
|
-
mailPreviewer,
|
|
828
|
-
mailDir,
|
|
829
|
-
mailos,
|
|
830
814
|
agentsHomeDir,
|
|
831
815
|
linkedFolderLoader,
|
|
832
816
|
remoteAccess = false,
|
|
@@ -839,10 +823,9 @@ export function createFolderApi({
|
|
|
839
823
|
readSessionTranscript,
|
|
840
824
|
};
|
|
841
825
|
const basePlugins = folderServerRegistryAsync({
|
|
842
|
-
mailDir,
|
|
843
|
-
previewer: mailPreviewer,
|
|
844
826
|
agentsHomeDir,
|
|
845
827
|
});
|
|
828
|
+
const baseExternalApiHandlers = externalApiHandlers();
|
|
846
829
|
const assetFiles = new Map<
|
|
847
830
|
string,
|
|
848
831
|
{ mediaType: IconAsset["mediaType"]; path: string }
|
|
@@ -1447,24 +1430,16 @@ export function createFolderApi({
|
|
|
1447
1430
|
}
|
|
1448
1431
|
return;
|
|
1449
1432
|
}
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
if (
|
|
1461
|
-
await handleTasksApiRoutes(request, response, {
|
|
1462
|
-
authorizeFolder: (value) => folderPath(value, root, lockedRoot),
|
|
1463
|
-
readOnly: remote,
|
|
1464
|
-
watch,
|
|
1465
|
-
})
|
|
1466
|
-
)
|
|
1467
|
-
return;
|
|
1433
|
+
for (const handler of await baseExternalApiHandlers) {
|
|
1434
|
+
if (
|
|
1435
|
+
await handler(request, response, {
|
|
1436
|
+
authorizeFolder: (value) => folderPath(value, root, lockedRoot),
|
|
1437
|
+
readOnly: remote,
|
|
1438
|
+
watch,
|
|
1439
|
+
})
|
|
1440
|
+
)
|
|
1441
|
+
return;
|
|
1442
|
+
}
|
|
1468
1443
|
if (url.pathname === "/api/create-agent-file") {
|
|
1469
1444
|
if (remote) {
|
|
1470
1445
|
response.writeHead(403, {
|
|
@@ -1,22 +1,16 @@
|
|
|
1
1
|
import type { FolderPluginContext } from "@raggle-ai/folder-plugin/server";
|
|
2
2
|
import type { FolderPluginServer } from "@raggle-ai/folder-plugin/server";
|
|
3
|
-
import type { MailCreatePluginOptions } from "@raggle-ai/mail/server";
|
|
4
3
|
import { pathToFileURL } from "node:url";
|
|
5
4
|
import { existsSync } from "node:fs";
|
|
6
5
|
import { mkdir, stat, writeFile } from "node:fs/promises";
|
|
7
6
|
import { dirname, relative, resolve, sep } from "node:path";
|
|
8
7
|
import { createAgentsPlugin } from "@raggle-ai/agents/server";
|
|
9
|
-
import { createCalendarPlugin } from "@raggle-ai/calendar/server";
|
|
10
8
|
import { FolderPluginFailure } from "@raggle-ai/folder-plugin/server";
|
|
11
|
-
import { createMailPlugin } from "@raggle-ai/mail/server";
|
|
12
9
|
import { createNotesPlugin } from "@raggle-ai/notes/server";
|
|
13
|
-
import { createProjectsPlugin } from "@raggle-ai/projects/server";
|
|
14
|
-
import { createTasksPlugin } from "@raggle-ai/tasks/server";
|
|
15
10
|
|
|
16
11
|
export { FolderPluginFailure };
|
|
17
|
-
export { handleMailApiRoutes } from "@raggle-ai/mail/api";
|
|
18
12
|
|
|
19
|
-
export type FolderServerRegistryOptions =
|
|
13
|
+
export type FolderServerRegistryOptions = {
|
|
20
14
|
/** Override the home directory used for Agent global files. Intended for tests. */
|
|
21
15
|
agentsHomeDir?: string;
|
|
22
16
|
};
|
|
@@ -49,23 +43,15 @@ export function configuredFolderServerRegistry(
|
|
|
49
43
|
return new Map(ids.map((id) => [id, registry.get(id)!]));
|
|
50
44
|
}
|
|
51
45
|
|
|
52
|
-
/**
|
|
53
|
-
* Explicit server-only plugin registry. Mail preview execution and the mail
|
|
54
|
-
* directory are injected here so the host and tests can keep their existing
|
|
55
|
-
* seams while the plugin owns its folder authorization.
|
|
56
|
-
*/
|
|
46
|
+
/** Core server plugins. Installed plugins are loaded separately. */
|
|
57
47
|
export function createFolderServerPlugins(
|
|
58
48
|
options: FolderServerRegistryOptions = {},
|
|
59
49
|
): FolderPluginServer[] {
|
|
60
50
|
return [
|
|
61
|
-
createCalendarPlugin(),
|
|
62
|
-
createMailPlugin(options),
|
|
63
51
|
createAgentsPlugin({
|
|
64
52
|
homeDir: options.agentsHomeDir,
|
|
65
53
|
}),
|
|
66
54
|
createNotesPlugin(),
|
|
67
|
-
createTasksPlugin(),
|
|
68
|
-
createProjectsPlugin(),
|
|
69
55
|
];
|
|
70
56
|
}
|
|
71
57
|
|
|
@@ -84,6 +70,22 @@ type ExternalServerEntry = {
|
|
|
84
70
|
trigger?: string;
|
|
85
71
|
};
|
|
86
72
|
|
|
73
|
+
export type ExternalApiHandler = (
|
|
74
|
+
request: import("node:http").IncomingMessage,
|
|
75
|
+
response: import("node:http").ServerResponse,
|
|
76
|
+
context: {
|
|
77
|
+
authorizeFolder: (value: string | null) => string;
|
|
78
|
+
readOnly: boolean;
|
|
79
|
+
watch: (folder: string) => void;
|
|
80
|
+
},
|
|
81
|
+
) => Promise<boolean>;
|
|
82
|
+
|
|
83
|
+
export type ExternalApiEntry = {
|
|
84
|
+
id: string;
|
|
85
|
+
module: string;
|
|
86
|
+
symbol: string;
|
|
87
|
+
};
|
|
88
|
+
|
|
87
89
|
function externalServerEntries(): ExternalServerEntry[] {
|
|
88
90
|
const source = process.env.KENNEL_EXTERNAL_SERVER_ENTRIES;
|
|
89
91
|
if (!source) return [];
|
|
@@ -143,6 +145,37 @@ export async function folderServerRegistryAsync(
|
|
|
143
145
|
return registry;
|
|
144
146
|
}
|
|
145
147
|
|
|
148
|
+
function externalApiEntries(): ExternalApiEntry[] {
|
|
149
|
+
const source = process.env.KENNEL_EXTERNAL_API_ENTRIES;
|
|
150
|
+
if (!source) return [];
|
|
151
|
+
const value = JSON.parse(source) as unknown;
|
|
152
|
+
if (!Array.isArray(value)) throw new Error("Invalid external plugin API config");
|
|
153
|
+
return value.map((entry) => {
|
|
154
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry))
|
|
155
|
+
throw new Error("Invalid external plugin API config");
|
|
156
|
+
const item = entry as Partial<ExternalApiEntry>;
|
|
157
|
+
if (
|
|
158
|
+
typeof item.id !== "string" ||
|
|
159
|
+
typeof item.module !== "string" ||
|
|
160
|
+
typeof item.symbol !== "string"
|
|
161
|
+
)
|
|
162
|
+
throw new Error("Invalid external plugin API config");
|
|
163
|
+
return { id: item.id, module: item.module, symbol: item.symbol };
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
export async function externalApiHandlers(): Promise<ExternalApiHandler[]> {
|
|
168
|
+
const handlers: ExternalApiHandler[] = [];
|
|
169
|
+
for (const entry of externalApiEntries()) {
|
|
170
|
+
const imported = await import(pathToFileURL(entry.module).href);
|
|
171
|
+
const handler = imported[entry.symbol];
|
|
172
|
+
if (typeof handler !== "function")
|
|
173
|
+
throw new Error(`External plugin ${entry.id} did not export API handler ${entry.symbol}`);
|
|
174
|
+
handlers.push(handler as ExternalApiHandler);
|
|
175
|
+
}
|
|
176
|
+
return handlers;
|
|
177
|
+
}
|
|
178
|
+
|
|
146
179
|
export type FolderPluginScaffoldFile = {
|
|
147
180
|
plugin: string;
|
|
148
181
|
path: string;
|
|
@@ -187,7 +187,7 @@ function plugin(id: string): FolderPluginServer {
|
|
|
187
187
|
};
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
-
test("plugin registry config disables and orders only
|
|
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
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kennel",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.5",
|
|
4
4
|
"description": "Open-source pop-up previews for AI output: markdown, HTML artifacts, email, images, code, tables, notes, and calendars, from the terminal or your agent session.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{g as p,r as u,d as a}from"./chunk-MOJQB5TN-
|
|
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};
|