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.
Files changed (173) hide show
  1. package/dist/cli/src/plugins/external.js +19 -7
  2. package/dist/cli/src/site/server-plugins.d.ts +1 -4
  3. package/dist/core/api-client.js +3 -11
  4. package/dist/core/runtime.js +84 -695
  5. package/dist/package/preview.js +99 -729
  6. package/dist/plugins/external.js +19 -7
  7. package/dist/site/server-plugins.d.ts +1 -4
  8. package/dist/site/server-plugins.js +28 -537
  9. package/kernel/apps/web/package.json +0 -1
  10. package/kernel/apps/web/src/app.css +0 -1
  11. package/kernel/apps/web/src/app.tsx +7 -24
  12. package/kernel/apps/web/src/folder-plugin-view.tsx +6 -3
  13. package/kernel/apps/web/src/plugins.ts +2 -14
  14. package/kernel/apps/web/vite.config.ts +22 -20
  15. package/kernel/packages/api/openapi.json +85 -224
  16. package/kernel/packages/api/package.json +0 -1
  17. package/kernel/packages/api/src/contracts/schemas.ts +1 -9
  18. package/kernel/packages/api/src/server/folder-metadata-plugin.ts +9 -151
  19. package/kernel/packages/api/src/server/plugins.ts +11 -26
  20. package/kernel/packages/api/src/shared/viewer-route.ts +3 -5
  21. package/kernel/packages/api-client/src/generated.d.ts +16 -53
  22. package/kernel/packages/markdown/README.md +2 -2
  23. package/kernel/packages/notes/package.json +1 -0
  24. package/kernel/packages/notes/src/client.tsx +0 -1
  25. package/kernel/packages/notes/src/manifest.ts +7 -0
  26. package/kernel/packages/notes/src/pages/notes-page.tsx +1 -1
  27. package/kernel/packages/notes/src/ui/folder-notes-list.tsx +52 -7
  28. package/kernel/packages/plugins/SKILL.md +3 -2
  29. package/kernel/packages/plugins/package.json +5 -1
  30. package/kernel/packages/plugins/src/hooks.ts +24 -0
  31. package/kernel/packages/plugins/src/index.ts +1 -7
  32. package/kernel/packages/plugins/src/page.ts +0 -7
  33. package/kernel/packages/plugins/src/types.ts +8 -0
  34. package/kernel/packages/plugins/tsconfig.json +1 -1
  35. package/kernel/packages/plugins/tsup.config.ts +1 -0
  36. package/kernel/packages/ui/src/components/folder-activity.tsx +16 -98
  37. package/kernel/packages/ui/src/components/folder-landing.tsx +4 -0
  38. package/kernel/packages/ui/src/components/markdown-copy-block.tsx +78 -0
  39. package/kernel/packages/ui/src/components/pagination.tsx +88 -2
  40. package/kernel/packages/ui/src/components/plugin-icon.tsx +19 -0
  41. package/kernel/packages/ui/src/lib/folder-activity.ts +4 -17
  42. package/kernel/packages/ui/src/lib/source-components.tsx +12 -6
  43. package/kernel/packages/ui/src/styles/folder-activity.css +1 -31
  44. package/package.json +2 -2
  45. package/web/assets/{abnfDiagram-VRR7QNED-CSaxgLw6.js → abnfDiagram-VRR7QNED-Dt7QEF5H.js} +1 -1
  46. package/web/assets/app-C1j063QX.js +2 -0
  47. package/web/assets/app-options-98-a6ivv.js +25 -0
  48. package/web/assets/{app-view-header-Cpx74SQs.js → app-view-header-BJ9CWTE1.js} +1 -1
  49. package/web/assets/{arc-DOrTJz--.js → arc-PFB0H7oD.js} +1 -1
  50. package/web/assets/{architectureDiagram-ZJ3FMSHR-EjOjwlGK.js → architectureDiagram-ZJ3FMSHR-BHLqEXlZ.js} +1 -1
  51. package/web/assets/{ask-tray-DLEoRbpV.js → ask-tray-C3gBesHJ.js} +1 -1
  52. package/web/assets/{blockDiagram-677ZJIJ3-Dg2LWLOW.js → blockDiagram-677ZJIJ3-UbnYoYDg.js} +1 -1
  53. package/web/assets/{button-C6arH7zt.js → button-CuuAtS1I.js} +1 -1
  54. package/web/assets/{c4Diagram-LMCZKHZV-CWHqGPk8.js → c4Diagram-LMCZKHZV-4OSx1V4W.js} +1 -1
  55. package/web/assets/channel-BuvY5cQN.js +1 -0
  56. package/web/assets/{chunk-2Q5K7J3B-Dzz0QWV_.js → chunk-2Q5K7J3B-CgxJ1aJb.js} +1 -1
  57. package/web/assets/{chunk-32BRIVSS-BocStooX.js → chunk-32BRIVSS-Bfwxg2LM.js} +1 -1
  58. package/web/assets/{chunk-5VM5RSS4-D8BF5Y5h.js → chunk-5VM5RSS4-BZN9a2hI.js} +1 -1
  59. package/web/assets/{chunk-EX3LRPZG-CWMl9KkL.js → chunk-EX3LRPZG-CrH6hhqq.js} +1 -1
  60. package/web/assets/{chunk-JWPE2WC7-BZEr7iFk.js → chunk-JWPE2WC7-Ddn7ZSp8.js} +1 -1
  61. package/web/assets/{chunk-MOJQB5TN-DbKnLJ33.js → chunk-MOJQB5TN-9lJ7f_hI.js} +1 -1
  62. package/web/assets/{chunk-RYQCIY6F-BF9KWoi2.js → chunk-RYQCIY6F-QrFo_00s.js} +1 -1
  63. package/web/assets/{chunk-V7JOEXUC-e88zamUH.js → chunk-V7JOEXUC-Dn0lQjVf.js} +1 -1
  64. package/web/assets/{chunk-VR4S4FIN-NDHM58HJ.js → chunk-VR4S4FIN-DXVPySkB.js} +1 -1
  65. package/web/assets/{chunk-XXDRQBXY-BtzSzNoD.js → chunk-XXDRQBXY-CBiFDOdZ.js} +1 -1
  66. package/web/assets/classDiagram-OUVF2IWQ-DCYNCJhe.js +1 -0
  67. package/web/assets/classDiagram-v2-EOCWNBFH-DCYNCJhe.js +1 -0
  68. package/web/assets/client-DBJY3XDL.js +43 -0
  69. package/web/assets/client-DKJs0w4y.js +6 -0
  70. package/web/assets/{command-BWtewOrt.js → command-onjTnuXT.js} +1 -1
  71. package/web/assets/{copy-context-YESgZ_hu.js → copy-context-CciRaLNN.js} +1 -1
  72. package/web/assets/{cose-bilkent-JH36ORCC-i7x8jZ9M.js → cose-bilkent-JH36ORCC-CGRic2um.js} +1 -1
  73. package/web/assets/{cynefin-VYW2F7L2-D8HPrHMt.js → cynefin-VYW2F7L2-Blk0Lu0l.js} +1 -1
  74. package/web/assets/{cynefinDiagram-TSTJHNR4-BtkeCNXb.js → cynefinDiagram-TSTJHNR4-DpnnHRDK.js} +1 -1
  75. package/web/assets/{dagre-VKFMJZFB-oIThwshO.js → dagre-VKFMJZFB-llzMokKp.js} +1 -1
  76. package/web/assets/{diagram-FQU43EPY-DTuhEo03.js → diagram-FQU43EPY-DC6xHovR.js} +1 -1
  77. package/web/assets/{diagram-G47NLZAW-BcQ_4_fE.js → diagram-G47NLZAW-B8GVS3EA.js} +1 -1
  78. package/web/assets/{diagram-NH7WQ7WH-BA4VC8Du.js → diagram-NH7WQ7WH-DWUaARfh.js} +1 -1
  79. package/web/assets/{diagram-OA4YK3LP-BOpyrmty.js → diagram-OA4YK3LP-9Uaes_Yi.js} +1 -1
  80. package/web/assets/{diagram-WEI45ONY-BzrSPDJ7.js → diagram-WEI45ONY-DPPTBWud.js} +1 -1
  81. package/web/assets/document-D23WzFsW.js +23 -0
  82. package/web/assets/{ebnfDiagram-CCIWWBDH-BNV_4xDp.js → ebnfDiagram-CCIWWBDH-BPrKneNw.js} +1 -1
  83. package/web/assets/{entities-D0qpC3B9.js → entities-DPg0B8vd.js} +1 -1
  84. package/web/assets/{erDiagram-Q63AITRT-NT1La9pi.js → erDiagram-Q63AITRT-CFqYBcnb.js} +1 -1
  85. package/web/assets/{file-viewer-C1N6vaip.js → file-viewer-Ck73SsLA.js} +1 -1
  86. package/web/assets/{flowDiagram-23GEKE2U-CIYWUYkz.js → flowDiagram-23GEKE2U-C7RpYqaT.js} +1 -1
  87. package/web/assets/folder-filter-bar-DzejUj87.js +4 -0
  88. package/web/assets/{folder-image-Bz0xznQT.js → folder-image-BjIicmQ6.js} +1 -1
  89. package/web/assets/folder-landing-CCIXZfkp.js +55 -0
  90. package/web/assets/folder-list-TuRwuTss.js +1 -0
  91. package/web/assets/folder-mobile-bar-Bqnfwi-z.js +1 -0
  92. package/web/assets/folder-plugin-view-CrinCX1o.js +2 -0
  93. package/web/assets/{ganttDiagram-NO4QXBWP-DeUfoXQA.js → ganttDiagram-NO4QXBWP-Cz2sxU8F.js} +1 -1
  94. package/web/assets/{gitGraphDiagram-IHSO6WYX-DMeTgUPh.js → gitGraphDiagram-IHSO6WYX-BSuz0yF-.js} +1 -1
  95. package/web/assets/{index-CCXE8zc9.js → index-BVyeNcuc.js} +1 -1
  96. package/web/assets/{index-CegvVQ1C.js → index-Cg-gtBkw.js} +1 -1
  97. package/web/assets/index-DLn_2LPp.js +2 -0
  98. package/web/assets/{index-DY0VGBht.js → index-DbVDdnzL.js} +1 -1
  99. package/web/assets/index-uY9jLiL5.css +1 -0
  100. package/web/assets/{infoDiagram-FWYZ7A6U-DI_P8Ghi.js → infoDiagram-FWYZ7A6U-CpeKgqoS.js} +1 -1
  101. package/web/assets/input-Bz_puamS.js +9 -0
  102. package/web/assets/{ishikawaDiagram-FXEZZL3T-B8bM-8CD.js → ishikawaDiagram-FXEZZL3T-5c2Tmknb.js} +1 -1
  103. package/web/assets/{journeyDiagram-5HDEW3XC-pviYejXU.js → journeyDiagram-5HDEW3XC-Cu-wRkR4.js} +1 -1
  104. package/web/assets/{kanban-definition-HUTT4EX6-DfvdDvpU.js → kanban-definition-HUTT4EX6-BunSqkPe.js} +1 -1
  105. package/web/assets/{linear-DNOuKTk_.js → linear-C8e8bGVv.js} +1 -1
  106. package/web/assets/{mermaid.core-CisVJ_Cs.js → mermaid.core-DLgjY1g2.js} +4 -4
  107. package/web/assets/{metadata-C7E_6HIN.js → metadata-DEfJKlnd.js} +1 -1
  108. package/web/assets/{mindmap-definition-LN4V7U3C-DzdcaduN.js → mindmap-definition-LN4V7U3C-W9ENYFOD.js} +1 -1
  109. package/web/assets/{pegDiagram-2B236MQR-D_7xhlXd.js → pegDiagram-2B236MQR-0vPlHCFp.js} +1 -1
  110. package/web/assets/{pieDiagram-ENE6RG2P-CisikHMW.js → pieDiagram-ENE6RG2P-CakaveRV.js} +1 -1
  111. package/web/assets/{popover-D7MTK-sz.js → popover-3AMcPJpt.js} +1 -1
  112. package/web/assets/{project-search-dialog-BsHc39D0.js → project-search-dialog-BSKA4peX.js} +1 -1
  113. package/web/assets/{quadrantDiagram-ABIIQ3AL-D6adg-7z.js → quadrantDiagram-ABIIQ3AL-jxHw_egj.js} +1 -1
  114. package/web/assets/{railroadDiagram-RFXS5EU6-CyPAHeJ-.js → railroadDiagram-RFXS5EU6-lIjDXPZt.js} +1 -1
  115. package/web/assets/{requirementDiagram-TGXJPOKE-CgpSiPTv.js → requirementDiagram-TGXJPOKE-C-JiT4bc.js} +1 -1
  116. package/web/assets/{sankeyDiagram-HTMAVEWB-BxvReW6S.js → sankeyDiagram-HTMAVEWB-SuLPAw9X.js} +1 -1
  117. package/web/assets/{search-DEgwpq-P.js → search-CKujW14f.js} +1 -1
  118. package/web/assets/{selection-popup-d94JnDPy.js → selection-popup-CtxT9SWn.js} +3 -3
  119. package/web/assets/{sequenceDiagram-DBY2YBRQ-uuplzETI.js → sequenceDiagram-DBY2YBRQ-o9UwTkZR.js} +1 -1
  120. package/web/assets/{sizeCapture-X5ZJPWSS-Bi3F7nOa.js → sizeCapture-X5ZJPWSS-ClbWGybF.js} +1 -1
  121. package/web/assets/{stateDiagram-2N3HPSRC-DqypF7lE.js → stateDiagram-2N3HPSRC-Ce4avoWx.js} +1 -1
  122. package/web/assets/stateDiagram-v2-6OUMAXLB-CsrPTZoJ.js +1 -0
  123. package/web/assets/{swimlanes-5IMT3BWC-CGD9YT1l.js → swimlanes-5IMT3BWC-DMZI4XZT.js} +2 -2
  124. package/web/assets/swimlanesDiagram-G3AALYLV-pShSVcTd.js +8 -0
  125. package/web/assets/{timeline-definition-FHXFAJF6-DCjNS9Ol.js → timeline-definition-FHXFAJF6-CPIpIgPN.js} +1 -1
  126. package/web/assets/{utils-DCaHk0Gm.js → utils-Cg80pk1W.js} +1 -1
  127. package/web/assets/{vennDiagram-L72KCM5P-BJ58yQgD.js → vennDiagram-L72KCM5P-_rha8uDZ.js} +1 -1
  128. package/web/assets/view-context-BDtIUHQy.js +229 -0
  129. package/web/assets/{viewer-capabilities-DCuJdf64.js → viewer-capabilities-YYZqMs56.js} +1 -1
  130. package/web/assets/{wardleyDiagram-EHGQE667-BiLuq9mr.js → wardleyDiagram-EHGQE667-D4EAOS35.js} +1 -1
  131. package/web/assets/{xychartDiagram-FW5EYKEG-DzAZpIRG.js → xychartDiagram-FW5EYKEG-DR8PwXpe.js} +1 -1
  132. package/web/index.html +2 -2
  133. package/kernel/packages/agents/eslint.config.js +0 -10
  134. package/kernel/packages/agents/package.json +0 -75
  135. package/kernel/packages/agents/src/agent-card.tsx +0 -334
  136. package/kernel/packages/agents/src/client.tsx +0 -13
  137. package/kernel/packages/agents/src/index.ts +0 -18
  138. package/kernel/packages/agents/src/manifest.ts +0 -7
  139. package/kernel/packages/agents/src/node.ts +0 -447
  140. package/kernel/packages/agents/src/profiles.ts +0 -137
  141. package/kernel/packages/agents/src/resolve.ts +0 -69
  142. package/kernel/packages/agents/src/server.ts +0 -60
  143. package/kernel/packages/agents/src/types.ts +0 -82
  144. package/kernel/packages/agents/src/viewer.tsx +0 -370
  145. package/kernel/packages/agents/test/profiles.test.mjs +0 -88
  146. package/kernel/packages/agents/test/resolve.test.mjs +0 -729
  147. package/kernel/packages/agents/tsconfig.json +0 -17
  148. package/kernel/packages/api/test/agents-loading.test.ts +0 -94
  149. package/kernel/packages/ui/src/components/folder-skill-list.tsx +0 -62
  150. package/web/assets/app-DoXXGPMx.js +0 -2
  151. package/web/assets/app-options-jTBHy0A7.js +0 -25
  152. package/web/assets/channel-54w4vQjC.js +0 -1
  153. package/web/assets/classDiagram-OUVF2IWQ-Bh9Ib2pw.js +0 -1
  154. package/web/assets/classDiagram-v2-EOCWNBFH-Bh9Ib2pw.js +0 -1
  155. package/web/assets/client-BgUDusrU.js +0 -5
  156. package/web/assets/client-COaHUqSC.js +0 -17
  157. package/web/assets/client-UC06V2VL.js +0 -22
  158. package/web/assets/document-BDtU3CbX.js +0 -19
  159. package/web/assets/folder-filter-bar-C_2Mobfq.js +0 -4
  160. package/web/assets/folder-landing-3gqbGaYS.js +0 -54
  161. package/web/assets/folder-list-DDI0TF2e.js +0 -1
  162. package/web/assets/folder-metadata-DjV3ZUra.js +0 -2
  163. package/web/assets/folder-mobile-bar-CF4CpJXL.js +0 -1
  164. package/web/assets/folder-plugin-view-C48J0HKe.js +0 -3
  165. package/web/assets/index-Bp9DidgD.js +0 -1
  166. package/web/assets/index-CXhBn-ar.js +0 -1
  167. package/web/assets/index-CtuOSBHa.js +0 -2
  168. package/web/assets/index-Dwhf8F_U.css +0 -1
  169. package/web/assets/select-DGaccqVB.js +0 -30
  170. package/web/assets/stateDiagram-v2-6OUMAXLB-EsEb0a5Q.js +0 -1
  171. package/web/assets/swimlanesDiagram-G3AALYLV-DKIYuN5l.js +0 -8
  172. package/web/assets/use-folder-filter-hA6fa7nm.js +0 -1
  173. package/web/assets/view-context-BrzQ7WBV.js +0 -229
