kennel 0.2.12 → 0.2.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/src/plugins/external.js +19 -7
- package/dist/cli/src/site/server-plugins.d.ts +1 -4
- package/dist/core/api-client.js +3 -11
- package/dist/core/runtime.js +84 -695
- package/dist/package/preview.js +99 -729
- package/dist/plugins/external.js +19 -7
- package/dist/site/server-plugins.d.ts +1 -4
- package/dist/site/server-plugins.js +28 -537
- package/kernel/apps/web/package.json +0 -1
- package/kernel/apps/web/src/app.css +0 -1
- package/kernel/apps/web/src/app.tsx +7 -24
- package/kernel/apps/web/src/folder-plugin-view.tsx +6 -3
- package/kernel/apps/web/src/plugins.ts +2 -14
- package/kernel/apps/web/vite.config.ts +16 -3
- package/kernel/packages/api/openapi.json +85 -224
- package/kernel/packages/api/package.json +0 -1
- package/kernel/packages/api/src/contracts/schemas.ts +1 -9
- package/kernel/packages/api/src/server/folder-metadata-plugin.ts +9 -151
- package/kernel/packages/api/src/server/plugins.ts +11 -26
- package/kernel/packages/api/src/shared/viewer-route.ts +3 -5
- package/kernel/packages/api-client/src/generated.d.ts +16 -53
- package/kernel/packages/markdown/README.md +2 -2
- package/kernel/packages/notes/package.json +1 -0
- package/kernel/packages/notes/src/client.tsx +0 -1
- package/kernel/packages/notes/src/manifest.ts +7 -0
- package/kernel/packages/notes/src/pages/notes-page.tsx +1 -1
- package/kernel/packages/notes/src/ui/folder-notes-list.tsx +52 -7
- package/kernel/packages/plugins/SKILL.md +3 -2
- package/kernel/packages/plugins/package.json +5 -1
- package/kernel/packages/plugins/src/hooks.ts +24 -0
- package/kernel/packages/plugins/src/index.ts +1 -7
- package/kernel/packages/plugins/src/page.ts +0 -7
- package/kernel/packages/plugins/src/types.ts +8 -0
- package/kernel/packages/plugins/tsconfig.json +1 -1
- package/kernel/packages/plugins/tsup.config.ts +1 -0
- package/kernel/packages/ui/src/components/folder-activity.tsx +16 -98
- package/kernel/packages/ui/src/components/folder-landing.tsx +4 -0
- package/kernel/packages/ui/src/components/pagination.tsx +88 -2
- package/kernel/packages/ui/src/components/plugin-icon.tsx +19 -0
- package/kernel/packages/ui/src/lib/folder-activity.ts +4 -17
- package/kernel/packages/ui/src/styles/folder-activity.css +1 -31
- package/package.json +2 -2
- package/web/assets/{abnfDiagram-VRR7QNED-Brm1vcGG.js → abnfDiagram-VRR7QNED-Dt7QEF5H.js} +1 -1
- package/web/assets/app-C1j063QX.js +2 -0
- package/web/assets/app-options-98-a6ivv.js +25 -0
- package/web/assets/{app-view-header-BSOI-wB6.js → app-view-header-BJ9CWTE1.js} +1 -1
- package/web/assets/{arc-zngHsMKV.js → arc-PFB0H7oD.js} +1 -1
- package/web/assets/{architectureDiagram-ZJ3FMSHR-BLklLqRP.js → architectureDiagram-ZJ3FMSHR-BHLqEXlZ.js} +1 -1
- package/web/assets/{ask-tray-B4SPj-fH.js → ask-tray-C3gBesHJ.js} +1 -1
- package/web/assets/{blockDiagram-677ZJIJ3-yhC2fEtu.js → blockDiagram-677ZJIJ3-UbnYoYDg.js} +1 -1
- package/web/assets/{c4Diagram-LMCZKHZV-DMcweQme.js → c4Diagram-LMCZKHZV-4OSx1V4W.js} +1 -1
- package/web/assets/channel-BuvY5cQN.js +1 -0
- package/web/assets/{chunk-2Q5K7J3B-DD-S6n8h.js → chunk-2Q5K7J3B-CgxJ1aJb.js} +1 -1
- package/web/assets/{chunk-32BRIVSS-DFIAKRv_.js → chunk-32BRIVSS-Bfwxg2LM.js} +1 -1
- package/web/assets/{chunk-5VM5RSS4-B23APb3c.js → chunk-5VM5RSS4-BZN9a2hI.js} +1 -1
- package/web/assets/{chunk-EX3LRPZG-BSVEB7db.js → chunk-EX3LRPZG-CrH6hhqq.js} +1 -1
- package/web/assets/{chunk-JWPE2WC7-B6qGd0ng.js → chunk-JWPE2WC7-Ddn7ZSp8.js} +1 -1
- package/web/assets/{chunk-MOJQB5TN-N4T1-ew1.js → chunk-MOJQB5TN-9lJ7f_hI.js} +1 -1
- package/web/assets/{chunk-RYQCIY6F-6oc6i_Xw.js → chunk-RYQCIY6F-QrFo_00s.js} +1 -1
- package/web/assets/{chunk-V7JOEXUC-Dftgm9ck.js → chunk-V7JOEXUC-Dn0lQjVf.js} +1 -1
- package/web/assets/{chunk-VR4S4FIN-DfjqwEsO.js → chunk-VR4S4FIN-DXVPySkB.js} +1 -1
- package/web/assets/{chunk-XXDRQBXY-CsFsQYow.js → chunk-XXDRQBXY-CBiFDOdZ.js} +1 -1
- package/web/assets/classDiagram-OUVF2IWQ-DCYNCJhe.js +1 -0
- package/web/assets/classDiagram-v2-EOCWNBFH-DCYNCJhe.js +1 -0
- package/web/assets/client-DBJY3XDL.js +43 -0
- package/web/assets/client-DKJs0w4y.js +6 -0
- package/web/assets/{command-D_9V8ejS.js → command-onjTnuXT.js} +1 -1
- package/web/assets/{copy-context-CevDWX59.js → copy-context-CciRaLNN.js} +1 -1
- package/web/assets/{cose-bilkent-JH36ORCC-DzKsIuDb.js → cose-bilkent-JH36ORCC-CGRic2um.js} +1 -1
- package/web/assets/{cynefin-VYW2F7L2-AL45ZHbw.js → cynefin-VYW2F7L2-Blk0Lu0l.js} +1 -1
- package/web/assets/{cynefinDiagram-TSTJHNR4-DSbBegxZ.js → cynefinDiagram-TSTJHNR4-DpnnHRDK.js} +1 -1
- package/web/assets/{dagre-VKFMJZFB-BaG6MGUE.js → dagre-VKFMJZFB-llzMokKp.js} +1 -1
- package/web/assets/{diagram-FQU43EPY-WbDotTX5.js → diagram-FQU43EPY-DC6xHovR.js} +1 -1
- package/web/assets/{diagram-G47NLZAW-DMbouYVI.js → diagram-G47NLZAW-B8GVS3EA.js} +1 -1
- package/web/assets/{diagram-NH7WQ7WH-DoEuaWd_.js → diagram-NH7WQ7WH-DWUaARfh.js} +1 -1
- package/web/assets/{diagram-OA4YK3LP-BjGd-PoH.js → diagram-OA4YK3LP-9Uaes_Yi.js} +1 -1
- package/web/assets/{diagram-WEI45ONY-CXHi27jF.js → diagram-WEI45ONY-DPPTBWud.js} +1 -1
- package/web/assets/{document-CVJCfWiQ.js → document-D23WzFsW.js} +3 -3
- package/web/assets/{ebnfDiagram-CCIWWBDH-B5vMUDOs.js → ebnfDiagram-CCIWWBDH-BPrKneNw.js} +1 -1
- package/web/assets/{entities-BTKzWJ-r.js → entities-DPg0B8vd.js} +1 -1
- package/web/assets/{erDiagram-Q63AITRT-DhO7ayzF.js → erDiagram-Q63AITRT-CFqYBcnb.js} +1 -1
- package/web/assets/{file-viewer-D1HK9J3A.js → file-viewer-Ck73SsLA.js} +1 -1
- package/web/assets/{flowDiagram-23GEKE2U-CublTUlC.js → flowDiagram-23GEKE2U-C7RpYqaT.js} +1 -1
- package/web/assets/folder-filter-bar-DzejUj87.js +4 -0
- package/web/assets/{folder-image-L_AjkRfI.js → folder-image-BjIicmQ6.js} +1 -1
- package/web/assets/folder-landing-CCIXZfkp.js +55 -0
- package/web/assets/folder-list-TuRwuTss.js +1 -0
- package/web/assets/folder-mobile-bar-Bqnfwi-z.js +1 -0
- package/web/assets/folder-plugin-view-CrinCX1o.js +2 -0
- package/web/assets/{ganttDiagram-NO4QXBWP-BLMJWerM.js → ganttDiagram-NO4QXBWP-Cz2sxU8F.js} +1 -1
- package/web/assets/{gitGraphDiagram-IHSO6WYX-Br0E6qyZ.js → gitGraphDiagram-IHSO6WYX-BSuz0yF-.js} +1 -1
- package/web/assets/index-DLn_2LPp.js +2 -0
- package/web/assets/index-uY9jLiL5.css +1 -0
- package/web/assets/{infoDiagram-FWYZ7A6U-Dgz0npJO.js → infoDiagram-FWYZ7A6U-CpeKgqoS.js} +1 -1
- package/web/assets/input-Bz_puamS.js +9 -0
- package/web/assets/{ishikawaDiagram-FXEZZL3T-rY5pdS3b.js → ishikawaDiagram-FXEZZL3T-5c2Tmknb.js} +1 -1
- package/web/assets/{journeyDiagram-5HDEW3XC-CKZALyR6.js → journeyDiagram-5HDEW3XC-Cu-wRkR4.js} +1 -1
- package/web/assets/{kanban-definition-HUTT4EX6-EGPY9Vda.js → kanban-definition-HUTT4EX6-BunSqkPe.js} +1 -1
- package/web/assets/{linear-DkJW9OwI.js → linear-C8e8bGVv.js} +1 -1
- package/web/assets/{mermaid.core-DVEpXYiF.js → mermaid.core-DLgjY1g2.js} +4 -4
- package/web/assets/{metadata-Bu_ffLUd.js → metadata-DEfJKlnd.js} +1 -1
- package/web/assets/{mindmap-definition-LN4V7U3C-BEOUVnDN.js → mindmap-definition-LN4V7U3C-W9ENYFOD.js} +1 -1
- package/web/assets/{pegDiagram-2B236MQR-DThjl3eK.js → pegDiagram-2B236MQR-0vPlHCFp.js} +1 -1
- package/web/assets/{pieDiagram-ENE6RG2P-DzmoGgw2.js → pieDiagram-ENE6RG2P-CakaveRV.js} +1 -1
- package/web/assets/{project-search-dialog-e2Jmhvfq.js → project-search-dialog-BSKA4peX.js} +1 -1
- package/web/assets/{quadrantDiagram-ABIIQ3AL-BqT8U3FS.js → quadrantDiagram-ABIIQ3AL-jxHw_egj.js} +1 -1
- package/web/assets/{railroadDiagram-RFXS5EU6-1k1tfPk1.js → railroadDiagram-RFXS5EU6-lIjDXPZt.js} +1 -1
- package/web/assets/{requirementDiagram-TGXJPOKE-bM4RTd2J.js → requirementDiagram-TGXJPOKE-C-JiT4bc.js} +1 -1
- package/web/assets/{sankeyDiagram-HTMAVEWB-TCgfqDLy.js → sankeyDiagram-HTMAVEWB-SuLPAw9X.js} +1 -1
- package/web/assets/{search-DQiFH2up.js → search-CKujW14f.js} +1 -1
- package/web/assets/{selection-popup-bqfgVd-L.js → selection-popup-CtxT9SWn.js} +3 -3
- package/web/assets/{sequenceDiagram-DBY2YBRQ-BRhGHI0i.js → sequenceDiagram-DBY2YBRQ-o9UwTkZR.js} +1 -1
- package/web/assets/{sizeCapture-X5ZJPWSS-EeUWgn0N.js → sizeCapture-X5ZJPWSS-ClbWGybF.js} +1 -1
- package/web/assets/{stateDiagram-2N3HPSRC-BSOG758d.js → stateDiagram-2N3HPSRC-Ce4avoWx.js} +1 -1
- package/web/assets/stateDiagram-v2-6OUMAXLB-CsrPTZoJ.js +1 -0
- package/web/assets/{swimlanes-5IMT3BWC-DpCo4aEm.js → swimlanes-5IMT3BWC-DMZI4XZT.js} +2 -2
- package/web/assets/swimlanesDiagram-G3AALYLV-pShSVcTd.js +8 -0
- package/web/assets/{timeline-definition-FHXFAJF6-BpaObe6u.js → timeline-definition-FHXFAJF6-CPIpIgPN.js} +1 -1
- package/web/assets/{vennDiagram-L72KCM5P-ClvUzW8B.js → vennDiagram-L72KCM5P-_rha8uDZ.js} +1 -1
- package/web/assets/view-context-BDtIUHQy.js +229 -0
- package/web/assets/{viewer-capabilities-CFBwvpcI.js → viewer-capabilities-YYZqMs56.js} +1 -1
- package/web/assets/{wardleyDiagram-EHGQE667-Dg1CX0Fl.js → wardleyDiagram-EHGQE667-D4EAOS35.js} +1 -1
- package/web/assets/{xychartDiagram-FW5EYKEG-C0c9zQTr.js → xychartDiagram-FW5EYKEG-DR8PwXpe.js} +1 -1
- package/web/index.html +2 -2
- package/kernel/packages/agents/eslint.config.js +0 -10
- package/kernel/packages/agents/package.json +0 -75
- package/kernel/packages/agents/src/agent-card.tsx +0 -334
- package/kernel/packages/agents/src/client.tsx +0 -13
- package/kernel/packages/agents/src/index.ts +0 -18
- package/kernel/packages/agents/src/manifest.ts +0 -7
- package/kernel/packages/agents/src/node.ts +0 -447
- package/kernel/packages/agents/src/profiles.ts +0 -137
- package/kernel/packages/agents/src/resolve.ts +0 -69
- package/kernel/packages/agents/src/server.ts +0 -60
- package/kernel/packages/agents/src/types.ts +0 -82
- package/kernel/packages/agents/src/viewer.tsx +0 -370
- package/kernel/packages/agents/test/profiles.test.mjs +0 -88
- package/kernel/packages/agents/test/resolve.test.mjs +0 -729
- package/kernel/packages/agents/tsconfig.json +0 -17
- package/kernel/packages/api/test/agents-loading.test.ts +0 -94
- package/kernel/packages/ui/src/components/folder-skill-list.tsx +0 -62
- package/web/assets/app-Debw-lUT.js +0 -2
- package/web/assets/app-options-UU_JlJQv.js +0 -25
- package/web/assets/channel-BgYLn5Cm.js +0 -1
- package/web/assets/classDiagram-OUVF2IWQ-Fzhmfbkt.js +0 -1
- package/web/assets/classDiagram-v2-EOCWNBFH-Fzhmfbkt.js +0 -1
- package/web/assets/client-C1WdY7jQ.js +0 -22
- package/web/assets/client-D__L4Hl0.js +0 -17
- package/web/assets/client-DoMhF9Tv.js +0 -5
- package/web/assets/folder-filter-bar-BHz7s9Vb.js +0 -4
- package/web/assets/folder-landing-Byh8W67L.js +0 -54
- package/web/assets/folder-list-jMyo-7pV.js +0 -1
- package/web/assets/folder-metadata-bCocvxpP.js +0 -2
- package/web/assets/folder-mobile-bar-DvvyOS-a.js +0 -1
- package/web/assets/folder-plugin-view-sib0Dwfw.js +0 -3
- package/web/assets/index-4Xh9UKim.js +0 -1
- package/web/assets/index-Bu75S2qS.js +0 -1
- package/web/assets/index-CPcMcCUY.js +0 -2
- package/web/assets/index-CXxkvzNJ.css +0 -1
- package/web/assets/select-CkOwL81C.js +0 -30
- package/web/assets/stateDiagram-v2-6OUMAXLB-DUeGDz1r.js +0 -1
- package/web/assets/swimlanesDiagram-G3AALYLV-BGOaCfyV.js +0 -8
- package/web/assets/use-folder-filter-hA6fa7nm.js +0 -1
- package/web/assets/view-context-CVvDw2JM.js +0 -229
package/dist/core/runtime.js
CHANGED
|
@@ -17027,8 +17027,8 @@ var require__2020 = __commonJS(function(exports, module) {
|
|
|
17027
17027
|
import {
|
|
17028
17028
|
createServer
|
|
17029
17029
|
} from "node:http";
|
|
17030
|
-
import { readFile as
|
|
17031
|
-
import { extname as extname7, isAbsolute as isAbsolute7, relative as relative11, resolve as
|
|
17030
|
+
import { readFile as readFile9, realpath as realpath5, stat as stat8 } from "node:fs/promises";
|
|
17031
|
+
import { extname as extname7, isAbsolute as isAbsolute7, relative as relative11, resolve as resolve12 } from "node:path";
|
|
17032
17032
|
|
|
17033
17033
|
// packages/api/src/server/watcher.ts
|
|
17034
17034
|
import { existsSync, statSync, watch } from "node:fs";
|
|
@@ -21857,13 +21857,6 @@ var project = object({
|
|
|
21857
21857
|
relativePath: string2(),
|
|
21858
21858
|
worktree: string2()
|
|
21859
21859
|
});
|
|
21860
|
-
var skill = object({
|
|
21861
|
-
description: string2().optional(),
|
|
21862
|
-
name: string2(),
|
|
21863
|
-
openHref: string2().optional(),
|
|
21864
|
-
relativePath: string2(),
|
|
21865
|
-
source: _enum(["global", "local"])
|
|
21866
|
-
});
|
|
21867
21860
|
var session = object({
|
|
21868
21861
|
client: _enum(["claude", "codex", "cursor", "opencode", "pi"]),
|
|
21869
21862
|
href: string2().optional(),
|
|
@@ -21891,6 +21884,7 @@ var workspace = object({
|
|
|
21891
21884
|
var plugin = object({
|
|
21892
21885
|
count: number2().optional(),
|
|
21893
21886
|
error: string2().optional(),
|
|
21887
|
+
icon: object({ paths: array(string2().min(1)).min(1) }).optional(),
|
|
21894
21888
|
id: string2(),
|
|
21895
21889
|
label: string2()
|
|
21896
21890
|
});
|
|
@@ -21908,7 +21902,6 @@ var folderMetadataSchema = object({
|
|
|
21908
21902
|
plugins: plugins.optional(),
|
|
21909
21903
|
projects: items(project),
|
|
21910
21904
|
sessions: items(session),
|
|
21911
|
-
skills: items(skill).optional(),
|
|
21912
21905
|
workspace: workspace.optional()
|
|
21913
21906
|
});
|
|
21914
21907
|
var collection = coreCollectionSchema;
|
|
@@ -21932,7 +21925,6 @@ var metadataSchemas = {
|
|
|
21932
21925
|
configWarnings: array(string2()).optional(),
|
|
21933
21926
|
plugins: plugins.optional()
|
|
21934
21927
|
}),
|
|
21935
|
-
skills: object({ ...folder, skills: items(skill) }),
|
|
21936
21928
|
sessions: folderMetadataSchema,
|
|
21937
21929
|
calendar: folderMetadataSchema,
|
|
21938
21930
|
schema: folderMetadataSchema
|
|
@@ -22145,15 +22137,15 @@ function sendContract(response, url, body, headers = {}) {
|
|
|
22145
22137
|
|
|
22146
22138
|
// packages/api/src/server/folder-metadata-plugin.ts
|
|
22147
22139
|
import { realpathSync as realpathSync2 } from "node:fs";
|
|
22148
|
-
import { readdir as readdir5, readFile as
|
|
22149
|
-
import { homedir as
|
|
22140
|
+
import { readdir as readdir5, readFile as readFile8, stat as stat7 } from "node:fs/promises";
|
|
22141
|
+
import { homedir as homedir3 } from "node:os";
|
|
22150
22142
|
import {
|
|
22151
|
-
basename as
|
|
22152
|
-
dirname as
|
|
22143
|
+
basename as basename6,
|
|
22144
|
+
dirname as dirname9,
|
|
22153
22145
|
extname as extname6,
|
|
22154
22146
|
isAbsolute as isAbsolute6,
|
|
22155
22147
|
relative as relative10,
|
|
22156
|
-
resolve as
|
|
22148
|
+
resolve as resolve11,
|
|
22157
22149
|
sep as sep7
|
|
22158
22150
|
} from "node:path";
|
|
22159
22151
|
|
|
@@ -37330,526 +37322,22 @@ async function workspaceBreadcrumbIcons(breadcrumbs, assetFiles, assets = {}) {
|
|
|
37330
37322
|
// packages/api/src/server/plugins.ts
|
|
37331
37323
|
import { pathToFileURL } from "node:url";
|
|
37332
37324
|
import { existsSync as existsSync3 } from "node:fs";
|
|
37333
|
-
import { dirname as
|
|
37334
|
-
|
|
37335
|
-
// packages/agents/src/manifest.ts
|
|
37336
|
-
var agentsManifest = {
|
|
37337
|
-
id: "agents",
|
|
37338
|
-
label: "Agents"
|
|
37339
|
-
};
|
|
37340
|
-
|
|
37341
|
-
// packages/agents/src/node.ts
|
|
37342
|
-
import { lstat, readFile as readFile8, realpath as realpath5, stat as stat6 } from "node:fs/promises";
|
|
37343
|
-
import { homedir as homedir3 } from "node:os";
|
|
37344
|
-
import { basename as basename5, dirname as dirname7, resolve as resolve9 } from "node:path";
|
|
37345
|
-
|
|
37346
|
-
// packages/agents/src/profiles.ts
|
|
37347
|
-
var CLIENT_ORDER = [
|
|
37348
|
-
"generic",
|
|
37349
|
-
"codex",
|
|
37350
|
-
"claude",
|
|
37351
|
-
"pi"
|
|
37352
|
-
];
|
|
37353
|
-
var PROFILES = {
|
|
37354
|
-
generic: {
|
|
37355
|
-
id: "generic",
|
|
37356
|
-
label: "Generic",
|
|
37357
|
-
scope: "root",
|
|
37358
|
-
files: ["AGENTS.md"],
|
|
37359
|
-
filesMode: "first",
|
|
37360
|
-
globalDir: ".agents",
|
|
37361
|
-
globalFiles: ["AGENTS.md"],
|
|
37362
|
-
globalMode: "first",
|
|
37363
|
-
verified: false,
|
|
37364
|
-
note: "Reference view of the ancestor AGENTS.md chain. No client execution behavior is claimed.",
|
|
37365
|
-
limits: "Walks to the filesystem root like Stepladder; only AGENTS.md files are read."
|
|
37366
|
-
},
|
|
37367
|
-
codex: {
|
|
37368
|
-
id: "codex",
|
|
37369
|
-
label: "Codex",
|
|
37370
|
-
scope: "git",
|
|
37371
|
-
files: ["AGENTS.override.md", "AGENTS.md"],
|
|
37372
|
-
filesMode: "first",
|
|
37373
|
-
globalDir: ".codex",
|
|
37374
|
-
globalEnv: "CODEX_HOME",
|
|
37375
|
-
globalFiles: ["AGENTS.override.md", "AGENTS.md"],
|
|
37376
|
-
globalMode: "first",
|
|
37377
|
-
verified: true,
|
|
37378
|
-
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.",
|
|
37379
|
-
limits: "A configured model_instructions_file fallback is not applied here; a warning appears when it is configured."
|
|
37380
|
-
},
|
|
37381
|
-
claude: {
|
|
37382
|
-
id: "claude",
|
|
37383
|
-
label: "Claude Code",
|
|
37384
|
-
scope: "root",
|
|
37385
|
-
files: ["CLAUDE.md", ".claude/CLAUDE.md", "CLAUDE.local.md"],
|
|
37386
|
-
filesMode: "all",
|
|
37387
|
-
globalDir: ".claude",
|
|
37388
|
-
globalFiles: ["CLAUDE.md"],
|
|
37389
|
-
globalMode: "first",
|
|
37390
|
-
verified: true,
|
|
37391
|
-
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.",
|
|
37392
|
-
limits: "Conditional .claude/rules/*.md files and @path imports are not expanded here."
|
|
37393
|
-
},
|
|
37394
|
-
pi: {
|
|
37395
|
-
id: "pi",
|
|
37396
|
-
label: "Pi",
|
|
37397
|
-
scope: "root",
|
|
37398
|
-
files: [
|
|
37399
|
-
"AGENTS.override.md",
|
|
37400
|
-
"AGENTS.md",
|
|
37401
|
-
"AGENTS.MD",
|
|
37402
|
-
"CLAUDE.md",
|
|
37403
|
-
"CLAUDE.MD"
|
|
37404
|
-
],
|
|
37405
|
-
filesMode: "first",
|
|
37406
|
-
globalDir: ".pi/agent",
|
|
37407
|
-
globalEnv: "PI_CODING_AGENT_DIR",
|
|
37408
|
-
globalFiles: [
|
|
37409
|
-
"AGENTS.override.md",
|
|
37410
|
-
"AGENTS.md",
|
|
37411
|
-
"AGENTS.MD",
|
|
37412
|
-
"CLAUDE.md",
|
|
37413
|
-
"CLAUDE.MD"
|
|
37414
|
-
],
|
|
37415
|
-
globalMode: "first",
|
|
37416
|
-
verified: true,
|
|
37417
|
-
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.",
|
|
37418
|
-
limits: "Uses the same candidate list for the global directory."
|
|
37419
|
-
}
|
|
37420
|
-
};
|
|
37421
|
-
function parseClientFilter(value) {
|
|
37422
|
-
if (value === "generic" || value === "codex" || value === "claude" || value === "pi") {
|
|
37423
|
-
return value;
|
|
37424
|
-
}
|
|
37425
|
-
return "pi";
|
|
37426
|
-
}
|
|
37427
|
-
|
|
37428
|
-
// packages/agents/src/resolve.ts
|
|
37429
|
-
var LEVEL_ORDER = {
|
|
37430
|
-
project: 0,
|
|
37431
|
-
parent: 1,
|
|
37432
|
-
repository: 2,
|
|
37433
|
-
linked: 3,
|
|
37434
|
-
global: 4
|
|
37435
|
-
};
|
|
37436
|
-
function unique(values) {
|
|
37437
|
-
return [...new Set(values)];
|
|
37438
|
-
}
|
|
37439
|
-
function pathSegments(path) {
|
|
37440
|
-
const normalized = path.replaceAll("\\", "/").replace(/\/+$/, "");
|
|
37441
|
-
if (!normalized)
|
|
37442
|
-
return 0;
|
|
37443
|
-
return normalized.split("/").length;
|
|
37444
|
-
}
|
|
37445
|
-
function dedupeSources(sources) {
|
|
37446
|
-
const merged = new Map;
|
|
37447
|
-
for (const source of sources) {
|
|
37448
|
-
const existing = merged.get(source.id);
|
|
37449
|
-
if (!existing) {
|
|
37450
|
-
merged.set(source.id, {
|
|
37451
|
-
...source,
|
|
37452
|
-
clientIds: [...source.clientIds],
|
|
37453
|
-
sourcePaths: unique([...source.sourcePaths])
|
|
37454
|
-
});
|
|
37455
|
-
continue;
|
|
37456
|
-
}
|
|
37457
|
-
existing.clientIds = unique([...existing.clientIds, ...source.clientIds]);
|
|
37458
|
-
existing.sourcePaths = unique([
|
|
37459
|
-
...existing.sourcePaths,
|
|
37460
|
-
...source.sourcePaths
|
|
37461
|
-
]);
|
|
37462
|
-
if (existing.status !== "loaded" && source.status === "loaded") {
|
|
37463
|
-
existing.status = source.status;
|
|
37464
|
-
existing.text = source.text;
|
|
37465
|
-
existing.size = source.size;
|
|
37466
|
-
existing.reason = source.reason;
|
|
37467
|
-
}
|
|
37468
|
-
if (source.override)
|
|
37469
|
-
existing.override = true;
|
|
37470
|
-
}
|
|
37471
|
-
return [...merged.values()];
|
|
37472
|
-
}
|
|
37473
|
-
function sortSources(sources) {
|
|
37474
|
-
return [...sources].sort((left, right) => {
|
|
37475
|
-
const level = LEVEL_ORDER[left.level] - LEVEL_ORDER[right.level];
|
|
37476
|
-
if (level !== 0)
|
|
37477
|
-
return level;
|
|
37478
|
-
const depth = pathSegments(right.directory) - pathSegments(left.directory);
|
|
37479
|
-
if (depth !== 0)
|
|
37480
|
-
return depth;
|
|
37481
|
-
return left.filename.localeCompare(right.filename);
|
|
37482
|
-
});
|
|
37483
|
-
}
|
|
37484
|
-
|
|
37485
|
-
// packages/agents/src/node.ts
|
|
37486
|
-
async function canonicalize(path) {
|
|
37487
|
-
try {
|
|
37488
|
-
return await realpath5(path);
|
|
37489
|
-
} catch {
|
|
37490
|
-
return null;
|
|
37491
|
-
}
|
|
37492
|
-
}
|
|
37493
|
-
async function hasGit(folder) {
|
|
37494
|
-
const entry = await lstat(resolve9(folder, ".git")).catch(() => {
|
|
37495
|
-
return;
|
|
37496
|
-
});
|
|
37497
|
-
return Boolean(entry);
|
|
37498
|
-
}
|
|
37499
|
-
async function nearestGitRoot(folder) {
|
|
37500
|
-
let current = folder;
|
|
37501
|
-
while (true) {
|
|
37502
|
-
if (await hasGit(current))
|
|
37503
|
-
return current;
|
|
37504
|
-
const parent = dirname7(current);
|
|
37505
|
-
if (parent === current)
|
|
37506
|
-
return null;
|
|
37507
|
-
current = parent;
|
|
37508
|
-
}
|
|
37509
|
-
}
|
|
37510
|
-
async function nearestRaggleRoot(folder) {
|
|
37511
|
-
let current = folder;
|
|
37512
|
-
while (true) {
|
|
37513
|
-
const entry = await lstat(resolve9(current, "raggle.json")).catch(() => {
|
|
37514
|
-
return;
|
|
37515
|
-
});
|
|
37516
|
-
if (entry)
|
|
37517
|
-
return current;
|
|
37518
|
-
const parent = dirname7(current);
|
|
37519
|
-
if (parent === current)
|
|
37520
|
-
return null;
|
|
37521
|
-
current = parent;
|
|
37522
|
-
}
|
|
37523
|
-
}
|
|
37524
|
-
async function ancestorBoundary(folder, scope) {
|
|
37525
|
-
let current = folder;
|
|
37526
|
-
while (true) {
|
|
37527
|
-
if (scope === "git" && await hasGit(current))
|
|
37528
|
-
return current;
|
|
37529
|
-
const parent = dirname7(current);
|
|
37530
|
-
if (parent === current)
|
|
37531
|
-
return current;
|
|
37532
|
-
current = parent;
|
|
37533
|
-
}
|
|
37534
|
-
}
|
|
37535
|
-
function ancestorChain(folder, boundary) {
|
|
37536
|
-
const chain = [];
|
|
37537
|
-
let current = folder;
|
|
37538
|
-
while (true) {
|
|
37539
|
-
chain.push(current);
|
|
37540
|
-
if (current === boundary)
|
|
37541
|
-
break;
|
|
37542
|
-
const parent = dirname7(current);
|
|
37543
|
-
if (parent === current)
|
|
37544
|
-
break;
|
|
37545
|
-
current = parent;
|
|
37546
|
-
}
|
|
37547
|
-
return chain;
|
|
37548
|
-
}
|
|
37549
|
-
function sourceLevel(index, total, scope) {
|
|
37550
|
-
if (total === 1)
|
|
37551
|
-
return "project";
|
|
37552
|
-
if (index === 0)
|
|
37553
|
-
return "project";
|
|
37554
|
-
if (scope === "git" && index === total - 1)
|
|
37555
|
-
return "repository";
|
|
37556
|
-
return "parent";
|
|
37557
|
-
}
|
|
37558
|
-
async function isRegularFile(path) {
|
|
37559
|
-
const details = await stat6(path).catch(() => {
|
|
37560
|
-
return;
|
|
37561
|
-
});
|
|
37562
|
-
return details?.isFile() === true;
|
|
37563
|
-
}
|
|
37564
|
-
function mergeChains(chains) {
|
|
37565
|
-
const byDirectory = new Map;
|
|
37566
|
-
const order = [];
|
|
37567
|
-
for (const chain of chains) {
|
|
37568
|
-
for (const entry of chain) {
|
|
37569
|
-
const existing = byDirectory.get(entry.directory);
|
|
37570
|
-
if (!existing) {
|
|
37571
|
-
byDirectory.set(entry.directory, {
|
|
37572
|
-
...entry,
|
|
37573
|
-
filenames: [...entry.filenames]
|
|
37574
|
-
});
|
|
37575
|
-
order.push(entry.directory);
|
|
37576
|
-
} else {
|
|
37577
|
-
for (const filename of entry.filenames) {
|
|
37578
|
-
if (!existing.filenames.includes(filename)) {
|
|
37579
|
-
existing.filenames.push(filename);
|
|
37580
|
-
}
|
|
37581
|
-
}
|
|
37582
|
-
}
|
|
37583
|
-
}
|
|
37584
|
-
}
|
|
37585
|
-
return order.map((directory) => byDirectory.get(directory));
|
|
37586
|
-
}
|
|
37587
|
-
async function selectFiles(directory, candidates, mode) {
|
|
37588
|
-
if (mode === "all") {
|
|
37589
|
-
const found = [];
|
|
37590
|
-
for (const relative of candidates) {
|
|
37591
|
-
if (await isRegularFile(resolve9(directory, relative))) {
|
|
37592
|
-
found.push({ filename: basename5(relative), relative });
|
|
37593
|
-
}
|
|
37594
|
-
}
|
|
37595
|
-
return found;
|
|
37596
|
-
}
|
|
37597
|
-
for (const relative of candidates) {
|
|
37598
|
-
if (await isRegularFile(resolve9(directory, relative))) {
|
|
37599
|
-
return [{ filename: basename5(relative), relative }];
|
|
37600
|
-
}
|
|
37601
|
-
}
|
|
37602
|
-
return [];
|
|
37603
|
-
}
|
|
37604
|
-
function expandHome(path, homeDir) {
|
|
37605
|
-
if (path === "~")
|
|
37606
|
-
return homeDir;
|
|
37607
|
-
if (path.startsWith("~/"))
|
|
37608
|
-
return resolve9(homeDir, path.slice(2));
|
|
37609
|
-
return path;
|
|
37610
|
-
}
|
|
37611
|
-
function globalDirectory(profile, homeDir) {
|
|
37612
|
-
if (profile.globalDir === null)
|
|
37613
|
-
return null;
|
|
37614
|
-
const envValue = profile.globalEnv ? process.env[profile.globalEnv]?.trim() : undefined;
|
|
37615
|
-
if (envValue)
|
|
37616
|
-
return expandHome(envValue, homeDir);
|
|
37617
|
-
if (profile.globalDir === "")
|
|
37618
|
-
return homeDir;
|
|
37619
|
-
return resolve9(homeDir, profile.globalDir);
|
|
37620
|
-
}
|
|
37621
|
-
function readError(error) {
|
|
37622
|
-
return error instanceof Error ? error.message : "Could not read file";
|
|
37623
|
-
}
|
|
37624
|
-
var INSTRUCTION_NAMES = new Set(Object.values(PROFILES).flatMap((profile) => [...profile.files, ...profile.globalFiles]).map((path) => basename5(path).toLowerCase()));
|
|
37625
|
-
async function codexModelInstructionsFile(codexHome) {
|
|
37626
|
-
try {
|
|
37627
|
-
const content = await readFile8(resolve9(codexHome, "config.toml"), "utf8");
|
|
37628
|
-
const match = /^\s*model_instructions_file\s*=\s*["']?([^"'\n]+)["']?\s*$/m.exec(content);
|
|
37629
|
-
return match?.[1]?.trim() ?? null;
|
|
37630
|
-
} catch {
|
|
37631
|
-
return null;
|
|
37632
|
-
}
|
|
37633
|
-
}
|
|
37634
|
-
async function loadSource(input) {
|
|
37635
|
-
const real = await canonicalize(input.literalPath);
|
|
37636
|
-
if (!real) {
|
|
37637
|
-
return {
|
|
37638
|
-
id: input.literalPath,
|
|
37639
|
-
path: input.literalPath,
|
|
37640
|
-
sourcePaths: [input.literalPath],
|
|
37641
|
-
filename: input.filename,
|
|
37642
|
-
directory: dirname7(input.literalPath),
|
|
37643
|
-
level: input.level,
|
|
37644
|
-
status: "unreadable",
|
|
37645
|
-
text: "",
|
|
37646
|
-
size: 0,
|
|
37647
|
-
clientIds: [input.clientId],
|
|
37648
|
-
override: input.override,
|
|
37649
|
-
applies: true,
|
|
37650
|
-
reason: "Path cannot be resolved"
|
|
37651
|
-
};
|
|
37652
|
-
}
|
|
37653
|
-
const record = {
|
|
37654
|
-
id: real,
|
|
37655
|
-
path: real,
|
|
37656
|
-
sourcePaths: [input.literalPath],
|
|
37657
|
-
filename: input.filename,
|
|
37658
|
-
directory: dirname7(real),
|
|
37659
|
-
level: input.level,
|
|
37660
|
-
status: "loaded",
|
|
37661
|
-
text: "",
|
|
37662
|
-
size: 0,
|
|
37663
|
-
clientIds: [input.clientId],
|
|
37664
|
-
override: input.override,
|
|
37665
|
-
applies: true
|
|
37666
|
-
};
|
|
37667
|
-
if (!INSTRUCTION_NAMES.has(basename5(real).toLowerCase())) {
|
|
37668
|
-
record.status = "unsafe";
|
|
37669
|
-
record.reason = "Symlink resolves to a non-instruction file";
|
|
37670
|
-
return record;
|
|
37671
|
-
}
|
|
37672
|
-
const details = await stat6(real).catch(() => {
|
|
37673
|
-
return;
|
|
37674
|
-
});
|
|
37675
|
-
if (!details?.isFile()) {
|
|
37676
|
-
record.status = "unreadable";
|
|
37677
|
-
record.reason = "Not a regular file";
|
|
37678
|
-
return record;
|
|
37679
|
-
}
|
|
37680
|
-
record.size = details.size;
|
|
37681
|
-
if (input.readText) {
|
|
37682
|
-
try {
|
|
37683
|
-
record.text = await readFile8(real, "utf8");
|
|
37684
|
-
} catch (error) {
|
|
37685
|
-
record.status = "unreadable";
|
|
37686
|
-
record.reason = readError(error);
|
|
37687
|
-
}
|
|
37688
|
-
}
|
|
37689
|
-
return record;
|
|
37690
|
-
}
|
|
37691
|
-
async function resolveAgents(options) {
|
|
37692
|
-
const homeDir = options.homeDir ?? homedir3();
|
|
37693
|
-
const client = options.client ?? "all";
|
|
37694
|
-
const readText = options.readText ?? true;
|
|
37695
|
-
const folder = await canonicalize(options.folder);
|
|
37696
|
-
if (!folder)
|
|
37697
|
-
throw new Error(`Folder not found: ${options.folder}`);
|
|
37698
|
-
const repositoryRoot = await nearestGitRoot(folder);
|
|
37699
|
-
const workspaceRoot = await nearestRaggleRoot(folder);
|
|
37700
|
-
const profileIds = client === "all" ? CLIENT_ORDER : [client];
|
|
37701
|
-
const sources = [];
|
|
37702
|
-
const warnings = [];
|
|
37703
|
-
const profileChains = [];
|
|
37704
|
-
for (const profileId of profileIds) {
|
|
37705
|
-
const profile = PROFILES[profileId];
|
|
37706
|
-
const boundary = workspaceRoot ?? await ancestorBoundary(folder, profile.scope);
|
|
37707
|
-
const ancestors = ancestorChain(folder, boundary);
|
|
37708
|
-
const chain = [];
|
|
37709
|
-
for (let index = 0;index < ancestors.length; index += 1) {
|
|
37710
|
-
const directory = ancestors[index];
|
|
37711
|
-
if (!directory)
|
|
37712
|
-
continue;
|
|
37713
|
-
const level = sourceLevel(index, ancestors.length, profile.scope);
|
|
37714
|
-
const files = await selectFiles(directory, profile.files, profile.filesMode);
|
|
37715
|
-
chain.push({
|
|
37716
|
-
directory,
|
|
37717
|
-
level,
|
|
37718
|
-
filenames: files.map((file) => file.filename)
|
|
37719
|
-
});
|
|
37720
|
-
for (const file of files) {
|
|
37721
|
-
const source = await loadSource({
|
|
37722
|
-
clientId: profileId,
|
|
37723
|
-
filename: file.filename,
|
|
37724
|
-
level,
|
|
37725
|
-
literalPath: resolve9(directory, file.relative),
|
|
37726
|
-
override: file.filename === "AGENTS.override.md",
|
|
37727
|
-
readText
|
|
37728
|
-
});
|
|
37729
|
-
sources.push(source);
|
|
37730
|
-
}
|
|
37731
|
-
}
|
|
37732
|
-
profileChains.push(chain);
|
|
37733
|
-
for (const linkedFolder of options.linkedFolders ?? []) {
|
|
37734
|
-
const canonicalLinked = await canonicalize(linkedFolder);
|
|
37735
|
-
if (!canonicalLinked || canonicalLinked === folder)
|
|
37736
|
-
continue;
|
|
37737
|
-
const linkedFiles = await selectFiles(canonicalLinked, profile.files, profile.filesMode);
|
|
37738
|
-
chain.push({
|
|
37739
|
-
directory: canonicalLinked,
|
|
37740
|
-
level: "linked",
|
|
37741
|
-
filenames: linkedFiles.map((file) => file.filename)
|
|
37742
|
-
});
|
|
37743
|
-
for (const file of linkedFiles) {
|
|
37744
|
-
const source = await loadSource({
|
|
37745
|
-
clientId: profileId,
|
|
37746
|
-
filename: file.filename,
|
|
37747
|
-
level: "linked",
|
|
37748
|
-
literalPath: resolve9(canonicalLinked, file.relative),
|
|
37749
|
-
override: file.filename === "AGENTS.override.md",
|
|
37750
|
-
readText
|
|
37751
|
-
});
|
|
37752
|
-
sources.push(source);
|
|
37753
|
-
}
|
|
37754
|
-
}
|
|
37755
|
-
const globalDir = globalDirectory(profile, homeDir);
|
|
37756
|
-
if (globalDir) {
|
|
37757
|
-
const globals = await selectFiles(globalDir, profile.globalFiles, profile.globalMode);
|
|
37758
|
-
for (const file of globals) {
|
|
37759
|
-
const source = await loadSource({
|
|
37760
|
-
clientId: profileId,
|
|
37761
|
-
filename: file.filename,
|
|
37762
|
-
level: "global",
|
|
37763
|
-
literalPath: resolve9(globalDir, file.relative),
|
|
37764
|
-
override: file.filename === "AGENTS.override.md",
|
|
37765
|
-
readText
|
|
37766
|
-
});
|
|
37767
|
-
sources.push(source);
|
|
37768
|
-
}
|
|
37769
|
-
if (globals.length === 0 && profile.globalFiles.length > 0) {
|
|
37770
|
-
warnings.push({
|
|
37771
|
-
kind: "missing",
|
|
37772
|
-
path: globalDir,
|
|
37773
|
-
clientIds: [profileId],
|
|
37774
|
-
reason: "No global instruction file found in this directory"
|
|
37775
|
-
});
|
|
37776
|
-
}
|
|
37777
|
-
}
|
|
37778
|
-
if (profileId === "codex") {
|
|
37779
|
-
const codexHome = globalDirectory(profile, homeDir);
|
|
37780
|
-
if (codexHome) {
|
|
37781
|
-
const fallback = await codexModelInstructionsFile(codexHome);
|
|
37782
|
-
if (fallback) {
|
|
37783
|
-
warnings.push({
|
|
37784
|
-
kind: "unsupported",
|
|
37785
|
-
clientIds: [profileId],
|
|
37786
|
-
reason: `Codex model_instructions_file (${fallback}) is configured but not applied here`
|
|
37787
|
-
});
|
|
37788
|
-
}
|
|
37789
|
-
}
|
|
37790
|
-
}
|
|
37791
|
-
}
|
|
37792
|
-
const deduped = dedupeSources(sources);
|
|
37793
|
-
const ordered = sortSources(deduped);
|
|
37794
|
-
return {
|
|
37795
|
-
folder,
|
|
37796
|
-
repositoryRoot,
|
|
37797
|
-
client,
|
|
37798
|
-
sources: ordered,
|
|
37799
|
-
warnings,
|
|
37800
|
-
chain: mergeChains(profileChains)
|
|
37801
|
-
};
|
|
37802
|
-
}
|
|
37803
|
-
|
|
37804
|
-
// packages/agents/src/server.ts
|
|
37805
|
-
function createAgentsPlugin(options = {}) {
|
|
37806
|
-
return {
|
|
37807
|
-
...agentsManifest,
|
|
37808
|
-
async detect(context) {
|
|
37809
|
-
try {
|
|
37810
|
-
const result = await resolveAgents({
|
|
37811
|
-
folder: context.folder,
|
|
37812
|
-
client: "all",
|
|
37813
|
-
homeDir: options.homeDir,
|
|
37814
|
-
linkedFolders: context.linkedFolders,
|
|
37815
|
-
readText: false
|
|
37816
|
-
});
|
|
37817
|
-
return { count: result.sources.length, status: "available" };
|
|
37818
|
-
} catch {
|
|
37819
|
-
return { status: "available" };
|
|
37820
|
-
}
|
|
37821
|
-
},
|
|
37822
|
-
async handle(context, subpath) {
|
|
37823
|
-
const client = parseClientFilter(subpath.trim() || null);
|
|
37824
|
-
const result = await resolveAgents({
|
|
37825
|
-
folder: context.folder,
|
|
37826
|
-
client,
|
|
37827
|
-
homeDir: options.homeDir,
|
|
37828
|
-
linkedFolders: context.linkedFolders
|
|
37829
|
-
});
|
|
37830
|
-
return {
|
|
37831
|
-
kind: "available",
|
|
37832
|
-
data: {
|
|
37833
|
-
client,
|
|
37834
|
-
folder: result.folder,
|
|
37835
|
-
repositoryRoot: result.repositoryRoot,
|
|
37836
|
-
sources: result.sources,
|
|
37837
|
-
status: "available",
|
|
37838
|
-
warnings: result.warnings,
|
|
37839
|
-
chain: result.chain
|
|
37840
|
-
}
|
|
37841
|
-
};
|
|
37842
|
-
}
|
|
37843
|
-
};
|
|
37844
|
-
}
|
|
37325
|
+
import { dirname as dirname7, resolve as resolve10, sep as sep6 } from "node:path";
|
|
37845
37326
|
|
|
37846
37327
|
// packages/notes/src/server.ts
|
|
37847
|
-
import { readdir as readdir4, stat as
|
|
37848
|
-
import { basename as
|
|
37328
|
+
import { readdir as readdir4, stat as stat6 } from "node:fs/promises";
|
|
37329
|
+
import { basename as basename5, extname as extname5, relative as relative8, resolve as resolve9, sep as sep5 } from "node:path";
|
|
37849
37330
|
|
|
37850
37331
|
// packages/notes/src/manifest.ts
|
|
37851
37332
|
var notesManifest = {
|
|
37852
37333
|
id: "notes",
|
|
37334
|
+
icon: {
|
|
37335
|
+
paths: [
|
|
37336
|
+
"M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8Z",
|
|
37337
|
+
"M14 2v6h6",
|
|
37338
|
+
"M8 13h8M8 17h6"
|
|
37339
|
+
]
|
|
37340
|
+
},
|
|
37853
37341
|
label: "Notes"
|
|
37854
37342
|
};
|
|
37855
37343
|
|
|
@@ -37862,7 +37350,7 @@ async function listMarkdownFiles(folder) {
|
|
|
37862
37350
|
for (const entry of entries) {
|
|
37863
37351
|
if (entry.name === "node_modules" || entry.name.startsWith("."))
|
|
37864
37352
|
continue;
|
|
37865
|
-
const path =
|
|
37353
|
+
const path = resolve9(current, entry.name);
|
|
37866
37354
|
if (entry.isDirectory()) {
|
|
37867
37355
|
await visit(path);
|
|
37868
37356
|
continue;
|
|
@@ -37870,12 +37358,12 @@ async function listMarkdownFiles(folder) {
|
|
|
37870
37358
|
if (!entry.isFile() || !markdownExtensions.has(extname5(entry.name))) {
|
|
37871
37359
|
continue;
|
|
37872
37360
|
}
|
|
37873
|
-
const details = await
|
|
37361
|
+
const details = await stat6(path).catch(() => {
|
|
37874
37362
|
return;
|
|
37875
37363
|
});
|
|
37876
37364
|
files.push({
|
|
37877
37365
|
activityAt: details?.mtimeMs ?? 0,
|
|
37878
|
-
name:
|
|
37366
|
+
name: basename5(entry.name, extname5(entry.name)),
|
|
37879
37367
|
relativePath: relative8(folder, path).split(sep5).join("/")
|
|
37880
37368
|
});
|
|
37881
37369
|
}
|
|
@@ -37928,16 +37416,11 @@ function configuredFolderServerRegistry(registry, resolvedConfig) {
|
|
|
37928
37416
|
];
|
|
37929
37417
|
return new Map(ids.map((id) => [id, registry.get(id)]));
|
|
37930
37418
|
}
|
|
37931
|
-
function createFolderServerPlugins(
|
|
37932
|
-
return [
|
|
37933
|
-
createAgentsPlugin({
|
|
37934
|
-
homeDir: options.agentsHomeDir
|
|
37935
|
-
}),
|
|
37936
|
-
createNotesPlugin()
|
|
37937
|
-
];
|
|
37419
|
+
function createFolderServerPlugins() {
|
|
37420
|
+
return [createNotesPlugin()];
|
|
37938
37421
|
}
|
|
37939
|
-
function folderServerRegistry(
|
|
37940
|
-
return new Map(createFolderServerPlugins(
|
|
37422
|
+
function folderServerRegistry() {
|
|
37423
|
+
return new Map(createFolderServerPlugins().map((plugin) => [plugin.id, plugin]));
|
|
37941
37424
|
}
|
|
37942
37425
|
function externalServerEntries() {
|
|
37943
37426
|
const source = process.env.KENNEL_EXTERNAL_SERVER_ENTRIES;
|
|
@@ -37957,14 +37440,14 @@ function externalServerEntries() {
|
|
|
37957
37440
|
return { id: item.id, module: item.module, symbol: item.symbol, trigger: item.trigger };
|
|
37958
37441
|
});
|
|
37959
37442
|
}
|
|
37960
|
-
async function folderServerRegistryAsync(
|
|
37961
|
-
const registry = folderServerRegistry(
|
|
37443
|
+
async function folderServerRegistryAsync() {
|
|
37444
|
+
const registry = folderServerRegistry();
|
|
37962
37445
|
for (const entry of externalServerEntries()) {
|
|
37963
37446
|
if (registry.has(entry.id))
|
|
37964
37447
|
throw new Error(`External plugin id collides with core plugin: ${entry.id}`);
|
|
37965
37448
|
const imported = await import(pathToFileURL(entry.module).href);
|
|
37966
37449
|
const value = imported[entry.symbol];
|
|
37967
|
-
const plugin = typeof value === "function" ? value(
|
|
37450
|
+
const plugin = typeof value === "function" ? value() : value;
|
|
37968
37451
|
if (!plugin || typeof plugin !== "object")
|
|
37969
37452
|
throw new Error(`External plugin ${entry.id} did not export ${entry.symbol}`);
|
|
37970
37453
|
const server = plugin;
|
|
@@ -37976,7 +37459,7 @@ async function folderServerRegistryAsync(options = {}) {
|
|
|
37976
37459
|
...server,
|
|
37977
37460
|
async detect(context) {
|
|
37978
37461
|
const detection = await server.detect(context);
|
|
37979
|
-
if (detection.status === "unavailable" && existsSync3(
|
|
37462
|
+
if (detection.status === "unavailable" && existsSync3(resolve10(context.folder, entry.trigger))) {
|
|
37980
37463
|
return { status: "available" };
|
|
37981
37464
|
}
|
|
37982
37465
|
return detection;
|
|
@@ -38021,7 +37504,7 @@ import { execFile as execFile3 } from "node:child_process";
|
|
|
38021
37504
|
import { execFile as execFile2 } from "node:child_process";
|
|
38022
37505
|
import { existsSync as existsSync4 } from "node:fs";
|
|
38023
37506
|
import { createRequire as createRequire2 } from "node:module";
|
|
38024
|
-
import { dirname as
|
|
37507
|
+
import { dirname as dirname8, join as join4 } from "node:path";
|
|
38025
37508
|
import { fileURLToPath } from "node:url";
|
|
38026
37509
|
var script = `
|
|
38027
37510
|
const local = require(process.argv[1]);
|
|
@@ -38044,11 +37527,11 @@ function resolveLocalModule(from = import.meta.url) {
|
|
|
38044
37527
|
try {
|
|
38045
37528
|
candidates.push(require2.resolve("@raggle-ai/local"));
|
|
38046
37529
|
} catch {}
|
|
38047
|
-
let directory =
|
|
38048
|
-
while (
|
|
37530
|
+
let directory = dirname8(fileURLToPath(from));
|
|
37531
|
+
while (dirname8(directory) !== directory) {
|
|
38049
37532
|
if (existsSync4(join4(directory, "raggle.json"))) {
|
|
38050
37533
|
for (const candidate of [
|
|
38051
|
-
join4(
|
|
37534
|
+
join4(dirname8(directory), "raggle-ai-scout", "packages", "local"),
|
|
38052
37535
|
join4(directory, "..", "..", "raggle-ai-scout", "packages", "local")
|
|
38053
37536
|
]) {
|
|
38054
37537
|
if (!candidates.includes(candidate))
|
|
@@ -38056,7 +37539,7 @@ function resolveLocalModule(from = import.meta.url) {
|
|
|
38056
37539
|
}
|
|
38057
37540
|
break;
|
|
38058
37541
|
}
|
|
38059
|
-
directory =
|
|
37542
|
+
directory = dirname8(directory);
|
|
38060
37543
|
}
|
|
38061
37544
|
for (const candidate of candidates) {
|
|
38062
37545
|
try {
|
|
@@ -38065,7 +37548,7 @@ function resolveLocalModule(from = import.meta.url) {
|
|
|
38065
37548
|
return candidate;
|
|
38066
37549
|
} catch {}
|
|
38067
37550
|
}
|
|
38068
|
-
return candidates[0] ?? join4(
|
|
37551
|
+
return candidates[0] ?? join4(dirname8(fileURLToPath(from)), "..", "..", "..", "raggle-ai-scout", "packages", "local");
|
|
38069
37552
|
}
|
|
38070
37553
|
function discoverLinkedFolders(folder, signal, modulePath = resolveLocalModule()) {
|
|
38071
37554
|
return new Promise((resolve, reject) => {
|
|
@@ -38401,24 +37884,6 @@ var {
|
|
|
38401
37884
|
searchProjectIndex,
|
|
38402
37885
|
sortProjectList
|
|
38403
37886
|
} = local;
|
|
38404
|
-
function skillDescription(content) {
|
|
38405
|
-
if (!content.startsWith(`---
|
|
38406
|
-
`))
|
|
38407
|
-
return;
|
|
38408
|
-
const end = content.indexOf(`
|
|
38409
|
-
---`, 4);
|
|
38410
|
-
if (end < 0)
|
|
38411
|
-
return;
|
|
38412
|
-
const schema = $parse(content.slice(4, end));
|
|
38413
|
-
return typeof schema.description === "string" ? schema.description : undefined;
|
|
38414
|
-
}
|
|
38415
|
-
function skillSource(folder, root) {
|
|
38416
|
-
if (root === folder)
|
|
38417
|
-
return "local";
|
|
38418
|
-
if (root.startsWith(resolve12(folder, ".gtl") + sep7))
|
|
38419
|
-
return "local";
|
|
38420
|
-
return "global";
|
|
38421
|
-
}
|
|
38422
37887
|
var maxIconBytes3 = 512 * 1024;
|
|
38423
37888
|
var iconTypes2 = new Map([
|
|
38424
37889
|
[".jpeg", "image/jpeg"],
|
|
@@ -38464,11 +37929,8 @@ async function configuredAiInputModule(folder) {
|
|
|
38464
37929
|
const module = config.aiInput?.module;
|
|
38465
37930
|
return typeof module === "string" && module.trim() ? module.trim() : null;
|
|
38466
37931
|
}
|
|
38467
|
-
function label(value) {
|
|
38468
|
-
return value.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[-_]+/g, " ").replace(/\b\w/g, (match) => match.toUpperCase());
|
|
38469
|
-
}
|
|
38470
37932
|
function folderPath(value, root, lockedRoot) {
|
|
38471
|
-
const folder = realpathSync2(
|
|
37933
|
+
const folder = realpathSync2(resolve11(value ?? root));
|
|
38472
37934
|
if (!lockedRoot)
|
|
38473
37935
|
return folder;
|
|
38474
37936
|
const path = relative10(lockedRoot, folder);
|
|
@@ -38528,12 +37990,12 @@ async function searchIconDataUrl(icon) {
|
|
|
38528
37990
|
const mediaType = searchIconTypes.get(extname6(icon).toLowerCase());
|
|
38529
37991
|
if (!mediaType)
|
|
38530
37992
|
return;
|
|
38531
|
-
const details = await
|
|
37993
|
+
const details = await stat7(icon).catch(() => {
|
|
38532
37994
|
return;
|
|
38533
37995
|
});
|
|
38534
37996
|
if (!details?.size || details.size > maxIconBytes3)
|
|
38535
37997
|
return;
|
|
38536
|
-
return `data:${mediaType};base64,${(await
|
|
37998
|
+
return `data:${mediaType};base64,${(await readFile8(icon)).toString("base64")}`;
|
|
38537
37999
|
}
|
|
38538
38000
|
async function iconWithFaviconFallback(folder, assets, assetFiles) {
|
|
38539
38001
|
return folderIcon(folder, assets, assetFiles, async (folderName) => {
|
|
@@ -38567,76 +38029,19 @@ async function hydrateAssets(metadata, assetFiles) {
|
|
|
38567
38029
|
projects: { items: projectItems }
|
|
38568
38030
|
};
|
|
38569
38031
|
}
|
|
38570
|
-
function
|
|
38032
|
+
function unique(values) {
|
|
38571
38033
|
return [...new Set(values)];
|
|
38572
38034
|
}
|
|
38573
|
-
async function existingDirectory(path) {
|
|
38574
|
-
const details = await stat8(path).catch(() => {
|
|
38575
|
-
return;
|
|
38576
|
-
});
|
|
38577
|
-
return details?.isDirectory() ? path : undefined;
|
|
38578
|
-
}
|
|
38579
|
-
function metadataPaths(metadata) {
|
|
38580
|
-
return (metadata.files?.items ?? []).flatMap((file) => [file.path, file.relativePath]).filter((path) => Boolean(path));
|
|
38581
|
-
}
|
|
38582
|
-
function ancestorFolders(folder) {
|
|
38583
|
-
const folders = [];
|
|
38584
|
-
for (let current = folder;dirname10(current) !== current; current = dirname10(current)) {
|
|
38585
|
-
folders.push(current);
|
|
38586
|
-
}
|
|
38587
|
-
return folders;
|
|
38588
|
-
}
|
|
38589
|
-
async function linkedSkillRoots(folder, metadata) {
|
|
38590
|
-
const gtlNames = metadataPaths(metadata).map((path) => path.split(/[\\/]\.gtl[\\/]/)[1]).filter((path) => Boolean(path)).map((path) => path.split(/[\\/]/)[0]).filter((name) => Boolean(name));
|
|
38591
|
-
const gtlRoots = gtlNames.flatMap((name) => [
|
|
38592
|
-
resolve12(folder, ".gtl", name),
|
|
38593
|
-
...ancestorFolders(folder).map((ancestor) => resolve12(ancestor, name))
|
|
38594
|
-
]);
|
|
38595
|
-
const name = folder.replace(/[\\/]+$/, "").split(/[\\/]/).at(-1);
|
|
38596
|
-
const siblingIndex = name ? [
|
|
38597
|
-
resolve12(dirname10(folder), `${name}-index`),
|
|
38598
|
-
resolve12(dirname10(dirname10(folder)), `${name}-index`)
|
|
38599
|
-
] : [];
|
|
38600
|
-
const roots = await Promise.all(unique2([...gtlRoots, ...siblingIndex]).map(existingDirectory));
|
|
38601
|
-
return roots.filter((path) => Boolean(path));
|
|
38602
|
-
}
|
|
38603
|
-
async function listFolderSkills(folder, metadata) {
|
|
38604
|
-
const roots = unique2([folder, ...await linkedSkillRoots(folder, metadata)]);
|
|
38605
|
-
const skills = await Promise.all(roots.map(async (root) => {
|
|
38606
|
-
const skillsFolder = resolve12(root, ".agents", "skills");
|
|
38607
|
-
const entries = await readdir5(skillsFolder, {
|
|
38608
|
-
withFileTypes: true
|
|
38609
|
-
}).catch(() => []);
|
|
38610
|
-
return (await Promise.all(entries.filter((entry) => entry.isDirectory() && !entry.name.startsWith(".")).map(async (entry) => {
|
|
38611
|
-
const path = resolve12(skillsFolder, entry.name);
|
|
38612
|
-
const skillPath = resolve12(path, "SKILL.md");
|
|
38613
|
-
const details = await stat8(skillPath).catch(() => {
|
|
38614
|
-
return;
|
|
38615
|
-
});
|
|
38616
|
-
if (!details?.isFile())
|
|
38617
|
-
return;
|
|
38618
|
-
const content = await readFile9(skillPath, "utf8").catch(() => "");
|
|
38619
|
-
return {
|
|
38620
|
-
description: skillDescription(content),
|
|
38621
|
-
name: label(entry.name),
|
|
38622
|
-
openHref: openPathHref(path),
|
|
38623
|
-
relativePath: relative10(root, path),
|
|
38624
|
-
source: skillSource(folder, root)
|
|
38625
|
-
};
|
|
38626
|
-
}))).filter((skill) => skill);
|
|
38627
|
-
}));
|
|
38628
|
-
return unique2(skills.flat().map((skill) => JSON.stringify(skill))).map((skill) => JSON.parse(skill)).sort((left, right) => left.name.localeCompare(right.name));
|
|
38629
|
-
}
|
|
38630
38035
|
function isMachineRoot(folder) {
|
|
38631
|
-
return folder ===
|
|
38036
|
+
return folder === homedir3() || dirname9(folder) === folder;
|
|
38632
38037
|
}
|
|
38633
38038
|
async function shallowMetadata(folder) {
|
|
38634
38039
|
const entries = await readdir5(folder, { withFileTypes: true });
|
|
38635
38040
|
const visible = entries.filter((entry) => !entry.name.startsWith(".") && entry.name !== "node_modules");
|
|
38636
38041
|
const files = await Promise.all(visible.filter((entry) => entry.isFile() && [".markdown", ".md"].includes(extname6(entry.name).toLowerCase())).map(async (entry) => {
|
|
38637
|
-
const path =
|
|
38638
|
-
const details = await
|
|
38639
|
-
const content = await
|
|
38042
|
+
const path = resolve11(folder, entry.name);
|
|
38043
|
+
const details = await stat7(path);
|
|
38044
|
+
const content = await readFile8(path, "utf8").catch(() => "");
|
|
38640
38045
|
const title = markdownMetadata(content).title;
|
|
38641
38046
|
return {
|
|
38642
38047
|
activityAt: details.mtimeMs,
|
|
@@ -38649,10 +38054,10 @@ async function shallowMetadata(folder) {
|
|
|
38649
38054
|
};
|
|
38650
38055
|
}));
|
|
38651
38056
|
const projects = visible.filter((entry) => entry.isDirectory()).map((entry) => ({
|
|
38652
|
-
id: createHash5("sha1").update(
|
|
38057
|
+
id: createHash5("sha1").update(resolve11(folder, entry.name)).digest("hex"),
|
|
38653
38058
|
name: entry.name,
|
|
38654
38059
|
relativePath: entry.name,
|
|
38655
|
-
worktree:
|
|
38060
|
+
worktree: resolve11(folder, entry.name)
|
|
38656
38061
|
})).sort((left, right) => left.name.localeCompare(right.name));
|
|
38657
38062
|
return {
|
|
38658
38063
|
changes: { items: [] },
|
|
@@ -38663,8 +38068,7 @@ async function shallowMetadata(folder) {
|
|
|
38663
38068
|
instructions: { items: [] },
|
|
38664
38069
|
projects: { items: projects },
|
|
38665
38070
|
schemaVersion: 3,
|
|
38666
|
-
sessions: { items: [] }
|
|
38667
|
-
skills: { items: [] }
|
|
38071
|
+
sessions: { items: [] }
|
|
38668
38072
|
};
|
|
38669
38073
|
}
|
|
38670
38074
|
async function loadFolderData(folder) {
|
|
@@ -38679,7 +38083,7 @@ async function loadFolderData(folder) {
|
|
|
38679
38083
|
items: projects.map((project) => ({
|
|
38680
38084
|
id: project.id,
|
|
38681
38085
|
worktree: project.worktree,
|
|
38682
|
-
name: project.name ??
|
|
38086
|
+
name: project.name ?? basename6(project.worktree),
|
|
38683
38087
|
relativePath: relative10(folder, project.worktree)
|
|
38684
38088
|
}))
|
|
38685
38089
|
}
|
|
@@ -38688,10 +38092,10 @@ async function loadFolderData(folder) {
|
|
|
38688
38092
|
async function notesFiles(folder, files, origin) {
|
|
38689
38093
|
return {
|
|
38690
38094
|
items: await Promise.all(files.map(async (file) => {
|
|
38691
|
-
const path = file.path ?? (file.relativePath ?
|
|
38095
|
+
const path = file.path ?? (file.relativePath ? resolve11(folder, file.relativePath) : undefined);
|
|
38692
38096
|
if (!path)
|
|
38693
38097
|
return origin ? { ...file, folder: origin } : file;
|
|
38694
|
-
const content = [".markdown", ".md"].includes(extname6(path).toLowerCase()) ? await
|
|
38098
|
+
const content = [".markdown", ".md"].includes(extname6(path).toLowerCase()) ? await readFile8(path, "utf8").catch(() => "") : "";
|
|
38695
38099
|
const title = content ? markdownMetadata(content).title : undefined;
|
|
38696
38100
|
return {
|
|
38697
38101
|
...file,
|
|
@@ -38724,8 +38128,8 @@ async function localProjectSearchCache(cache) {
|
|
|
38724
38128
|
function mediaTarget(folder, file, lockedTarget) {
|
|
38725
38129
|
if (!file)
|
|
38726
38130
|
return;
|
|
38727
|
-
const rootReal = realpathSync2(
|
|
38728
|
-
const path =
|
|
38131
|
+
const rootReal = realpathSync2(resolve11(folder));
|
|
38132
|
+
const path = resolve11(folder, file);
|
|
38729
38133
|
let pathReal;
|
|
38730
38134
|
try {
|
|
38731
38135
|
pathReal = realpathSync2(path);
|
|
@@ -38772,8 +38176,8 @@ function documentError(response) {
|
|
|
38772
38176
|
function documentTarget(folder, file, lockedTarget) {
|
|
38773
38177
|
if (!file)
|
|
38774
38178
|
return;
|
|
38775
|
-
const rootReal = realpathSync2(
|
|
38776
|
-
const path =
|
|
38179
|
+
const rootReal = realpathSync2(resolve11(folder));
|
|
38180
|
+
const path = resolve11(folder, file);
|
|
38777
38181
|
let pathReal;
|
|
38778
38182
|
try {
|
|
38779
38183
|
pathReal = realpathSync2(path);
|
|
@@ -38826,14 +38230,14 @@ function parsePluginRegistryConfig(content) {
|
|
|
38826
38230
|
};
|
|
38827
38231
|
}
|
|
38828
38232
|
async function nearestKennelConfig(folder) {
|
|
38829
|
-
for (let current = folder;; current =
|
|
38830
|
-
const candidate =
|
|
38831
|
-
const details = await
|
|
38233
|
+
for (let current = folder;; current = dirname9(current)) {
|
|
38234
|
+
const candidate = resolve11(current, "kennel.json");
|
|
38235
|
+
const details = await stat7(candidate).catch(() => {
|
|
38832
38236
|
return;
|
|
38833
38237
|
});
|
|
38834
38238
|
if (details?.isFile())
|
|
38835
38239
|
return candidate;
|
|
38836
|
-
if (
|
|
38240
|
+
if (dirname9(current) === current)
|
|
38837
38241
|
return;
|
|
38838
38242
|
}
|
|
38839
38243
|
}
|
|
@@ -38842,13 +38246,13 @@ async function folderPluginRegistryConfig(folder) {
|
|
|
38842
38246
|
if (!path)
|
|
38843
38247
|
return defaultPluginRegistryConfig;
|
|
38844
38248
|
try {
|
|
38845
|
-
return parsePluginRegistryConfig(await
|
|
38249
|
+
return parsePluginRegistryConfig(await readFile8(path, "utf8"));
|
|
38846
38250
|
} catch {
|
|
38847
38251
|
return defaultPluginRegistryConfig;
|
|
38848
38252
|
}
|
|
38849
38253
|
}
|
|
38850
38254
|
function pluginConfigWarnings(registry, config) {
|
|
38851
|
-
const ids =
|
|
38255
|
+
const ids = unique([...config.plugins.disable, ...config.plugins.order]);
|
|
38852
38256
|
return ids.filter((id) => !registry.has(id)).map((id) => `unknown plugin id "${id}" — not installed in this build`);
|
|
38853
38257
|
}
|
|
38854
38258
|
async function pluginAvailability(registry, folder, linkedFolders, configWarnings = []) {
|
|
@@ -38862,12 +38266,14 @@ async function pluginAvailability(registry, folder, linkedFolders, configWarning
|
|
|
38862
38266
|
if (detection.status === "available") {
|
|
38863
38267
|
items.push({
|
|
38864
38268
|
count: detection.count,
|
|
38269
|
+
icon: plugin.icon,
|
|
38865
38270
|
id: plugin.id,
|
|
38866
38271
|
label: plugin.label
|
|
38867
38272
|
});
|
|
38868
38273
|
} else if (detection.status === "error") {
|
|
38869
38274
|
items.push({
|
|
38870
38275
|
error: detection.error,
|
|
38276
|
+
icon: plugin.icon,
|
|
38871
38277
|
id: plugin.id,
|
|
38872
38278
|
label: plugin.label
|
|
38873
38279
|
});
|
|
@@ -38881,7 +38287,6 @@ function createFolderApi({
|
|
|
38881
38287
|
restrictToRoot = false,
|
|
38882
38288
|
root,
|
|
38883
38289
|
sessionFinding,
|
|
38884
|
-
agentsHomeDir,
|
|
38885
38290
|
linkedFolderLoader,
|
|
38886
38291
|
remoteAccess = false,
|
|
38887
38292
|
lockedFile
|
|
@@ -38892,9 +38297,7 @@ function createFolderApi({
|
|
|
38892
38297
|
listFolderSessions,
|
|
38893
38298
|
readSessionTranscript
|
|
38894
38299
|
};
|
|
38895
|
-
const basePlugins = folderServerRegistryAsync(
|
|
38896
|
-
agentsHomeDir
|
|
38897
|
-
});
|
|
38300
|
+
const basePlugins = folderServerRegistryAsync();
|
|
38898
38301
|
const baseExternalApiHandlers = externalApiHandlers();
|
|
38899
38302
|
const assetFiles = new Map;
|
|
38900
38303
|
let projectSearchCache;
|
|
@@ -39029,7 +38432,7 @@ function createFolderApi({
|
|
|
39029
38432
|
"Content-Type": asset.mediaType,
|
|
39030
38433
|
ETag: `"${hash}"`
|
|
39031
38434
|
});
|
|
39032
|
-
response.end(await
|
|
38435
|
+
response.end(await readFile8(asset.path));
|
|
39033
38436
|
} catch (error) {
|
|
39034
38437
|
response.writeHead(404, {
|
|
39035
38438
|
"Content-Type": "text/plain; charset=utf-8"
|
|
@@ -39108,7 +38511,7 @@ function createFolderApi({
|
|
|
39108
38511
|
{
|
|
39109
38512
|
path: relative10(folder, target.path),
|
|
39110
38513
|
kind: target.kind,
|
|
39111
|
-
content: previewTextKind(target.kind) ? await
|
|
38514
|
+
content: previewTextKind(target.kind) ? await readFile8(target.path, "utf8") : ""
|
|
39112
38515
|
}
|
|
39113
38516
|
] : []
|
|
39114
38517
|
} : await readFolder(folder);
|
|
@@ -39124,7 +38527,7 @@ function createFolderApi({
|
|
|
39124
38527
|
documentError(response);
|
|
39125
38528
|
return;
|
|
39126
38529
|
}
|
|
39127
|
-
const details = await
|
|
38530
|
+
const details = await stat7(target.path);
|
|
39128
38531
|
if (!details.isFile()) {
|
|
39129
38532
|
documentError(response);
|
|
39130
38533
|
return;
|
|
@@ -39136,7 +38539,7 @@ function createFolderApi({
|
|
|
39136
38539
|
return;
|
|
39137
38540
|
}
|
|
39138
38541
|
watch(folder);
|
|
39139
|
-
const content = previewTextKind(target.kind) ? await
|
|
38542
|
+
const content = previewTextKind(target.kind) ? await readFile8(target.path, "utf8") : "";
|
|
39140
38543
|
sendContract(response, url, {
|
|
39141
38544
|
content,
|
|
39142
38545
|
kind: target.kind,
|
|
@@ -39165,7 +38568,7 @@ function createFolderApi({
|
|
|
39165
38568
|
documentError(response);
|
|
39166
38569
|
return;
|
|
39167
38570
|
}
|
|
39168
|
-
const details = await
|
|
38571
|
+
const details = await stat7(target.path);
|
|
39169
38572
|
if (!details.isFile()) {
|
|
39170
38573
|
documentError(response);
|
|
39171
38574
|
return;
|
|
@@ -39186,10 +38589,10 @@ function createFolderApi({
|
|
|
39186
38589
|
ETag: etag,
|
|
39187
38590
|
"X-Content-Type-Options": "nosniff",
|
|
39188
38591
|
...download ? {
|
|
39189
|
-
"Content-Disposition": `attachment; filename="${
|
|
38592
|
+
"Content-Disposition": `attachment; filename="${basename6(target.path)}"`
|
|
39190
38593
|
} : {}
|
|
39191
38594
|
});
|
|
39192
|
-
response.end(await
|
|
38595
|
+
response.end(await readFile8(target.path));
|
|
39193
38596
|
} catch (error) {
|
|
39194
38597
|
documentError(response);
|
|
39195
38598
|
}
|
|
@@ -39203,7 +38606,7 @@ function createFolderApi({
|
|
|
39203
38606
|
documentError(response);
|
|
39204
38607
|
return;
|
|
39205
38608
|
}
|
|
39206
|
-
const details = await
|
|
38609
|
+
const details = await stat7(target.path);
|
|
39207
38610
|
if (!details.isFile()) {
|
|
39208
38611
|
documentError(response);
|
|
39209
38612
|
return;
|
|
@@ -39215,7 +38618,7 @@ function createFolderApi({
|
|
|
39215
38618
|
return;
|
|
39216
38619
|
}
|
|
39217
38620
|
watch(folder);
|
|
39218
|
-
const data = await
|
|
38621
|
+
const data = await readFile8(target.path);
|
|
39219
38622
|
const baseHeaders = {
|
|
39220
38623
|
"Accept-Ranges": "bytes",
|
|
39221
38624
|
"Cache-Control": "private, max-age=0, must-revalidate",
|
|
@@ -39287,10 +38690,10 @@ function createFolderApi({
|
|
|
39287
38690
|
const subpath = url.searchParams.get("subpath") ?? "";
|
|
39288
38691
|
if (!lockedRoot && !isMachineRoot(folder) && request.headers["x-kennel-retry-linked"] === "1")
|
|
39289
38692
|
linkedDiscovery.retry(folder);
|
|
39290
|
-
const discovery =
|
|
38693
|
+
const discovery = linkedState(folder);
|
|
39291
38694
|
const result = await plugin.handle({
|
|
39292
38695
|
folder,
|
|
39293
|
-
linkedFolders: discovery
|
|
38696
|
+
linkedFolders: discovery.folders
|
|
39294
38697
|
}, subpath);
|
|
39295
38698
|
if (result.kind === "unavailable") {
|
|
39296
38699
|
response.writeHead(200, {
|
|
@@ -39301,7 +38704,7 @@ function createFolderApi({
|
|
|
39301
38704
|
folder,
|
|
39302
38705
|
plugin: pluginId,
|
|
39303
38706
|
status: "unavailable",
|
|
39304
|
-
|
|
38707
|
+
linkedStatus: discovery.status
|
|
39305
38708
|
}));
|
|
39306
38709
|
return;
|
|
39307
38710
|
}
|
|
@@ -39314,7 +38717,7 @@ function createFolderApi({
|
|
|
39314
38717
|
folder,
|
|
39315
38718
|
plugin: pluginId,
|
|
39316
38719
|
...data,
|
|
39317
|
-
|
|
38720
|
+
linkedStatus: discovery.status
|
|
39318
38721
|
}));
|
|
39319
38722
|
} catch (error) {
|
|
39320
38723
|
if (error instanceof FolderPluginFailure) {
|
|
@@ -39384,7 +38787,6 @@ function createFolderApi({
|
|
|
39384
38787
|
folder,
|
|
39385
38788
|
projects: { items: [] },
|
|
39386
38789
|
sessions: { items: [] },
|
|
39387
|
-
skills: { items: [] },
|
|
39388
38790
|
workspace: await readWorkspace(folder)
|
|
39389
38791
|
}, { "Cache-Control": "private, max-age=0, must-revalidate" });
|
|
39390
38792
|
return;
|
|
@@ -39394,7 +38796,7 @@ function createFolderApi({
|
|
|
39394
38796
|
workspace.breadcrumbs = await workspaceBreadcrumbIcons(workspace.breadcrumbs ?? [], assetFiles);
|
|
39395
38797
|
const files = [
|
|
39396
38798
|
workspace.configPath,
|
|
39397
|
-
|
|
38799
|
+
resolve11(workspace.root, "raggle.json")
|
|
39398
38800
|
].filter((path) => Boolean(path));
|
|
39399
38801
|
for (const path of files)
|
|
39400
38802
|
contexts.add(path);
|
|
@@ -39498,25 +38900,12 @@ function createFolderApi({
|
|
|
39498
38900
|
return;
|
|
39499
38901
|
}
|
|
39500
38902
|
const metadata = machine ? await shallowMetadata(folder) : await loadFolderData(folder);
|
|
39501
|
-
|
|
39502
|
-
respond({
|
|
39503
|
-
folder: metadata.folder,
|
|
39504
|
-
skills: {
|
|
39505
|
-
items: await listFolderSkills(metadata.folder, metadata)
|
|
39506
|
-
}
|
|
39507
|
-
});
|
|
39508
|
-
return;
|
|
39509
|
-
}
|
|
39510
|
-
const [assets, skills] = await Promise.all([
|
|
39511
|
-
hydrateAssets(metadata, assetFiles),
|
|
39512
|
-
listFolderSkills(metadata.folder, metadata)
|
|
39513
|
-
]);
|
|
38903
|
+
const assets = await hydrateAssets(metadata, assetFiles);
|
|
39514
38904
|
const body = {
|
|
39515
38905
|
...metadata,
|
|
39516
38906
|
...assets,
|
|
39517
38907
|
sessions: { items: [] },
|
|
39518
|
-
files: await notesFiles(metadata.folder, metadata.files.items)
|
|
39519
|
-
skills: { items: skills }
|
|
38908
|
+
files: await notesFiles(metadata.folder, metadata.files.items)
|
|
39520
38909
|
};
|
|
39521
38910
|
respond(body);
|
|
39522
38911
|
} catch (error) {
|
|
@@ -44098,8 +43487,8 @@ data: ${JSON.stringify(event.data)}
|
|
|
44098
43487
|
return;
|
|
44099
43488
|
}
|
|
44100
43489
|
if (options.webRoot && (request.method === "GET" || request.method === "HEAD")) {
|
|
44101
|
-
const root = await
|
|
44102
|
-
let target =
|
|
43490
|
+
const root = await realpath5(options.webRoot);
|
|
43491
|
+
let target = resolve12(root, `.${decodeURIComponent(url.pathname)}`);
|
|
44103
43492
|
const inside = (path) => {
|
|
44104
43493
|
const local = relative11(root, path);
|
|
44105
43494
|
return local !== ".." && !local.startsWith("../") && !isAbsolute7(local);
|
|
@@ -44109,9 +43498,9 @@ data: ${JSON.stringify(event.data)}
|
|
|
44109
43498
|
response.end();
|
|
44110
43499
|
return;
|
|
44111
43500
|
}
|
|
44112
|
-
if (!(await
|
|
44113
|
-
target =
|
|
44114
|
-
target = await
|
|
43501
|
+
if (!(await stat8(target).catch(() => null))?.isFile())
|
|
43502
|
+
target = resolve12(root, "index.html");
|
|
43503
|
+
target = await realpath5(target);
|
|
44115
43504
|
if (!inside(target)) {
|
|
44116
43505
|
response.writeHead(403);
|
|
44117
43506
|
response.end();
|
|
@@ -44131,7 +43520,7 @@ data: ${JSON.stringify(event.data)}
|
|
|
44131
43520
|
"Content-Type": types[extname7(target)] ?? "application/octet-stream",
|
|
44132
43521
|
"X-Content-Type-Options": "nosniff"
|
|
44133
43522
|
});
|
|
44134
|
-
response.end(request.method === "HEAD" ? undefined : await
|
|
43523
|
+
response.end(request.method === "HEAD" ? undefined : await readFile9(target));
|
|
44135
43524
|
return;
|
|
44136
43525
|
}
|
|
44137
43526
|
next();
|