kennel 0.2.3 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -13
- package/dist/cli/dispatch.js +16 -3
- package/dist/cli/src/cli/dispatch.js +16 -3
- package/dist/cli/src/cli/usage.js +1 -1
- package/dist/cli/src/core/command.js +1 -0
- package/dist/cli/src/core/init.js +5 -5
- package/dist/cli/src/plugins/external.d.ts +28 -2
- package/dist/cli/src/plugins/external.js +77 -23
- package/dist/cli/src/site/server-plugins.d.ts +4 -9
- package/dist/cli/src/site/viewer.js +1 -0
- package/dist/cli/usage.js +1 -1
- package/dist/core/api-client.js +576 -10317
- package/dist/core/command.js +1 -0
- package/dist/core/core-folders.js +2313 -12088
- package/dist/core/init.js +5 -5
- package/dist/core/runtime.js +8237 -20713
- package/dist/package/preview.js +19617 -33352
- package/dist/plugins/external.d.ts +28 -2
- package/dist/plugins/external.js +77 -23
- package/dist/site/server-plugins.d.ts +4 -9
- package/dist/site/server-plugins.js +557 -10452
- package/dist/site/viewer.js +1 -0
- package/kernel/apps/web/package.json +2 -6
- package/kernel/apps/web/scripts/dev.mjs +53 -0
- package/kernel/apps/web/src/app.css +0 -3
- package/kernel/apps/web/src/external-plugins.ts +1 -1
- package/kernel/apps/web/src/folder-filter-icons.tsx +1 -1
- package/kernel/apps/web/src/folder-plugin-view.tsx +1 -1
- package/kernel/apps/web/src/main.tsx +0 -1
- package/kernel/apps/web/src/plugins.ts +1 -31
- package/kernel/apps/web/tsconfig.json +1 -2
- package/kernel/apps/web/vite.config.ts +32 -14
- package/kernel/packages/agents/package.json +1 -1
- package/kernel/packages/agents/src/agent-card.tsx +1 -1
- package/kernel/packages/agents/src/client.tsx +1 -1
- package/kernel/packages/agents/src/manifest.ts +1 -1
- package/kernel/packages/agents/src/server.ts +1 -1
- package/kernel/packages/agents/src/viewer.tsx +1 -1
- package/kernel/packages/api/package.json +1 -5
- package/kernel/packages/api/src/server/acp-live-plugin.ts +1 -1
- package/kernel/packages/api/src/server/api/create-agent-file.ts +2 -2
- package/kernel/packages/api/src/server/api/document-edit.ts +2 -2
- package/kernel/packages/api/src/server/api/open-path.ts +2 -2
- package/kernel/packages/api/src/server/folder-metadata-plugin.ts +17 -42
- package/kernel/packages/api/src/server/index.ts +0 -1
- package/kernel/packages/api/src/server/plugins.ts +52 -19
- package/kernel/packages/api/src/shared/viewer-route.ts +1 -1
- package/kernel/packages/api/test/core.test.ts +14 -26
- package/kernel/packages/markdown/README.md +1 -1
- package/kernel/packages/notes/package.json +1 -1
- package/kernel/packages/notes/src/client.tsx +1 -1
- package/kernel/packages/notes/src/manifest.ts +1 -1
- package/kernel/packages/notes/src/server.ts +1 -1
- package/kernel/packages/plugins/SKILL.md +39 -0
- package/kernel/{plugins/mail → packages/plugins}/package.json +53 -28
- package/kernel/packages/plugins/src/index.ts +52 -0
- package/kernel/packages/plugins/src/page.ts +17 -0
- package/kernel/{plugins/projects → packages/plugins}/tsconfig.json +5 -1
- package/kernel/packages/plugins/tsup.config.ts +25 -0
- package/kernel/packages/ui/src/components/content-issues.tsx +1 -1
- package/kernel/packages/ui/tsconfig.json +1 -1
- package/package.json +2 -3
- package/web/assets/{abnfDiagram-VRR7QNED-Bgfb1nEB.js → abnfDiagram-VRR7QNED-xd_g1uK3.js} +1 -1
- package/web/assets/app-CX20nNIa.js +2 -0
- package/web/assets/{app-options-D-RJiQ-X.js → app-options-CkPJE5ep.js} +1 -1
- package/web/assets/{app-view-header-BLvLq02T.js → app-view-header-CNk5KnA-.js} +1 -1
- package/web/assets/{arc-Dk_KI36B.js → arc-B0u5yBJA.js} +1 -1
- package/web/assets/{architectureDiagram-ZJ3FMSHR-NR_KhRCf.js → architectureDiagram-ZJ3FMSHR-DfxOAo8P.js} +1 -1
- package/web/assets/{ask-tray-TzeTcO6-.js → ask-tray-SscJecDY.js} +1 -1
- package/web/assets/{blockDiagram-677ZJIJ3-CkLkwx9C.js → blockDiagram-677ZJIJ3-Ci3Usxh6.js} +1 -1
- package/web/assets/{c4Diagram-LMCZKHZV-CFCUH8e_.js → c4Diagram-LMCZKHZV-BqgwIVgh.js} +1 -1
- package/web/assets/channel-X7WHyxxT.js +1 -0
- package/web/assets/{chunk-2Q5K7J3B-B_BPLWsW.js → chunk-2Q5K7J3B-CfX69l2U.js} +1 -1
- package/web/assets/{chunk-32BRIVSS-B1VB1hOy.js → chunk-32BRIVSS-CuFlzZkl.js} +1 -1
- package/web/assets/{chunk-5VM5RSS4-KFcYr8Co.js → chunk-5VM5RSS4-DidCMlJa.js} +1 -1
- package/web/assets/{chunk-EX3LRPZG-CpBX3kuK.js → chunk-EX3LRPZG-B5CDm1dS.js} +1 -1
- package/web/assets/{chunk-JWPE2WC7-BPSl40wG.js → chunk-JWPE2WC7-D5fGV_sH.js} +1 -1
- package/web/assets/{chunk-MOJQB5TN-D2RcYmoU.js → chunk-MOJQB5TN-ayhH5Q-H.js} +1 -1
- package/web/assets/{chunk-RYQCIY6F-m7Gyn-t3.js → chunk-RYQCIY6F-C4BfOOZn.js} +1 -1
- package/web/assets/{chunk-V7JOEXUC-TDvdopxS.js → chunk-V7JOEXUC-DpUEIM9V.js} +1 -1
- package/web/assets/{chunk-VR4S4FIN-DZTsG51a.js → chunk-VR4S4FIN-DoQuFFRh.js} +1 -1
- package/web/assets/{chunk-XXDRQBXY-Dp0--RE2.js → chunk-XXDRQBXY-CI9eiLwn.js} +1 -1
- package/web/assets/classDiagram-OUVF2IWQ-BjsLQ3dz.js +1 -0
- package/web/assets/classDiagram-v2-EOCWNBFH-BjsLQ3dz.js +1 -0
- package/web/assets/client-7OWw5kW2.js +6 -0
- package/web/assets/client-DYj_td4Q.js +17 -0
- package/web/assets/{client-j2kQmxsO.js → client-Dk-NBvJR.js} +4 -4
- package/web/assets/command-zkzH4hVz.js +38 -0
- package/web/assets/{copy-context-C0Uqsp-3.js → copy-context-D5oiWrYC.js} +1 -1
- package/web/assets/{cose-bilkent-JH36ORCC-CPu3PI8h.js → cose-bilkent-JH36ORCC-BHRk1mO3.js} +1 -1
- package/web/assets/{cynefin-VYW2F7L2-DWxftYAm.js → cynefin-VYW2F7L2-C1B09TRE.js} +1 -1
- package/web/assets/{cynefinDiagram-TSTJHNR4-DsmN2V-p.js → cynefinDiagram-TSTJHNR4-B27qXQbv.js} +1 -1
- package/web/assets/{dagre-VKFMJZFB-COEbApyY.js → dagre-VKFMJZFB-B1qEi32g.js} +1 -1
- package/web/assets/{diagram-FQU43EPY-0O9WGWKB.js → diagram-FQU43EPY-BMkkgADD.js} +1 -1
- package/web/assets/{diagram-G47NLZAW-CutEdMVh.js → diagram-G47NLZAW-Cb8_g1A5.js} +1 -1
- package/web/assets/{diagram-NH7WQ7WH-C9KZc3B2.js → diagram-NH7WQ7WH-B51wuc5m.js} +1 -1
- package/web/assets/{diagram-OA4YK3LP-D8kkPXbY.js → diagram-OA4YK3LP-xnsecbbI.js} +1 -1
- package/web/assets/{diagram-WEI45ONY-_YqiTaGP.js → diagram-WEI45ONY-DSZdyaAV.js} +1 -1
- package/web/assets/{document-Dgt5eZFj.js → document-Dc2dftTW.js} +3 -3
- package/web/assets/{ebnfDiagram-CCIWWBDH-JO-zQh6g.js → ebnfDiagram-CCIWWBDH-aTHmcUGy.js} +1 -1
- package/web/assets/{entities-C3wz7FCx.js → entities-CCUtpskY.js} +1 -1
- package/web/assets/{erDiagram-Q63AITRT-9UjQwJ4P.js → erDiagram-Q63AITRT-CUUPBcvo.js} +1 -1
- package/web/assets/{file-viewer-DZJ8nYnl.js → file-viewer-DJ3rsmef.js} +1 -1
- package/web/assets/{flowDiagram-23GEKE2U-Ca08tnYM.js → flowDiagram-23GEKE2U-aTQXx2Mh.js} +1 -1
- package/web/assets/{folder-image-BfGgxo7i.js → folder-image-Bnv43tzP.js} +1 -1
- package/web/assets/{folder-landing-qUKBCnG-.js → folder-landing-DCnzYXXY.js} +1 -1
- package/web/assets/{folder-list-BfFjv7rR.js → folder-list-DvVkVjiR.js} +1 -1
- package/web/assets/{folder-metadata-DCw8xzHk.js → folder-metadata-C9hMMzIH.js} +1 -1
- package/web/assets/{folder-mobile-bar-Ubz4babf.js → folder-mobile-bar-VoTL1GS0.js} +1 -1
- package/web/assets/folder-plugin-view-Cvd804ZU.js +6 -0
- package/web/assets/{ganttDiagram-NO4QXBWP-KnHzX5W3.js → ganttDiagram-NO4QXBWP-DiwdUp7u.js} +1 -1
- package/web/assets/{gitGraphDiagram-IHSO6WYX-Cm8woNtK.js → gitGraphDiagram-IHSO6WYX-BL2gG_IS.js} +1 -1
- package/web/assets/{index-CNyy98F8.js → index-CUTtMSyJ.js} +2 -2
- package/web/assets/index-CegvVQ1C.js +1 -0
- package/web/assets/index-Dwhf8F_U.css +1 -0
- package/web/assets/{infoDiagram-FWYZ7A6U-yyqmUtIb.js → infoDiagram-FWYZ7A6U-B3n0zZpt.js} +1 -1
- package/web/assets/{ishikawaDiagram-FXEZZL3T-BfvR_Zy4.js → ishikawaDiagram-FXEZZL3T-D7YytbEv.js} +1 -1
- package/web/assets/{journeyDiagram-5HDEW3XC-BKuw06HM.js → journeyDiagram-5HDEW3XC-BYwqEl3C.js} +1 -1
- package/web/assets/{kanban-definition-HUTT4EX6-n0010rmQ.js → kanban-definition-HUTT4EX6-BQHNJgXZ.js} +1 -1
- package/web/assets/{linear-C0d0lT8O.js → linear-BPiQCLNk.js} +1 -1
- package/web/assets/{mermaid.core-BDVbShyO.js → mermaid.core-CD-KvBjV.js} +4 -4
- package/web/assets/{metadata-KV0dpp4G.js → metadata-COJ7fZul.js} +1 -1
- package/web/assets/{mindmap-definition-LN4V7U3C--_0ks3GF.js → mindmap-definition-LN4V7U3C-C1L_gyoj.js} +1 -1
- package/web/assets/{pegDiagram-2B236MQR-CBoNIpKR.js → pegDiagram-2B236MQR-BDAfItqS.js} +1 -1
- package/web/assets/{pieDiagram-ENE6RG2P-MA5tkYh5.js → pieDiagram-ENE6RG2P-CkZYH3Vz.js} +1 -1
- package/web/assets/{popover-DBD7FF-W.js → popover-0oA2lLUV.js} +2 -2
- package/web/assets/{project-search-dialog-DM1IkSZu.js → project-search-dialog-B2oqMT6h.js} +1 -1
- package/web/assets/{quadrantDiagram-ABIIQ3AL-CWT1ryqF.js → quadrantDiagram-ABIIQ3AL-Dy8Al3YZ.js} +1 -1
- package/web/assets/{railroadDiagram-RFXS5EU6-ZiLB5FGi.js → railroadDiagram-RFXS5EU6-Dd9_yo7B.js} +1 -1
- package/web/assets/{requirementDiagram-TGXJPOKE-CQq9uneq.js → requirementDiagram-TGXJPOKE-DPhIUsbs.js} +1 -1
- package/web/assets/{sankeyDiagram-HTMAVEWB-qDG-0JqI.js → sankeyDiagram-HTMAVEWB-B2QkYtub.js} +1 -1
- package/web/assets/{search-DNrQA5fF.js → search-C1J0-xiB.js} +1 -1
- package/web/assets/select-CtXC_PLC.js +30 -0
- package/web/assets/{selection-popup-DmtTeRs2.js → selection-popup-qhlUFzGq.js} +1 -1
- package/web/assets/{sequenceDiagram-DBY2YBRQ-CiApurLO.js → sequenceDiagram-DBY2YBRQ-Bx7fcZDx.js} +1 -1
- package/web/assets/{sizeCapture-X5ZJPWSS-DZSR5QXm.js → sizeCapture-X5ZJPWSS-CIXIhl_A.js} +1 -1
- package/web/assets/{stateDiagram-2N3HPSRC-CjJJR9_z.js → stateDiagram-2N3HPSRC-DCrdAflB.js} +1 -1
- package/web/assets/stateDiagram-v2-6OUMAXLB-0KCFLYeQ.js +1 -0
- package/web/assets/{swimlanes-5IMT3BWC-CKmo1sg6.js → swimlanes-5IMT3BWC-DA2vc7iZ.js} +2 -2
- package/web/assets/swimlanesDiagram-G3AALYLV-CAw3AV84.js +8 -0
- package/web/assets/{timeline-definition-FHXFAJF6-D-NMwS3y.js → timeline-definition-FHXFAJF6-lKfJiV9V.js} +1 -1
- package/web/assets/{vennDiagram-L72KCM5P-CfL6LBWw.js → vennDiagram-L72KCM5P-DO1q2KzG.js} +1 -1
- package/web/assets/{view-context-gyDl_p2V.js → view-context-DXKM3-l1.js} +4 -4
- package/web/assets/{viewer-capabilities-Bpp8Uvcg.js → viewer-capabilities-Cig_xM9u.js} +1 -1
- package/web/assets/{wardleyDiagram-EHGQE667-DgldMxaj.js → wardleyDiagram-EHGQE667-Dal9LkuZ.js} +1 -1
- package/web/assets/{xychartDiagram-FW5EYKEG-CIoAIFX8.js → xychartDiagram-FW5EYKEG-B3dPLPII.js} +1 -1
- package/web/index.html +2 -2
- package/kernel/packages/api/test/partial-loading.test.ts +0 -43
- package/kernel/packages/folder-plugin/package.json +0 -50
- package/kernel/packages/folder-plugin/src/index.ts +0 -15
- package/kernel/packages/folder-plugin/tsconfig.json +0 -17
- package/kernel/plugins/calendar/SKILL.md +0 -173
- package/kernel/plugins/calendar/eslint.config.js +0 -10
- package/kernel/plugins/calendar/package.json +0 -73
- package/kernel/plugins/calendar/schema.json +0 -137
- package/kernel/plugins/calendar/src/calendar.tsx +0 -328
- package/kernel/plugins/calendar/src/client.tsx +0 -139
- package/kernel/plugins/calendar/src/context.ts +0 -48
- package/kernel/plugins/calendar/src/copy-button.tsx +0 -66
- package/kernel/plugins/calendar/src/event-dialog.tsx +0 -270
- package/kernel/plugins/calendar/src/index.ts +0 -4
- package/kernel/plugins/calendar/src/manifest.ts +0 -7
- package/kernel/plugins/calendar/src/parse.ts +0 -610
- package/kernel/plugins/calendar/src/server.ts +0 -160
- package/kernel/plugins/calendar/src/utils.ts +0 -80
- package/kernel/plugins/calendar/src/views.tsx +0 -418
- package/kernel/plugins/calendar/test/context.test.mjs +0 -60
- package/kernel/plugins/calendar/test/package.test.mjs +0 -43
- package/kernel/plugins/calendar/test/parse.test.mjs +0 -392
- package/kernel/plugins/calendar/test/server.test.mjs +0 -126
- package/kernel/plugins/calendar/tsconfig.json +0 -17
- package/kernel/plugins/mail/SKILL.md +0 -97
- package/kernel/plugins/mail/eslint.config.js +0 -10
- package/kernel/plugins/mail/src/api.ts +0 -359
- package/kernel/plugins/mail/src/bun-ffi.d.ts +0 -14
- package/kernel/plugins/mail/src/client.tsx +0 -14
- package/kernel/plugins/mail/src/flock.ts +0 -137
- package/kernel/plugins/mail/src/folders.ts +0 -37
- package/kernel/plugins/mail/src/history.ts +0 -485
- package/kernel/plugins/mail/src/index.ts +0 -3
- package/kernel/plugins/mail/src/mail-card.tsx +0 -123
- package/kernel/plugins/mail/src/mail-conversation.tsx +0 -153
- package/kernel/plugins/mail/src/mail-detail-page.tsx +0 -467
- package/kernel/plugins/mail/src/mail-hooks.ts +0 -252
- package/kernel/plugins/mail/src/mail-page.tsx +0 -109
- package/kernel/plugins/mail/src/mail-request.ts +0 -78
- package/kernel/plugins/mail/src/mail-send-box.tsx +0 -175
- package/kernel/plugins/mail/src/mailos.ts +0 -723
- package/kernel/plugins/mail/src/manifest.ts +0 -7
- package/kernel/plugins/mail/src/node.ts +0 -171
- package/kernel/plugins/mail/src/parse.ts +0 -139
- package/kernel/plugins/mail/src/server.ts +0 -125
- package/kernel/plugins/mail/src/types.ts +0 -10
- package/kernel/plugins/mail/src/viewer.tsx +0 -147
- package/kernel/plugins/mail/test/flock.test.mjs +0 -156
- package/kernel/plugins/mail/test/folders.test.mjs +0 -138
- package/kernel/plugins/mail/test/history.test.mjs +0 -460
- package/kernel/plugins/mail/test/mailos.test.mjs +0 -752
- package/kernel/plugins/mail/test/node.test.mjs +0 -207
- package/kernel/plugins/mail/test/package.test.mjs +0 -54
- package/kernel/plugins/mail/test/parse.test.mjs +0 -32
- package/kernel/plugins/mail/test/server.test.mjs +0 -116
- package/kernel/plugins/mail/test/viewer.test.mjs +0 -192
- package/kernel/plugins/mail/tsconfig.json +0 -17
- package/kernel/plugins/projects/SKILL.md +0 -73
- package/kernel/plugins/projects/eslint.config.js +0 -10
- package/kernel/plugins/projects/package.json +0 -70
- package/kernel/plugins/projects/src/client.tsx +0 -17
- package/kernel/plugins/projects/src/data/model.ts +0 -129
- package/kernel/plugins/projects/src/index.ts +0 -17
- package/kernel/plugins/projects/src/manifest.ts +0 -7
- package/kernel/plugins/projects/src/project-context.ts +0 -41
- package/kernel/plugins/projects/src/server.ts +0 -276
- package/kernel/plugins/projects/src/ui/project-card.tsx +0 -61
- package/kernel/plugins/projects/src/ui/projects-page.tsx +0 -102
- package/kernel/plugins/projects/test/package.test.mjs +0 -51
- package/kernel/plugins/tasks/SKILL.md +0 -341
- package/kernel/plugins/tasks/eslint.config.js +0 -10
- package/kernel/plugins/tasks/package.json +0 -74
- package/kernel/plugins/tasks/schema.json +0 -939
- package/kernel/plugins/tasks/src/api.ts +0 -212
- package/kernel/plugins/tasks/src/client.tsx +0 -23
- package/kernel/plugins/tasks/src/data/parse.ts +0 -544
- package/kernel/plugins/tasks/src/data/task-id.ts +0 -56
- package/kernel/plugins/tasks/src/data/todo-model.ts +0 -795
- package/kernel/plugins/tasks/src/index.ts +0 -34
- package/kernel/plugins/tasks/src/manifest.ts +0 -7
- package/kernel/plugins/tasks/src/pages/task-detail.tsx +0 -48
- package/kernel/plugins/tasks/src/pages/task-list.tsx +0 -88
- package/kernel/plugins/tasks/src/server.ts +0 -447
- package/kernel/plugins/tasks/src/styles.css +0 -9
- package/kernel/plugins/tasks/src/ui/compact-todo-list.tsx +0 -372
- package/kernel/plugins/tasks/src/ui/error-details.tsx +0 -78
- package/kernel/plugins/tasks/src/ui/task-page.tsx +0 -392
- package/kernel/plugins/tasks/src/ui/todo-agent-filter.tsx +0 -36
- package/kernel/plugins/tasks/src/ui/todo-filter-bar.tsx +0 -66
- package/kernel/plugins/tasks/src/ui/todo-item.tsx +0 -494
- package/kernel/plugins/tasks/src/ui/todo-status-filter.tsx +0 -60
- package/kernel/plugins/tasks/src/ui/todo-tag-filter.tsx +0 -48
- package/kernel/plugins/tasks/src/ui/todo-warnings.tsx +0 -106
- package/kernel/plugins/tasks/test/api.test.mjs +0 -99
- package/kernel/plugins/tasks/test/folder-sources.test.mjs +0 -46
- package/kernel/plugins/tasks/test/package.test.mjs +0 -54
- package/kernel/plugins/tasks/test/parse.test.mjs +0 -225
- package/kernel/plugins/tasks/test/server.test.mjs +0 -386
- package/kernel/plugins/tasks/tsconfig.json +0 -17
- package/web/assets/app-DoGr2Zi7.js +0 -2
- package/web/assets/channel-uMEjV8qc.js +0 -1
- package/web/assets/classDiagram-OUVF2IWQ-fbZocVor.js +0 -1
- package/web/assets/classDiagram-v2-EOCWNBFH-fbZocVor.js +0 -1
- package/web/assets/client-C6Nxdfif.js +0 -2
- package/web/assets/client-CXYfBko5.js +0 -17
- package/web/assets/client-CoKtOq-X.js +0 -7
- package/web/assets/client-DyRQz5RU.js +0 -53
- package/web/assets/client-OY6HUzuD.js +0 -98
- package/web/assets/client-YOYWZIFi.js +0 -34
- package/web/assets/command-BugZBGXE.js +0 -38
- package/web/assets/folder-plugin-view-DsWR1zmQ.js +0 -6
- package/web/assets/index-BaRnbYRw.js +0 -1
- package/web/assets/index-BexmLxIP.css +0 -1
- package/web/assets/index-DDirZMgx.js +0 -1
- package/web/assets/note-card-DBfX6gW1.js +0 -6
- package/web/assets/select-D8cqNgcp.js +0 -30
- package/web/assets/stateDiagram-v2-6OUMAXLB-BpeGSCu9.js +0 -1
- package/web/assets/swimlanesDiagram-G3AALYLV-D9RjLKb9.js +0 -8
- package/web/assets/use-folder-filter-LQyXns5Q.js +0 -1
- /package/kernel/packages/{folder-plugin → plugins}/eslint.config.js +0 -0
- /package/kernel/packages/{folder-plugin → plugins}/src/client.ts +0 -0
- /package/kernel/packages/{folder-plugin → plugins}/src/endpoint.ts +0 -0
- /package/kernel/packages/{folder-plugin → plugins}/src/server.ts +0 -0
- /package/kernel/packages/{folder-plugin → plugins}/src/subpath.ts +0 -0
- /package/kernel/packages/{folder-plugin → plugins}/src/types.ts +0 -0
- /package/kernel/packages/{folder-plugin → plugins}/src/validation.ts +0 -0
- /package/kernel/packages/{folder-plugin → plugins}/test/contract.test.mjs +0 -0
|
@@ -1,386 +0,0 @@
|
|
|
1
|
-
import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises"
|
|
2
|
-
import { tmpdir } from "node:os"
|
|
3
|
-
import { basename, join } from "node:path"
|
|
4
|
-
import { afterAll, beforeAll, expect, test } from "bun:test"
|
|
5
|
-
|
|
6
|
-
import { createTasksPlugin } from "../src/server.ts"
|
|
7
|
-
|
|
8
|
-
let base
|
|
9
|
-
let empty
|
|
10
|
-
let withTasks
|
|
11
|
-
let withZeroTasks
|
|
12
|
-
let withInvalidStatus
|
|
13
|
-
let withBrokenJson
|
|
14
|
-
|
|
15
|
-
beforeAll(async () => {
|
|
16
|
-
base = await mkdtemp(join(tmpdir(), "kennel-tasks-plugin-"))
|
|
17
|
-
empty = join(base, "empty")
|
|
18
|
-
withTasks = join(base, "with-tasks")
|
|
19
|
-
withZeroTasks = join(base, "with-zero-tasks")
|
|
20
|
-
withInvalidStatus = join(base, "with-invalid-status")
|
|
21
|
-
withBrokenJson = join(base, "with-broken-json")
|
|
22
|
-
for (const folder of [
|
|
23
|
-
empty,
|
|
24
|
-
withTasks,
|
|
25
|
-
withZeroTasks,
|
|
26
|
-
withInvalidStatus,
|
|
27
|
-
withBrokenJson,
|
|
28
|
-
]) {
|
|
29
|
-
await mkdir(folder, { recursive: true })
|
|
30
|
-
}
|
|
31
|
-
await writeFile(
|
|
32
|
-
join(withTasks, "todo.json"),
|
|
33
|
-
JSON.stringify({
|
|
34
|
-
id: "todo",
|
|
35
|
-
tasks: [{ id: "t1", key: "TODO-1", name: "One", done: false }],
|
|
36
|
-
title: "Project",
|
|
37
|
-
}),
|
|
38
|
-
)
|
|
39
|
-
await writeFile(
|
|
40
|
-
join(withZeroTasks, "todo.json"),
|
|
41
|
-
JSON.stringify({
|
|
42
|
-
id: "todo",
|
|
43
|
-
tasks: [],
|
|
44
|
-
title: "Empty",
|
|
45
|
-
}),
|
|
46
|
-
)
|
|
47
|
-
await writeFile(
|
|
48
|
-
join(withInvalidStatus, "todo.json"),
|
|
49
|
-
JSON.stringify({
|
|
50
|
-
id: "todo",
|
|
51
|
-
tasks: [{ id: "t1", name: "One", status: "in-progress" }],
|
|
52
|
-
title: "Broken",
|
|
53
|
-
}),
|
|
54
|
-
)
|
|
55
|
-
await writeFile(join(withBrokenJson, "todo.json"), '{"tasks": [')
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
afterAll(async () => {
|
|
59
|
-
await rm(base, { recursive: true, force: true })
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
test("detect is unavailable without a todo.json file", async () => {
|
|
63
|
-
const plugin = createTasksPlugin()
|
|
64
|
-
const detection = await plugin.detect({ folder: empty })
|
|
65
|
-
expect(detection.status).toBe("unavailable")
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
test("a valid todo document activates even with zero tasks", async () => {
|
|
69
|
-
const plugin = createTasksPlugin()
|
|
70
|
-
const zero = await plugin.detect({ folder: withZeroTasks })
|
|
71
|
-
expect(zero.status).toBe("available")
|
|
72
|
-
expect(zero.count).toBe(0)
|
|
73
|
-
|
|
74
|
-
const withCount = await plugin.detect({ folder: withTasks })
|
|
75
|
-
expect(withCount.status).toBe("available")
|
|
76
|
-
expect(withCount.count).toBe(1)
|
|
77
|
-
})
|
|
78
|
-
|
|
79
|
-
test("handle list returns a schema-valid task dataset", async () => {
|
|
80
|
-
const plugin = createTasksPlugin()
|
|
81
|
-
const result = await plugin.handle({ folder: withTasks }, "")
|
|
82
|
-
expect(result.kind).toBe("available")
|
|
83
|
-
if (result.kind !== "available") return
|
|
84
|
-
expect(result.data.status).toBe("available")
|
|
85
|
-
expect(result.data.dataset.tasks).toHaveLength(1)
|
|
86
|
-
expect(result.data.dataset.summary.open).toBe(1)
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
test("handle returns an empty dataset when the folder has no task document", async () => {
|
|
90
|
-
const plugin = createTasksPlugin()
|
|
91
|
-
const result = await plugin.handle({ folder: empty }, "")
|
|
92
|
-
expect(result.kind).toBe("available")
|
|
93
|
-
expect(result.data.dataset.tasks).toEqual([])
|
|
94
|
-
expect(result.data.dataset.summary).toEqual({
|
|
95
|
-
completed: 0,
|
|
96
|
-
open: 0,
|
|
97
|
-
sources: 1,
|
|
98
|
-
})
|
|
99
|
-
expect(result.data.dataset.version).toBe(1)
|
|
100
|
-
expect(result.data.dataset.$schema).toBe(
|
|
101
|
-
"https://raggle.co/schemas/tasks.json",
|
|
102
|
-
)
|
|
103
|
-
})
|
|
104
|
-
|
|
105
|
-
test("detect reports an error, not availability, for an invalid document", async () => {
|
|
106
|
-
const plugin = createTasksPlugin()
|
|
107
|
-
const invalid = await plugin.detect({ folder: withInvalidStatus })
|
|
108
|
-
expect(invalid.status).toBe("error")
|
|
109
|
-
if (invalid.status !== "error") return
|
|
110
|
-
expect(invalid.error).toContain("tasks[0].status")
|
|
111
|
-
|
|
112
|
-
const broken = await plugin.detect({ folder: withBrokenJson })
|
|
113
|
-
expect(broken.status).toBe("error")
|
|
114
|
-
if (broken.status !== "error") return
|
|
115
|
-
expect(broken.error).toContain("not valid JSON")
|
|
116
|
-
})
|
|
117
|
-
|
|
118
|
-
test("handle returns in-band issues for an invalid document", async () => {
|
|
119
|
-
const plugin = createTasksPlugin()
|
|
120
|
-
const result = await plugin.handle({ folder: withInvalidStatus }, "")
|
|
121
|
-
expect(result.kind).toBe("available")
|
|
122
|
-
if (result.kind !== "available") return
|
|
123
|
-
expect(result.data.status).toBe("error")
|
|
124
|
-
expect(result.data.issues).toContainEqual({
|
|
125
|
-
path: "tasks[0].status",
|
|
126
|
-
message:
|
|
127
|
-
'must be one of todo, in_progress, blocked, review, done, canceled; got "in-progress"',
|
|
128
|
-
})
|
|
129
|
-
})
|
|
130
|
-
|
|
131
|
-
test("handle reports broken JSON as an issue, not a throw", async () => {
|
|
132
|
-
const plugin = createTasksPlugin()
|
|
133
|
-
const result = await plugin.handle({ folder: withBrokenJson }, "")
|
|
134
|
-
expect(result.kind).toBe("available")
|
|
135
|
-
if (result.kind !== "available") return
|
|
136
|
-
expect(result.data.status).toBe("error")
|
|
137
|
-
expect(result.data.issues).toHaveLength(1)
|
|
138
|
-
expect(result.data.issues[0].path).toBe("#")
|
|
139
|
-
expect(result.data.issues[0].message).toContain("not valid JSON")
|
|
140
|
-
})
|
|
141
|
-
|
|
142
|
-
test("handle with a task id subpath returns a single-task dataset", async () => {
|
|
143
|
-
const plugin = createTasksPlugin()
|
|
144
|
-
const result = await plugin.handle({ folder: withTasks }, "t1")
|
|
145
|
-
expect(result.kind).toBe("available")
|
|
146
|
-
if (result.kind !== "available") return
|
|
147
|
-
expect(result.data.status).toBe("available")
|
|
148
|
-
expect(result.data.dataset.tasks).toHaveLength(1)
|
|
149
|
-
expect(result.data.dataset.tasks[0].id).toBe("t1")
|
|
150
|
-
expect(result.data.dataset.summary.open).toBe(1)
|
|
151
|
-
})
|
|
152
|
-
|
|
153
|
-
test("handle with a task key subpath returns the matching task", async () => {
|
|
154
|
-
const plugin = createTasksPlugin()
|
|
155
|
-
const result = await plugin.handle({ folder: withTasks }, "TODO-1")
|
|
156
|
-
expect(result.kind).toBe("available")
|
|
157
|
-
if (result.kind !== "available") return
|
|
158
|
-
expect(result.data.status).toBe("available")
|
|
159
|
-
expect(result.data.dataset.tasks).toHaveLength(1)
|
|
160
|
-
expect(result.data.dataset.tasks[0].id).toBe("t1")
|
|
161
|
-
})
|
|
162
|
-
|
|
163
|
-
test("handle with an unknown task subpath returns an error message", async () => {
|
|
164
|
-
const plugin = createTasksPlugin()
|
|
165
|
-
const result = await plugin.handle({ folder: withTasks }, "nope")
|
|
166
|
-
expect(result.kind).toBe("available")
|
|
167
|
-
if (result.kind !== "available") return
|
|
168
|
-
expect(result.data.status).toBe("error")
|
|
169
|
-
expect(result.data.message).toContain("nope")
|
|
170
|
-
expect(result.data.dataset).toBeUndefined()
|
|
171
|
-
})
|
|
172
|
-
|
|
173
|
-
test("handle with a task subpath surfaces issues for an invalid document", async () => {
|
|
174
|
-
const plugin = createTasksPlugin()
|
|
175
|
-
const result = await plugin.handle({ folder: withInvalidStatus }, "t1")
|
|
176
|
-
expect(result.kind).toBe("available")
|
|
177
|
-
if (result.kind !== "available") return
|
|
178
|
-
expect(result.data.status).toBe("error")
|
|
179
|
-
expect(result.data.issues).toHaveLength(1)
|
|
180
|
-
expect(result.data.issues[0].path).toBe("tasks[0].status")
|
|
181
|
-
})
|
|
182
|
-
|
|
183
|
-
test("handle with a task subpath on a missing document returns an empty dataset", async () => {
|
|
184
|
-
const plugin = createTasksPlugin()
|
|
185
|
-
const result = await plugin.handle({ folder: empty }, "t1")
|
|
186
|
-
expect(result.kind).toBe("available")
|
|
187
|
-
if (result.kind !== "available") return
|
|
188
|
-
expect(result.data.status).toBe("available")
|
|
189
|
-
expect(result.data.dataset.tasks).toEqual([])
|
|
190
|
-
})
|
|
191
|
-
|
|
192
|
-
test("a nested workspace merges task files into folder-tagged sources", async () => {
|
|
193
|
-
const folder = await mkdtemp(join(tmpdir(), "kennel-tasks-plugin-"))
|
|
194
|
-
try {
|
|
195
|
-
const nested = join(folder, "clients", "client-one")
|
|
196
|
-
await mkdir(nested, { recursive: true })
|
|
197
|
-
await writeFile(
|
|
198
|
-
join(folder, "todo.json"),
|
|
199
|
-
JSON.stringify({
|
|
200
|
-
id: "todo",
|
|
201
|
-
tasks: [{ id: "root1", key: "ROOT-1", name: "Root", done: false }],
|
|
202
|
-
title: "Example Workspace",
|
|
203
|
-
}),
|
|
204
|
-
)
|
|
205
|
-
await writeFile(
|
|
206
|
-
join(nested, "todo.json"),
|
|
207
|
-
JSON.stringify({
|
|
208
|
-
id: "todo",
|
|
209
|
-
tasks: [{ id: "n1", key: "N-1", name: "Nested", done: true }],
|
|
210
|
-
title: "Client One",
|
|
211
|
-
}),
|
|
212
|
-
)
|
|
213
|
-
|
|
214
|
-
const plugin = createTasksPlugin()
|
|
215
|
-
const detection = await plugin.detect({ folder })
|
|
216
|
-
expect(detection.status).toBe("available")
|
|
217
|
-
if (detection.status !== "available") return
|
|
218
|
-
expect(detection.count).toBe(2)
|
|
219
|
-
|
|
220
|
-
const result = await plugin.handle({ folder }, "")
|
|
221
|
-
expect(result.kind).toBe("available")
|
|
222
|
-
if (result.kind !== "available") return
|
|
223
|
-
const dataset = result.data.dataset
|
|
224
|
-
expect(dataset.tasks).toHaveLength(2)
|
|
225
|
-
expect(dataset.summary).toEqual({ completed: 1, open: 1, sources: 2 })
|
|
226
|
-
// Each task is tagged with its owning folder for the shared chips.
|
|
227
|
-
expect(dataset.tasks.map((task) => task.source.id).sort()).toEqual(
|
|
228
|
-
[folder, nested].sort(),
|
|
229
|
-
)
|
|
230
|
-
expect(dataset.sources.map((source) => source.id).sort()).toEqual(
|
|
231
|
-
[folder, nested].sort(),
|
|
232
|
-
)
|
|
233
|
-
} finally {
|
|
234
|
-
await rm(folder, { recursive: true, force: true })
|
|
235
|
-
}
|
|
236
|
-
})
|
|
237
|
-
|
|
238
|
-
test("detail subpaths match tasks inside nested files", async () => {
|
|
239
|
-
const folder = await mkdtemp(join(tmpdir(), "kennel-tasks-plugin-"))
|
|
240
|
-
try {
|
|
241
|
-
const nested = join(folder, "clients", "client-one")
|
|
242
|
-
await mkdir(nested, { recursive: true })
|
|
243
|
-
await writeFile(
|
|
244
|
-
join(folder, "todo.json"),
|
|
245
|
-
JSON.stringify({ tasks: [{ id: "root1", name: "Root" }] }),
|
|
246
|
-
)
|
|
247
|
-
await writeFile(
|
|
248
|
-
join(nested, "todo.json"),
|
|
249
|
-
JSON.stringify({ tasks: [{ id: "n1", name: "Nested" }] }),
|
|
250
|
-
)
|
|
251
|
-
|
|
252
|
-
const plugin = createTasksPlugin()
|
|
253
|
-
const result = await plugin.handle({ folder }, "n1")
|
|
254
|
-
expect(result.kind).toBe("available")
|
|
255
|
-
if (result.kind !== "available") return
|
|
256
|
-
expect(result.data.status).toBe("available")
|
|
257
|
-
expect(result.data.dataset.tasks).toHaveLength(1)
|
|
258
|
-
expect(result.data.dataset.tasks[0].id).toBe("n1")
|
|
259
|
-
expect(result.data.dataset.tasks[0].source.id).toBe(nested)
|
|
260
|
-
} finally {
|
|
261
|
-
await rm(folder, { recursive: true, force: true })
|
|
262
|
-
}
|
|
263
|
-
})
|
|
264
|
-
|
|
265
|
-
test("linked folder tasks merge into the dataset under their own source", async () => {
|
|
266
|
-
const folder = await mkdtemp(join(tmpdir(), "kennel-tasks-plugin-"))
|
|
267
|
-
const linked = await mkdtemp(join(tmpdir(), "kennel-tasks-linked-"))
|
|
268
|
-
try {
|
|
269
|
-
await writeFile(
|
|
270
|
-
join(folder, "todo.json"),
|
|
271
|
-
JSON.stringify({
|
|
272
|
-
id: "todo",
|
|
273
|
-
tasks: [{ id: "root1", name: "Root" }],
|
|
274
|
-
title: "Local project",
|
|
275
|
-
}),
|
|
276
|
-
)
|
|
277
|
-
await writeFile(
|
|
278
|
-
join(linked, "todo.json"),
|
|
279
|
-
JSON.stringify({
|
|
280
|
-
id: "todo",
|
|
281
|
-
tasks: [
|
|
282
|
-
{ id: "l1", key: "LINK-1", name: "Linked one", done: false },
|
|
283
|
-
{ id: "l2", key: "LINK-2", name: "Linked two", done: true },
|
|
284
|
-
],
|
|
285
|
-
title: "Linked project",
|
|
286
|
-
}),
|
|
287
|
-
)
|
|
288
|
-
|
|
289
|
-
const plugin = createTasksPlugin()
|
|
290
|
-
|
|
291
|
-
// Without the host-provided link the folder stays a single local source.
|
|
292
|
-
const local = await plugin.detect({ folder })
|
|
293
|
-
expect(local.status).toBe("available")
|
|
294
|
-
if (local.status !== "available") return
|
|
295
|
-
expect(local.count).toBe(1)
|
|
296
|
-
|
|
297
|
-
const detection = await plugin.detect({
|
|
298
|
-
folder,
|
|
299
|
-
linkedFolders: [linked],
|
|
300
|
-
})
|
|
301
|
-
expect(detection.status).toBe("available")
|
|
302
|
-
if (detection.status !== "available") return
|
|
303
|
-
expect(detection.count).toBe(3)
|
|
304
|
-
|
|
305
|
-
const result = await plugin.handle({ folder, linkedFolders: [linked] }, "")
|
|
306
|
-
expect(result.kind).toBe("available")
|
|
307
|
-
if (result.kind !== "available") return
|
|
308
|
-
expect(result.data.status).toBe("available")
|
|
309
|
-
const dataset = result.data.dataset
|
|
310
|
-
expect(dataset.title).toBe("Local project")
|
|
311
|
-
expect(dataset.summary).toEqual({ completed: 1, open: 2, sources: 2 })
|
|
312
|
-
expect(dataset.sources).toContainEqual({
|
|
313
|
-
id: linked,
|
|
314
|
-
open: 1,
|
|
315
|
-
title: `${basename(linked)} tasks`,
|
|
316
|
-
total: 2,
|
|
317
|
-
})
|
|
318
|
-
const linkedTask = dataset.tasks.find((task) => task.id === "l1")
|
|
319
|
-
expect(linkedTask?.source).toEqual({
|
|
320
|
-
id: linked,
|
|
321
|
-
title: `${basename(linked)} tasks`,
|
|
322
|
-
})
|
|
323
|
-
// Detail subpaths resolve across linked sources too.
|
|
324
|
-
const detail = await plugin.handle(
|
|
325
|
-
{ folder, linkedFolders: [linked] },
|
|
326
|
-
"LINK-2",
|
|
327
|
-
)
|
|
328
|
-
expect(detail.kind).toBe("available")
|
|
329
|
-
if (detail.kind !== "available") return
|
|
330
|
-
expect(detail.data.dataset.tasks).toHaveLength(1)
|
|
331
|
-
expect(detail.data.dataset.tasks[0].id).toBe("l2")
|
|
332
|
-
expect(detail.data.dataset.summary.completed).toBe(1)
|
|
333
|
-
} finally {
|
|
334
|
-
await rm(folder, { recursive: true, force: true })
|
|
335
|
-
await rm(linked, { recursive: true, force: true })
|
|
336
|
-
}
|
|
337
|
-
})
|
|
338
|
-
|
|
339
|
-
test("linked files never shadow the root todo.json semantics", async () => {
|
|
340
|
-
const folder = await mkdtemp(join(tmpdir(), "kennel-tasks-plugin-"))
|
|
341
|
-
const linked = await mkdtemp(join(tmpdir(), "kennel-tasks-linked-"))
|
|
342
|
-
try {
|
|
343
|
-
await writeFile(
|
|
344
|
-
join(folder, "todo.json"),
|
|
345
|
-
JSON.stringify({ tasks: [{ id: "root1", name: "Root" }] }),
|
|
346
|
-
)
|
|
347
|
-
await writeFile(
|
|
348
|
-
join(linked, "todo.json"),
|
|
349
|
-
JSON.stringify({ tasks: [{ id: "l1", name: "Linked" }] }),
|
|
350
|
-
)
|
|
351
|
-
|
|
352
|
-
const plugin = createTasksPlugin()
|
|
353
|
-
// A linked folder alone activates the item, with the viewed root title.
|
|
354
|
-
const alone = await plugin.handle(
|
|
355
|
-
{ folder: empty, linkedFolders: [linked] },
|
|
356
|
-
"",
|
|
357
|
-
)
|
|
358
|
-
expect(alone.kind).toBe("available")
|
|
359
|
-
if (alone.kind !== "available") return
|
|
360
|
-
expect(alone.data.status).toBe("available")
|
|
361
|
-
expect(alone.data.dataset.tasks).toHaveLength(1)
|
|
362
|
-
expect(alone.data.dataset.tasks[0].source.id).toBe(linked)
|
|
363
|
-
// The viewed root always owns an (empty) source row, so linked-only
|
|
364
|
-
// content shows root + linked sources.
|
|
365
|
-
expect(alone.data.dataset.summary).toEqual({
|
|
366
|
-
completed: 0,
|
|
367
|
-
open: 1,
|
|
368
|
-
sources: 2,
|
|
369
|
-
})
|
|
370
|
-
// Invalid linked json is skipped from content and never breaks the root
|
|
371
|
-
// error panel, but still flags detection like any nested file would.
|
|
372
|
-
await writeFile(join(linked, "todo.json"), '{"tasks": [')
|
|
373
|
-
const broken = await plugin.detect({ folder, linkedFolders: [linked] })
|
|
374
|
-
expect(broken.status).toBe("error")
|
|
375
|
-
if (broken.status !== "error") return
|
|
376
|
-
expect(broken.error).toContain("not valid JSON")
|
|
377
|
-
const panel = await plugin.handle({ folder, linkedFolders: [linked] }, "")
|
|
378
|
-
expect(panel.kind).toBe("available")
|
|
379
|
-
if (panel.kind !== "available") return
|
|
380
|
-
expect(panel.data.status).toBe("available")
|
|
381
|
-
expect(panel.data.dataset.tasks).toHaveLength(1)
|
|
382
|
-
} finally {
|
|
383
|
-
await rm(folder, { recursive: true, force: true })
|
|
384
|
-
await rm(linked, { recursive: true, force: true })
|
|
385
|
-
}
|
|
386
|
-
})
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json.schemastore.org/tsconfig",
|
|
3
|
-
"extends": "@raggle-ai/tsconfig/base.json",
|
|
4
|
-
"compilerOptions": {
|
|
5
|
-
"target": "ES2022",
|
|
6
|
-
"lib": ["dom", "dom.iterable", "esnext"],
|
|
7
|
-
"jsx": "preserve",
|
|
8
|
-
"baseUrl": ".",
|
|
9
|
-
"allowImportingTsExtensions": true,
|
|
10
|
-
// local copy: bun doesn't read paths inherited via `extends`
|
|
11
|
-
"paths": {
|
|
12
|
-
"~/*": ["${configDir}/../../packages/*/src"]
|
|
13
|
-
}
|
|
14
|
-
},
|
|
15
|
-
"include": ["src"],
|
|
16
|
-
"exclude": ["node_modules", "dist", "eslint.config.mjs"]
|
|
17
|
-
}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/ask-tray-TzeTcO6-.js","assets/react-B9jn2M18.js","assets/markdown-Bw9RgUGR.js","assets/view-context-gyDl_p2V.js","assets/index-CNyy98F8.js","assets/index-BexmLxIP.css","assets/tanstack-YzX_Mi37.js","assets/button-C6arH7zt.js","assets/utils-DCaHk0Gm.js","assets/folder-plugin-view-DsWR1zmQ.js","assets/command-BugZBGXE.js","assets/index-CCXE8zc9.js","assets/index-DDirZMgx.js","assets/popover-DBD7FF-W.js","assets/folder-image-BfGgxo7i.js","assets/viewer-capabilities-Bpp8Uvcg.js","assets/entities-C3wz7FCx.js","assets/search-DNrQA5fF.js","assets/search-BOHZTLC-.css","assets/folder-landing-qUKBCnG-.js","assets/folder-metadata-DCw8xzHk.js","assets/copy-context-C0Uqsp-3.js","assets/index-Bp9DidgD.js","assets/app-options-D-RJiQ-X.js","assets/index-CXhBn-ar.js","assets/folder-list-BfFjv7rR.js","assets/folder-activity-Cv1X2ezj.js","assets/folder-mobile-bar-Ubz4babf.js","assets/app-view-header-BLvLq02T.js","assets/file-viewer-DZJ8nYnl.js","assets/metadata-KV0dpp4G.js","assets/project-search-dialog-DM1IkSZu.js","assets/client-j2kQmxsO.js","assets/select-D8cqNgcp.js","assets/index-BaRnbYRw.js","assets/client-C6Nxdfif.js","assets/note-card-DBfX6gW1.js"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{_ as g,i as ne,f as T,b as re,c as ae,p as S,l as je,d as Re,r as _e,e as be}from"./index-CNyy98F8.js";import{c as s,j as r}from"./react-B9jn2M18.js";import{m as x,c as f}from"./tanstack-YzX_Mi37.js";import{b as ke,c as Ee,q as Ie,L as Te,T as Se,v as Q,V as De,i as se,s as ie,a as M,t as ce,g as Ae,h as Oe,j as E,k as F,m as Fe}from"./view-context-gyDl_p2V.js";function N(e){const t=new TextEncoder().encode(e);let o="";for(const c of t)o+=String.fromCharCode(c);return btoa(o).replaceAll("+","-").replaceAll("/","_").replaceAll("=","")}function Le(e){const t=new URL(e,window.location.origin),o=t.pathname.split("/").filter(Boolean),c=o.indexOf("folder"),d=c>=0?o[c+1]:void 0;let i=t.searchParams.get("folder")??void 0;if(!i&&d){const l=d.replaceAll("-","+").replaceAll("_","/"),a=l.padEnd(Math.ceil(l.length/4)*4,"="),u=atob(a),m=Uint8Array.from(u,j=>j.charCodeAt(0));i=new TextDecoder().decode(m)}return{folder:i}}function xt(e,t){return`/folder/${N(e)}/${t}`}function jt(e,t){return`/folder/${N(e)}/document/${N(t)}`}async function Ne(e,t,o={}){const c=new URL(e,window.location.origin),d=new URL("/api/metadata",window.location.origin),i=c.pathname.split("/").filter(Boolean),l=i[0]==="folder"?i[1]:void 0,a=c.searchParams.get("folder");if(a)d.searchParams.set("path",a);else if(l){const m=l.replaceAll("-","+").replaceAll("_","/"),j=m.padEnd(Math.ceil(m.length/4)*4,"="),y=atob(j),C=Uint8Array.from(y,V=>V.charCodeAt(0));d.searchParams.set("path",new TextDecoder().decode(C))}d.searchParams.set("part",t),o.notesScope&&d.searchParams.set("notesScope",o.notesScope);const u=await fetch(d,{headers:o.headers,signal:o.signal});if(!u.ok)throw new Error(await u.text());return await u.json()}function Ce(e,t=!0){const o=s.useRef(!1),c=Le(e).folder,d=c?N(c):"none",i=m=>({enabled:t&&!!c,gcTime:5*6e4,queryFn:({signal:j})=>{const y=m==="linked"&&o.current;return y&&(o.current=!1),Ne(e,"notes",{headers:y?{"x-kennel-retry-linked":"1"}:void 0,notesScope:m,signal:j})},queryKey:["folder",d,"notes",m],staleTime:15e3}),l=x.useQuery(i("local")),a=x.useQuery(i("linked")),u=s.useMemo(()=>l.data||a.data?[...l.data?.files.items??[],...a.data?.files.items??[]]:void 0,[l.data,a.data]);return{local:l,linked:a,files:u,retryLinked:()=>{o.current=!0,a.refetch()}}}const Ve=s.lazy(async()=>({default:(await g(async()=>{const{AskTray:e}=await import("./ask-tray-TzeTcO6-.js");return{AskTray:e}},__vite__mapDeps([0,1,2,3,4,5,6,7,8]))).AskTray}));function $e({folder:e}){const{enabled:t}=ke(),{draft:o}=Ee(e);return!t&&!o.comments.length&&!o.attachments.length?null:r.jsx(s.Suspense,{fallback:null,children:r.jsx(Ve,{folder:e})})}function Ke(e){const t=e.slice(e.lastIndexOf(".")).toLowerCase();if(t===".htm"||t===".html")return"html";if(t===".md"||t===".markdown")return"markdown";if(t===".text"||t===".txt")return"text"}async function le(e,t=""){const o=[];for await(const c of e.values()){const d=t?`${t}/${c.name}`:c.name;if(c.kind==="directory"){o.push(...await le(c,d));continue}const i=Ke(c.name);if(!i)continue;const l=await c.getFile();o.push({path:d,content:await l.text(),kind:i})}return o}async function qe(e){const t=await le(e);return t.sort((o,c)=>o.path.localeCompare(c.path)),{root:e.name,documents:t}}async function He(e){for(const t of e){if(t.kind!=="file")continue;const o=t.getAsFileSystemHandle;if(!o)throw new Error("This browser cannot read dropped folders.");const c=await o.call(t);if(c?.kind==="directory")return c}throw new Error("Drop one folder to open it.")}const Qe="kennel-folder-query-cache",z="queries",U=1,Me=10080*60*1e3;function ze(){return new Promise((e,t)=>{const o=indexedDB.open(Qe,U);o.onupgradeneeded=()=>{o.result.createObjectStore(z)},o.onerror=()=>t(o.error),o.onsuccess=()=>e(o.result)})}async function de(e,t){const o=await ze();return new Promise((c,d)=>{const i=o.transaction(z,e),l=t(i.objectStore(z));l.onerror=()=>d(l.error),l.onsuccess=()=>c(l.result),i.oncomplete=()=>o.close(),i.onerror=()=>{o.close(),d(i.error)}})}async function ee(e){const t=await de("readonly",o=>o.get(JSON.stringify(e))).catch(()=>{});if(t?.version===U&&!(Date.now()-t.savedAt>Me))return t.data}async function te(e,t){t&&await de("readwrite",o=>o.put({data:t,savedAt:Date.now(),version:U},JSON.stringify(e))).catch(()=>{})}const ue=s.lazy(async()=>({default:(await g(async()=>{const{FolderPluginPage:e}=await import("./folder-plugin-view-DsWR1zmQ.js").then(t=>t.f);return{FolderPluginPage:e}},__vite__mapDeps([9,1,2,6,3,4,5,7,8,10,11,12,13,14,15]))).FolderPluginPage})),Be=s.lazy(async()=>({default:(await g(async()=>{const{EntitySearchPage:e}=await import("./entities-C3wz7FCx.js");return{EntitySearchPage:e}},__vite__mapDeps([16,1,2,6,3,4,5]))).EntitySearchPage})),Ue=s.lazy(async()=>({default:(await g(async()=>{const{ProjectSearchPage:e}=await import("./search-DNrQA5fF.js");return{ProjectSearchPage:e}},__vite__mapDeps([17,1,2,6,3,4,5,18]))).ProjectSearchPage}));function I(){return r.jsx("p",{role:"status",className:"text-muted-foreground p-4 text-sm",children:"Loading page…"})}const D=f.createRootRoute({component:f.Outlet}),oe=s.lazy(async()=>({default:(await g(()=>import("./folder-landing-qUKBCnG-.js"),__vite__mapDeps([19,1,2,3,4,5,6,7,8,20,21,11,12,14,22,23,24,25,26]))).FolderLanding})),Ye=s.lazy(async()=>({default:(await g(()=>import("./folder-mobile-bar-Ubz4babf.js"),__vite__mapDeps([27,1,2,23,3,4,5,6,21,7,8,11,24,14,28,13]))).FolderMobileBar})),Je=s.lazy(async()=>({default:(await g(()=>import("./file-viewer-DZJ8nYnl.js"),__vite__mapDeps([29,1,2,3,4,5,6,30]))).FileViewer})),We=s.lazy(async()=>({default:(await g(()=>import("./project-search-dialog-DM1IkSZu.js"),__vite__mapDeps([31,1,2,6,3,4,5,10,11,8,12]))).ProjectSearchDialog})),Ge=s.lazy(async()=>{const e=await g(()=>import("./client-j2kQmxsO.js"),__vite__mapDeps([32,1,2,6,23,3,4,5,21,7,8,11,24,14,28,13,33,34,22,25]));return{default:function(){const o=f.useLocation(),c=`${window.location.origin}${o.href}`;return r.jsx(e.CollectionPage,{href:c,request:(d,i,l)=>M.metadata(d,i,l),subscribeApiEvent:ie,parseRoute:S,collectionHref:ae,documentHref:re,folderHref:B,homeHref:d=>T(d,"notes"),openFolder:d=>{M.openPath(d).catch(i=>ce.error(i instanceof Error?i.message:"Could not open the default app."))}})}}}),Xe=s.lazy(async()=>({default:(await g(()=>import("./client-C6Nxdfif.js"),__vite__mapDeps([35,1,2,3,4,5,6,7,8,36,21,26]))).NotesPage})),Ze=f.createRoute({getParentRoute:()=>D,path:"/",component:fe}),b=f.createRoute({getParentRoute:()=>D,path:"folder/$folderId",component:fe}),et=f.createRoute({getParentRoute:()=>b,path:"skills"}),tt=f.createRoute({getParentRoute:()=>b,path:"views/$pluginId",component:ue}),ot=f.createRoute({getParentRoute:()=>b,path:"views/$pluginId/$subpath",component:ue}),nt=f.createRoute({getParentRoute:()=>b,path:"collections/$collectionId",component:()=>r.jsx(s.Suspense,{fallback:r.jsx("p",{role:"status",children:"Loading collection…"}),children:r.jsx(Ge,{})})}),rt=f.createRoute({getParentRoute:()=>b,path:"notes",component:Xe}),at=f.createRoute({getParentRoute:()=>b,path:"projects"}),st=f.createRoute({getParentRoute:()=>D,path:"entities",component:Be}),it=f.createRoute({getParentRoute:()=>D,path:"search",component:Ue}),ct=D.addChildren([Ze,st,it,b.addChildren([rt,nt,et,tt,ot,at])]),lt=f.createRouter({routeTree:ct});function dt(){const e=S(window.location.href).folder;return e?T(e,"notes"):"/"}function B(e){return T(e,"notes")}function ut(e){const t=S(window.location.href).folder;return t?re(t,e):e}function ft(e){const t=S(window.location.href).folder;return t?e==="files"?T(t,"notes"):T(t,e):"/"}function pt(e){const t=S(window.location.href).folder;return t?be(t,e):"/"}function mt({href:e,...t}){return!e?.startsWith("/")||ne(e)?r.jsx("a",{href:e,...t}):r.jsx(f.Link,{to:e,...t})}function ht(){return r.jsx(x.QueryClientProvider,{client:Ie,children:r.jsxs(Te,{component:mt,children:[r.jsx(s.Suspense,{fallback:r.jsx(I,{}),children:r.jsx(f.RouterProvider,{router:lt})}),r.jsx(Se,{})]})})}const L={discovery:Number.POSITIVE_INFINITY,identity:Number.POSITIVE_INFINITY,plugins:Number.POSITIVE_INFINITY,skills:15e3};function P(e,t){return["folder",e,t]}function fe(){const e=f.useLocation(),t=`${window.location.origin}${e.href}`,o=Q(t);return r.jsx(De,{kind:"folder",folder:se(t)?void 0:o.folder,children:r.jsx(yt,{})})}function yt(){const e=Ae(),t=je(window.location.href);t&&window.history.replaceState(null,"",t);const o=x.useQueryClient(),c=f.useNavigate(),d=f.useLocation(),i=`${window.location.origin}${d.href}`,l=se(i),a=Q(i),u=a.folder?Re(a.folder):"none",[m,j]=s.useState(()=>window.matchMedia("(max-width: 767px)").matches),[y,C]=s.useState(),[V,$]=s.useState(!1),[Y,J]=s.useState(!1),[pe,me]=s.useState(!1),W=pe&&!a.document,A=s.useRef(0),k=!l&&!y,R=k&&!!a.folder,he=P(u,"identity"),ye=P(u,"discovery");Oe(i,k);const ge=s.useMemo(()=>y?{read:async()=>y}:l?{read:E.read}:{...E},[y,l]),v=x.useQuery({enabled:!!R,gcTime:Number.POSITIVE_INFINITY,queryFn:({signal:n})=>F(i,"identity",{signal:n}),queryKey:he,staleTime:L.identity}),h=x.useQuery({enabled:!!(R&&a.section==="projects"),gcTime:Number.POSITIVE_INFINITY,queryFn:({signal:n})=>F(i,"discovery",{signal:n}),queryKey:ye,staleTime:L.discovery}),G=x.useQuery({enabled:!!R,gcTime:Number.POSITIVE_INFINITY,queryFn:({signal:n})=>F(i,"plugins",{signal:n}),queryKey:P(u,"plugins"),staleTime:L.plugins}),X=Ce(i,R&&a.section==="notes"),Z=x.useQuery({enabled:!!(R&&a.section==="skills"),gcTime:5*6e4,queryFn:({signal:n})=>F(i,"skills",{signal:n}),queryKey:P(u,"skills"),staleTime:L.skills}),_=s.useMemo(()=>{if(v.data)return{assets:{...h.data?.assets,...v.data.assets},files:{items:X.files??[]},folder:v.data.folder,iconAssetKey:v.data.iconAssetKey,plugins:G.data?.plugins??{items:[]},projects:h.data?.projects??{items:[]},workspace:e.workspace??h.data?.workspace,sessions:{items:[]},skills:Z.data?.skills??{items:[]}}},[h.data,v.data,X.files,G.data,Z.data,e.workspace]),K=v.error??(a.section==="projects"?h.error:void 0)??void 0,we=K?K instanceof Error?K.message:"Could not load folder activity.":"",ve=(_?.folder??y?.root??a.folder??"Kennel").replace(/\/+$/,"").split("/").pop()??"Kennel",Pe=_?.iconAssetKey?_.assets[_.iconAssetKey]:void 0;s.useEffect(()=>{const n=window.matchMedia("(max-width: 767px)"),p=()=>j(n.matches);return n.addEventListener("change",p),()=>n.removeEventListener("change",p)},[]),s.useEffect(()=>ie("kennel:metadata-changed",()=>{o.invalidateQueries({queryKey:["folder",u]})}),[u,o]),s.useEffect(()=>Fe("kennel:linked-folders-changed",a.folder,()=>{for(const n of[["notes","linked"],["plugins"]])o.invalidateQueries({queryKey:["folder",u,...n]},{cancelRefetch:!1})}),[u,a.folder,o]),s.useEffect(()=>{if(!R)return;const n=P(u,"identity"),p=P(u,"discovery");ee(n).then(w=>{w&&!o.getQueryData(n)&&o.setQueryData(n,w)}),ee(p).then(w=>{w&&!o.getQueryData(p)&&o.setQueryData(p,w)})},[u,R,o]),s.useEffect(()=>{te(P(u,"identity"),v.data)},[u,v.data]),s.useEffect(()=>{te(P(u,"discovery"),h.data)},[h.data,u]);const xe=n=>{const p=new URL(n,window.location.origin);Q(p.href),c({to:`${p.pathname}${p.search}`})},q=a.view||a.collectionId||a.section==="notes"?r.jsx(s.Suspense,{fallback:r.jsx(I,{}),children:r.jsx(f.Outlet,{})}):a.section==="projects"&&!h.data&&(h.isPending||h.error)?r.jsx("div",{className:"p-4",role:h.error?"alert":"status",children:h.error?r.jsxs(r.Fragment,{children:["Projects could not load."," ",r.jsx("button",{onClick:()=>{h.refetch()},children:"Retry projects"})]}):"Loading projects…"}):null,O=!!a.collectionId,H={data:_,collectionId:a.collectionId,collectionHref:n=>a.folder?ae(a.folder,n):"/",documentHref:ut,error:we,folder:a.folder,folderHref:B,onFindProject:()=>J(!0),onOpenFolder:()=>{E.openRoot?.()},onOpenPath:n=>{M.openPath(n).catch(p=>ce.error(p instanceof Error?p.message:"Could not open the default app."))},pluginHref:pt,tab:_e(a),tabHref:ft,view:a.view};return r.jsxs("div",{className:"folder-drop-zone","data-mobile-landing":k&&m?"true":void 0,onClickCapture:n=>{if(n.defaultPrevented||n.button!==0||n.metaKey||n.ctrlKey||n.shiftKey||n.altKey||!(n.target instanceof Element))return;const w=n.target.closest("a[href]")?.getAttribute("href");if(w?.startsWith("/folder/")&&!ne(w)){n.preventDefault(),xe(w);return}},onDragEnter:n=>{l||[...n.dataTransfer.items].some(p=>p.kind==="file")&&(n.preventDefault(),A.current+=1,$(!0))},onDragLeave:()=>{A.current-=1,A.current<=0&&$(!1)},onDragOver:n=>{l||(n.preventDefault(),n.dataTransfer.dropEffect="copy")},onDrop:n=>{l||(n.preventDefault(),A.current=0,$(!1),He(n.dataTransfer.items).then(qe).then(p=>{window.history.replaceState(null,"",window.location.pathname),C(p)}))},children:[O?null:r.jsx(s.Suspense,{fallback:null,children:r.jsx(Ye,{canOpen:!l&&!y,homeHref:dt(),icon:Pe,name:ve,folder:_?.folder??a.folder,folderHref:B,collectionHref:H.collectionHref,workspace:e.workspace??_?.workspace,onOpen:()=>{if(m){me(!0);return}E.openRoot?.()},onOpenFolder:()=>{E.openRoot?.()}})}),k&&O?r.jsx(s.Suspense,{fallback:r.jsx(I,{}),children:q}):null,k&&!O&&!m?r.jsx(s.Suspense,{fallback:r.jsx(I,{}),children:r.jsx(oe,{...H,children:q})}):null,k&&!O&&m?r.jsx("div",{className:"mobile-landing-content",children:r.jsx(s.Suspense,{fallback:r.jsx(I,{}),children:r.jsx(oe,{...H,children:q})})}):null,W?r.jsx(s.Suspense,{fallback:null,children:r.jsx(Je,{source:ge})}):null,a.folder&&!W?r.jsx($e,{folder:a.folder},a.folder):null,V?r.jsx("div",{className:"folder-drop-overlay",children:"Drop folder to open"}):null,Y?r.jsx(s.Suspense,{fallback:null,children:r.jsx(We,{open:Y,onOpenChange:J})}):null]})}const Rt=Object.freeze(Object.defineProperty({__proto__:null,App:ht},Symbol.toStringTag,{value:"Module"}));export{xt as a,jt as b,Rt as c,N as f,Le as p,Ce as u};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{U as a,T as n}from"./mermaid.core-BDVbShyO.js";const t=(r,o)=>a.lang.round(n.parse(r)[o]);export{t as c};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as a,c as s,a as e,C as t}from"./chunk-V7JOEXUC-TDvdopxS.js";import{_ as i}from"./mermaid.core-BDVbShyO.js";import"./chunk-5VM5RSS4-KFcYr8Co.js";import"./chunk-XXDRQBXY-Dp0--RE2.js";import"./chunk-VR4S4FIN-DZTsG51a.js";import"./chunk-32BRIVSS-B1VB1hOy.js";import"./index-CNyy98F8.js";import"./react-B9jn2M18.js";import"./markdown-Bw9RgUGR.js";var b={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{b as diagram};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as a,c as s,a as e,C as t}from"./chunk-V7JOEXUC-TDvdopxS.js";import{_ as i}from"./mermaid.core-BDVbShyO.js";import"./chunk-5VM5RSS4-KFcYr8Co.js";import"./chunk-XXDRQBXY-Dp0--RE2.js";import"./chunk-VR4S4FIN-DZTsG51a.js";import"./chunk-32BRIVSS-B1VB1hOy.js";import"./index-CNyy98F8.js";import"./react-B9jn2M18.js";import"./markdown-Bw9RgUGR.js";var b={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{b as diagram};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{c as x,j as t}from"./react-B9jn2M18.js";import{p as v,f as k,u as w,a as y,b as C}from"./app-DoGr2Zi7.js";import{l as g}from"./view-context-gyDl_p2V.js";import{B as j}from"./button-C6arH7zt.js";import{N as P}from"./note-card-DBfX6gW1.js";import"./markdown-Bw9RgUGR.js";import"./index-CNyy98F8.js";import"./tanstack-YzX_Mi37.js";import"./utils-DCaHk0Gm.js";import"./copy-context-C0Uqsp-3.js";import"./folder-activity-Cv1X2ezj.js";const A={id:"notes",label:"Notes"},b=new Map;async function $(a){const r=new URL("/api/config",window.location.origin);a&&r.searchParams.set("path",a);const l=await fetch(r);if(!l.ok)return null;const n=(await l.json()).aiInputModule;if(typeof n!="string"||!n)return null;const u=b.get(n);if(u)return u;const s=import(n).then(d=>{const p=d.default;if(!p?.Composer)throw new Error("The AI input module must default-export an adapter with a Composer component.");return p});return b.set(n,s),s}function L(a){const[r,l]=x.useState();return x.useEffect(()=>{let o=!0;return $(a).then(async n=>{o&&(await n?.install?.(),o&&l({folder:a,adapter:n}))}).catch(n=>{console.error("Could not load the configured AI input adapter.",n)}),()=>{o=!1}},[a]),r?.folder===a?r?.adapter??null:null}function N(a,r){return()=>r(!a)}function I({open:a,onOpenChange:r}){const l=a?"Hide bark input":"Open bark input";return t.jsx(j,{"aria-controls":"bark-composer","aria-expanded":a,"aria-label":l,onClick:N(a,r),title:l,type:"button",variant:"outline",children:t.jsx(g.Plus,{"aria-hidden":"true",className:"size-4"})})}function F({adapter:a,open:r,onOpenChange:l}){const o=r?"Hide bark input":"Open bark input";return t.jsxs(t.Fragment,{children:[t.jsx(j,{"aria-controls":"bark-composer","aria-expanded":r,"aria-label":o,className:"mobile-bark-toggle",onClick:N(r,l),title:o,type:"button",variant:"outline",children:t.jsx(g.Plus,{"aria-hidden":"true"})}),r?t.jsx("section",{"aria-label":"AI composer",className:"ai-input-host",id:"bark-composer",children:t.jsx(a.Composer,{})}):null]})}function H(a){return a.replace(/[\\/]+$/,"").split(/[\\/]/).at(-1)??a}function O({action:a,documentHref:r,error:l,files:o=[],folder:n,folderHref:u,loading:s}){const[d,p]=x.useState("all"),m=[...new Set(o.flatMap(e=>e.folder?[e.folder]:[]))],i=[{id:"all",label:"All",count:o.length},{id:"local",label:"This folder",count:o.filter(e=>!e.folder).length},...m.map(e=>({id:e,label:H(e),count:o.filter(h=>h.folder===e).length}))],c=i.some(e=>e.id===d)?d:"all",f=o.filter(e=>c==="all"||(c==="local"?!e.folder:e.folder===c)).sort((e,h)=>h.activityAt-e.activityAt||`${e.folder??""}/${e.relativePath}`.localeCompare(`${h.folder??""}/${h.relativePath}`));return t.jsxs("div",{className:"mx-auto grid w-full max-w-3xl gap-4 px-4 py-5",children:[t.jsxs("div",{className:"flex flex-wrap items-center justify-between gap-3",children:[t.jsx("h1",{className:"m-0 text-2xl font-semibold text-[#233025]",children:"Notes"}),a]}),m.length?t.jsx("div",{role:"group","aria-label":"Filter notes by source",className:"flex flex-wrap gap-2",children:i.map(e=>t.jsxs(j,{type:"button",size:"sm",variant:c===e.id?"secondary":"outline",className:`h-auto min-h-8 max-w-full rounded-full
|
|
2
|
-
whitespace-normal`,"aria-pressed":c===e.id,onClick:()=>p(e.id),title:e.id==="local"?n:m.includes(e.id)?e.id:void 0,children:[m.includes(e.id)?t.jsx(g.Link2,{"aria-hidden":"true"}):null,t.jsx("span",{className:"break-all",children:e.label}),t.jsx("span",{className:"text-muted-foreground",children:e.count})]},e.id))}):null,s?t.jsx("p",{className:"m-0 text-sm text-[#6c7a6d]",children:"Loading…"}):null,l?t.jsx("p",{className:"m-0 text-sm text-[#9c3a3a]",children:l}):null,!s&&!l&&!f.length?t.jsx("p",{className:"m-0 text-sm text-[#6c7a6d]",children:o.length?"No notes match this filter.":"No notes found."}):null,f.length?t.jsx("ol",{className:"m-0 grid list-none gap-2 p-0",children:f.map(e=>t.jsx("li",{children:t.jsx(P,{activityAt:e.activityAt,context:e.folder?`${e.folder.replace(/[\\/]+$/,"")}/${e.relativePath}`:n?`${n.replace(/[\\/]+$/,"")}/${e.relativePath}`:e.relativePath,folderHref:e.folder?u(e.folder):void 0,href:r(e),linkedFolder:e.folder,path:e.relativePath,title:e.name})},`${e.folder??""}:${e.relativePath}`))}):null]})}function R(){const[a,r]=x.useState(!1),l=window.location.href,o=v(l).folder,n=L(o),u=o?k(o):"none",{local:s,linked:d,files:p,retryLinked:m}=w(l);return t.jsxs(t.Fragment,{children:[t.jsx(O,{action:n?t.jsx(I,{onOpenChange:r,open:a}):void 0,documentHref:i=>{const c=i.folder??o;return c?C(c,i.relativePath):i.relativePath},error:s.error?String(s.error):"",files:p,folder:o,folderHref:i=>y(i,"notes"),loading:s.isLoading},u),s.error?t.jsx("button",{className:"px-4",onClick:()=>{s.refetch()},children:"Retry local notes"}):null,d.isLoading?t.jsx("p",{role:"status",className:"text-muted-foreground px-4 text-sm",children:"Loading linked notes…"}):null,d.error?t.jsxs("p",{role:"alert",className:"px-4 text-sm",children:["Linked notes could not load."," ",t.jsx("button",{type:"button",onClick:m,children:"Retry"})]}):null,n?t.jsx(F,{adapter:n,onOpenChange:r,open:a}):null]})}const J={...A,component:R};export{R as NotesPage,J as notesClient,w as useFolderNotes};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import{j as e,c as d}from"./react-B9jn2M18.js";import{F as A,a as B,b as W}from"./folder-plugin-view-DsWR1zmQ.js";import{m as H}from"./tanstack-YzX_Mi37.js";import{l as f,t as b,e as q}from"./view-context-gyDl_p2V.js";import{C as M,a as L,b as I,S as K,c as J,d as Q,e as X,f as Y}from"./select-D8cqNgcp.js";import{u as Z}from"./use-folder-filter-LQyXns5Q.js";import{a as v}from"./utils-DCaHk0Gm.js";import{m as ee}from"./metadata-KV0dpp4G.js";import{F as E,f as O}from"./folder-metadata-DCw8xzHk.js";import"./markdown-Bw9RgUGR.js";import"./index-CNyy98F8.js";import"./button-C6arH7zt.js";import"./command-BugZBGXE.js";import"./index-CCXE8zc9.js";import"./index-DDirZMgx.js";import"./popover-DBD7FF-W.js";import"./folder-image-BfGgxo7i.js";import"./viewer-capabilities-Bpp8Uvcg.js";import"./index-BaRnbYRw.js";import"./index-CXhBn-ar.js";import"./index-Bp9DidgD.js";import"./copy-context-C0Uqsp-3.js";const w="min-w-0 overflow-hidden rounded-lg border border-[#e7ebe7] bg-white",te="inline-flex min-h-11 shrink-0 items-center justify-center gap-2 rounded-md border border-[#d5dcd5] bg-white px-3 py-2 text-sm font-medium text-[#4a554b] transition-colors hover:bg-[#f3f5f2] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#56725e] disabled:cursor-wait disabled:opacity-60",se="inline-flex h-9 shrink-0 items-center justify-center gap-1.5 rounded-md border border-[#d5dcd5] bg-white px-2.5 text-xs font-medium text-[#4a554b] transition-colors hover:bg-[#f3f5f2] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[#56725e] disabled:cursor-wait disabled:opacity-60";function S({children:s,actions:i}){return e.jsxs("div",{className:"flex min-w-0 items-start justify-between gap-3 p-4",children:[e.jsx("div",{className:"min-w-0 flex-1 space-y-2",children:s}),i?e.jsx("div",{className:"ml-auto flex shrink-0 items-center gap-2",children:i}):null]})}function y({hostActions:s,source:i,embedded:l=!1}){const[o,u]=d.useState(!1),p=s?.openPath,a=d.useMemo(()=>i.status==="loaded"?ee(i.text):null,[i]);return e.jsxs("article",{className:l?"min-w-0":w,children:[e.jsxs(S,{actions:p?e.jsxs("button",{"aria-label":`Edit ${i.filename} in the default Markdown app`,className:te,disabled:o,title:`Edit ${i.filename} in the default Markdown app`,type:"button",onClick:()=>{u(!0),p(i.path).then(()=>{u(!1),b.success(`Opened ${i.filename}`)},n=>{u(!1),b.error(n instanceof Error?n.message:`Could not open ${i.filename}`)})},children:[o?e.jsx(f.LoaderCircle,{"aria-hidden":"true",className:"size-3.5 animate-spin"}):e.jsx(f.Pencil,{"aria-hidden":"true",className:"size-3.5"}),"Edit"]}):null,children:[e.jsx(E,{className:"max-w-full",path:i.directory,icon:e.jsx(A,{folder:i.directory})}),e.jsxs("div",{className:"flex min-w-0 flex-wrap items-center gap-2",children:[e.jsx("h4",{className:"m-0 text-sm font-semibold break-words text-[#2f382f]",children:i.filename}),i.override?e.jsx("span",{className:"rounded bg-[#f3f5f2] px-2 py-1 text-xs text-[#4a554b]",children:"override"}):null]})]}),e.jsx("div",{className:"min-w-0 overflow-x-auto px-4 pb-4 break-words",children:i.status==="loaded"?i.text.trim()&&a?e.jsxs(e.Fragment,{children:[a.entries.length?e.jsxs("details",{className:`mb-4 rounded-lg border border-[#e7ebe7]
|
|
2
|
-
bg-[#fafbfa] px-3 py-2`,children:[e.jsxs("summary",{className:`cursor-pointer text-sm font-semibold
|
|
3
|
-
text-[#435447]`,children:["Document details (",a.entries.length,")"]}),e.jsx("dl",{className:"mt-3 grid gap-2 text-sm",children:a.entries.map(([n,r])=>e.jsxs("div",{className:`grid grid-cols-[120px_1fr] gap-3
|
|
4
|
-
max-[767px]:grid-cols-1`,children:[e.jsx("dt",{className:"font-semibold text-[#5a6b5c] capitalize",children:n.replaceAll(/[-_]/g," ")}),e.jsx("dd",{className:"m-0 text-[#2f382f]",children:Array.isArray(r)?r.map(String).join(", "):typeof r=="object"&&r?JSON.stringify(r):String(r??"")})]},n))})]}):null,a.body.trim()?e.jsx("div",{className:`prose prose-neutral max-w-none
|
|
5
|
-
[&>:first-child]:mt-0 [&>:last-child]:mb-0`,children:e.jsx(q,{value:a.body})}):null]}):e.jsx("p",{className:"m-0 mt-2 text-[0.8rem] text-[#6c7a6d]",children:"(empty file)"}):e.jsx("p",{className:"m-0 mt-2 text-[0.8rem] text-[#9c3a3a]",children:i.reason??"Could not read this file"})})]})}function U({folder:s,createAction:i,onCreated:l}){const[o,u]=d.useState(!1);if(!i)return null;const p=async()=>{u(!0);try{const a=await i(s),n=a&&typeof a=="object"&&"path"in a&&typeof a.path=="string"?a.path:null;b.success(n?`Created ${O(n)} — edit it to add instructions`:"AGENTS.md created"),l()}catch(a){b.error(a instanceof Error?a.message:"Could not create AGENTS.md")}finally{u(!1)}};return e.jsxs("button",{className:se,title:`Create an empty AGENTS.md in ${s}`,disabled:o,type:"button",onClick:()=>{p()},children:[o?e.jsx(f.LoaderCircle,{"aria-hidden":"true",className:"size-3.5 animate-spin"}):e.jsx(f.FilePlus2,{"aria-hidden":"true",className:"size-3.5"}),"Create"]})}function ie({folder:s,hasOwn:i,createAction:l,onCreated:o}){return e.jsx(S,{actions:i?void 0:e.jsx(U,{createAction:l,folder:s,onCreated:o}),children:e.jsx("div",{className:"flex min-w-0 flex-wrap items-center gap-2",children:e.jsx(E,{className:"max-w-full",path:s,icon:e.jsx(A,{folder:s})})})})}function le({entry:s,createAction:i,onCreated:l}){const o=s.filenames.length>0;return e.jsx(S,{actions:o?void 0:e.jsx(U,{createAction:i,folder:s.directory,onCreated:l}),children:e.jsx("div",{className:"flex min-w-0 flex-wrap items-center gap-2",children:e.jsx(E,{className:"max-w-full",icon:e.jsx(A,{folder:s.directory}),name:O(s.directory)||"Filesystem root",path:s.directory})})})}const $={generic:{id:"generic",label:"Generic",scope:"root",files:["AGENTS.md"],filesMode:"first",globalDir:".agents",globalFiles:["AGENTS.md"],globalMode:"first",verified:!1,note:"Reference view of the ancestor AGENTS.md chain. No client execution behavior is claimed.",limits:"Walks to the filesystem root like Stepladder; only AGENTS.md files are read."},codex:{id:"codex",label:"Codex",scope:"git",files:["AGENTS.override.md","AGENTS.md"],filesMode:"first",globalDir:".codex",globalEnv:"CODEX_HOME",globalFiles:["AGENTS.override.md","AGENTS.md"],globalMode:"first",verified:!0,note:"Verified from the Codex 0.154.0 binary: reads the repository root plus every directory from the CWD up to the root, and prefers AGENTS.override.md over AGENTS.md per directory.",limits:"A configured model_instructions_file fallback is not applied here; a warning appears when it is configured."},claude:{id:"claude",label:"Claude Code",scope:"root",files:["CLAUDE.md",".claude/CLAUDE.md","CLAUDE.local.md"],filesMode:"all",globalDir:".claude",globalFiles:["CLAUDE.md"],globalMode:"first",verified:!0,note:"Verified from the Claude Code 2.1.274 binary: loads ~/.claude/CLAUDE.md and, walking to the filesystem root, each ancestor's CLAUDE.md, .claude/CLAUDE.md, and CLAUDE.local.md.",limits:"Conditional .claude/rules/*.md files and @path imports are not expanded here."},pi:{id:"pi",label:"Pi",scope:"root",files:["AGENTS.override.md","AGENTS.md","AGENTS.MD","CLAUDE.md","CLAUDE.MD"],filesMode:"first",globalDir:".pi/agent",globalEnv:"PI_CODING_AGENT_DIR",globalFiles:["AGENTS.override.md","AGENTS.md","AGENTS.MD","CLAUDE.md","CLAUDE.MD"],globalMode:"first",verified:!0,note:"Verified from the Pi 0.85.1 source (resource-loader.js): first match wins from AGENTS.override.md, AGENTS.md, AGENTS.MD, CLAUDE.md, CLAUDE.MD, in each ancestor directory and in the global directory.",limits:"Uses the same candidate list for the global directory."}},ae=[{id:"generic",label:"Generic"},{id:"codex",label:"Codex"},{id:"claude",label:"Claude Code"},{id:"pi",label:"Pi"}];function re(s){return $[s].label}function ne(s){return s==="generic"||s==="codex"||s==="claude"||s==="pi"?s:"pi"}function oe({client:s,href:i}){return e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("label",{className:`text-[0.78rem] font-medium tracking-wide text-[#6c7a6d]
|
|
6
|
-
uppercase`,children:"AI client"}),e.jsxs(K,{onValueChange:l=>{window.location.href=i(l)},value:s,children:[e.jsx(J,{"aria-label":"AI client",size:"sm",className:"w-44",children:e.jsx(Q,{placeholder:"Select client"})}),e.jsx(X,{children:ae.map(l=>e.jsx(Y,{value:l.id,children:l.label},l.id))})]})]})}function de({folder:s,folderId:i,hostActions:l,href:o,request:u,subpath:p}){const a=ne(p||null),n=d.useRef(!1),r=H.useQuery({enabled:!!s,gcTime:5*6e4,queryFn:({signal:t})=>{const x=n.current?{"x-kennel-retry-linked":"1"}:void 0;return n.current=!1,u(p,{signal:t,headers:x})},queryKey:["folder",i,"agents",p??""],staleTime:15e3,refetchInterval:t=>t.state.data?.linkedStatus==="pending"?1e3:!1}),c=r.data,k=d.useMemo(()=>c?.sources??[],[c]),j=d.useMemo(()=>c?.warnings??[],[c]),m=Z(k,{allowOutside:!0,getFolder:t=>t.directory,rootFolder:s}),D=$[a],[h,P]=d.useState(!1),[g,z]=d.useState(!1),R=c?.folder??s,_=k.some(t=>t.level==="project"),T=d.useMemo(()=>(c?.chain??[]).slice(1),[c]),N=d.useMemo(()=>m.visibleItems.filter(t=>t.level==="project"),[m.visibleItems]),G=d.useMemo(()=>m.visibleItems.filter(t=>t.level==="global"),[m.visibleItems]),V=t=>m.visibleItems.filter(x=>x.directory===t),C=t=>`${t.id}:${t.clientIds.join(",")}`;return e.jsxs("div",{className:`mx-auto grid w-full max-w-5xl min-w-0 grid-cols-1 gap-4 px-4
|
|
7
|
-
py-5`,children:[e.jsxs(M,{onOpenChange:P,open:h,children:[e.jsxs("header",{className:"flex flex-wrap items-center justify-between gap-3",children:[e.jsx("h1",{className:"m-0 text-2xl font-semibold text-[#233025]",children:"Agents"}),e.jsx(L,{asChild:!0,children:e.jsxs("button",{"aria-expanded":h,"aria-label":h?"Hide client details":"Show client details",className:`inline-flex items-center gap-1.5 rounded-md border
|
|
8
|
-
border-[#e7ebe7] bg-white px-2.5 py-1 text-[0.78rem] font-medium
|
|
9
|
-
text-[#4a554b] hover:bg-[#f3f5f2] focus-visible:outline-2
|
|
10
|
-
focus-visible:outline-[#56725e]`,type:"button",children:[e.jsx(f.Info,{className:"size-4 text-[#6c7a6d]"}),"Details",e.jsx(f.ChevronDown,{className:v("size-3.5 text-[#6c7a6d] transition-transform",h&&"rotate-180")})]})})]}),e.jsx(I,{className:`data-[state=closed]:animate-out
|
|
11
|
-
data-[state=open]:animate-in`,children:e.jsxs("p",{className:`m-0 mt-3 flex items-start gap-2 text-[0.72rem]
|
|
12
|
-
text-[#6c7a6d]`,children:[e.jsx(f.TriangleAlert,{className:"mt-0.5 size-3.5 shrink-0"}),e.jsxs("span",{children:[D.note," ",D.limits]})]})})]}),e.jsxs("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-2",children:[e.jsx(oe,{client:a,href:o}),m.choices.length>1?e.jsx(B,{ariaLabel:"Filter by instruction folder",choices:m.choices,onSelect:m.setSelected,selected:m.effectiveSelected,total:m.total}):null]}),c?e.jsxs("section",{className:w,"aria-label":"Current folder instructions",children:[N.length?null:e.jsx(ie,{createAction:l?.createAgentFile,folder:R,hasOwn:_,onCreated:()=>{r.refetch()}}),N.length?e.jsx("div",{className:"grid grid-cols-1",children:N.map(t=>e.jsx(y,{hostActions:l,source:t,embedded:!0},C(t)))}):null]}):null,c?.linkedStatus==="pending"?e.jsx("p",{role:"status",className:"m-0 text-sm text-[#6c7a6d]",children:"Local instructions loaded. Looking for linked project instructions…"}):null,c?.linkedStatus==="error"?e.jsxs("p",{role:"status",className:"m-0 text-sm text-[#9c3a3a]",children:["Linked project discovery is unavailable. Local instructions are shown.",e.jsx("button",{onClick:()=>{n.current=!0,r.refetch()},children:"Retry linked instructions"})]}):null,r.isPending?e.jsx("p",{className:"m-0 text-sm text-[#6c7a6d]",children:"Loading…"}):null,r.error?e.jsxs("p",{role:"alert",className:"m-0 text-sm text-[#9c3a3a]",children:[String(r.error)," ",e.jsx("button",{onClick:()=>{r.refetch()},children:"Retry instructions"})]}):null,j.length?e.jsxs(M,{onOpenChange:z,open:g,children:[e.jsx(L,{asChild:!0,children:e.jsxs("button",{"aria-expanded":g,"aria-label":g?"Hide warnings":"Show warnings",className:`inline-flex items-center gap-1.5 rounded-md border
|
|
13
|
-
border-[#e7ebe7] bg-white px-2.5 py-1 text-[0.78rem] font-medium
|
|
14
|
-
text-[#4a554b] hover:bg-[#f3f5f2] focus-visible:outline-2
|
|
15
|
-
focus-visible:outline-[#56725e]`,type:"button",children:[e.jsx(f.TriangleAlert,{className:"size-4 text-[#6c7a6d]"}),"Warnings",e.jsx("span",{className:`rounded-full bg-[#f3f5f2] px-1.5 py-0.5
|
|
16
|
-
text-[0.68rem] text-[#6c7a6d]`,children:j.length}),e.jsx(f.ChevronDown,{className:v("size-3.5 text-[#6c7a6d] transition-transform",g&&"rotate-180")})]})}),e.jsx(I,{className:`data-[state=closed]:animate-out
|
|
17
|
-
data-[state=open]:animate-in`,children:e.jsx("ul",{className:"m-0 mt-3 list-none space-y-1 p-0",children:j.map(t=>e.jsxs("li",{className:"text-[0.72rem] text-[#6c7a6d]",children:["path"in t?`${t.path} — `:"",t.reason," (",t.clientIds.map(x=>re(x)).join(", "),")"]},`${t.kind}:${"path"in t?t.path:""}:${t.clientIds.join(",")}`))})})]}):null,T.length?e.jsx("div",{className:"grid grid-cols-1 gap-4",children:T.map(t=>{const x=V(t.directory);return e.jsxs("section",{className:v(w,"scroll-mt-6"),"aria-label":`Instructions for ${t.directory}`,id:`agents-folder-${t.directory}`,children:[x.length?null:e.jsx(le,{createAction:l?.createAgentFile,entry:t,onCreated:()=>{r.refetch()}}),x.length?e.jsx("div",{className:"grid grid-cols-1",children:x.map(F=>e.jsx(y,{hostActions:l,source:F,embedded:!0},C(F)))}):null]},t.directory)})}):null,G.length?e.jsxs("section",{className:"scroll-mt-6",children:[e.jsxs("div",{className:"flex items-baseline gap-2",children:[e.jsx("h3",{className:"m-0 text-[0.82rem] font-semibold",style:{color:"#315c3b"},children:"Global instructions"}),e.jsx("span",{className:"text-[0.7rem] text-[#6c7a6d]",children:"Global"})]}),e.jsx("div",{className:"mt-1 grid grid-cols-1 gap-3",children:G.map(t=>e.jsx(y,{hostActions:l,source:t},C(t)))})]}):null]})}function ce(s){return e.jsx(de,{...s})}const Me={...W,component:ce};export{ce as AgentsPlugin,Me as agentsClient};
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import{j as t}from"./react-B9jn2M18.js";import{F as f,p as h}from"./folder-plugin-view-DsWR1zmQ.js";import{m as j}from"./tanstack-YzX_Mi37.js";import{C as m}from"./copy-context-C0Uqsp-3.js";import{l as g}from"./view-context-gyDl_p2V.js";import{a as x}from"./index-CNyy98F8.js";import{B as y}from"./button-C6arH7zt.js";import{a}from"./utils-DCaHk0Gm.js";import{F as w}from"./folder-metadata-DCw8xzHk.js";import"./markdown-Bw9RgUGR.js";import"./command-BugZBGXE.js";import"./index-CCXE8zc9.js";import"./index-DDirZMgx.js";import"./popover-DBD7FF-W.js";import"./folder-image-BfGgxo7i.js";import"./viewer-capabilities-Bpp8Uvcg.js";const l=["dependency","implementation","notes","related"];function b(r){if(typeof r!="object"||r===null)throw new Error("connected project entry must be an object");const e=r;if(typeof e.worktree!="string"||!e.worktree.trim())throw new Error("connected project entry needs a worktree path");if(!l.includes(e.type))throw new Error(`connected project type must be one of ${l.join(", ")}; got ${String(e.type)||"nothing"}`);if(e.direction!=="incoming"&&e.direction!=="outgoing")throw new Error(`connected project direction must be "incoming" or "outgoing"; got ${String(e.direction)||"nothing"}`);if(typeof e.depth!="number"||e.depth<1)throw new Error("connected project depth must be a positive number");return{repository:typeof e.repository=="string"&&e.repository.trim()?e.repository:void 0,type:e.type,direction:e.direction,depth:e.depth,worktree:e.worktree}}function N(r){if(typeof r!="object"||r===null)throw new Error("Project data is not valid.");const e=r;if(typeof e.folder!="string"||!e.folder.trim())throw new Error("Project data needs a folder path");if(e.status!=="available"&&e.status!=="error")throw new Error("Project data status must be available or error");if(!Array.isArray(e.projects))throw new Error("Project data needs a projects array");return{folder:e.folder,projects:e.projects.map(b),status:e.status,message:typeof e.message=="string"&&e.message.trim()?e.message:void 0}}function P(r,e){return["The Kennel Projects view for this folder failed. Use the context below to","diagnose the cause, then re-check the Projects tab.","","Instructions for the LLM:","- The Projects view runs Raggle Scout connected-project discovery"," (`@raggle-ai/local` listConnectedProjects) in a child process and"," renders one card per relation.",`- Folder: ${r}`,"","Failure:",e].join(`
|
|
2
|
-
`)}function v({className:r,...e}){return t.jsx("div",{"data-slot":"card",className:a(`bg-card text-card-foreground flex flex-col gap-6 rounded-xl border py-6
|
|
3
|
-
shadow-sm`,r),...e})}function C({className:r,...e}){return t.jsx("div",{"data-slot":"card-header",className:a(`@container/card-header grid auto-rows-min grid-rows-[auto_auto]
|
|
4
|
-
items-start gap-2 px-6 has-data-[slot=card-action]:grid-cols-[1fr_auto]
|
|
5
|
-
[.border-b]:pb-6`,r),...e})}function E({className:r,...e}){return t.jsx("div",{"data-slot":"card-title",className:a("leading-none font-semibold",r),...e})}function k({className:r,...e}){return t.jsx("div",{"data-slot":"card-action",className:a("col-start-2 row-span-2 row-start-1 self-start justify-self-end",r),...e})}function F({project:r}){const i=`/folder/${x(r.worktree)}/notes`;return t.jsx("article",{className:"min-w-0",children:t.jsx(v,{className:"h-full min-h-48 py-5",children:t.jsxs(C,{className:"min-w-0 gap-1.5",children:[t.jsx(E,{className:"min-w-0 break-words",children:t.jsx(w,{href:i,icon:t.jsx(f,{folder:r.worktree}),path:r.worktree,size:"large"})}),t.jsxs(k,{className:"flex items-center gap-1",children:[r.repository?t.jsx(y,{asChild:!0,size:"icon-sm",variant:"ghost",children:t.jsx("a",{"aria-label":"Open Git repository",href:r.repository,rel:"noreferrer",target:"_blank",title:"Open Git repository",children:t.jsx(g.Link,{className:"size-4"})})}):null,t.jsx(m,{context:r.worktree,label:"Copy folder path",size:"icon-sm"})]})]})})})}function I(r){const{folder:e,folderId:i,request:p,subpath:d}=r,o=j.useQuery({queryKey:["folder",i,"projects",d],queryFn:({signal:s})=>p(d,{signal:s}),staleTime:3e4}),n=o.data?(()=>{try{return N(o.data)}catch(s){return{folder:e,message:s instanceof Error&&s.message?s.message:"Could not parse the projects payload.",projects:[],status:"error"}}})():void 0,c=(o.error instanceof Error&&o.error.message?o.error.message:void 0)??(n?.status==="error"?n.message:void 0)??void 0,u=!o.error&&!n&&o.isPending;return t.jsx("main",{className:"min-h-full bg-transparent text-slate-950",children:t.jsxs("section",{className:`mx-auto grid w-full max-w-5xl min-w-0 grid-cols-1 gap-4 px-4
|
|
6
|
-
py-5`,children:[t.jsx("h2",{className:"m-0 text-lg font-semibold",children:"Connected projects"}),u?t.jsx("p",{className:"text-muted-foreground m-0 text-sm",children:"Loading connected projects…"}):null,c?t.jsxs("div",{className:`rounded-lg border border-red-200 bg-red-50 px-3 py-2
|
|
7
|
-
text-sm text-red-700`,children:[t.jsx("p",{className:"m-0",role:"alert",children:c}),t.jsx("button",{className:"mt-2 underline underline-offset-2",onClick:()=>{o.refetch()},type:"button",children:"Retry"}),t.jsx(m,{className:"mt-2",context:()=>P(e,c),label:"Copy full context for the Projects failure"})]}):null,n?.status==="available"?n.projects.length?t.jsx("div",{className:"grid min-w-0 grid-cols-1 gap-4",children:n.projects.map(s=>t.jsx(F,{project:s},s.worktree))}):t.jsx("p",{className:"text-muted-foreground m-0 text-sm",children:"No connected projects found."}):null]})})}function L(r){return t.jsx(I,{...r})}const D={...h,component:L};export{L as ProjectsPlugin,D as projectsClient};
|