@@ -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 readFile10, realpath as realpath6, stat as stat9 } from "node:fs/promises";
17031
- import { extname as extname7, isAbsolute as isAbsolute7, relative as relative11, resolve as resolve13 } from "node:path";
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 readFile9, stat as stat8 } from "node:fs/promises";
22149
- import { homedir as homedir4 } from "node:os";
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 basename7,
22152
- dirname as dirname10,
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 resolve12,
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 dirname8, resolve as resolve11, sep as sep6 } from "node:path";
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 stat7 } from "node:fs/promises";
37848
- import { basename as basename6, extname as extname5, relative as relative8, resolve as resolve10, sep as sep5 } from "node:path";
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 = resolve10(current, entry.name);
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 stat7(path).catch(() => {
37361
+ const details = await stat6(path).catch(() => {
37874
37362
  return;
37875
37363
  });
37876
37364
  files.push({
37877
37365
  activityAt: details?.mtimeMs ?? 0,
37878
- name: basename6(entry.name, extname5(entry.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(options = {}) {
37932
- return [
37933
- createAgentsPlugin({
37934
- homeDir: options.agentsHomeDir
37935
- }),
37936
- createNotesPlugin()
37937
- ];
37419
+ function createFolderServerPlugins() {
37420
+ return [createNotesPlugin()];
37938
37421
  }
37939
- function folderServerRegistry(options = {}) {
37940
- return new Map(createFolderServerPlugins(options).map((plugin) => [plugin.id, plugin]));
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(options = {}) {
37961
- const registry = folderServerRegistry(options);
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(options) : 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(resolve11(context.folder, entry.trigger))) {
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 dirname9, join as join4 } from "node:path";
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 = dirname9(fileURLToPath(from));
38048
- while (dirname9(directory) !== directory) {
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(dirname9(directory), "raggle-ai-scout", "packages", "local"),
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 = dirname9(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(dirname9(fileURLToPath(from)), "..", "..", "..", "raggle-ai-scout", "packages", "local");
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(resolve12(value ?? root));
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 stat8(icon).catch(() => {
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 readFile9(icon)).toString("base64")}`;
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 unique2(values) {
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 === homedir4() || dirname10(folder) === 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 = resolve12(folder, entry.name);
38638
- const details = await stat8(path);
38639
- const content = await readFile9(path, "utf8").catch(() => "");
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(resolve12(folder, entry.name)).digest("hex"),
38057
+ id: createHash5("sha1").update(resolve11(folder, entry.name)).digest("hex"),
38653
38058
  name: entry.name,
38654
38059
  relativePath: entry.name,
38655
- worktree: resolve12(folder, entry.name)
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 ?? basename7(project.worktree),
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 ? resolve12(folder, file.relativePath) : undefined);
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 readFile9(path, "utf8").catch(() => "") : "";
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(resolve12(folder));
38728
- const path = resolve12(folder, file);
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(resolve12(folder));
38776
- const path = resolve12(folder, file);
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 = dirname10(current)) {
38830
- const candidate = resolve12(current, "kennel.json");
38831
- const details = await stat8(candidate).catch(() => {
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 (dirname10(current) === current)
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 readFile9(path, "utf8"));
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 = unique2([...config.plugins.disable, ...config.plugins.order]);
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 readFile9(asset.path));
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 readFile9(target.path, "utf8") : ""
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 stat8(target.path);
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 readFile9(target.path, "utf8") : "";
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 stat8(target.path);
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="${basename7(target.path)}"`
38592
+ "Content-Disposition": `attachment; filename="${basename6(target.path)}"`
39190
38593
  } : {}
39191
38594
  });
39192
- response.end(await readFile9(target.path));
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 stat8(target.path);
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 readFile9(target.path);
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 = pluginId === "agents" || pluginId === "tasks" ? linkedState(folder) : undefined;
38693
+ const discovery = linkedState(folder);
39291
38694
  const result = await plugin.handle({
39292
38695
  folder,
39293
- linkedFolders: discovery?.folders ?? []
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
- ...discovery ? { linkedStatus: discovery.status } : {}
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
- ...discovery ? { linkedStatus: discovery.status } : {}
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
- resolve12(workspace.root, "raggle.json")
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
- if (part === "skills") {
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 realpath6(options.webRoot);
44102
- let target = resolve13(root, `.${decodeURIComponent(url.pathname)}`);
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 stat9(target).catch(() => null))?.isFile())
44113
- target = resolve13(root, "index.html");
44114
- target = await realpath6(target);
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 readFile10(target));
43523
+ response.end(request.method === "HEAD" ? undefined : await readFile9(target));
44135
43524
  return;
44136
43525
  }
44137
43526
  next();