kennel 0.2.12 → 0.2.13
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/dist/cli/src/plugins/external.js +19 -7
- package/dist/cli/src/site/server-plugins.d.ts +1 -4
- package/dist/core/api-client.js +3 -11
- package/dist/core/runtime.js +84 -695
- package/dist/package/preview.js +99 -729
- package/dist/plugins/external.js +19 -7
- package/dist/site/server-plugins.d.ts +1 -4
- package/dist/site/server-plugins.js +28 -537
- package/kernel/apps/web/package.json +0 -1
- package/kernel/apps/web/src/app.css +0 -1
- package/kernel/apps/web/src/app.tsx +7 -24
- package/kernel/apps/web/src/folder-plugin-view.tsx +6 -3
- package/kernel/apps/web/src/plugins.ts +2 -14
- package/kernel/apps/web/vite.config.ts +16 -3
- package/kernel/packages/api/openapi.json +85 -224
- package/kernel/packages/api/package.json +0 -1
- package/kernel/packages/api/src/contracts/schemas.ts +1 -9
- package/kernel/packages/api/src/server/folder-metadata-plugin.ts +9 -151
- package/kernel/packages/api/src/server/plugins.ts +11 -26
- package/kernel/packages/api/src/shared/viewer-route.ts +3 -5
- package/kernel/packages/api-client/src/generated.d.ts +16 -53
- package/kernel/packages/markdown/README.md +2 -2
- package/kernel/packages/notes/package.json +1 -0
- package/kernel/packages/notes/src/client.tsx +0 -1
- package/kernel/packages/notes/src/manifest.ts +7 -0
- package/kernel/packages/notes/src/pages/notes-page.tsx +1 -1
- package/kernel/packages/notes/src/ui/folder-notes-list.tsx +52 -7
- package/kernel/packages/plugins/SKILL.md +3 -2
- package/kernel/packages/plugins/package.json +5 -1
- package/kernel/packages/plugins/src/hooks.ts +24 -0
- package/kernel/packages/plugins/src/index.ts +1 -7
- package/kernel/packages/plugins/src/page.ts +0 -7
- package/kernel/packages/plugins/src/types.ts +8 -0
- package/kernel/packages/plugins/tsconfig.json +1 -1
- package/kernel/packages/plugins/tsup.config.ts +1 -0
- package/kernel/packages/ui/src/components/folder-activity.tsx +16 -98
- package/kernel/packages/ui/src/components/folder-landing.tsx +4 -0
- package/kernel/packages/ui/src/components/pagination.tsx +88 -2
- package/kernel/packages/ui/src/components/plugin-icon.tsx +19 -0
- package/kernel/packages/ui/src/lib/folder-activity.ts +4 -17
- package/kernel/packages/ui/src/styles/folder-activity.css +1 -31
- package/package.json +2 -2
- package/web/assets/{abnfDiagram-VRR7QNED-Brm1vcGG.js → abnfDiagram-VRR7QNED-Dt7QEF5H.js} +1 -1
- package/web/assets/app-C1j063QX.js +2 -0
- package/web/assets/app-options-98-a6ivv.js +25 -0
- package/web/assets/{app-view-header-BSOI-wB6.js → app-view-header-BJ9CWTE1.js} +1 -1
- package/web/assets/{arc-zngHsMKV.js → arc-PFB0H7oD.js} +1 -1
- package/web/assets/{architectureDiagram-ZJ3FMSHR-BLklLqRP.js → architectureDiagram-ZJ3FMSHR-BHLqEXlZ.js} +1 -1
- package/web/assets/{ask-tray-B4SPj-fH.js → ask-tray-C3gBesHJ.js} +1 -1
- package/web/assets/{blockDiagram-677ZJIJ3-yhC2fEtu.js → blockDiagram-677ZJIJ3-UbnYoYDg.js} +1 -1
- package/web/assets/{c4Diagram-LMCZKHZV-DMcweQme.js → c4Diagram-LMCZKHZV-4OSx1V4W.js} +1 -1
- package/web/assets/channel-BuvY5cQN.js +1 -0
- package/web/assets/{chunk-2Q5K7J3B-DD-S6n8h.js → chunk-2Q5K7J3B-CgxJ1aJb.js} +1 -1
- package/web/assets/{chunk-32BRIVSS-DFIAKRv_.js → chunk-32BRIVSS-Bfwxg2LM.js} +1 -1
- package/web/assets/{chunk-5VM5RSS4-B23APb3c.js → chunk-5VM5RSS4-BZN9a2hI.js} +1 -1
- package/web/assets/{chunk-EX3LRPZG-BSVEB7db.js → chunk-EX3LRPZG-CrH6hhqq.js} +1 -1
- package/web/assets/{chunk-JWPE2WC7-B6qGd0ng.js → chunk-JWPE2WC7-Ddn7ZSp8.js} +1 -1
- package/web/assets/{chunk-MOJQB5TN-N4T1-ew1.js → chunk-MOJQB5TN-9lJ7f_hI.js} +1 -1
- package/web/assets/{chunk-RYQCIY6F-6oc6i_Xw.js → chunk-RYQCIY6F-QrFo_00s.js} +1 -1
- package/web/assets/{chunk-V7JOEXUC-Dftgm9ck.js → chunk-V7JOEXUC-Dn0lQjVf.js} +1 -1
- package/web/assets/{chunk-VR4S4FIN-DfjqwEsO.js → chunk-VR4S4FIN-DXVPySkB.js} +1 -1
- package/web/assets/{chunk-XXDRQBXY-CsFsQYow.js → chunk-XXDRQBXY-CBiFDOdZ.js} +1 -1
- package/web/assets/classDiagram-OUVF2IWQ-DCYNCJhe.js +1 -0
- package/web/assets/classDiagram-v2-EOCWNBFH-DCYNCJhe.js +1 -0
- package/web/assets/client-DBJY3XDL.js +43 -0
- package/web/assets/client-DKJs0w4y.js +6 -0
- package/web/assets/{command-D_9V8ejS.js → command-onjTnuXT.js} +1 -1
- package/web/assets/{copy-context-CevDWX59.js → copy-context-CciRaLNN.js} +1 -1
- package/web/assets/{cose-bilkent-JH36ORCC-DzKsIuDb.js → cose-bilkent-JH36ORCC-CGRic2um.js} +1 -1
- package/web/assets/{cynefin-VYW2F7L2-AL45ZHbw.js → cynefin-VYW2F7L2-Blk0Lu0l.js} +1 -1
- package/web/assets/{cynefinDiagram-TSTJHNR4-DSbBegxZ.js → cynefinDiagram-TSTJHNR4-DpnnHRDK.js} +1 -1
- package/web/assets/{dagre-VKFMJZFB-BaG6MGUE.js → dagre-VKFMJZFB-llzMokKp.js} +1 -1
- package/web/assets/{diagram-FQU43EPY-WbDotTX5.js → diagram-FQU43EPY-DC6xHovR.js} +1 -1
- package/web/assets/{diagram-G47NLZAW-DMbouYVI.js → diagram-G47NLZAW-B8GVS3EA.js} +1 -1
- package/web/assets/{diagram-NH7WQ7WH-DoEuaWd_.js → diagram-NH7WQ7WH-DWUaARfh.js} +1 -1
- package/web/assets/{diagram-OA4YK3LP-BjGd-PoH.js → diagram-OA4YK3LP-9Uaes_Yi.js} +1 -1
- package/web/assets/{diagram-WEI45ONY-CXHi27jF.js → diagram-WEI45ONY-DPPTBWud.js} +1 -1
- package/web/assets/{document-CVJCfWiQ.js → document-D23WzFsW.js} +3 -3
- package/web/assets/{ebnfDiagram-CCIWWBDH-B5vMUDOs.js → ebnfDiagram-CCIWWBDH-BPrKneNw.js} +1 -1
- package/web/assets/{entities-BTKzWJ-r.js → entities-DPg0B8vd.js} +1 -1
- package/web/assets/{erDiagram-Q63AITRT-DhO7ayzF.js → erDiagram-Q63AITRT-CFqYBcnb.js} +1 -1
- package/web/assets/{file-viewer-D1HK9J3A.js → file-viewer-Ck73SsLA.js} +1 -1
- package/web/assets/{flowDiagram-23GEKE2U-CublTUlC.js → flowDiagram-23GEKE2U-C7RpYqaT.js} +1 -1
- package/web/assets/folder-filter-bar-DzejUj87.js +4 -0
- package/web/assets/{folder-image-L_AjkRfI.js → folder-image-BjIicmQ6.js} +1 -1
- package/web/assets/folder-landing-CCIXZfkp.js +55 -0
- package/web/assets/folder-list-TuRwuTss.js +1 -0
- package/web/assets/folder-mobile-bar-Bqnfwi-z.js +1 -0
- package/web/assets/folder-plugin-view-CrinCX1o.js +2 -0
- package/web/assets/{ganttDiagram-NO4QXBWP-BLMJWerM.js → ganttDiagram-NO4QXBWP-Cz2sxU8F.js} +1 -1
- package/web/assets/{gitGraphDiagram-IHSO6WYX-Br0E6qyZ.js → gitGraphDiagram-IHSO6WYX-BSuz0yF-.js} +1 -1
- package/web/assets/index-DLn_2LPp.js +2 -0
- package/web/assets/index-uY9jLiL5.css +1 -0
- package/web/assets/{infoDiagram-FWYZ7A6U-Dgz0npJO.js → infoDiagram-FWYZ7A6U-CpeKgqoS.js} +1 -1
- package/web/assets/input-Bz_puamS.js +9 -0
- package/web/assets/{ishikawaDiagram-FXEZZL3T-rY5pdS3b.js → ishikawaDiagram-FXEZZL3T-5c2Tmknb.js} +1 -1
- package/web/assets/{journeyDiagram-5HDEW3XC-CKZALyR6.js → journeyDiagram-5HDEW3XC-Cu-wRkR4.js} +1 -1
- package/web/assets/{kanban-definition-HUTT4EX6-EGPY9Vda.js → kanban-definition-HUTT4EX6-BunSqkPe.js} +1 -1
- package/web/assets/{linear-DkJW9OwI.js → linear-C8e8bGVv.js} +1 -1
- package/web/assets/{mermaid.core-DVEpXYiF.js → mermaid.core-DLgjY1g2.js} +4 -4
- package/web/assets/{metadata-Bu_ffLUd.js → metadata-DEfJKlnd.js} +1 -1
- package/web/assets/{mindmap-definition-LN4V7U3C-BEOUVnDN.js → mindmap-definition-LN4V7U3C-W9ENYFOD.js} +1 -1
- package/web/assets/{pegDiagram-2B236MQR-DThjl3eK.js → pegDiagram-2B236MQR-0vPlHCFp.js} +1 -1
- package/web/assets/{pieDiagram-ENE6RG2P-DzmoGgw2.js → pieDiagram-ENE6RG2P-CakaveRV.js} +1 -1
- package/web/assets/{project-search-dialog-e2Jmhvfq.js → project-search-dialog-BSKA4peX.js} +1 -1
- package/web/assets/{quadrantDiagram-ABIIQ3AL-BqT8U3FS.js → quadrantDiagram-ABIIQ3AL-jxHw_egj.js} +1 -1
- package/web/assets/{railroadDiagram-RFXS5EU6-1k1tfPk1.js → railroadDiagram-RFXS5EU6-lIjDXPZt.js} +1 -1
- package/web/assets/{requirementDiagram-TGXJPOKE-bM4RTd2J.js → requirementDiagram-TGXJPOKE-C-JiT4bc.js} +1 -1
- package/web/assets/{sankeyDiagram-HTMAVEWB-TCgfqDLy.js → sankeyDiagram-HTMAVEWB-SuLPAw9X.js} +1 -1
- package/web/assets/{search-DQiFH2up.js → search-CKujW14f.js} +1 -1
- package/web/assets/{selection-popup-bqfgVd-L.js → selection-popup-CtxT9SWn.js} +3 -3
- package/web/assets/{sequenceDiagram-DBY2YBRQ-BRhGHI0i.js → sequenceDiagram-DBY2YBRQ-o9UwTkZR.js} +1 -1
- package/web/assets/{sizeCapture-X5ZJPWSS-EeUWgn0N.js → sizeCapture-X5ZJPWSS-ClbWGybF.js} +1 -1
- package/web/assets/{stateDiagram-2N3HPSRC-BSOG758d.js → stateDiagram-2N3HPSRC-Ce4avoWx.js} +1 -1
- package/web/assets/stateDiagram-v2-6OUMAXLB-CsrPTZoJ.js +1 -0
- package/web/assets/{swimlanes-5IMT3BWC-DpCo4aEm.js → swimlanes-5IMT3BWC-DMZI4XZT.js} +2 -2
- package/web/assets/swimlanesDiagram-G3AALYLV-pShSVcTd.js +8 -0
- package/web/assets/{timeline-definition-FHXFAJF6-BpaObe6u.js → timeline-definition-FHXFAJF6-CPIpIgPN.js} +1 -1
- package/web/assets/{vennDiagram-L72KCM5P-ClvUzW8B.js → vennDiagram-L72KCM5P-_rha8uDZ.js} +1 -1
- package/web/assets/view-context-BDtIUHQy.js +229 -0
- package/web/assets/{viewer-capabilities-CFBwvpcI.js → viewer-capabilities-YYZqMs56.js} +1 -1
- package/web/assets/{wardleyDiagram-EHGQE667-Dg1CX0Fl.js → wardleyDiagram-EHGQE667-D4EAOS35.js} +1 -1
- package/web/assets/{xychartDiagram-FW5EYKEG-C0c9zQTr.js → xychartDiagram-FW5EYKEG-DR8PwXpe.js} +1 -1
- package/web/index.html +2 -2
- package/kernel/packages/agents/eslint.config.js +0 -10
- package/kernel/packages/agents/package.json +0 -75
- package/kernel/packages/agents/src/agent-card.tsx +0 -334
- package/kernel/packages/agents/src/client.tsx +0 -13
- package/kernel/packages/agents/src/index.ts +0 -18
- package/kernel/packages/agents/src/manifest.ts +0 -7
- package/kernel/packages/agents/src/node.ts +0 -447
- package/kernel/packages/agents/src/profiles.ts +0 -137
- package/kernel/packages/agents/src/resolve.ts +0 -69
- package/kernel/packages/agents/src/server.ts +0 -60
- package/kernel/packages/agents/src/types.ts +0 -82
- package/kernel/packages/agents/src/viewer.tsx +0 -370
- package/kernel/packages/agents/test/profiles.test.mjs +0 -88
- package/kernel/packages/agents/test/resolve.test.mjs +0 -729
- package/kernel/packages/agents/tsconfig.json +0 -17
- package/kernel/packages/api/test/agents-loading.test.ts +0 -94
- package/kernel/packages/ui/src/components/folder-skill-list.tsx +0 -62
- package/web/assets/app-Debw-lUT.js +0 -2
- package/web/assets/app-options-UU_JlJQv.js +0 -25
- package/web/assets/channel-BgYLn5Cm.js +0 -1
- package/web/assets/classDiagram-OUVF2IWQ-Fzhmfbkt.js +0 -1
- package/web/assets/classDiagram-v2-EOCWNBFH-Fzhmfbkt.js +0 -1
- package/web/assets/client-C1WdY7jQ.js +0 -22
- package/web/assets/client-D__L4Hl0.js +0 -17
- package/web/assets/client-DoMhF9Tv.js +0 -5
- package/web/assets/folder-filter-bar-BHz7s9Vb.js +0 -4
- package/web/assets/folder-landing-Byh8W67L.js +0 -54
- package/web/assets/folder-list-jMyo-7pV.js +0 -1
- package/web/assets/folder-metadata-bCocvxpP.js +0 -2
- package/web/assets/folder-mobile-bar-DvvyOS-a.js +0 -1
- package/web/assets/folder-plugin-view-sib0Dwfw.js +0 -3
- package/web/assets/index-4Xh9UKim.js +0 -1
- package/web/assets/index-Bu75S2qS.js +0 -1
- package/web/assets/index-CPcMcCUY.js +0 -2
- package/web/assets/index-CXxkvzNJ.css +0 -1
- package/web/assets/select-CkOwL81C.js +0 -30
- package/web/assets/stateDiagram-v2-6OUMAXLB-DUeGDz1r.js +0 -1
- package/web/assets/swimlanesDiagram-G3AALYLV-BGOaCfyV.js +0 -8
- package/web/assets/use-folder-filter-hA6fa7nm.js +0 -1
- package/web/assets/view-context-CVvDw2JM.js +0 -229
|
@@ -16,7 +16,8 @@ Keep each concern in its owner:
|
|
|
16
16
|
| Folder metadata API and server registry | `packages/api` |
|
|
17
17
|
| Browser route and static external-plugin registry | `apps/web` |
|
|
18
18
|
| Install, pin, cache, validate, and compose external plugins | `cli/src/plugins/external.ts` |
|
|
19
|
-
| Built-in
|
|
19
|
+
| Built-in Notes feature code | `packages/notes` |
|
|
20
|
+
| Skills and Agents feature code | `raggle-ai/kennel-starter-plugins`, under `plugins/skills` and `plugins/agents` |
|
|
20
21
|
| External plugin feature code | Its own repository |
|
|
21
22
|
|
|
22
23
|
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.
|
|
@@ -34,6 +35,6 @@ Keep new plugin feature code in its own repository. Add to `packages/plugins` on
|
|
|
34
35
|
|
|
35
36
|
- Start with the smallest plugin repository change. Do not copy plugin feature code into Kennel.
|
|
36
37
|
- 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.
|
|
38
|
+
- Keep plugin ids stable. Only `notes` is reserved for the core. The starter plugins use `skills` and `kennel-agents`; both use `/views/<id>` routes.
|
|
38
39
|
- 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
40
|
- A CLI behavior change requires a new `cli/package.json` version. The publish workflow releases it after merge to `main`.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "kennel-plugins",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.4",
|
|
5
5
|
"description": "Small shared contract for trusted folder view plugins in the Kennel web viewer.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"license": "MIT",
|
|
@@ -32,6 +32,10 @@
|
|
|
32
32
|
"types": "./dist/endpoint.d.ts",
|
|
33
33
|
"import": "./dist/endpoint.js"
|
|
34
34
|
},
|
|
35
|
+
"./hooks": {
|
|
36
|
+
"types": "./dist/hooks.d.ts",
|
|
37
|
+
"import": "./dist/hooks.js"
|
|
38
|
+
},
|
|
35
39
|
"./page": {
|
|
36
40
|
"types": "./dist/page.d.ts",
|
|
37
41
|
"import": "./dist/page.js"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createContext, createElement, useContext } from "react"
|
|
2
|
+
import type { ReactNode } from "react"
|
|
3
|
+
|
|
4
|
+
const FolderPathContext = createContext<string | undefined>(undefined)
|
|
5
|
+
|
|
6
|
+
/** Host boundary. The host and plugin must resolve this module once. */
|
|
7
|
+
export function FolderPathProvider({
|
|
8
|
+
folder,
|
|
9
|
+
children,
|
|
10
|
+
}: {
|
|
11
|
+
folder: string
|
|
12
|
+
children: ReactNode
|
|
13
|
+
}) {
|
|
14
|
+
return createElement(FolderPathContext.Provider, { value: folder }, children)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/** Current viewed folder. This is not a filter selection or a permission check. */
|
|
18
|
+
export function useFolderPath(): string {
|
|
19
|
+
const folder = useContext(FolderPathContext)
|
|
20
|
+
if (folder === undefined) {
|
|
21
|
+
throw new Error("useFolderPath must be used inside FolderPathProvider")
|
|
22
|
+
}
|
|
23
|
+
return folder
|
|
24
|
+
}
|
|
@@ -5,11 +5,9 @@ export {
|
|
|
5
5
|
CopyContextButton,
|
|
6
6
|
FilePreview,
|
|
7
7
|
FilePreviewList,
|
|
8
|
-
FolderFilterBar,
|
|
9
8
|
PluginPage,
|
|
10
9
|
PluginPageError,
|
|
11
10
|
PluginPageStatus,
|
|
12
|
-
useFolderFilter,
|
|
13
11
|
} from "./page.ts"
|
|
14
12
|
export { folderPathId } from "./client.ts"
|
|
15
13
|
export {
|
|
@@ -27,6 +25,7 @@ export { isPluginPayloadError } from "./types.ts"
|
|
|
27
25
|
export type {
|
|
28
26
|
FolderPluginDataset,
|
|
29
27
|
FolderPluginDetection,
|
|
28
|
+
FolderPluginIcon,
|
|
30
29
|
FolderPluginId,
|
|
31
30
|
FolderPluginManifest,
|
|
32
31
|
FolderPluginPayload,
|
|
@@ -45,8 +44,3 @@ export type {
|
|
|
45
44
|
FolderPluginInitResult,
|
|
46
45
|
FolderPluginServer,
|
|
47
46
|
} from "./server.ts"
|
|
48
|
-
export type {
|
|
49
|
-
FolderFilterChoice,
|
|
50
|
-
FolderFilterMode,
|
|
51
|
-
FolderSelection,
|
|
52
|
-
} from "./page.ts"
|
|
@@ -8,10 +8,3 @@ export {
|
|
|
8
8
|
FilePreview,
|
|
9
9
|
FilePreviewList,
|
|
10
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"
|
|
@@ -13,9 +13,17 @@ export type ContentIssue = {
|
|
|
13
13
|
severity?: "warning"
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
/** Plugin-owned SVG path data. No React or page imports are needed for tabs. */
|
|
17
|
+
export type FolderPluginIcon = {
|
|
18
|
+
/** Paths use a 24 × 24 view box and the navigation text color. */
|
|
19
|
+
paths: string[]
|
|
20
|
+
}
|
|
21
|
+
|
|
16
22
|
export type FolderPluginManifest = {
|
|
17
23
|
/** Stable identifier used in routes, URLs, and registries. Never a URL segment turned into an import path. */
|
|
18
24
|
id: FolderPluginId
|
|
25
|
+
/** Optional plugin-owned navigation icon. Omit for a text-only tab. */
|
|
26
|
+
icon?: FolderPluginIcon
|
|
19
27
|
/** Navigation label shown in the folder shell. */
|
|
20
28
|
label: string
|
|
21
29
|
}
|
|
@@ -1,21 +1,16 @@
|
|
|
1
1
|
import type { CSSProperties, ReactNode } from "react"
|
|
2
2
|
import {
|
|
3
|
-
Bot,
|
|
4
|
-
CalendarRange,
|
|
5
3
|
ChevronRight,
|
|
6
4
|
FileText,
|
|
7
5
|
Folder,
|
|
8
|
-
FolderGit2,
|
|
9
6
|
FolderOpen,
|
|
10
|
-
ListTodo,
|
|
11
|
-
Mail,
|
|
12
7
|
// Sessions functionality is commented out (can be re-enabled).
|
|
13
8
|
// MessageCircle,
|
|
14
|
-
Sparkles,
|
|
15
9
|
} from "lucide-react"
|
|
16
10
|
|
|
17
11
|
import type {
|
|
18
12
|
FolderMetadata,
|
|
13
|
+
FolderPluginItem,
|
|
19
14
|
// Sessions functionality is commented out (can be re-enabled).
|
|
20
15
|
// FolderSession,
|
|
21
16
|
FolderTab,
|
|
@@ -31,8 +26,8 @@ import { FolderImage } from "@raggle-ai/ui/components/folder-image"
|
|
|
31
26
|
import { FolderProjectList } from "@raggle-ai/ui/components/folder-project-list"
|
|
32
27
|
// Sessions functionality is commented out (can be re-enabled).
|
|
33
28
|
// import { FolderSessionList } from "@raggle-ai/ui/components/folder-session-list"
|
|
34
|
-
import { FolderSkillList } from "@raggle-ai/ui/components/folder-skill-list"
|
|
35
29
|
import { FolderTabs } from "@raggle-ai/ui/components/folder-tabs"
|
|
30
|
+
import { FolderPluginIcon } from "@raggle-ai/ui/components/plugin-icon"
|
|
36
31
|
import {
|
|
37
32
|
SidebarInset,
|
|
38
33
|
SidebarMenuButton,
|
|
@@ -45,9 +40,7 @@ import { Skeleton } from "@raggle-ai/ui/components/skeleton"
|
|
|
45
40
|
type ActivityView =
|
|
46
41
|
// Sessions functionality is commented out (can be re-enabled).
|
|
47
42
|
// | { type: "sessions" }
|
|
48
|
-
|
|
49
|
-
| { skills?: true; type: "skills" }
|
|
50
|
-
| { type: "folder"; id?: string }
|
|
43
|
+
{ id: string; type: "plugin" } | { type: "folder"; id?: string }
|
|
51
44
|
type ActivityItem =
|
|
52
45
|
| {
|
|
53
46
|
count: number
|
|
@@ -68,16 +61,6 @@ type ActivityItem =
|
|
|
68
61
|
view?: undefined
|
|
69
62
|
}
|
|
70
63
|
|
|
71
|
-
/** Presentation-only mapping for explicitly registered plugin ids. */
|
|
72
|
-
function pluginIcon(id: string): ReactNode {
|
|
73
|
-
if (id === "calendar") return <CalendarRange aria-hidden="true" />
|
|
74
|
-
if (id === "tasks") return <ListTodo aria-hidden="true" />
|
|
75
|
-
if (id === "mail") return <Mail aria-hidden="true" />
|
|
76
|
-
if (id === "agents") return <Bot aria-hidden="true" />
|
|
77
|
-
if (id === "projects") return <FolderGit2 aria-hidden="true" />
|
|
78
|
-
return <Folder aria-hidden="true" />
|
|
79
|
-
}
|
|
80
|
-
|
|
81
64
|
function Section({
|
|
82
65
|
children,
|
|
83
66
|
count,
|
|
@@ -178,6 +161,7 @@ function FolderActivityLoading({
|
|
|
178
161
|
onOpenFolder,
|
|
179
162
|
pluginHref,
|
|
180
163
|
view,
|
|
164
|
+
viewNavigation,
|
|
181
165
|
tab,
|
|
182
166
|
tabHref,
|
|
183
167
|
}: {
|
|
@@ -188,6 +172,7 @@ function FolderActivityLoading({
|
|
|
188
172
|
onOpenFolder?: () => void
|
|
189
173
|
pluginHref: (id: string) => string
|
|
190
174
|
view?: { pluginId: string; subpath?: string }
|
|
175
|
+
viewNavigation?: Pick<FolderPluginItem, "icon" | "label">
|
|
191
176
|
tab?: FolderTab
|
|
192
177
|
tabHref: (tab: FolderTab) => string
|
|
193
178
|
}) {
|
|
@@ -195,7 +180,7 @@ function FolderActivityLoading({
|
|
|
195
180
|
// const active = tab ?? "sessions"
|
|
196
181
|
const active = tab ?? "files"
|
|
197
182
|
const pluginSelected = Boolean(view)
|
|
198
|
-
const title =
|
|
183
|
+
const title = "Notes"
|
|
199
184
|
|
|
200
185
|
const tabs: Array<{
|
|
201
186
|
href: string
|
|
@@ -209,25 +194,13 @@ function FolderActivityLoading({
|
|
|
209
194
|
key: "files",
|
|
210
195
|
label: "Notes",
|
|
211
196
|
},
|
|
212
|
-
{
|
|
213
|
-
href: pluginHref("tasks"),
|
|
214
|
-
icon: pluginIcon("tasks"),
|
|
215
|
-
key: "plugin:tasks",
|
|
216
|
-
label: "Tasks",
|
|
217
|
-
},
|
|
218
|
-
{
|
|
219
|
-
href: tabHref("skills"),
|
|
220
|
-
icon: <Sparkles aria-hidden="true" />,
|
|
221
|
-
key: "skills",
|
|
222
|
-
label: "Skills",
|
|
223
|
-
},
|
|
224
197
|
]
|
|
225
|
-
if (view
|
|
198
|
+
if (view) {
|
|
226
199
|
tabs.push({
|
|
227
200
|
href: pluginHref(view.pluginId),
|
|
228
|
-
icon:
|
|
201
|
+
icon: <FolderPluginIcon icon={viewNavigation?.icon} />,
|
|
229
202
|
key: `plugin:${view.pluginId}`,
|
|
230
|
-
label: view.pluginId,
|
|
203
|
+
label: viewNavigation?.label ?? view.pluginId,
|
|
231
204
|
})
|
|
232
205
|
}
|
|
233
206
|
|
|
@@ -253,11 +226,7 @@ function FolderActivityLoading({
|
|
|
253
226
|
<section className="landing-section landing-loading-section">
|
|
254
227
|
<header>
|
|
255
228
|
<h2>
|
|
256
|
-
|
|
257
|
-
<Sparkles aria-hidden="true" />
|
|
258
|
-
) : (
|
|
259
|
-
<FileText aria-hidden="true" />
|
|
260
|
-
)}
|
|
229
|
+
<FileText aria-hidden="true" />
|
|
261
230
|
{title}
|
|
262
231
|
</h2>
|
|
263
232
|
<Skeleton className="landing-skeleton-count" />
|
|
@@ -348,6 +317,7 @@ function FolderActivity({
|
|
|
348
317
|
// sessionTranscriptHref,
|
|
349
318
|
pluginHref,
|
|
350
319
|
view,
|
|
320
|
+
viewNavigation,
|
|
351
321
|
tab,
|
|
352
322
|
tabHref,
|
|
353
323
|
}: {
|
|
@@ -367,12 +337,11 @@ function FolderActivity({
|
|
|
367
337
|
// sessionTranscriptHref?: (session: FolderSession) => string
|
|
368
338
|
pluginHref: (id: string) => string
|
|
369
339
|
view?: { pluginId: string; subpath?: string }
|
|
340
|
+
viewNavigation?: Pick<FolderPluginItem, "icon" | "label">
|
|
370
341
|
tab?: FolderTab
|
|
371
342
|
tabHref: (tab: FolderTab) => string
|
|
372
343
|
}) {
|
|
373
|
-
const skills = data?.skills?.items ?? []
|
|
374
344
|
const plugins = data?.plugins?.items ?? []
|
|
375
|
-
const pluginMap = new Map(plugins.map((plugin) => [plugin.id, plugin]))
|
|
376
345
|
const configWarnings =
|
|
377
346
|
data?.plugins?.configWarnings ?? data?.configWarnings ?? []
|
|
378
347
|
const coreFolders = data?.workspace?.schemas ?? []
|
|
@@ -389,6 +358,7 @@ function FolderActivity({
|
|
|
389
358
|
tabHref={tabHref}
|
|
390
359
|
pluginHref={pluginHref}
|
|
391
360
|
view={view}
|
|
361
|
+
viewNavigation={viewNavigation}
|
|
392
362
|
/>
|
|
393
363
|
)
|
|
394
364
|
}
|
|
@@ -400,7 +370,6 @@ function FolderActivity({
|
|
|
400
370
|
// tab === "sessions" ? data.sessions.items : data.sessions.items.slice(0, 8)
|
|
401
371
|
// Sessions functionality is commented out (can be re-enabled).
|
|
402
372
|
// const sessionsSelected = tab === "sessions"
|
|
403
|
-
const skillsSelected = tab === "skills"
|
|
404
373
|
// A plugin view can render without a navigation item. Disabled plugins are
|
|
405
374
|
// rejected by the API request, so direct URLs show the shell error state.
|
|
406
375
|
const pluginSelected = Boolean(view)
|
|
@@ -415,52 +384,13 @@ function FolderActivity({
|
|
|
415
384
|
key: "files",
|
|
416
385
|
label: "Notes",
|
|
417
386
|
},
|
|
418
|
-
...(pluginMap.has("projects")
|
|
419
|
-
? [
|
|
420
|
-
{
|
|
421
|
-
count: pluginMap.get("projects")?.count ?? 0,
|
|
422
|
-
error: pluginMap.get("projects")?.error,
|
|
423
|
-
href: pluginHref("projects"),
|
|
424
|
-
icon: pluginIcon("projects"),
|
|
425
|
-
key: "plugin:projects",
|
|
426
|
-
label: "Projects",
|
|
427
|
-
view: { id: "projects", type: "plugin" } as ActivityView,
|
|
428
|
-
},
|
|
429
|
-
]
|
|
430
|
-
: []),
|
|
431
|
-
...(pluginMap.has("tasks")
|
|
432
|
-
? [
|
|
433
|
-
{
|
|
434
|
-
count: pluginMap.get("tasks")?.count ?? 0,
|
|
435
|
-
error: pluginMap.get("tasks")?.error,
|
|
436
|
-
href: pluginHref("tasks"),
|
|
437
|
-
icon: pluginIcon("tasks"),
|
|
438
|
-
key: "plugin:tasks",
|
|
439
|
-
label: "Tasks",
|
|
440
|
-
view: { id: "tasks", type: "plugin" } as ActivityView,
|
|
441
|
-
},
|
|
442
|
-
]
|
|
443
|
-
: []),
|
|
444
|
-
{
|
|
445
|
-
count: skills.length,
|
|
446
|
-
href: tabHref("skills"),
|
|
447
|
-
icon: <Sparkles aria-hidden="true" />,
|
|
448
|
-
key: "skills",
|
|
449
|
-
label: "Skills",
|
|
450
|
-
view: { skills: true, type: "skills" },
|
|
451
|
-
},
|
|
452
387
|
...plugins
|
|
453
|
-
.filter(
|
|
454
|
-
(plugin) =>
|
|
455
|
-
plugin.id !== "notes" &&
|
|
456
|
-
plugin.id !== "tasks" &&
|
|
457
|
-
plugin.id !== "projects",
|
|
458
|
-
)
|
|
388
|
+
.filter((plugin) => plugin.id !== "notes")
|
|
459
389
|
.map((plugin) => ({
|
|
460
390
|
count: plugin.count ?? 0,
|
|
461
391
|
error: plugin.error,
|
|
462
392
|
href: pluginHref(plugin.id),
|
|
463
|
-
icon:
|
|
393
|
+
icon: <FolderPluginIcon icon={plugin.icon} />,
|
|
464
394
|
key: `plugin:${plugin.id}`,
|
|
465
395
|
label: plugin.label,
|
|
466
396
|
view: { id: plugin.id, type: "plugin" } as ActivityView,
|
|
@@ -505,16 +435,6 @@ function FolderActivity({
|
|
|
505
435
|
</div>
|
|
506
436
|
) : null}
|
|
507
437
|
|
|
508
|
-
{skillsSelected ? (
|
|
509
|
-
<Section
|
|
510
|
-
count={skills.length}
|
|
511
|
-
icon={<Sparkles aria-hidden="true" />}
|
|
512
|
-
title="Skills"
|
|
513
|
-
>
|
|
514
|
-
<FolderSkillList onOpenPath={onOpenPath} skills={skills} />
|
|
515
|
-
</Section>
|
|
516
|
-
) : null}
|
|
517
|
-
|
|
518
438
|
{tab === "projects" && projects.length ? (
|
|
519
439
|
<Section
|
|
520
440
|
count={projects.length}
|
|
@@ -567,9 +487,7 @@ function FolderActivity({
|
|
|
567
487
|
return Boolean(collectionId && item.view.id === collectionId)
|
|
568
488
|
return item.view?.type === "plugin"
|
|
569
489
|
? pluginSelected && item.view.id === view?.pluginId
|
|
570
|
-
:
|
|
571
|
-
? skillsSelected
|
|
572
|
-
: tab === "files" || showDefaultFiles
|
|
490
|
+
: tab === "files" || showDefaultFiles
|
|
573
491
|
}
|
|
574
492
|
|
|
575
493
|
return (
|
|
@@ -2,6 +2,7 @@ import type { ReactNode } from "react"
|
|
|
2
2
|
|
|
3
3
|
import type {
|
|
4
4
|
FolderMetadata,
|
|
5
|
+
FolderPluginItem,
|
|
5
6
|
// Sessions functionality is commented out (can be re-enabled).
|
|
6
7
|
// FolderSession,
|
|
7
8
|
FolderTab,
|
|
@@ -26,6 +27,7 @@ export function FolderLanding({
|
|
|
26
27
|
tab,
|
|
27
28
|
tabHref,
|
|
28
29
|
view,
|
|
30
|
+
viewNavigation,
|
|
29
31
|
}: {
|
|
30
32
|
children?: ReactNode
|
|
31
33
|
collectionHref?: (id: string) => string
|
|
@@ -45,6 +47,7 @@ export function FolderLanding({
|
|
|
45
47
|
tab?: FolderTab
|
|
46
48
|
tabHref: (tab: FolderTab) => string
|
|
47
49
|
view?: { pluginId: string; subpath?: string }
|
|
50
|
+
viewNavigation?: Pick<FolderPluginItem, "icon" | "label">
|
|
48
51
|
}) {
|
|
49
52
|
return (
|
|
50
53
|
<FolderActivity
|
|
@@ -65,6 +68,7 @@ export function FolderLanding({
|
|
|
65
68
|
tab={tab}
|
|
66
69
|
tabHref={tabHref}
|
|
67
70
|
view={view}
|
|
71
|
+
viewNavigation={viewNavigation}
|
|
68
72
|
/>
|
|
69
73
|
)
|
|
70
74
|
}
|
|
@@ -5,8 +5,7 @@ import {
|
|
|
5
5
|
MoreHorizontalIcon,
|
|
6
6
|
} from "lucide-react"
|
|
7
7
|
|
|
8
|
-
import
|
|
9
|
-
import { buttonVariants } from "@raggle-ai/ui/components/button"
|
|
8
|
+
import { Button, buttonVariants } from "@raggle-ai/ui/components/button"
|
|
10
9
|
import { cn } from "@raggle-ai/ui/lib/utils"
|
|
11
10
|
|
|
12
11
|
function Pagination({ className, ...props }: React.ComponentProps<"nav">) {
|
|
@@ -117,7 +116,94 @@ function PaginationEllipsis({
|
|
|
117
116
|
)
|
|
118
117
|
}
|
|
119
118
|
|
|
119
|
+
/** Controlled, zero-based offset pagination for an in-memory collection. */
|
|
120
|
+
function OffsetPagination({
|
|
121
|
+
total,
|
|
122
|
+
offset,
|
|
123
|
+
pageSize,
|
|
124
|
+
onOffsetChange,
|
|
125
|
+
label = "Items",
|
|
126
|
+
}: {
|
|
127
|
+
total: number
|
|
128
|
+
offset: number
|
|
129
|
+
pageSize: number
|
|
130
|
+
onOffsetChange: (offset: number) => void
|
|
131
|
+
label?: string
|
|
132
|
+
}) {
|
|
133
|
+
const pageCount = Math.max(1, Math.ceil(total / pageSize))
|
|
134
|
+
const page = Math.min(Math.floor(offset / pageSize), pageCount - 1)
|
|
135
|
+
const pages = Array.from(
|
|
136
|
+
new Set([0, page - 1, page, page + 1, pageCount - 1]),
|
|
137
|
+
)
|
|
138
|
+
.filter((value) => value >= 0 && value < pageCount)
|
|
139
|
+
.sort((left, right) => left - right)
|
|
140
|
+
|
|
141
|
+
return (
|
|
142
|
+
<div className="grid gap-2">
|
|
143
|
+
<p
|
|
144
|
+
className="text-muted-foreground m-0 text-center text-sm"
|
|
145
|
+
role="status"
|
|
146
|
+
>
|
|
147
|
+
{label} {total ? page * pageSize + 1 : 0}–
|
|
148
|
+
{Math.min((page + 1) * pageSize, total)} of {total}
|
|
149
|
+
</p>
|
|
150
|
+
{pageCount > 1 ? (
|
|
151
|
+
<Pagination aria-label={`${label} pagination`}>
|
|
152
|
+
<PaginationContent className="gap-0 sm:gap-1">
|
|
153
|
+
<PaginationItem>
|
|
154
|
+
<Button
|
|
155
|
+
variant="ghost"
|
|
156
|
+
size="icon"
|
|
157
|
+
className="size-8 sm:size-9"
|
|
158
|
+
aria-label="Previous page"
|
|
159
|
+
disabled={page === 0}
|
|
160
|
+
onClick={() => onOffsetChange((page - 1) * pageSize)}
|
|
161
|
+
>
|
|
162
|
+
<ChevronLeftIcon aria-hidden="true" />
|
|
163
|
+
</Button>
|
|
164
|
+
</PaginationItem>
|
|
165
|
+
{pages.map((value, index) => (
|
|
166
|
+
<React.Fragment key={value}>
|
|
167
|
+
{index > 0 && value - pages[index - 1]! > 1 ? (
|
|
168
|
+
<PaginationItem>
|
|
169
|
+
<PaginationEllipsis className="size-6 sm:size-9" />
|
|
170
|
+
</PaginationItem>
|
|
171
|
+
) : null}
|
|
172
|
+
<PaginationItem>
|
|
173
|
+
<Button
|
|
174
|
+
variant={value === page ? "outline" : "ghost"}
|
|
175
|
+
size="icon"
|
|
176
|
+
className="size-8 sm:size-9"
|
|
177
|
+
aria-label={`Page ${value + 1}`}
|
|
178
|
+
aria-current={value === page ? "page" : undefined}
|
|
179
|
+
onClick={() => onOffsetChange(value * pageSize)}
|
|
180
|
+
>
|
|
181
|
+
{value + 1}
|
|
182
|
+
</Button>
|
|
183
|
+
</PaginationItem>
|
|
184
|
+
</React.Fragment>
|
|
185
|
+
))}
|
|
186
|
+
<PaginationItem>
|
|
187
|
+
<Button
|
|
188
|
+
variant="ghost"
|
|
189
|
+
size="icon"
|
|
190
|
+
className="size-8 sm:size-9"
|
|
191
|
+
aria-label="Next page"
|
|
192
|
+
disabled={page === pageCount - 1}
|
|
193
|
+
onClick={() => onOffsetChange((page + 1) * pageSize)}
|
|
194
|
+
>
|
|
195
|
+
<ChevronRightIcon aria-hidden="true" />
|
|
196
|
+
</Button>
|
|
197
|
+
</PaginationItem>
|
|
198
|
+
</PaginationContent>
|
|
199
|
+
</Pagination>
|
|
200
|
+
) : null}
|
|
201
|
+
</div>
|
|
202
|
+
)
|
|
203
|
+
}
|
|
204
|
+
|
|
120
205
|
export {
|
|
206
|
+
OffsetPagination,
|
|
121
207
|
Pagination,
|
|
122
208
|
PaginationContent,
|
|
123
209
|
PaginationLink,
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** Render plugin-owned path data without importing its page or an icon catalog. */
|
|
2
|
+
export function FolderPluginIcon({ icon }: { icon?: { paths: string[] } }) {
|
|
3
|
+
if (!icon) return null
|
|
4
|
+
return (
|
|
5
|
+
<svg
|
|
6
|
+
aria-hidden="true"
|
|
7
|
+
viewBox="0 0 24 24"
|
|
8
|
+
fill="none"
|
|
9
|
+
stroke="currentColor"
|
|
10
|
+
strokeWidth={2}
|
|
11
|
+
strokeLinecap="round"
|
|
12
|
+
strokeLinejoin="round"
|
|
13
|
+
>
|
|
14
|
+
{icon.paths.map((path, index) => (
|
|
15
|
+
<path key={index} d={path} />
|
|
16
|
+
))}
|
|
17
|
+
</svg>
|
|
18
|
+
)
|
|
19
|
+
}
|
|
@@ -22,14 +22,6 @@ export type FolderProject = {
|
|
|
22
22
|
worktree: string
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
export type FolderSkill = {
|
|
26
|
-
description?: string
|
|
27
|
-
name: string
|
|
28
|
-
openHref?: string
|
|
29
|
-
relativePath: string
|
|
30
|
-
source: "global" | "local"
|
|
31
|
-
}
|
|
32
|
-
|
|
33
25
|
export type FolderSession = {
|
|
34
26
|
client: "claude" | "codex" | "cursor" | "opencode" | "pi"
|
|
35
27
|
href?: string
|
|
@@ -58,6 +50,8 @@ export type FolderPluginItem = {
|
|
|
58
50
|
count?: number
|
|
59
51
|
/** Detection failure detail; the item is still shown but flagged. */
|
|
60
52
|
error?: string
|
|
53
|
+
/** Plugin-owned SVG path data. Omit for a text-only tab. */
|
|
54
|
+
icon?: { paths: string[] }
|
|
61
55
|
/** Trusted plugin id, registered in the host's explicit browser registry. */
|
|
62
56
|
id: string
|
|
63
57
|
label: string
|
|
@@ -72,7 +66,6 @@ export type FolderMetadata = {
|
|
|
72
66
|
plugins?: { configWarnings?: string[]; items: FolderPluginItem[] }
|
|
73
67
|
projects: { items: FolderProject[] }
|
|
74
68
|
sessions: { items: FolderSession[] }
|
|
75
|
-
skills?: { items: FolderSkill[] }
|
|
76
69
|
workspace?: {
|
|
77
70
|
breadcrumbs: Array<{
|
|
78
71
|
icon?: FolderIcon
|
|
@@ -104,17 +97,11 @@ export type FolderMetadata = {
|
|
|
104
97
|
}
|
|
105
98
|
}
|
|
106
99
|
|
|
107
|
-
export type FolderTab = "files" | "projects" | "sessions"
|
|
100
|
+
export type FolderTab = "files" | "projects" | "sessions"
|
|
108
101
|
|
|
109
102
|
export function folderTab(search: string): FolderTab | undefined {
|
|
110
103
|
const tab = new URLSearchParams(search).get("tab")
|
|
111
|
-
if (
|
|
112
|
-
tab === "files" ||
|
|
113
|
-
tab === "projects" ||
|
|
114
|
-
tab === "sessions" ||
|
|
115
|
-
tab === "skills"
|
|
116
|
-
)
|
|
117
|
-
return tab
|
|
104
|
+
if (tab === "files" || tab === "projects" || tab === "sessions") return tab
|
|
118
105
|
return undefined
|
|
119
106
|
}
|
|
120
107
|
|
|
@@ -965,8 +965,7 @@
|
|
|
965
965
|
color: #747c75;
|
|
966
966
|
}
|
|
967
967
|
|
|
968
|
-
.landing-sessions li
|
|
969
|
-
.landing-skills li {
|
|
968
|
+
.landing-sessions li {
|
|
970
969
|
display: grid;
|
|
971
970
|
grid-template-columns: minmax(0, 1fr) 36px;
|
|
972
971
|
}
|
|
@@ -975,35 +974,6 @@
|
|
|
975
974
|
grid-template-columns: 24px auto minmax(0, 1fr) auto;
|
|
976
975
|
}
|
|
977
976
|
|
|
978
|
-
.landing-skills .landing-list-row {
|
|
979
|
-
grid-template-columns: minmax(100px, 190px) minmax(0, 1fr) auto;
|
|
980
|
-
min-height: 32px;
|
|
981
|
-
padding-block: 6px;
|
|
982
|
-
}
|
|
983
|
-
|
|
984
|
-
.landing-skills strong {
|
|
985
|
-
min-width: 0;
|
|
986
|
-
color: #363d37;
|
|
987
|
-
font-size: 13px;
|
|
988
|
-
font-weight: 450;
|
|
989
|
-
}
|
|
990
|
-
|
|
991
|
-
.landing-skills span {
|
|
992
|
-
overflow: hidden;
|
|
993
|
-
min-width: 0;
|
|
994
|
-
color: #9aa09a;
|
|
995
|
-
font-size: 12px;
|
|
996
|
-
text-overflow: ellipsis;
|
|
997
|
-
white-space: nowrap;
|
|
998
|
-
}
|
|
999
|
-
|
|
1000
|
-
.landing-skills small {
|
|
1001
|
-
margin-top: 0;
|
|
1002
|
-
color: #8d948e;
|
|
1003
|
-
font-size: 12px;
|
|
1004
|
-
text-align: right;
|
|
1005
|
-
}
|
|
1006
|
-
|
|
1007
977
|
.landing-sessions li.is-resumable {
|
|
1008
978
|
grid-template-columns: minmax(0, 1fr) 44px;
|
|
1009
979
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kennel",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.13",
|
|
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",
|
|
@@ -116,7 +116,7 @@
|
|
|
116
116
|
},
|
|
117
117
|
"devDependencies": {
|
|
118
118
|
"@raggle-ai/kennel-preview": "0.1.0",
|
|
119
|
-
"kennel-plugins": "0.1.
|
|
119
|
+
"kennel-plugins": "0.1.4",
|
|
120
120
|
"@types/node": "^22.13.4",
|
|
121
121
|
"typescript": "^5.9.3"
|
|
122
122
|
},
|
|
@@ -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-9lJ7f_hI.js";import{p as f}from"./chunk-JWPE2WC7-Ddn7ZSp8.js";import{_ as n,l as o}from"./mermaid.core-DLgjY1g2.js";import{b as c,M as d}from"./cynefin-VYW2F7L2-Blk0Lu0l.js";import"./index-DLn_2LPp.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};
|