kennel 0.2.11 → 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 +22 -20
- 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/markdown-copy-block.tsx +78 -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/lib/source-components.tsx +12 -6
- package/kernel/packages/ui/src/styles/folder-activity.css +1 -31
- package/package.json +2 -2
- package/web/assets/{abnfDiagram-VRR7QNED-CSaxgLw6.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-Cpx74SQs.js → app-view-header-BJ9CWTE1.js} +1 -1
- package/web/assets/{arc-DOrTJz--.js → arc-PFB0H7oD.js} +1 -1
- package/web/assets/{architectureDiagram-ZJ3FMSHR-EjOjwlGK.js → architectureDiagram-ZJ3FMSHR-BHLqEXlZ.js} +1 -1
- package/web/assets/{ask-tray-DLEoRbpV.js → ask-tray-C3gBesHJ.js} +1 -1
- package/web/assets/{blockDiagram-677ZJIJ3-Dg2LWLOW.js → blockDiagram-677ZJIJ3-UbnYoYDg.js} +1 -1
- package/web/assets/{button-C6arH7zt.js → button-CuuAtS1I.js} +1 -1
- package/web/assets/{c4Diagram-LMCZKHZV-CWHqGPk8.js → c4Diagram-LMCZKHZV-4OSx1V4W.js} +1 -1
- package/web/assets/channel-BuvY5cQN.js +1 -0
- package/web/assets/{chunk-2Q5K7J3B-Dzz0QWV_.js → chunk-2Q5K7J3B-CgxJ1aJb.js} +1 -1
- package/web/assets/{chunk-32BRIVSS-BocStooX.js → chunk-32BRIVSS-Bfwxg2LM.js} +1 -1
- package/web/assets/{chunk-5VM5RSS4-D8BF5Y5h.js → chunk-5VM5RSS4-BZN9a2hI.js} +1 -1
- package/web/assets/{chunk-EX3LRPZG-CWMl9KkL.js → chunk-EX3LRPZG-CrH6hhqq.js} +1 -1
- package/web/assets/{chunk-JWPE2WC7-BZEr7iFk.js → chunk-JWPE2WC7-Ddn7ZSp8.js} +1 -1
- package/web/assets/{chunk-MOJQB5TN-DbKnLJ33.js → chunk-MOJQB5TN-9lJ7f_hI.js} +1 -1
- package/web/assets/{chunk-RYQCIY6F-BF9KWoi2.js → chunk-RYQCIY6F-QrFo_00s.js} +1 -1
- package/web/assets/{chunk-V7JOEXUC-e88zamUH.js → chunk-V7JOEXUC-Dn0lQjVf.js} +1 -1
- package/web/assets/{chunk-VR4S4FIN-NDHM58HJ.js → chunk-VR4S4FIN-DXVPySkB.js} +1 -1
- package/web/assets/{chunk-XXDRQBXY-BtzSzNoD.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-BWtewOrt.js → command-onjTnuXT.js} +1 -1
- package/web/assets/{copy-context-YESgZ_hu.js → copy-context-CciRaLNN.js} +1 -1
- package/web/assets/{cose-bilkent-JH36ORCC-i7x8jZ9M.js → cose-bilkent-JH36ORCC-CGRic2um.js} +1 -1
- package/web/assets/{cynefin-VYW2F7L2-D8HPrHMt.js → cynefin-VYW2F7L2-Blk0Lu0l.js} +1 -1
- package/web/assets/{cynefinDiagram-TSTJHNR4-BtkeCNXb.js → cynefinDiagram-TSTJHNR4-DpnnHRDK.js} +1 -1
- package/web/assets/{dagre-VKFMJZFB-oIThwshO.js → dagre-VKFMJZFB-llzMokKp.js} +1 -1
- package/web/assets/{diagram-FQU43EPY-DTuhEo03.js → diagram-FQU43EPY-DC6xHovR.js} +1 -1
- package/web/assets/{diagram-G47NLZAW-BcQ_4_fE.js → diagram-G47NLZAW-B8GVS3EA.js} +1 -1
- package/web/assets/{diagram-NH7WQ7WH-BA4VC8Du.js → diagram-NH7WQ7WH-DWUaARfh.js} +1 -1
- package/web/assets/{diagram-OA4YK3LP-BOpyrmty.js → diagram-OA4YK3LP-9Uaes_Yi.js} +1 -1
- package/web/assets/{diagram-WEI45ONY-BzrSPDJ7.js → diagram-WEI45ONY-DPPTBWud.js} +1 -1
- package/web/assets/document-D23WzFsW.js +23 -0
- package/web/assets/{ebnfDiagram-CCIWWBDH-BNV_4xDp.js → ebnfDiagram-CCIWWBDH-BPrKneNw.js} +1 -1
- package/web/assets/{entities-D0qpC3B9.js → entities-DPg0B8vd.js} +1 -1
- package/web/assets/{erDiagram-Q63AITRT-NT1La9pi.js → erDiagram-Q63AITRT-CFqYBcnb.js} +1 -1
- package/web/assets/{file-viewer-C1N6vaip.js → file-viewer-Ck73SsLA.js} +1 -1
- package/web/assets/{flowDiagram-23GEKE2U-CIYWUYkz.js → flowDiagram-23GEKE2U-C7RpYqaT.js} +1 -1
- package/web/assets/folder-filter-bar-DzejUj87.js +4 -0
- package/web/assets/{folder-image-Bz0xznQT.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-DeUfoXQA.js → ganttDiagram-NO4QXBWP-Cz2sxU8F.js} +1 -1
- package/web/assets/{gitGraphDiagram-IHSO6WYX-DMeTgUPh.js → gitGraphDiagram-IHSO6WYX-BSuz0yF-.js} +1 -1
- package/web/assets/{index-CCXE8zc9.js → index-BVyeNcuc.js} +1 -1
- package/web/assets/{index-CegvVQ1C.js → index-Cg-gtBkw.js} +1 -1
- package/web/assets/index-DLn_2LPp.js +2 -0
- package/web/assets/{index-DY0VGBht.js → index-DbVDdnzL.js} +1 -1
- package/web/assets/index-uY9jLiL5.css +1 -0
- package/web/assets/{infoDiagram-FWYZ7A6U-DI_P8Ghi.js → infoDiagram-FWYZ7A6U-CpeKgqoS.js} +1 -1
- package/web/assets/input-Bz_puamS.js +9 -0
- package/web/assets/{ishikawaDiagram-FXEZZL3T-B8bM-8CD.js → ishikawaDiagram-FXEZZL3T-5c2Tmknb.js} +1 -1
- package/web/assets/{journeyDiagram-5HDEW3XC-pviYejXU.js → journeyDiagram-5HDEW3XC-Cu-wRkR4.js} +1 -1
- package/web/assets/{kanban-definition-HUTT4EX6-DfvdDvpU.js → kanban-definition-HUTT4EX6-BunSqkPe.js} +1 -1
- package/web/assets/{linear-DNOuKTk_.js → linear-C8e8bGVv.js} +1 -1
- package/web/assets/{mermaid.core-CisVJ_Cs.js → mermaid.core-DLgjY1g2.js} +4 -4
- package/web/assets/{metadata-C7E_6HIN.js → metadata-DEfJKlnd.js} +1 -1
- package/web/assets/{mindmap-definition-LN4V7U3C-DzdcaduN.js → mindmap-definition-LN4V7U3C-W9ENYFOD.js} +1 -1
- package/web/assets/{pegDiagram-2B236MQR-D_7xhlXd.js → pegDiagram-2B236MQR-0vPlHCFp.js} +1 -1
- package/web/assets/{pieDiagram-ENE6RG2P-CisikHMW.js → pieDiagram-ENE6RG2P-CakaveRV.js} +1 -1
- package/web/assets/{popover-D7MTK-sz.js → popover-3AMcPJpt.js} +1 -1
- package/web/assets/{project-search-dialog-BsHc39D0.js → project-search-dialog-BSKA4peX.js} +1 -1
- package/web/assets/{quadrantDiagram-ABIIQ3AL-D6adg-7z.js → quadrantDiagram-ABIIQ3AL-jxHw_egj.js} +1 -1
- package/web/assets/{railroadDiagram-RFXS5EU6-CyPAHeJ-.js → railroadDiagram-RFXS5EU6-lIjDXPZt.js} +1 -1
- package/web/assets/{requirementDiagram-TGXJPOKE-CgpSiPTv.js → requirementDiagram-TGXJPOKE-C-JiT4bc.js} +1 -1
- package/web/assets/{sankeyDiagram-HTMAVEWB-BxvReW6S.js → sankeyDiagram-HTMAVEWB-SuLPAw9X.js} +1 -1
- package/web/assets/{search-DEgwpq-P.js → search-CKujW14f.js} +1 -1
- package/web/assets/{selection-popup-d94JnDPy.js → selection-popup-CtxT9SWn.js} +3 -3
- package/web/assets/{sequenceDiagram-DBY2YBRQ-uuplzETI.js → sequenceDiagram-DBY2YBRQ-o9UwTkZR.js} +1 -1
- package/web/assets/{sizeCapture-X5ZJPWSS-Bi3F7nOa.js → sizeCapture-X5ZJPWSS-ClbWGybF.js} +1 -1
- package/web/assets/{stateDiagram-2N3HPSRC-DqypF7lE.js → stateDiagram-2N3HPSRC-Ce4avoWx.js} +1 -1
- package/web/assets/stateDiagram-v2-6OUMAXLB-CsrPTZoJ.js +1 -0
- package/web/assets/{swimlanes-5IMT3BWC-CGD9YT1l.js → swimlanes-5IMT3BWC-DMZI4XZT.js} +2 -2
- package/web/assets/swimlanesDiagram-G3AALYLV-pShSVcTd.js +8 -0
- package/web/assets/{timeline-definition-FHXFAJF6-DCjNS9Ol.js → timeline-definition-FHXFAJF6-CPIpIgPN.js} +1 -1
- package/web/assets/{utils-DCaHk0Gm.js → utils-Cg80pk1W.js} +1 -1
- package/web/assets/{vennDiagram-L72KCM5P-BJ58yQgD.js → vennDiagram-L72KCM5P-_rha8uDZ.js} +1 -1
- package/web/assets/view-context-BDtIUHQy.js +229 -0
- package/web/assets/{viewer-capabilities-DCuJdf64.js → viewer-capabilities-YYZqMs56.js} +1 -1
- package/web/assets/{wardleyDiagram-EHGQE667-BiLuq9mr.js → wardleyDiagram-EHGQE667-D4EAOS35.js} +1 -1
- package/web/assets/{xychartDiagram-FW5EYKEG-DzAZpIRG.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-DoXXGPMx.js +0 -2
- package/web/assets/app-options-jTBHy0A7.js +0 -25
- package/web/assets/channel-54w4vQjC.js +0 -1
- package/web/assets/classDiagram-OUVF2IWQ-Bh9Ib2pw.js +0 -1
- package/web/assets/classDiagram-v2-EOCWNBFH-Bh9Ib2pw.js +0 -1
- package/web/assets/client-BgUDusrU.js +0 -5
- package/web/assets/client-COaHUqSC.js +0 -17
- package/web/assets/client-UC06V2VL.js +0 -22
- package/web/assets/document-BDtU3CbX.js +0 -19
- package/web/assets/folder-filter-bar-C_2Mobfq.js +0 -4
- package/web/assets/folder-landing-3gqbGaYS.js +0 -54
- package/web/assets/folder-list-DDI0TF2e.js +0 -1
- package/web/assets/folder-metadata-DjV3ZUra.js +0 -2
- package/web/assets/folder-mobile-bar-CF4CpJXL.js +0 -1
- package/web/assets/folder-plugin-view-C48J0HKe.js +0 -3
- package/web/assets/index-Bp9DidgD.js +0 -1
- package/web/assets/index-CXhBn-ar.js +0 -1
- package/web/assets/index-CtuOSBHa.js +0 -2
- package/web/assets/index-Dwhf8F_U.css +0 -1
- package/web/assets/select-DGaccqVB.js +0 -30
- package/web/assets/stateDiagram-v2-6OUMAXLB-EsEb0a5Q.js +0 -1
- package/web/assets/swimlanesDiagram-G3AALYLV-DKIYuN5l.js +0 -8
- package/web/assets/use-folder-filter-hA6fa7nm.js +0 -1
- package/web/assets/view-context-BrzQ7WBV.js +0 -229
package/dist/package/preview.js
CHANGED
|
@@ -5530,7 +5530,7 @@ var init_src = __esm(() => {
|
|
|
5530
5530
|
});
|
|
5531
5531
|
|
|
5532
5532
|
// packages/api/src/contracts/schemas.ts
|
|
5533
|
-
var items = (item) => object({ items: array(item) }), icon, file, project,
|
|
5533
|
+
var items = (item) => object({ items: array(item) }), icon, file, project, session, collectionSummary2, workspace, plugin, plugins, folder, assets, folderMetadataSchema, collection, metadataSchemas, metadataQuerySchema, documentEditSchema, document2, documentSchema, entity, projectSearchItemSchema, pathQuery, emptyQuery, routes;
|
|
5534
5534
|
var init_schemas3 = __esm(() => {
|
|
5535
5535
|
init_src();
|
|
5536
5536
|
init_zod();
|
|
@@ -5555,13 +5555,6 @@ var init_schemas3 = __esm(() => {
|
|
|
5555
5555
|
relativePath: string2(),
|
|
5556
5556
|
worktree: string2()
|
|
5557
5557
|
});
|
|
5558
|
-
skill = object({
|
|
5559
|
-
description: string2().optional(),
|
|
5560
|
-
name: string2(),
|
|
5561
|
-
openHref: string2().optional(),
|
|
5562
|
-
relativePath: string2(),
|
|
5563
|
-
source: _enum(["global", "local"])
|
|
5564
|
-
});
|
|
5565
5558
|
session = object({
|
|
5566
5559
|
client: _enum(["claude", "codex", "cursor", "opencode", "pi"]),
|
|
5567
5560
|
href: string2().optional(),
|
|
@@ -5589,6 +5582,7 @@ var init_schemas3 = __esm(() => {
|
|
|
5589
5582
|
plugin = object({
|
|
5590
5583
|
count: number2().optional(),
|
|
5591
5584
|
error: string2().optional(),
|
|
5585
|
+
icon: object({ paths: array(string2().min(1)).min(1) }).optional(),
|
|
5592
5586
|
id: string2(),
|
|
5593
5587
|
label: string2()
|
|
5594
5588
|
});
|
|
@@ -5606,7 +5600,6 @@ var init_schemas3 = __esm(() => {
|
|
|
5606
5600
|
plugins: plugins.optional(),
|
|
5607
5601
|
projects: items(project),
|
|
5608
5602
|
sessions: items(session),
|
|
5609
|
-
skills: items(skill).optional(),
|
|
5610
5603
|
workspace: workspace.optional()
|
|
5611
5604
|
});
|
|
5612
5605
|
collection = coreCollectionSchema;
|
|
@@ -5630,7 +5623,6 @@ var init_schemas3 = __esm(() => {
|
|
|
5630
5623
|
configWarnings: array(string2()).optional(),
|
|
5631
5624
|
plugins: plugins.optional()
|
|
5632
5625
|
}),
|
|
5633
|
-
skills: object({ ...folder, skills: items(skill) }),
|
|
5634
5626
|
sessions: folderMetadataSchema,
|
|
5635
5627
|
calendar: folderMetadataSchema,
|
|
5636
5628
|
schema: folderMetadataSchema
|
|
@@ -5811,7 +5803,7 @@ function url2(value) {
|
|
|
5811
5803
|
function tabSection(tab) {
|
|
5812
5804
|
if (tab === "files")
|
|
5813
5805
|
return "notes";
|
|
5814
|
-
if (tab === "projects" || tab === "sessions"
|
|
5806
|
+
if (tab === "projects" || tab === "sessions")
|
|
5815
5807
|
return tab;
|
|
5816
5808
|
return;
|
|
5817
5809
|
}
|
|
@@ -5862,7 +5854,7 @@ function parseViewerRoute(value) {
|
|
|
5862
5854
|
}
|
|
5863
5855
|
};
|
|
5864
5856
|
}
|
|
5865
|
-
if (section === "notes" || section === "projects" || section === "sessions"
|
|
5857
|
+
if (section === "notes" || section === "projects" || section === "sessions") {
|
|
5866
5858
|
return { ...route, section };
|
|
5867
5859
|
}
|
|
5868
5860
|
if (section === "document" && parts[3]) {
|
|
@@ -84308,546 +84300,25 @@ var init_folder_icons = __esm(() => {
|
|
|
84308
84300
|
]);
|
|
84309
84301
|
});
|
|
84310
84302
|
|
|
84311
|
-
// packages/agents/src/manifest.ts
|
|
84312
|
-
var agentsManifest;
|
|
84313
|
-
var init_manifest2 = __esm(() => {
|
|
84314
|
-
agentsManifest = {
|
|
84315
|
-
id: "agents",
|
|
84316
|
-
label: "Agents"
|
|
84317
|
-
};
|
|
84318
|
-
});
|
|
84319
|
-
|
|
84320
|
-
// packages/agents/src/profiles.ts
|
|
84321
|
-
function parseClientFilter(value) {
|
|
84322
|
-
if (value === "generic" || value === "codex" || value === "claude" || value === "pi") {
|
|
84323
|
-
return value;
|
|
84324
|
-
}
|
|
84325
|
-
return "pi";
|
|
84326
|
-
}
|
|
84327
|
-
var CLIENT_ORDER, PROFILES;
|
|
84328
|
-
var init_profiles = __esm(() => {
|
|
84329
|
-
CLIENT_ORDER = [
|
|
84330
|
-
"generic",
|
|
84331
|
-
"codex",
|
|
84332
|
-
"claude",
|
|
84333
|
-
"pi"
|
|
84334
|
-
];
|
|
84335
|
-
PROFILES = {
|
|
84336
|
-
generic: {
|
|
84337
|
-
id: "generic",
|
|
84338
|
-
label: "Generic",
|
|
84339
|
-
scope: "root",
|
|
84340
|
-
files: ["AGENTS.md"],
|
|
84341
|
-
filesMode: "first",
|
|
84342
|
-
globalDir: ".agents",
|
|
84343
|
-
globalFiles: ["AGENTS.md"],
|
|
84344
|
-
globalMode: "first",
|
|
84345
|
-
verified: false,
|
|
84346
|
-
note: "Reference view of the ancestor AGENTS.md chain. No client execution behavior is claimed.",
|
|
84347
|
-
limits: "Walks to the filesystem root like Stepladder; only AGENTS.md files are read."
|
|
84348
|
-
},
|
|
84349
|
-
codex: {
|
|
84350
|
-
id: "codex",
|
|
84351
|
-
label: "Codex",
|
|
84352
|
-
scope: "git",
|
|
84353
|
-
files: ["AGENTS.override.md", "AGENTS.md"],
|
|
84354
|
-
filesMode: "first",
|
|
84355
|
-
globalDir: ".codex",
|
|
84356
|
-
globalEnv: "CODEX_HOME",
|
|
84357
|
-
globalFiles: ["AGENTS.override.md", "AGENTS.md"],
|
|
84358
|
-
globalMode: "first",
|
|
84359
|
-
verified: true,
|
|
84360
|
-
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.",
|
|
84361
|
-
limits: "A configured model_instructions_file fallback is not applied here; a warning appears when it is configured."
|
|
84362
|
-
},
|
|
84363
|
-
claude: {
|
|
84364
|
-
id: "claude",
|
|
84365
|
-
label: "Claude Code",
|
|
84366
|
-
scope: "root",
|
|
84367
|
-
files: ["CLAUDE.md", ".claude/CLAUDE.md", "CLAUDE.local.md"],
|
|
84368
|
-
filesMode: "all",
|
|
84369
|
-
globalDir: ".claude",
|
|
84370
|
-
globalFiles: ["CLAUDE.md"],
|
|
84371
|
-
globalMode: "first",
|
|
84372
|
-
verified: true,
|
|
84373
|
-
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.",
|
|
84374
|
-
limits: "Conditional .claude/rules/*.md files and @path imports are not expanded here."
|
|
84375
|
-
},
|
|
84376
|
-
pi: {
|
|
84377
|
-
id: "pi",
|
|
84378
|
-
label: "Pi",
|
|
84379
|
-
scope: "root",
|
|
84380
|
-
files: [
|
|
84381
|
-
"AGENTS.override.md",
|
|
84382
|
-
"AGENTS.md",
|
|
84383
|
-
"AGENTS.MD",
|
|
84384
|
-
"CLAUDE.md",
|
|
84385
|
-
"CLAUDE.MD"
|
|
84386
|
-
],
|
|
84387
|
-
filesMode: "first",
|
|
84388
|
-
globalDir: ".pi/agent",
|
|
84389
|
-
globalEnv: "PI_CODING_AGENT_DIR",
|
|
84390
|
-
globalFiles: [
|
|
84391
|
-
"AGENTS.override.md",
|
|
84392
|
-
"AGENTS.md",
|
|
84393
|
-
"AGENTS.MD",
|
|
84394
|
-
"CLAUDE.md",
|
|
84395
|
-
"CLAUDE.MD"
|
|
84396
|
-
],
|
|
84397
|
-
globalMode: "first",
|
|
84398
|
-
verified: true,
|
|
84399
|
-
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.",
|
|
84400
|
-
limits: "Uses the same candidate list for the global directory."
|
|
84401
|
-
}
|
|
84402
|
-
};
|
|
84403
|
-
});
|
|
84404
|
-
|
|
84405
|
-
// packages/agents/src/resolve.ts
|
|
84406
|
-
function unique(values) {
|
|
84407
|
-
return [...new Set(values)];
|
|
84408
|
-
}
|
|
84409
|
-
function pathSegments(path) {
|
|
84410
|
-
const normalized = path.replaceAll("\\", "/").replace(/\/+$/, "");
|
|
84411
|
-
if (!normalized)
|
|
84412
|
-
return 0;
|
|
84413
|
-
return normalized.split("/").length;
|
|
84414
|
-
}
|
|
84415
|
-
function dedupeSources(sources) {
|
|
84416
|
-
const merged = new Map;
|
|
84417
|
-
for (const source of sources) {
|
|
84418
|
-
const existing = merged.get(source.id);
|
|
84419
|
-
if (!existing) {
|
|
84420
|
-
merged.set(source.id, {
|
|
84421
|
-
...source,
|
|
84422
|
-
clientIds: [...source.clientIds],
|
|
84423
|
-
sourcePaths: unique([...source.sourcePaths])
|
|
84424
|
-
});
|
|
84425
|
-
continue;
|
|
84426
|
-
}
|
|
84427
|
-
existing.clientIds = unique([...existing.clientIds, ...source.clientIds]);
|
|
84428
|
-
existing.sourcePaths = unique([
|
|
84429
|
-
...existing.sourcePaths,
|
|
84430
|
-
...source.sourcePaths
|
|
84431
|
-
]);
|
|
84432
|
-
if (existing.status !== "loaded" && source.status === "loaded") {
|
|
84433
|
-
existing.status = source.status;
|
|
84434
|
-
existing.text = source.text;
|
|
84435
|
-
existing.size = source.size;
|
|
84436
|
-
existing.reason = source.reason;
|
|
84437
|
-
}
|
|
84438
|
-
if (source.override)
|
|
84439
|
-
existing.override = true;
|
|
84440
|
-
}
|
|
84441
|
-
return [...merged.values()];
|
|
84442
|
-
}
|
|
84443
|
-
function sortSources(sources) {
|
|
84444
|
-
return [...sources].sort((left, right) => {
|
|
84445
|
-
const level = LEVEL_ORDER[left.level] - LEVEL_ORDER[right.level];
|
|
84446
|
-
if (level !== 0)
|
|
84447
|
-
return level;
|
|
84448
|
-
const depth = pathSegments(right.directory) - pathSegments(left.directory);
|
|
84449
|
-
if (depth !== 0)
|
|
84450
|
-
return depth;
|
|
84451
|
-
return left.filename.localeCompare(right.filename);
|
|
84452
|
-
});
|
|
84453
|
-
}
|
|
84454
|
-
var LEVEL_ORDER;
|
|
84455
|
-
var init_resolve = __esm(() => {
|
|
84456
|
-
LEVEL_ORDER = {
|
|
84457
|
-
project: 0,
|
|
84458
|
-
parent: 1,
|
|
84459
|
-
repository: 2,
|
|
84460
|
-
linked: 3,
|
|
84461
|
-
global: 4
|
|
84462
|
-
};
|
|
84463
|
-
});
|
|
84464
|
-
|
|
84465
|
-
// packages/agents/src/node.ts
|
|
84466
|
-
import { lstat, readFile as readFile9, realpath as realpath5, stat as stat6 } from "node:fs/promises";
|
|
84467
|
-
import { homedir as homedir3 } from "node:os";
|
|
84468
|
-
import { basename as basename5, dirname as dirname8, resolve as resolve10 } from "node:path";
|
|
84469
|
-
async function canonicalize(path) {
|
|
84470
|
-
try {
|
|
84471
|
-
return await realpath5(path);
|
|
84472
|
-
} catch {
|
|
84473
|
-
return null;
|
|
84474
|
-
}
|
|
84475
|
-
}
|
|
84476
|
-
async function hasGit(folder) {
|
|
84477
|
-
const entry = await lstat(resolve10(folder, ".git")).catch(() => {
|
|
84478
|
-
return;
|
|
84479
|
-
});
|
|
84480
|
-
return Boolean(entry);
|
|
84481
|
-
}
|
|
84482
|
-
async function nearestGitRoot(folder) {
|
|
84483
|
-
let current = folder;
|
|
84484
|
-
while (true) {
|
|
84485
|
-
if (await hasGit(current))
|
|
84486
|
-
return current;
|
|
84487
|
-
const parent = dirname8(current);
|
|
84488
|
-
if (parent === current)
|
|
84489
|
-
return null;
|
|
84490
|
-
current = parent;
|
|
84491
|
-
}
|
|
84492
|
-
}
|
|
84493
|
-
async function nearestRaggleRoot(folder) {
|
|
84494
|
-
let current = folder;
|
|
84495
|
-
while (true) {
|
|
84496
|
-
const entry = await lstat(resolve10(current, "raggle.json")).catch(() => {
|
|
84497
|
-
return;
|
|
84498
|
-
});
|
|
84499
|
-
if (entry)
|
|
84500
|
-
return current;
|
|
84501
|
-
const parent = dirname8(current);
|
|
84502
|
-
if (parent === current)
|
|
84503
|
-
return null;
|
|
84504
|
-
current = parent;
|
|
84505
|
-
}
|
|
84506
|
-
}
|
|
84507
|
-
async function ancestorBoundary(folder, scope) {
|
|
84508
|
-
let current = folder;
|
|
84509
|
-
while (true) {
|
|
84510
|
-
if (scope === "git" && await hasGit(current))
|
|
84511
|
-
return current;
|
|
84512
|
-
const parent = dirname8(current);
|
|
84513
|
-
if (parent === current)
|
|
84514
|
-
return current;
|
|
84515
|
-
current = parent;
|
|
84516
|
-
}
|
|
84517
|
-
}
|
|
84518
|
-
function ancestorChain(folder, boundary) {
|
|
84519
|
-
const chain = [];
|
|
84520
|
-
let current = folder;
|
|
84521
|
-
while (true) {
|
|
84522
|
-
chain.push(current);
|
|
84523
|
-
if (current === boundary)
|
|
84524
|
-
break;
|
|
84525
|
-
const parent = dirname8(current);
|
|
84526
|
-
if (parent === current)
|
|
84527
|
-
break;
|
|
84528
|
-
current = parent;
|
|
84529
|
-
}
|
|
84530
|
-
return chain;
|
|
84531
|
-
}
|
|
84532
|
-
function sourceLevel(index, total, scope) {
|
|
84533
|
-
if (total === 1)
|
|
84534
|
-
return "project";
|
|
84535
|
-
if (index === 0)
|
|
84536
|
-
return "project";
|
|
84537
|
-
if (scope === "git" && index === total - 1)
|
|
84538
|
-
return "repository";
|
|
84539
|
-
return "parent";
|
|
84540
|
-
}
|
|
84541
|
-
async function isRegularFile(path) {
|
|
84542
|
-
const details = await stat6(path).catch(() => {
|
|
84543
|
-
return;
|
|
84544
|
-
});
|
|
84545
|
-
return details?.isFile() === true;
|
|
84546
|
-
}
|
|
84547
|
-
function mergeChains(chains) {
|
|
84548
|
-
const byDirectory = new Map;
|
|
84549
|
-
const order = [];
|
|
84550
|
-
for (const chain of chains) {
|
|
84551
|
-
for (const entry of chain) {
|
|
84552
|
-
const existing = byDirectory.get(entry.directory);
|
|
84553
|
-
if (!existing) {
|
|
84554
|
-
byDirectory.set(entry.directory, {
|
|
84555
|
-
...entry,
|
|
84556
|
-
filenames: [...entry.filenames]
|
|
84557
|
-
});
|
|
84558
|
-
order.push(entry.directory);
|
|
84559
|
-
} else {
|
|
84560
|
-
for (const filename of entry.filenames) {
|
|
84561
|
-
if (!existing.filenames.includes(filename)) {
|
|
84562
|
-
existing.filenames.push(filename);
|
|
84563
|
-
}
|
|
84564
|
-
}
|
|
84565
|
-
}
|
|
84566
|
-
}
|
|
84567
|
-
}
|
|
84568
|
-
return order.map((directory) => byDirectory.get(directory));
|
|
84569
|
-
}
|
|
84570
|
-
async function selectFiles(directory, candidates, mode) {
|
|
84571
|
-
if (mode === "all") {
|
|
84572
|
-
const found = [];
|
|
84573
|
-
for (const relative of candidates) {
|
|
84574
|
-
if (await isRegularFile(resolve10(directory, relative))) {
|
|
84575
|
-
found.push({ filename: basename5(relative), relative });
|
|
84576
|
-
}
|
|
84577
|
-
}
|
|
84578
|
-
return found;
|
|
84579
|
-
}
|
|
84580
|
-
for (const relative of candidates) {
|
|
84581
|
-
if (await isRegularFile(resolve10(directory, relative))) {
|
|
84582
|
-
return [{ filename: basename5(relative), relative }];
|
|
84583
|
-
}
|
|
84584
|
-
}
|
|
84585
|
-
return [];
|
|
84586
|
-
}
|
|
84587
|
-
function expandHome(path, homeDir) {
|
|
84588
|
-
if (path === "~")
|
|
84589
|
-
return homeDir;
|
|
84590
|
-
if (path.startsWith("~/"))
|
|
84591
|
-
return resolve10(homeDir, path.slice(2));
|
|
84592
|
-
return path;
|
|
84593
|
-
}
|
|
84594
|
-
function globalDirectory(profile, homeDir) {
|
|
84595
|
-
if (profile.globalDir === null)
|
|
84596
|
-
return null;
|
|
84597
|
-
const envValue = profile.globalEnv ? process.env[profile.globalEnv]?.trim() : undefined;
|
|
84598
|
-
if (envValue)
|
|
84599
|
-
return expandHome(envValue, homeDir);
|
|
84600
|
-
if (profile.globalDir === "")
|
|
84601
|
-
return homeDir;
|
|
84602
|
-
return resolve10(homeDir, profile.globalDir);
|
|
84603
|
-
}
|
|
84604
|
-
function readError(error) {
|
|
84605
|
-
return error instanceof Error ? error.message : "Could not read file";
|
|
84606
|
-
}
|
|
84607
|
-
async function codexModelInstructionsFile(codexHome) {
|
|
84608
|
-
try {
|
|
84609
|
-
const content = await readFile9(resolve10(codexHome, "config.toml"), "utf8");
|
|
84610
|
-
const match = /^\s*model_instructions_file\s*=\s*["']?([^"'\n]+)["']?\s*$/m.exec(content);
|
|
84611
|
-
return match?.[1]?.trim() ?? null;
|
|
84612
|
-
} catch {
|
|
84613
|
-
return null;
|
|
84614
|
-
}
|
|
84615
|
-
}
|
|
84616
|
-
async function loadSource(input) {
|
|
84617
|
-
const real = await canonicalize(input.literalPath);
|
|
84618
|
-
if (!real) {
|
|
84619
|
-
return {
|
|
84620
|
-
id: input.literalPath,
|
|
84621
|
-
path: input.literalPath,
|
|
84622
|
-
sourcePaths: [input.literalPath],
|
|
84623
|
-
filename: input.filename,
|
|
84624
|
-
directory: dirname8(input.literalPath),
|
|
84625
|
-
level: input.level,
|
|
84626
|
-
status: "unreadable",
|
|
84627
|
-
text: "",
|
|
84628
|
-
size: 0,
|
|
84629
|
-
clientIds: [input.clientId],
|
|
84630
|
-
override: input.override,
|
|
84631
|
-
applies: true,
|
|
84632
|
-
reason: "Path cannot be resolved"
|
|
84633
|
-
};
|
|
84634
|
-
}
|
|
84635
|
-
const record = {
|
|
84636
|
-
id: real,
|
|
84637
|
-
path: real,
|
|
84638
|
-
sourcePaths: [input.literalPath],
|
|
84639
|
-
filename: input.filename,
|
|
84640
|
-
directory: dirname8(real),
|
|
84641
|
-
level: input.level,
|
|
84642
|
-
status: "loaded",
|
|
84643
|
-
text: "",
|
|
84644
|
-
size: 0,
|
|
84645
|
-
clientIds: [input.clientId],
|
|
84646
|
-
override: input.override,
|
|
84647
|
-
applies: true
|
|
84648
|
-
};
|
|
84649
|
-
if (!INSTRUCTION_NAMES.has(basename5(real).toLowerCase())) {
|
|
84650
|
-
record.status = "unsafe";
|
|
84651
|
-
record.reason = "Symlink resolves to a non-instruction file";
|
|
84652
|
-
return record;
|
|
84653
|
-
}
|
|
84654
|
-
const details = await stat6(real).catch(() => {
|
|
84655
|
-
return;
|
|
84656
|
-
});
|
|
84657
|
-
if (!details?.isFile()) {
|
|
84658
|
-
record.status = "unreadable";
|
|
84659
|
-
record.reason = "Not a regular file";
|
|
84660
|
-
return record;
|
|
84661
|
-
}
|
|
84662
|
-
record.size = details.size;
|
|
84663
|
-
if (input.readText) {
|
|
84664
|
-
try {
|
|
84665
|
-
record.text = await readFile9(real, "utf8");
|
|
84666
|
-
} catch (error) {
|
|
84667
|
-
record.status = "unreadable";
|
|
84668
|
-
record.reason = readError(error);
|
|
84669
|
-
}
|
|
84670
|
-
}
|
|
84671
|
-
return record;
|
|
84672
|
-
}
|
|
84673
|
-
async function resolveAgents(options) {
|
|
84674
|
-
const homeDir = options.homeDir ?? homedir3();
|
|
84675
|
-
const client = options.client ?? "all";
|
|
84676
|
-
const readText = options.readText ?? true;
|
|
84677
|
-
const folder = await canonicalize(options.folder);
|
|
84678
|
-
if (!folder)
|
|
84679
|
-
throw new Error(`Folder not found: ${options.folder}`);
|
|
84680
|
-
const repositoryRoot = await nearestGitRoot(folder);
|
|
84681
|
-
const workspaceRoot = await nearestRaggleRoot(folder);
|
|
84682
|
-
const profileIds = client === "all" ? CLIENT_ORDER : [client];
|
|
84683
|
-
const sources = [];
|
|
84684
|
-
const warnings = [];
|
|
84685
|
-
const profileChains = [];
|
|
84686
|
-
for (const profileId of profileIds) {
|
|
84687
|
-
const profile = PROFILES[profileId];
|
|
84688
|
-
const boundary = workspaceRoot ?? await ancestorBoundary(folder, profile.scope);
|
|
84689
|
-
const ancestors = ancestorChain(folder, boundary);
|
|
84690
|
-
const chain = [];
|
|
84691
|
-
for (let index = 0;index < ancestors.length; index += 1) {
|
|
84692
|
-
const directory = ancestors[index];
|
|
84693
|
-
if (!directory)
|
|
84694
|
-
continue;
|
|
84695
|
-
const level = sourceLevel(index, ancestors.length, profile.scope);
|
|
84696
|
-
const files = await selectFiles(directory, profile.files, profile.filesMode);
|
|
84697
|
-
chain.push({
|
|
84698
|
-
directory,
|
|
84699
|
-
level,
|
|
84700
|
-
filenames: files.map((file) => file.filename)
|
|
84701
|
-
});
|
|
84702
|
-
for (const file of files) {
|
|
84703
|
-
const source = await loadSource({
|
|
84704
|
-
clientId: profileId,
|
|
84705
|
-
filename: file.filename,
|
|
84706
|
-
level,
|
|
84707
|
-
literalPath: resolve10(directory, file.relative),
|
|
84708
|
-
override: file.filename === "AGENTS.override.md",
|
|
84709
|
-
readText
|
|
84710
|
-
});
|
|
84711
|
-
sources.push(source);
|
|
84712
|
-
}
|
|
84713
|
-
}
|
|
84714
|
-
profileChains.push(chain);
|
|
84715
|
-
for (const linkedFolder of options.linkedFolders ?? []) {
|
|
84716
|
-
const canonicalLinked = await canonicalize(linkedFolder);
|
|
84717
|
-
if (!canonicalLinked || canonicalLinked === folder)
|
|
84718
|
-
continue;
|
|
84719
|
-
const linkedFiles = await selectFiles(canonicalLinked, profile.files, profile.filesMode);
|
|
84720
|
-
chain.push({
|
|
84721
|
-
directory: canonicalLinked,
|
|
84722
|
-
level: "linked",
|
|
84723
|
-
filenames: linkedFiles.map((file) => file.filename)
|
|
84724
|
-
});
|
|
84725
|
-
for (const file of linkedFiles) {
|
|
84726
|
-
const source = await loadSource({
|
|
84727
|
-
clientId: profileId,
|
|
84728
|
-
filename: file.filename,
|
|
84729
|
-
level: "linked",
|
|
84730
|
-
literalPath: resolve10(canonicalLinked, file.relative),
|
|
84731
|
-
override: file.filename === "AGENTS.override.md",
|
|
84732
|
-
readText
|
|
84733
|
-
});
|
|
84734
|
-
sources.push(source);
|
|
84735
|
-
}
|
|
84736
|
-
}
|
|
84737
|
-
const globalDir = globalDirectory(profile, homeDir);
|
|
84738
|
-
if (globalDir) {
|
|
84739
|
-
const globals = await selectFiles(globalDir, profile.globalFiles, profile.globalMode);
|
|
84740
|
-
for (const file of globals) {
|
|
84741
|
-
const source = await loadSource({
|
|
84742
|
-
clientId: profileId,
|
|
84743
|
-
filename: file.filename,
|
|
84744
|
-
level: "global",
|
|
84745
|
-
literalPath: resolve10(globalDir, file.relative),
|
|
84746
|
-
override: file.filename === "AGENTS.override.md",
|
|
84747
|
-
readText
|
|
84748
|
-
});
|
|
84749
|
-
sources.push(source);
|
|
84750
|
-
}
|
|
84751
|
-
if (globals.length === 0 && profile.globalFiles.length > 0) {
|
|
84752
|
-
warnings.push({
|
|
84753
|
-
kind: "missing",
|
|
84754
|
-
path: globalDir,
|
|
84755
|
-
clientIds: [profileId],
|
|
84756
|
-
reason: "No global instruction file found in this directory"
|
|
84757
|
-
});
|
|
84758
|
-
}
|
|
84759
|
-
}
|
|
84760
|
-
if (profileId === "codex") {
|
|
84761
|
-
const codexHome = globalDirectory(profile, homeDir);
|
|
84762
|
-
if (codexHome) {
|
|
84763
|
-
const fallback = await codexModelInstructionsFile(codexHome);
|
|
84764
|
-
if (fallback) {
|
|
84765
|
-
warnings.push({
|
|
84766
|
-
kind: "unsupported",
|
|
84767
|
-
clientIds: [profileId],
|
|
84768
|
-
reason: `Codex model_instructions_file (${fallback}) is configured but not applied here`
|
|
84769
|
-
});
|
|
84770
|
-
}
|
|
84771
|
-
}
|
|
84772
|
-
}
|
|
84773
|
-
}
|
|
84774
|
-
const deduped = dedupeSources(sources);
|
|
84775
|
-
const ordered = sortSources(deduped);
|
|
84776
|
-
return {
|
|
84777
|
-
folder,
|
|
84778
|
-
repositoryRoot,
|
|
84779
|
-
client,
|
|
84780
|
-
sources: ordered,
|
|
84781
|
-
warnings,
|
|
84782
|
-
chain: mergeChains(profileChains)
|
|
84783
|
-
};
|
|
84784
|
-
}
|
|
84785
|
-
var INSTRUCTION_NAMES;
|
|
84786
|
-
var init_node4 = __esm(() => {
|
|
84787
|
-
init_profiles();
|
|
84788
|
-
init_resolve();
|
|
84789
|
-
INSTRUCTION_NAMES = new Set(Object.values(PROFILES).flatMap((profile) => [...profile.files, ...profile.globalFiles]).map((path) => basename5(path).toLowerCase()));
|
|
84790
|
-
});
|
|
84791
|
-
|
|
84792
|
-
// packages/agents/src/server.ts
|
|
84793
|
-
function createAgentsPlugin(options = {}) {
|
|
84794
|
-
return {
|
|
84795
|
-
...agentsManifest,
|
|
84796
|
-
async detect(context) {
|
|
84797
|
-
try {
|
|
84798
|
-
const result = await resolveAgents({
|
|
84799
|
-
folder: context.folder,
|
|
84800
|
-
client: "all",
|
|
84801
|
-
homeDir: options.homeDir,
|
|
84802
|
-
linkedFolders: context.linkedFolders,
|
|
84803
|
-
readText: false
|
|
84804
|
-
});
|
|
84805
|
-
return { count: result.sources.length, status: "available" };
|
|
84806
|
-
} catch {
|
|
84807
|
-
return { status: "available" };
|
|
84808
|
-
}
|
|
84809
|
-
},
|
|
84810
|
-
async handle(context, subpath) {
|
|
84811
|
-
const client = parseClientFilter(subpath.trim() || null);
|
|
84812
|
-
const result = await resolveAgents({
|
|
84813
|
-
folder: context.folder,
|
|
84814
|
-
client,
|
|
84815
|
-
homeDir: options.homeDir,
|
|
84816
|
-
linkedFolders: context.linkedFolders
|
|
84817
|
-
});
|
|
84818
|
-
return {
|
|
84819
|
-
kind: "available",
|
|
84820
|
-
data: {
|
|
84821
|
-
client,
|
|
84822
|
-
folder: result.folder,
|
|
84823
|
-
repositoryRoot: result.repositoryRoot,
|
|
84824
|
-
sources: result.sources,
|
|
84825
|
-
status: "available",
|
|
84826
|
-
warnings: result.warnings,
|
|
84827
|
-
chain: result.chain
|
|
84828
|
-
}
|
|
84829
|
-
};
|
|
84830
|
-
}
|
|
84831
|
-
};
|
|
84832
|
-
}
|
|
84833
|
-
var init_server3 = __esm(() => {
|
|
84834
|
-
init_manifest2();
|
|
84835
|
-
init_node4();
|
|
84836
|
-
init_profiles();
|
|
84837
|
-
});
|
|
84838
|
-
|
|
84839
84303
|
// packages/notes/src/manifest.ts
|
|
84840
84304
|
var notesManifest;
|
|
84841
|
-
var
|
|
84305
|
+
var init_manifest2 = __esm(() => {
|
|
84842
84306
|
notesManifest = {
|
|
84843
84307
|
id: "notes",
|
|
84308
|
+
icon: {
|
|
84309
|
+
paths: [
|
|
84310
|
+
"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8Z",
|
|
84311
|
+
"M14 2v6h6",
|
|
84312
|
+
"M8 13h8M8 17h6"
|
|
84313
|
+
]
|
|
84314
|
+
},
|
|
84844
84315
|
label: "Notes"
|
|
84845
84316
|
};
|
|
84846
84317
|
});
|
|
84847
84318
|
|
|
84848
84319
|
// packages/notes/src/server.ts
|
|
84849
|
-
import { readdir as readdir4, stat as
|
|
84850
|
-
import { basename as
|
|
84320
|
+
import { readdir as readdir4, stat as stat6 } from "node:fs/promises";
|
|
84321
|
+
import { basename as basename5, extname as extname5, relative as relative9, resolve as resolve10, sep as sep5 } from "node:path";
|
|
84851
84322
|
async function listMarkdownFiles(folder) {
|
|
84852
84323
|
const files = [];
|
|
84853
84324
|
const visit = async (current) => {
|
|
@@ -84855,7 +84326,7 @@ async function listMarkdownFiles(folder) {
|
|
|
84855
84326
|
for (const entry of entries) {
|
|
84856
84327
|
if (entry.name === "node_modules" || entry.name.startsWith("."))
|
|
84857
84328
|
continue;
|
|
84858
|
-
const path =
|
|
84329
|
+
const path = resolve10(current, entry.name);
|
|
84859
84330
|
if (entry.isDirectory()) {
|
|
84860
84331
|
await visit(path);
|
|
84861
84332
|
continue;
|
|
@@ -84863,12 +84334,12 @@ async function listMarkdownFiles(folder) {
|
|
|
84863
84334
|
if (!entry.isFile() || !markdownExtensions.has(extname5(entry.name))) {
|
|
84864
84335
|
continue;
|
|
84865
84336
|
}
|
|
84866
|
-
const details = await
|
|
84337
|
+
const details = await stat6(path).catch(() => {
|
|
84867
84338
|
return;
|
|
84868
84339
|
});
|
|
84869
84340
|
files.push({
|
|
84870
84341
|
activityAt: details?.mtimeMs ?? 0,
|
|
84871
|
-
name:
|
|
84342
|
+
name: basename5(entry.name, extname5(entry.name)),
|
|
84872
84343
|
relativePath: relative9(folder, path).split(sep5).join("/")
|
|
84873
84344
|
});
|
|
84874
84345
|
}
|
|
@@ -84911,15 +84382,15 @@ function createNotesPlugin() {
|
|
|
84911
84382
|
};
|
|
84912
84383
|
}
|
|
84913
84384
|
var markdownExtensions;
|
|
84914
|
-
var
|
|
84915
|
-
|
|
84385
|
+
var init_server3 = __esm(() => {
|
|
84386
|
+
init_manifest2();
|
|
84916
84387
|
markdownExtensions = new Set([".md", ".markdown"]);
|
|
84917
84388
|
});
|
|
84918
84389
|
|
|
84919
84390
|
// packages/api/src/server/plugins.ts
|
|
84920
84391
|
import { pathToFileURL } from "node:url";
|
|
84921
84392
|
import { existsSync as existsSync4 } from "node:fs";
|
|
84922
|
-
import { dirname as
|
|
84393
|
+
import { dirname as dirname8, resolve as resolve11, sep as sep6 } from "node:path";
|
|
84923
84394
|
function configuredFolderServerRegistry(registry, resolvedConfig) {
|
|
84924
84395
|
const disabled = new Set(resolvedConfig.plugins.disable);
|
|
84925
84396
|
const orderedIds = resolvedConfig.plugins.order.filter((id) => registry.has(id) && !disabled.has(id));
|
|
@@ -84929,16 +84400,11 @@ function configuredFolderServerRegistry(registry, resolvedConfig) {
|
|
|
84929
84400
|
];
|
|
84930
84401
|
return new Map(ids.map((id) => [id, registry.get(id)]));
|
|
84931
84402
|
}
|
|
84932
|
-
function createFolderServerPlugins(
|
|
84933
|
-
return [
|
|
84934
|
-
createAgentsPlugin({
|
|
84935
|
-
homeDir: options.agentsHomeDir
|
|
84936
|
-
}),
|
|
84937
|
-
createNotesPlugin()
|
|
84938
|
-
];
|
|
84403
|
+
function createFolderServerPlugins() {
|
|
84404
|
+
return [createNotesPlugin()];
|
|
84939
84405
|
}
|
|
84940
|
-
function folderServerRegistry(
|
|
84941
|
-
return new Map(createFolderServerPlugins(
|
|
84406
|
+
function folderServerRegistry() {
|
|
84407
|
+
return new Map(createFolderServerPlugins().map((plugin) => [plugin.id, plugin]));
|
|
84942
84408
|
}
|
|
84943
84409
|
function externalServerEntries() {
|
|
84944
84410
|
const source = process.env.KENNEL_EXTERNAL_SERVER_ENTRIES;
|
|
@@ -84958,14 +84424,14 @@ function externalServerEntries() {
|
|
|
84958
84424
|
return { id: item.id, module: item.module, symbol: item.symbol, trigger: item.trigger };
|
|
84959
84425
|
});
|
|
84960
84426
|
}
|
|
84961
|
-
async function folderServerRegistryAsync(
|
|
84962
|
-
const registry = folderServerRegistry(
|
|
84427
|
+
async function folderServerRegistryAsync() {
|
|
84428
|
+
const registry = folderServerRegistry();
|
|
84963
84429
|
for (const entry of externalServerEntries()) {
|
|
84964
84430
|
if (registry.has(entry.id))
|
|
84965
84431
|
throw new Error(`External plugin id collides with core plugin: ${entry.id}`);
|
|
84966
84432
|
const imported = await import(pathToFileURL(entry.module).href);
|
|
84967
84433
|
const value = imported[entry.symbol];
|
|
84968
|
-
const plugin = typeof value === "function" ? value(
|
|
84434
|
+
const plugin = typeof value === "function" ? value() : value;
|
|
84969
84435
|
if (!plugin || typeof plugin !== "object")
|
|
84970
84436
|
throw new Error(`External plugin ${entry.id} did not export ${entry.symbol}`);
|
|
84971
84437
|
const server = plugin;
|
|
@@ -84977,7 +84443,7 @@ async function folderServerRegistryAsync(options = {}) {
|
|
|
84977
84443
|
...server,
|
|
84978
84444
|
async detect(context) {
|
|
84979
84445
|
const detection = await server.detect(context);
|
|
84980
|
-
if (detection.status === "unavailable" && existsSync4(
|
|
84446
|
+
if (detection.status === "unavailable" && existsSync4(resolve11(context.folder, entry.trigger))) {
|
|
84981
84447
|
return { status: "available" };
|
|
84982
84448
|
}
|
|
84983
84449
|
return detection;
|
|
@@ -85016,14 +84482,13 @@ async function externalApiHandlers() {
|
|
|
85016
84482
|
}
|
|
85017
84483
|
var init_plugins = __esm(() => {
|
|
85018
84484
|
init_server3();
|
|
85019
|
-
init_server4();
|
|
85020
84485
|
});
|
|
85021
84486
|
|
|
85022
84487
|
// packages/api/src/server/linked-folder-discovery.ts
|
|
85023
84488
|
import { execFile as execFile3 } from "node:child_process";
|
|
85024
84489
|
import { existsSync as existsSync5 } from "node:fs";
|
|
85025
84490
|
import { createRequire as createRequire4 } from "node:module";
|
|
85026
|
-
import { dirname as
|
|
84491
|
+
import { dirname as dirname9, join as join4 } from "node:path";
|
|
85027
84492
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
85028
84493
|
function resolveLocalModule(from = import.meta.url) {
|
|
85029
84494
|
const require2 = createRequire4(from);
|
|
@@ -85031,11 +84496,11 @@ function resolveLocalModule(from = import.meta.url) {
|
|
|
85031
84496
|
try {
|
|
85032
84497
|
candidates.push(require2.resolve("@raggle-ai/local"));
|
|
85033
84498
|
} catch {}
|
|
85034
|
-
let directory =
|
|
85035
|
-
while (
|
|
84499
|
+
let directory = dirname9(fileURLToPath2(from));
|
|
84500
|
+
while (dirname9(directory) !== directory) {
|
|
85036
84501
|
if (existsSync5(join4(directory, "raggle.json"))) {
|
|
85037
84502
|
for (const candidate of [
|
|
85038
|
-
join4(
|
|
84503
|
+
join4(dirname9(directory), "raggle-ai-scout", "packages", "local"),
|
|
85039
84504
|
join4(directory, "..", "..", "raggle-ai-scout", "packages", "local")
|
|
85040
84505
|
]) {
|
|
85041
84506
|
if (!candidates.includes(candidate))
|
|
@@ -85043,7 +84508,7 @@ function resolveLocalModule(from = import.meta.url) {
|
|
|
85043
84508
|
}
|
|
85044
84509
|
break;
|
|
85045
84510
|
}
|
|
85046
|
-
directory =
|
|
84511
|
+
directory = dirname9(directory);
|
|
85047
84512
|
}
|
|
85048
84513
|
for (const candidate of candidates) {
|
|
85049
84514
|
try {
|
|
@@ -85052,7 +84517,7 @@ function resolveLocalModule(from = import.meta.url) {
|
|
|
85052
84517
|
return candidate;
|
|
85053
84518
|
} catch {}
|
|
85054
84519
|
}
|
|
85055
|
-
return candidates[0] ?? join4(
|
|
84520
|
+
return candidates[0] ?? join4(dirname9(fileURLToPath2(from)), "..", "..", "..", "raggle-ai-scout", "packages", "local");
|
|
85056
84521
|
}
|
|
85057
84522
|
function discoverLinkedFolders(folder, signal, modulePath = resolveLocalModule()) {
|
|
85058
84523
|
return new Promise((resolve, reject) => {
|
|
@@ -85242,36 +84707,18 @@ var init_project_discovery = __esm(() => {
|
|
|
85242
84707
|
// packages/api/src/server/folder-metadata-plugin.ts
|
|
85243
84708
|
import { createHash as createHash6 } from "node:crypto";
|
|
85244
84709
|
import { realpathSync as realpathSync2 } from "node:fs";
|
|
85245
|
-
import { readdir as readdir5, readFile as
|
|
85246
|
-
import { homedir as
|
|
84710
|
+
import { readdir as readdir5, readFile as readFile9, stat as stat7 } from "node:fs/promises";
|
|
84711
|
+
import { homedir as homedir3 } from "node:os";
|
|
85247
84712
|
import {
|
|
85248
|
-
basename as
|
|
85249
|
-
dirname as
|
|
84713
|
+
basename as basename6,
|
|
84714
|
+
dirname as dirname10,
|
|
85250
84715
|
extname as extname6,
|
|
85251
84716
|
isAbsolute as isAbsolute6,
|
|
85252
84717
|
relative as relative11,
|
|
85253
|
-
resolve as
|
|
84718
|
+
resolve as resolve12,
|
|
85254
84719
|
sep as sep7
|
|
85255
84720
|
} from "node:path";
|
|
85256
84721
|
import { execFile as execFile5 } from "node:child_process";
|
|
85257
|
-
function skillDescription(content) {
|
|
85258
|
-
if (!content.startsWith(`---
|
|
85259
|
-
`))
|
|
85260
|
-
return;
|
|
85261
|
-
const end = content.indexOf(`
|
|
85262
|
-
---`, 4);
|
|
85263
|
-
if (end < 0)
|
|
85264
|
-
return;
|
|
85265
|
-
const schema = $parse(content.slice(4, end));
|
|
85266
|
-
return typeof schema.description === "string" ? schema.description : undefined;
|
|
85267
|
-
}
|
|
85268
|
-
function skillSource(folder, root) {
|
|
85269
|
-
if (root === folder)
|
|
85270
|
-
return "local";
|
|
85271
|
-
if (root.startsWith(resolve13(folder, ".gtl") + sep7))
|
|
85272
|
-
return "local";
|
|
85273
|
-
return "global";
|
|
85274
|
-
}
|
|
85275
84722
|
function metadataFile(path, root) {
|
|
85276
84723
|
const candidate = relative11(root, path);
|
|
85277
84724
|
if (!candidate || candidate.startsWith("..") || isAbsolute6(candidate))
|
|
@@ -85286,11 +84733,8 @@ async function configuredAiInputModule(folder) {
|
|
|
85286
84733
|
const module = config.aiInput?.module;
|
|
85287
84734
|
return typeof module === "string" && module.trim() ? module.trim() : null;
|
|
85288
84735
|
}
|
|
85289
|
-
function label(value) {
|
|
85290
|
-
return value.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[-_]+/g, " ").replace(/\b\w/g, (match) => match.toUpperCase());
|
|
85291
|
-
}
|
|
85292
84736
|
function folderPath(value, root, lockedRoot) {
|
|
85293
|
-
const folder = realpathSync2(
|
|
84737
|
+
const folder = realpathSync2(resolve12(value ?? root));
|
|
85294
84738
|
if (!lockedRoot)
|
|
85295
84739
|
return folder;
|
|
85296
84740
|
const path = relative11(lockedRoot, folder);
|
|
@@ -85343,12 +84787,12 @@ async function searchIconDataUrl(icon) {
|
|
|
85343
84787
|
const mediaType = searchIconTypes.get(extname6(icon).toLowerCase());
|
|
85344
84788
|
if (!mediaType)
|
|
85345
84789
|
return;
|
|
85346
|
-
const details = await
|
|
84790
|
+
const details = await stat7(icon).catch(() => {
|
|
85347
84791
|
return;
|
|
85348
84792
|
});
|
|
85349
84793
|
if (!details?.size || details.size > maxIconBytes3)
|
|
85350
84794
|
return;
|
|
85351
|
-
return `data:${mediaType};base64,${(await
|
|
84795
|
+
return `data:${mediaType};base64,${(await readFile9(icon)).toString("base64")}`;
|
|
85352
84796
|
}
|
|
85353
84797
|
async function iconWithFaviconFallback(folder, assets, assetFiles) {
|
|
85354
84798
|
return folderIcon(folder, assets, assetFiles, async (folderName) => {
|
|
@@ -85382,76 +84826,19 @@ async function hydrateAssets(metadata, assetFiles) {
|
|
|
85382
84826
|
projects: { items: projectItems }
|
|
85383
84827
|
};
|
|
85384
84828
|
}
|
|
85385
|
-
function
|
|
84829
|
+
function unique(values) {
|
|
85386
84830
|
return [...new Set(values)];
|
|
85387
84831
|
}
|
|
85388
|
-
async function existingDirectory(path) {
|
|
85389
|
-
const details = await stat8(path).catch(() => {
|
|
85390
|
-
return;
|
|
85391
|
-
});
|
|
85392
|
-
return details?.isDirectory() ? path : undefined;
|
|
85393
|
-
}
|
|
85394
|
-
function metadataPaths(metadata) {
|
|
85395
|
-
return (metadata.files?.items ?? []).flatMap((file) => [file.path, file.relativePath]).filter((path) => Boolean(path));
|
|
85396
|
-
}
|
|
85397
|
-
function ancestorFolders(folder) {
|
|
85398
|
-
const folders = [];
|
|
85399
|
-
for (let current = folder;dirname11(current) !== current; current = dirname11(current)) {
|
|
85400
|
-
folders.push(current);
|
|
85401
|
-
}
|
|
85402
|
-
return folders;
|
|
85403
|
-
}
|
|
85404
|
-
async function linkedSkillRoots(folder, metadata) {
|
|
85405
|
-
const gtlNames = metadataPaths(metadata).map((path) => path.split(/[\\/]\.gtl[\\/]/)[1]).filter((path) => Boolean(path)).map((path) => path.split(/[\\/]/)[0]).filter((name) => Boolean(name));
|
|
85406
|
-
const gtlRoots = gtlNames.flatMap((name) => [
|
|
85407
|
-
resolve13(folder, ".gtl", name),
|
|
85408
|
-
...ancestorFolders(folder).map((ancestor) => resolve13(ancestor, name))
|
|
85409
|
-
]);
|
|
85410
|
-
const name = folder.replace(/[\\/]+$/, "").split(/[\\/]/).at(-1);
|
|
85411
|
-
const siblingIndex = name ? [
|
|
85412
|
-
resolve13(dirname11(folder), `${name}-index`),
|
|
85413
|
-
resolve13(dirname11(dirname11(folder)), `${name}-index`)
|
|
85414
|
-
] : [];
|
|
85415
|
-
const roots = await Promise.all(unique2([...gtlRoots, ...siblingIndex]).map(existingDirectory));
|
|
85416
|
-
return roots.filter((path) => Boolean(path));
|
|
85417
|
-
}
|
|
85418
|
-
async function listFolderSkills(folder, metadata) {
|
|
85419
|
-
const roots = unique2([folder, ...await linkedSkillRoots(folder, metadata)]);
|
|
85420
|
-
const skills = await Promise.all(roots.map(async (root) => {
|
|
85421
|
-
const skillsFolder = resolve13(root, ".agents", "skills");
|
|
85422
|
-
const entries = await readdir5(skillsFolder, {
|
|
85423
|
-
withFileTypes: true
|
|
85424
|
-
}).catch(() => []);
|
|
85425
|
-
return (await Promise.all(entries.filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map(async (entry) => {
|
|
85426
|
-
const path = resolve13(skillsFolder, entry.name);
|
|
85427
|
-
const skillPath = resolve13(path, "SKILL.md");
|
|
85428
|
-
const details = await stat8(skillPath).catch(() => {
|
|
85429
|
-
return;
|
|
85430
|
-
});
|
|
85431
|
-
if (!details?.isFile())
|
|
85432
|
-
return;
|
|
85433
|
-
const content = await readFile10(skillPath, "utf8").catch(() => "");
|
|
85434
|
-
return {
|
|
85435
|
-
description: skillDescription(content),
|
|
85436
|
-
name: label(entry.name),
|
|
85437
|
-
openHref: openPathHref(path),
|
|
85438
|
-
relativePath: relative11(root, path),
|
|
85439
|
-
source: skillSource(folder, root)
|
|
85440
|
-
};
|
|
85441
|
-
}))).filter((skill) => skill);
|
|
85442
|
-
}));
|
|
85443
|
-
return unique2(skills.flat().map((skill) => JSON.stringify(skill))).map((skill) => JSON.parse(skill)).sort((left, right) => left.name.localeCompare(right.name));
|
|
85444
|
-
}
|
|
85445
84832
|
function isMachineRoot(folder) {
|
|
85446
|
-
return folder ===
|
|
84833
|
+
return folder === homedir3() || dirname10(folder) === folder;
|
|
85447
84834
|
}
|
|
85448
84835
|
async function shallowMetadata(folder) {
|
|
85449
84836
|
const entries = await readdir5(folder, { withFileTypes: true });
|
|
85450
84837
|
const visible = entries.filter((entry) => !entry.name.startsWith(".") && entry.name !== "node_modules");
|
|
85451
84838
|
const files = await Promise.all(visible.filter((entry) => entry.isFile() && [".markdown", ".md"].includes(extname6(entry.name).toLowerCase())).map(async (entry) => {
|
|
85452
|
-
const path =
|
|
85453
|
-
const details = await
|
|
85454
|
-
const content = await
|
|
84839
|
+
const path = resolve12(folder, entry.name);
|
|
84840
|
+
const details = await stat7(path);
|
|
84841
|
+
const content = await readFile9(path, "utf8").catch(() => "");
|
|
85455
84842
|
const title = markdownMetadata(content).title;
|
|
85456
84843
|
return {
|
|
85457
84844
|
activityAt: details.mtimeMs,
|
|
@@ -85464,10 +84851,10 @@ async function shallowMetadata(folder) {
|
|
|
85464
84851
|
};
|
|
85465
84852
|
}));
|
|
85466
84853
|
const projects = visible.filter((entry) => entry.isDirectory()).map((entry) => ({
|
|
85467
|
-
id: createHash6("sha1").update(
|
|
84854
|
+
id: createHash6("sha1").update(resolve12(folder, entry.name)).digest("hex"),
|
|
85468
84855
|
name: entry.name,
|
|
85469
84856
|
relativePath: entry.name,
|
|
85470
|
-
worktree:
|
|
84857
|
+
worktree: resolve12(folder, entry.name)
|
|
85471
84858
|
})).sort((left, right) => left.name.localeCompare(right.name));
|
|
85472
84859
|
return {
|
|
85473
84860
|
changes: { items: [] },
|
|
@@ -85478,8 +84865,7 @@ async function shallowMetadata(folder) {
|
|
|
85478
84865
|
instructions: { items: [] },
|
|
85479
84866
|
projects: { items: projects },
|
|
85480
84867
|
schemaVersion: 3,
|
|
85481
|
-
sessions: { items: [] }
|
|
85482
|
-
skills: { items: [] }
|
|
84868
|
+
sessions: { items: [] }
|
|
85483
84869
|
};
|
|
85484
84870
|
}
|
|
85485
84871
|
async function loadFolderData(folder) {
|
|
@@ -85494,7 +84880,7 @@ async function loadFolderData(folder) {
|
|
|
85494
84880
|
items: projects.map((project) => ({
|
|
85495
84881
|
id: project.id,
|
|
85496
84882
|
worktree: project.worktree,
|
|
85497
|
-
name: project.name ??
|
|
84883
|
+
name: project.name ?? basename6(project.worktree),
|
|
85498
84884
|
relativePath: relative11(folder, project.worktree)
|
|
85499
84885
|
}))
|
|
85500
84886
|
}
|
|
@@ -85503,10 +84889,10 @@ async function loadFolderData(folder) {
|
|
|
85503
84889
|
async function notesFiles(folder, files, origin) {
|
|
85504
84890
|
return {
|
|
85505
84891
|
items: await Promise.all(files.map(async (file) => {
|
|
85506
|
-
const path = file.path ?? (file.relativePath ?
|
|
84892
|
+
const path = file.path ?? (file.relativePath ? resolve12(folder, file.relativePath) : undefined);
|
|
85507
84893
|
if (!path)
|
|
85508
84894
|
return origin ? { ...file, folder: origin } : file;
|
|
85509
|
-
const content = [".markdown", ".md"].includes(extname6(path).toLowerCase()) ? await
|
|
84895
|
+
const content = [".markdown", ".md"].includes(extname6(path).toLowerCase()) ? await readFile9(path, "utf8").catch(() => "") : "";
|
|
85510
84896
|
const title = content ? markdownMetadata(content).title : undefined;
|
|
85511
84897
|
return {
|
|
85512
84898
|
...file,
|
|
@@ -85539,8 +84925,8 @@ async function localProjectSearchCache(cache) {
|
|
|
85539
84925
|
function mediaTarget(folder, file, lockedTarget) {
|
|
85540
84926
|
if (!file)
|
|
85541
84927
|
return;
|
|
85542
|
-
const rootReal = realpathSync2(
|
|
85543
|
-
const path =
|
|
84928
|
+
const rootReal = realpathSync2(resolve12(folder));
|
|
84929
|
+
const path = resolve12(folder, file);
|
|
85544
84930
|
let pathReal;
|
|
85545
84931
|
try {
|
|
85546
84932
|
pathReal = realpathSync2(path);
|
|
@@ -85587,8 +84973,8 @@ function documentError(response) {
|
|
|
85587
84973
|
function documentTarget(folder, file, lockedTarget) {
|
|
85588
84974
|
if (!file)
|
|
85589
84975
|
return;
|
|
85590
|
-
const rootReal = realpathSync2(
|
|
85591
|
-
const path =
|
|
84976
|
+
const rootReal = realpathSync2(resolve12(folder));
|
|
84977
|
+
const path = resolve12(folder, file);
|
|
85592
84978
|
let pathReal;
|
|
85593
84979
|
try {
|
|
85594
84980
|
pathReal = realpathSync2(path);
|
|
@@ -85638,14 +85024,14 @@ function parsePluginRegistryConfig(content) {
|
|
|
85638
85024
|
};
|
|
85639
85025
|
}
|
|
85640
85026
|
async function nearestKennelConfig(folder) {
|
|
85641
|
-
for (let current = folder;; current =
|
|
85642
|
-
const candidate =
|
|
85643
|
-
const details = await
|
|
85027
|
+
for (let current = folder;; current = dirname10(current)) {
|
|
85028
|
+
const candidate = resolve12(current, "kennel.json");
|
|
85029
|
+
const details = await stat7(candidate).catch(() => {
|
|
85644
85030
|
return;
|
|
85645
85031
|
});
|
|
85646
85032
|
if (details?.isFile())
|
|
85647
85033
|
return candidate;
|
|
85648
|
-
if (
|
|
85034
|
+
if (dirname10(current) === current)
|
|
85649
85035
|
return;
|
|
85650
85036
|
}
|
|
85651
85037
|
}
|
|
@@ -85654,13 +85040,13 @@ async function folderPluginRegistryConfig(folder) {
|
|
|
85654
85040
|
if (!path)
|
|
85655
85041
|
return defaultPluginRegistryConfig;
|
|
85656
85042
|
try {
|
|
85657
|
-
return parsePluginRegistryConfig(await
|
|
85043
|
+
return parsePluginRegistryConfig(await readFile9(path, "utf8"));
|
|
85658
85044
|
} catch {
|
|
85659
85045
|
return defaultPluginRegistryConfig;
|
|
85660
85046
|
}
|
|
85661
85047
|
}
|
|
85662
85048
|
function pluginConfigWarnings(registry, config) {
|
|
85663
|
-
const ids =
|
|
85049
|
+
const ids = unique([...config.plugins.disable, ...config.plugins.order]);
|
|
85664
85050
|
return ids.filter((id) => !registry.has(id)).map((id) => `unknown plugin id "${id}" — not installed in this build`);
|
|
85665
85051
|
}
|
|
85666
85052
|
async function pluginAvailability(registry, folder, linkedFolders, configWarnings = []) {
|
|
@@ -85674,12 +85060,14 @@ async function pluginAvailability(registry, folder, linkedFolders, configWarning
|
|
|
85674
85060
|
if (detection.status === "available") {
|
|
85675
85061
|
items.push({
|
|
85676
85062
|
count: detection.count,
|
|
85063
|
+
icon: plugin.icon,
|
|
85677
85064
|
id: plugin.id,
|
|
85678
85065
|
label: plugin.label
|
|
85679
85066
|
});
|
|
85680
85067
|
} else if (detection.status === "error") {
|
|
85681
85068
|
items.push({
|
|
85682
85069
|
error: detection.error,
|
|
85070
|
+
icon: plugin.icon,
|
|
85683
85071
|
id: plugin.id,
|
|
85684
85072
|
label: plugin.label
|
|
85685
85073
|
});
|
|
@@ -85693,7 +85081,6 @@ function createFolderApi({
|
|
|
85693
85081
|
restrictToRoot = false,
|
|
85694
85082
|
root,
|
|
85695
85083
|
sessionFinding,
|
|
85696
|
-
agentsHomeDir,
|
|
85697
85084
|
linkedFolderLoader,
|
|
85698
85085
|
remoteAccess = false,
|
|
85699
85086
|
lockedFile
|
|
@@ -85704,9 +85091,7 @@ function createFolderApi({
|
|
|
85704
85091
|
listFolderSessions,
|
|
85705
85092
|
readSessionTranscript
|
|
85706
85093
|
};
|
|
85707
|
-
const basePlugins = folderServerRegistryAsync(
|
|
85708
|
-
agentsHomeDir
|
|
85709
|
-
});
|
|
85094
|
+
const basePlugins = folderServerRegistryAsync();
|
|
85710
85095
|
const baseExternalApiHandlers = externalApiHandlers();
|
|
85711
85096
|
const assetFiles = new Map;
|
|
85712
85097
|
let projectSearchCache;
|
|
@@ -85841,7 +85226,7 @@ function createFolderApi({
|
|
|
85841
85226
|
"Content-Type": asset.mediaType,
|
|
85842
85227
|
ETag: `"${hash}"`
|
|
85843
85228
|
});
|
|
85844
|
-
response.end(await
|
|
85229
|
+
response.end(await readFile9(asset.path));
|
|
85845
85230
|
} catch (error) {
|
|
85846
85231
|
response.writeHead(404, {
|
|
85847
85232
|
"Content-Type": "text/plain; charset=utf-8"
|
|
@@ -85920,7 +85305,7 @@ function createFolderApi({
|
|
|
85920
85305
|
{
|
|
85921
85306
|
path: relative11(folder, target.path),
|
|
85922
85307
|
kind: target.kind,
|
|
85923
|
-
content: previewTextKind(target.kind) ? await
|
|
85308
|
+
content: previewTextKind(target.kind) ? await readFile9(target.path, "utf8") : ""
|
|
85924
85309
|
}
|
|
85925
85310
|
] : []
|
|
85926
85311
|
} : await readFolder(folder);
|
|
@@ -85936,7 +85321,7 @@ function createFolderApi({
|
|
|
85936
85321
|
documentError(response);
|
|
85937
85322
|
return;
|
|
85938
85323
|
}
|
|
85939
|
-
const details = await
|
|
85324
|
+
const details = await stat7(target.path);
|
|
85940
85325
|
if (!details.isFile()) {
|
|
85941
85326
|
documentError(response);
|
|
85942
85327
|
return;
|
|
@@ -85948,7 +85333,7 @@ function createFolderApi({
|
|
|
85948
85333
|
return;
|
|
85949
85334
|
}
|
|
85950
85335
|
watch(folder);
|
|
85951
|
-
const content = previewTextKind(target.kind) ? await
|
|
85336
|
+
const content = previewTextKind(target.kind) ? await readFile9(target.path, "utf8") : "";
|
|
85952
85337
|
sendContract(response, url, {
|
|
85953
85338
|
content,
|
|
85954
85339
|
kind: target.kind,
|
|
@@ -85977,7 +85362,7 @@ function createFolderApi({
|
|
|
85977
85362
|
documentError(response);
|
|
85978
85363
|
return;
|
|
85979
85364
|
}
|
|
85980
|
-
const details = await
|
|
85365
|
+
const details = await stat7(target.path);
|
|
85981
85366
|
if (!details.isFile()) {
|
|
85982
85367
|
documentError(response);
|
|
85983
85368
|
return;
|
|
@@ -85998,10 +85383,10 @@ function createFolderApi({
|
|
|
85998
85383
|
ETag: etag,
|
|
85999
85384
|
"X-Content-Type-Options": "nosniff",
|
|
86000
85385
|
...download ? {
|
|
86001
|
-
"Content-Disposition": `attachment; filename="${
|
|
85386
|
+
"Content-Disposition": `attachment; filename="${basename6(target.path)}"`
|
|
86002
85387
|
} : {}
|
|
86003
85388
|
});
|
|
86004
|
-
response.end(await
|
|
85389
|
+
response.end(await readFile9(target.path));
|
|
86005
85390
|
} catch (error) {
|
|
86006
85391
|
documentError(response);
|
|
86007
85392
|
}
|
|
@@ -86015,7 +85400,7 @@ function createFolderApi({
|
|
|
86015
85400
|
documentError(response);
|
|
86016
85401
|
return;
|
|
86017
85402
|
}
|
|
86018
|
-
const details = await
|
|
85403
|
+
const details = await stat7(target.path);
|
|
86019
85404
|
if (!details.isFile()) {
|
|
86020
85405
|
documentError(response);
|
|
86021
85406
|
return;
|
|
@@ -86027,7 +85412,7 @@ function createFolderApi({
|
|
|
86027
85412
|
return;
|
|
86028
85413
|
}
|
|
86029
85414
|
watch(folder);
|
|
86030
|
-
const data = await
|
|
85415
|
+
const data = await readFile9(target.path);
|
|
86031
85416
|
const baseHeaders = {
|
|
86032
85417
|
"Accept-Ranges": "bytes",
|
|
86033
85418
|
"Cache-Control": "private, max-age=0, must-revalidate",
|
|
@@ -86099,10 +85484,10 @@ function createFolderApi({
|
|
|
86099
85484
|
const subpath = url.searchParams.get("subpath") ?? "";
|
|
86100
85485
|
if (!lockedRoot && !isMachineRoot(folder) && request.headers["x-kennel-retry-linked"] === "1")
|
|
86101
85486
|
linkedDiscovery.retry(folder);
|
|
86102
|
-
const discovery =
|
|
85487
|
+
const discovery = linkedState(folder);
|
|
86103
85488
|
const result = await plugin.handle({
|
|
86104
85489
|
folder,
|
|
86105
|
-
linkedFolders: discovery
|
|
85490
|
+
linkedFolders: discovery.folders
|
|
86106
85491
|
}, subpath);
|
|
86107
85492
|
if (result.kind === "unavailable") {
|
|
86108
85493
|
response.writeHead(200, {
|
|
@@ -86113,7 +85498,7 @@ function createFolderApi({
|
|
|
86113
85498
|
folder,
|
|
86114
85499
|
plugin: pluginId,
|
|
86115
85500
|
status: "unavailable",
|
|
86116
|
-
|
|
85501
|
+
linkedStatus: discovery.status
|
|
86117
85502
|
}));
|
|
86118
85503
|
return;
|
|
86119
85504
|
}
|
|
@@ -86126,7 +85511,7 @@ function createFolderApi({
|
|
|
86126
85511
|
folder,
|
|
86127
85512
|
plugin: pluginId,
|
|
86128
85513
|
...data,
|
|
86129
|
-
|
|
85514
|
+
linkedStatus: discovery.status
|
|
86130
85515
|
}));
|
|
86131
85516
|
} catch (error) {
|
|
86132
85517
|
if (error instanceof FolderPluginFailure) {
|
|
@@ -86196,7 +85581,6 @@ function createFolderApi({
|
|
|
86196
85581
|
folder,
|
|
86197
85582
|
projects: { items: [] },
|
|
86198
85583
|
sessions: { items: [] },
|
|
86199
|
-
skills: { items: [] },
|
|
86200
85584
|
workspace: await readWorkspace(folder)
|
|
86201
85585
|
}, { "Cache-Control": "private, max-age=0, must-revalidate" });
|
|
86202
85586
|
return;
|
|
@@ -86206,7 +85590,7 @@ function createFolderApi({
|
|
|
86206
85590
|
workspace.breadcrumbs = await workspaceBreadcrumbIcons(workspace.breadcrumbs ?? [], assetFiles);
|
|
86207
85591
|
const files = [
|
|
86208
85592
|
workspace.configPath,
|
|
86209
|
-
|
|
85593
|
+
resolve12(workspace.root, "raggle.json")
|
|
86210
85594
|
].filter((path) => Boolean(path));
|
|
86211
85595
|
for (const path of files)
|
|
86212
85596
|
contexts.add(path);
|
|
@@ -86310,25 +85694,12 @@ function createFolderApi({
|
|
|
86310
85694
|
return;
|
|
86311
85695
|
}
|
|
86312
85696
|
const metadata = machine ? await shallowMetadata(folder) : await loadFolderData(folder);
|
|
86313
|
-
|
|
86314
|
-
respond({
|
|
86315
|
-
folder: metadata.folder,
|
|
86316
|
-
skills: {
|
|
86317
|
-
items: await listFolderSkills(metadata.folder, metadata)
|
|
86318
|
-
}
|
|
86319
|
-
});
|
|
86320
|
-
return;
|
|
86321
|
-
}
|
|
86322
|
-
const [assets, skills] = await Promise.all([
|
|
86323
|
-
hydrateAssets(metadata, assetFiles),
|
|
86324
|
-
listFolderSkills(metadata.folder, metadata)
|
|
86325
|
-
]);
|
|
85697
|
+
const assets = await hydrateAssets(metadata, assetFiles);
|
|
86326
85698
|
const body = {
|
|
86327
85699
|
...metadata,
|
|
86328
85700
|
...assets,
|
|
86329
85701
|
sessions: { items: [] },
|
|
86330
|
-
files: await notesFiles(metadata.folder, metadata.files.items)
|
|
86331
|
-
skills: { items: skills }
|
|
85702
|
+
files: await notesFiles(metadata.folder, metadata.files.items)
|
|
86332
85703
|
};
|
|
86333
85704
|
respond(body);
|
|
86334
85705
|
} catch (error) {
|
|
@@ -86347,7 +85718,6 @@ var init_folder_metadata_plugin = __esm(() => {
|
|
|
86347
85718
|
init_src3();
|
|
86348
85719
|
init_node2();
|
|
86349
85720
|
init_endpoint();
|
|
86350
|
-
init_dist3();
|
|
86351
85721
|
init_endpoint();
|
|
86352
85722
|
init_server();
|
|
86353
85723
|
init_workspace();
|
|
@@ -90954,8 +90324,8 @@ var init_acp_live_plugin = __esm(() => {
|
|
|
90954
90324
|
import {
|
|
90955
90325
|
createServer
|
|
90956
90326
|
} from "node:http";
|
|
90957
|
-
import { readFile as
|
|
90958
|
-
import { extname as extname7, isAbsolute as isAbsolute7, relative as relative12, resolve as
|
|
90327
|
+
import { readFile as readFile10, realpath as realpath5, stat as stat8 } from "node:fs/promises";
|
|
90328
|
+
import { extname as extname7, isAbsolute as isAbsolute7, relative as relative12, resolve as resolve13 } from "node:path";
|
|
90959
90329
|
function createKennelApi(options) {
|
|
90960
90330
|
const remote = options.remoteAccess || !isLoopbackServerHost(options.host);
|
|
90961
90331
|
let closed = false;
|
|
@@ -91044,8 +90414,8 @@ data: ${JSON.stringify(event.data)}
|
|
|
91044
90414
|
return;
|
|
91045
90415
|
}
|
|
91046
90416
|
if (options.webRoot && (request.method === "GET" || request.method === "HEAD")) {
|
|
91047
|
-
const root = await
|
|
91048
|
-
let target =
|
|
90417
|
+
const root = await realpath5(options.webRoot);
|
|
90418
|
+
let target = resolve13(root, `.${decodeURIComponent(url.pathname)}`);
|
|
91049
90419
|
const inside = (path) => {
|
|
91050
90420
|
const local = relative12(root, path);
|
|
91051
90421
|
return local !== ".." && !local.startsWith("../") && !isAbsolute7(local);
|
|
@@ -91055,9 +90425,9 @@ data: ${JSON.stringify(event.data)}
|
|
|
91055
90425
|
response.end();
|
|
91056
90426
|
return;
|
|
91057
90427
|
}
|
|
91058
|
-
if (!(await
|
|
91059
|
-
target =
|
|
91060
|
-
target = await
|
|
90428
|
+
if (!(await stat8(target).catch(() => null))?.isFile())
|
|
90429
|
+
target = resolve13(root, "index.html");
|
|
90430
|
+
target = await realpath5(target);
|
|
91061
90431
|
if (!inside(target)) {
|
|
91062
90432
|
response.writeHead(403);
|
|
91063
90433
|
response.end();
|
|
@@ -91077,7 +90447,7 @@ data: ${JSON.stringify(event.data)}
|
|
|
91077
90447
|
"Content-Type": types[extname7(target)] ?? "application/octet-stream",
|
|
91078
90448
|
"X-Content-Type-Options": "nosniff"
|
|
91079
90449
|
});
|
|
91080
|
-
response.end(request.method === "HEAD" ? undefined : await
|
|
90450
|
+
response.end(request.method === "HEAD" ? undefined : await readFile10(target));
|
|
91081
90451
|
return;
|
|
91082
90452
|
}
|
|
91083
90453
|
next();
|
|
@@ -91123,21 +90493,21 @@ data: ${JSON.stringify(event.data)}
|
|
|
91123
90493
|
}
|
|
91124
90494
|
};
|
|
91125
90495
|
}
|
|
91126
|
-
var
|
|
90496
|
+
var init_server4 = __esm(() => {
|
|
91127
90497
|
init_watcher();
|
|
91128
90498
|
init_folder_metadata_plugin();
|
|
91129
90499
|
init_acp_live_plugin();
|
|
91130
90500
|
});
|
|
91131
90501
|
|
|
91132
90502
|
// packages/preview/src/share.ts
|
|
91133
|
-
import { resolve as
|
|
90503
|
+
import { resolve as resolve15 } from "node:path";
|
|
91134
90504
|
import { existsSync as existsSync7 } from "node:fs";
|
|
91135
90505
|
|
|
91136
90506
|
// packages/preview/src/viewer.ts
|
|
91137
90507
|
import { execFile as execFile6, execFileSync as execFileSync2 } from "node:child_process";
|
|
91138
90508
|
import { existsSync as existsSync6, realpathSync as realpathSync3, statSync as statSync3 } from "node:fs";
|
|
91139
90509
|
import { createServer as createServer2 } from "node:net";
|
|
91140
|
-
import { dirname as
|
|
90510
|
+
import { dirname as dirname11, isAbsolute as isAbsolute8, relative as relative13, resolve as resolve14 } from "node:path";
|
|
91141
90511
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
91142
90512
|
|
|
91143
90513
|
// packages/preview/src/kinds.ts
|
|
@@ -91227,7 +90597,7 @@ function splitViewerArgs(input) {
|
|
|
91227
90597
|
}
|
|
91228
90598
|
if (arg.startsWith("-"))
|
|
91229
90599
|
throw new Error(`Unknown viewer option: ${arg}`);
|
|
91230
|
-
const candidate =
|
|
90600
|
+
const candidate = resolve14(arg);
|
|
91231
90601
|
const isDirectory = existsSync6(candidate) && statSync3(candidate).isDirectory();
|
|
91232
90602
|
if (isDirectory) {
|
|
91233
90603
|
if (hasRoot)
|
|
@@ -91238,7 +90608,7 @@ function splitViewerArgs(input) {
|
|
|
91238
90608
|
}
|
|
91239
90609
|
if (hasRoot)
|
|
91240
90610
|
throw new Error("kennel accepts one folder");
|
|
91241
|
-
options.root =
|
|
90611
|
+
options.root = dirname11(candidate);
|
|
91242
90612
|
options.target = candidate;
|
|
91243
90613
|
hasRoot = true;
|
|
91244
90614
|
}
|
|
@@ -91359,13 +90729,13 @@ async function viewer(input) {
|
|
|
91359
90729
|
await hotViewer(options);
|
|
91360
90730
|
return;
|
|
91361
90731
|
}
|
|
91362
|
-
const web =
|
|
91363
|
-
if (!existsSync6(
|
|
90732
|
+
const web = resolve14(dirname11(fileURLToPath3(import.meta.url)), "../../web");
|
|
90733
|
+
if (!existsSync6(resolve14(web, "index.html"))) {
|
|
91364
90734
|
throw new Error(`Kennel web app not found. Run the CLI build first.`);
|
|
91365
90735
|
}
|
|
91366
90736
|
const remote = options.tailscale || !isLoopbackHost(options.host);
|
|
91367
90737
|
const lockedTarget = options.target ? realpathSync3(options.target) : undefined;
|
|
91368
|
-
await Promise.resolve().then(() =>
|
|
90738
|
+
await Promise.resolve().then(() => init_server4());
|
|
91369
90739
|
const displayHost = options.tailscale ? tailscaleHost() : options.lan ? lanHost2() : options.host;
|
|
91370
90740
|
if (remote)
|
|
91371
90741
|
process.env.KENNEL_VIEWER_HOSTS = [
|
|
@@ -91473,7 +90843,7 @@ function splitShareArgs(input) {
|
|
|
91473
90843
|
if (folder && !existsSync7(folder)) {
|
|
91474
90844
|
throw new Error(`Folder not found: ${folder}`);
|
|
91475
90845
|
}
|
|
91476
|
-
options.folder = folder ?
|
|
90846
|
+
options.folder = folder ? resolve15(folder) : undefined;
|
|
91477
90847
|
return options;
|
|
91478
90848
|
}
|
|
91479
90849
|
async function runningViewerRoot(port = plainViewerPort) {
|