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
@@ -1,519 +1,8 @@
1
1
  // packages/api/src/server/plugins.ts
2
2
  import { pathToFileURL } from "node:url";
3
3
  import { existsSync } from "node:fs";
4
- import { mkdir, stat as stat3, writeFile } from "node:fs/promises";
5
- import { dirname as dirname2, resolve as resolve3, sep as sep2 } from "node:path";
6
-
7
- // packages/agents/src/manifest.ts
8
- var agentsManifest = {
9
- id: "agents",
10
- label: "Agents"
11
- };
12
-
13
- // packages/agents/src/node.ts
14
- import { lstat, readFile, realpath, stat } from "node:fs/promises";
15
- import { homedir } from "node:os";
16
- import { basename, dirname, resolve } from "node:path";
17
-
18
- // packages/agents/src/profiles.ts
19
- var CLIENT_ORDER = [
20
- "generic",
21
- "codex",
22
- "claude",
23
- "pi"
24
- ];
25
- var PROFILES = {
26
- generic: {
27
- id: "generic",
28
- label: "Generic",
29
- scope: "root",
30
- files: ["AGENTS.md"],
31
- filesMode: "first",
32
- globalDir: ".agents",
33
- globalFiles: ["AGENTS.md"],
34
- globalMode: "first",
35
- verified: false,
36
- note: "Reference view of the ancestor AGENTS.md chain. No client execution behavior is claimed.",
37
- limits: "Walks to the filesystem root like Stepladder; only AGENTS.md files are read."
38
- },
39
- codex: {
40
- id: "codex",
41
- label: "Codex",
42
- scope: "git",
43
- files: ["AGENTS.override.md", "AGENTS.md"],
44
- filesMode: "first",
45
- globalDir: ".codex",
46
- globalEnv: "CODEX_HOME",
47
- globalFiles: ["AGENTS.override.md", "AGENTS.md"],
48
- globalMode: "first",
49
- verified: true,
50
- 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.",
51
- limits: "A configured model_instructions_file fallback is not applied here; a warning appears when it is configured."
52
- },
53
- claude: {
54
- id: "claude",
55
- label: "Claude Code",
56
- scope: "root",
57
- files: ["CLAUDE.md", ".claude/CLAUDE.md", "CLAUDE.local.md"],
58
- filesMode: "all",
59
- globalDir: ".claude",
60
- globalFiles: ["CLAUDE.md"],
61
- globalMode: "first",
62
- verified: true,
63
- 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.",
64
- limits: "Conditional .claude/rules/*.md files and @path imports are not expanded here."
65
- },
66
- pi: {
67
- id: "pi",
68
- label: "Pi",
69
- scope: "root",
70
- files: [
71
- "AGENTS.override.md",
72
- "AGENTS.md",
73
- "AGENTS.MD",
74
- "CLAUDE.md",
75
- "CLAUDE.MD"
76
- ],
77
- filesMode: "first",
78
- globalDir: ".pi/agent",
79
- globalEnv: "PI_CODING_AGENT_DIR",
80
- globalFiles: [
81
- "AGENTS.override.md",
82
- "AGENTS.md",
83
- "AGENTS.MD",
84
- "CLAUDE.md",
85
- "CLAUDE.MD"
86
- ],
87
- globalMode: "first",
88
- verified: true,
89
- 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.",
90
- limits: "Uses the same candidate list for the global directory."
91
- }
92
- };
93
- function parseClientFilter(value) {
94
- if (value === "generic" || value === "codex" || value === "claude" || value === "pi") {
95
- return value;
96
- }
97
- return "pi";
98
- }
99
-
100
- // packages/agents/src/resolve.ts
101
- var LEVEL_ORDER = {
102
- project: 0,
103
- parent: 1,
104
- repository: 2,
105
- linked: 3,
106
- global: 4
107
- };
108
- function unique(values) {
109
- return [...new Set(values)];
110
- }
111
- function pathSegments(path) {
112
- const normalized = path.replaceAll("\\", "/").replace(/\/+$/, "");
113
- if (!normalized)
114
- return 0;
115
- return normalized.split("/").length;
116
- }
117
- function dedupeSources(sources) {
118
- const merged = new Map;
119
- for (const source of sources) {
120
- const existing = merged.get(source.id);
121
- if (!existing) {
122
- merged.set(source.id, {
123
- ...source,
124
- clientIds: [...source.clientIds],
125
- sourcePaths: unique([...source.sourcePaths])
126
- });
127
- continue;
128
- }
129
- existing.clientIds = unique([...existing.clientIds, ...source.clientIds]);
130
- existing.sourcePaths = unique([
131
- ...existing.sourcePaths,
132
- ...source.sourcePaths
133
- ]);
134
- if (existing.status !== "loaded" && source.status === "loaded") {
135
- existing.status = source.status;
136
- existing.text = source.text;
137
- existing.size = source.size;
138
- existing.reason = source.reason;
139
- }
140
- if (source.override)
141
- existing.override = true;
142
- }
143
- return [...merged.values()];
144
- }
145
- function sortSources(sources) {
146
- return [...sources].sort((left, right) => {
147
- const level = LEVEL_ORDER[left.level] - LEVEL_ORDER[right.level];
148
- if (level !== 0)
149
- return level;
150
- const depth = pathSegments(right.directory) - pathSegments(left.directory);
151
- if (depth !== 0)
152
- return depth;
153
- return left.filename.localeCompare(right.filename);
154
- });
155
- }
156
-
157
- // packages/agents/src/node.ts
158
- async function canonicalize(path) {
159
- try {
160
- return await realpath(path);
161
- } catch {
162
- return null;
163
- }
164
- }
165
- async function hasGit(folder) {
166
- const entry = await lstat(resolve(folder, ".git")).catch(() => {
167
- return;
168
- });
169
- return Boolean(entry);
170
- }
171
- async function nearestGitRoot(folder) {
172
- let current = folder;
173
- while (true) {
174
- if (await hasGit(current))
175
- return current;
176
- const parent = dirname(current);
177
- if (parent === current)
178
- return null;
179
- current = parent;
180
- }
181
- }
182
- async function nearestRaggleRoot(folder) {
183
- let current = folder;
184
- while (true) {
185
- const entry = await lstat(resolve(current, "raggle.json")).catch(() => {
186
- return;
187
- });
188
- if (entry)
189
- return current;
190
- const parent = dirname(current);
191
- if (parent === current)
192
- return null;
193
- current = parent;
194
- }
195
- }
196
- async function ancestorBoundary(folder, scope) {
197
- let current = folder;
198
- while (true) {
199
- if (scope === "git" && await hasGit(current))
200
- return current;
201
- const parent = dirname(current);
202
- if (parent === current)
203
- return current;
204
- current = parent;
205
- }
206
- }
207
- function ancestorChain(folder, boundary) {
208
- const chain = [];
209
- let current = folder;
210
- while (true) {
211
- chain.push(current);
212
- if (current === boundary)
213
- break;
214
- const parent = dirname(current);
215
- if (parent === current)
216
- break;
217
- current = parent;
218
- }
219
- return chain;
220
- }
221
- function sourceLevel(index, total, scope) {
222
- if (total === 1)
223
- return "project";
224
- if (index === 0)
225
- return "project";
226
- if (scope === "git" && index === total - 1)
227
- return "repository";
228
- return "parent";
229
- }
230
- async function isRegularFile(path) {
231
- const details = await stat(path).catch(() => {
232
- return;
233
- });
234
- return details?.isFile() === true;
235
- }
236
- function mergeChains(chains) {
237
- const byDirectory = new Map;
238
- const order = [];
239
- for (const chain of chains) {
240
- for (const entry of chain) {
241
- const existing = byDirectory.get(entry.directory);
242
- if (!existing) {
243
- byDirectory.set(entry.directory, {
244
- ...entry,
245
- filenames: [...entry.filenames]
246
- });
247
- order.push(entry.directory);
248
- } else {
249
- for (const filename of entry.filenames) {
250
- if (!existing.filenames.includes(filename)) {
251
- existing.filenames.push(filename);
252
- }
253
- }
254
- }
255
- }
256
- }
257
- return order.map((directory) => byDirectory.get(directory));
258
- }
259
- async function selectFiles(directory, candidates, mode) {
260
- if (mode === "all") {
261
- const found = [];
262
- for (const relative of candidates) {
263
- if (await isRegularFile(resolve(directory, relative))) {
264
- found.push({ filename: basename(relative), relative });
265
- }
266
- }
267
- return found;
268
- }
269
- for (const relative of candidates) {
270
- if (await isRegularFile(resolve(directory, relative))) {
271
- return [{ filename: basename(relative), relative }];
272
- }
273
- }
274
- return [];
275
- }
276
- function expandHome(path, homeDir) {
277
- if (path === "~")
278
- return homeDir;
279
- if (path.startsWith("~/"))
280
- return resolve(homeDir, path.slice(2));
281
- return path;
282
- }
283
- function globalDirectory(profile, homeDir) {
284
- if (profile.globalDir === null)
285
- return null;
286
- const envValue = profile.globalEnv ? process.env[profile.globalEnv]?.trim() : undefined;
287
- if (envValue)
288
- return expandHome(envValue, homeDir);
289
- if (profile.globalDir === "")
290
- return homeDir;
291
- return resolve(homeDir, profile.globalDir);
292
- }
293
- function readError(error) {
294
- return error instanceof Error ? error.message : "Could not read file";
295
- }
296
- var INSTRUCTION_NAMES = new Set(Object.values(PROFILES).flatMap((profile) => [...profile.files, ...profile.globalFiles]).map((path) => basename(path).toLowerCase()));
297
- async function codexModelInstructionsFile(codexHome) {
298
- try {
299
- const content = await readFile(resolve(codexHome, "config.toml"), "utf8");
300
- const match = /^\s*model_instructions_file\s*=\s*["']?([^"'\n]+)["']?\s*$/m.exec(content);
301
- return match?.[1]?.trim() ?? null;
302
- } catch {
303
- return null;
304
- }
305
- }
306
- async function loadSource(input) {
307
- const real = await canonicalize(input.literalPath);
308
- if (!real) {
309
- return {
310
- id: input.literalPath,
311
- path: input.literalPath,
312
- sourcePaths: [input.literalPath],
313
- filename: input.filename,
314
- directory: dirname(input.literalPath),
315
- level: input.level,
316
- status: "unreadable",
317
- text: "",
318
- size: 0,
319
- clientIds: [input.clientId],
320
- override: input.override,
321
- applies: true,
322
- reason: "Path cannot be resolved"
323
- };
324
- }
325
- const record = {
326
- id: real,
327
- path: real,
328
- sourcePaths: [input.literalPath],
329
- filename: input.filename,
330
- directory: dirname(real),
331
- level: input.level,
332
- status: "loaded",
333
- text: "",
334
- size: 0,
335
- clientIds: [input.clientId],
336
- override: input.override,
337
- applies: true
338
- };
339
- if (!INSTRUCTION_NAMES.has(basename(real).toLowerCase())) {
340
- record.status = "unsafe";
341
- record.reason = "Symlink resolves to a non-instruction file";
342
- return record;
343
- }
344
- const details = await stat(real).catch(() => {
345
- return;
346
- });
347
- if (!details?.isFile()) {
348
- record.status = "unreadable";
349
- record.reason = "Not a regular file";
350
- return record;
351
- }
352
- record.size = details.size;
353
- if (input.readText) {
354
- try {
355
- record.text = await readFile(real, "utf8");
356
- } catch (error) {
357
- record.status = "unreadable";
358
- record.reason = readError(error);
359
- }
360
- }
361
- return record;
362
- }
363
- async function resolveAgents(options) {
364
- const homeDir = options.homeDir ?? homedir();
365
- const client = options.client ?? "all";
366
- const readText = options.readText ?? true;
367
- const folder = await canonicalize(options.folder);
368
- if (!folder)
369
- throw new Error(`Folder not found: ${options.folder}`);
370
- const repositoryRoot = await nearestGitRoot(folder);
371
- const workspaceRoot = await nearestRaggleRoot(folder);
372
- const profileIds = client === "all" ? CLIENT_ORDER : [client];
373
- const sources = [];
374
- const warnings = [];
375
- const profileChains = [];
376
- for (const profileId of profileIds) {
377
- const profile = PROFILES[profileId];
378
- const boundary = workspaceRoot ?? await ancestorBoundary(folder, profile.scope);
379
- const ancestors = ancestorChain(folder, boundary);
380
- const chain = [];
381
- for (let index = 0;index < ancestors.length; index += 1) {
382
- const directory = ancestors[index];
383
- if (!directory)
384
- continue;
385
- const level = sourceLevel(index, ancestors.length, profile.scope);
386
- const files = await selectFiles(directory, profile.files, profile.filesMode);
387
- chain.push({
388
- directory,
389
- level,
390
- filenames: files.map((file) => file.filename)
391
- });
392
- for (const file of files) {
393
- const source = await loadSource({
394
- clientId: profileId,
395
- filename: file.filename,
396
- level,
397
- literalPath: resolve(directory, file.relative),
398
- override: file.filename === "AGENTS.override.md",
399
- readText
400
- });
401
- sources.push(source);
402
- }
403
- }
404
- profileChains.push(chain);
405
- for (const linkedFolder of options.linkedFolders ?? []) {
406
- const canonicalLinked = await canonicalize(linkedFolder);
407
- if (!canonicalLinked || canonicalLinked === folder)
408
- continue;
409
- const linkedFiles = await selectFiles(canonicalLinked, profile.files, profile.filesMode);
410
- chain.push({
411
- directory: canonicalLinked,
412
- level: "linked",
413
- filenames: linkedFiles.map((file) => file.filename)
414
- });
415
- for (const file of linkedFiles) {
416
- const source = await loadSource({
417
- clientId: profileId,
418
- filename: file.filename,
419
- level: "linked",
420
- literalPath: resolve(canonicalLinked, file.relative),
421
- override: file.filename === "AGENTS.override.md",
422
- readText
423
- });
424
- sources.push(source);
425
- }
426
- }
427
- const globalDir = globalDirectory(profile, homeDir);
428
- if (globalDir) {
429
- const globals = await selectFiles(globalDir, profile.globalFiles, profile.globalMode);
430
- for (const file of globals) {
431
- const source = await loadSource({
432
- clientId: profileId,
433
- filename: file.filename,
434
- level: "global",
435
- literalPath: resolve(globalDir, file.relative),
436
- override: file.filename === "AGENTS.override.md",
437
- readText
438
- });
439
- sources.push(source);
440
- }
441
- if (globals.length === 0 && profile.globalFiles.length > 0) {
442
- warnings.push({
443
- kind: "missing",
444
- path: globalDir,
445
- clientIds: [profileId],
446
- reason: "No global instruction file found in this directory"
447
- });
448
- }
449
- }
450
- if (profileId === "codex") {
451
- const codexHome = globalDirectory(profile, homeDir);
452
- if (codexHome) {
453
- const fallback = await codexModelInstructionsFile(codexHome);
454
- if (fallback) {
455
- warnings.push({
456
- kind: "unsupported",
457
- clientIds: [profileId],
458
- reason: `Codex model_instructions_file (${fallback}) is configured but not applied here`
459
- });
460
- }
461
- }
462
- }
463
- }
464
- const deduped = dedupeSources(sources);
465
- const ordered = sortSources(deduped);
466
- return {
467
- folder,
468
- repositoryRoot,
469
- client,
470
- sources: ordered,
471
- warnings,
472
- chain: mergeChains(profileChains)
473
- };
474
- }
475
-
476
- // packages/agents/src/server.ts
477
- function createAgentsPlugin(options = {}) {
478
- return {
479
- ...agentsManifest,
480
- async detect(context) {
481
- try {
482
- const result = await resolveAgents({
483
- folder: context.folder,
484
- client: "all",
485
- homeDir: options.homeDir,
486
- linkedFolders: context.linkedFolders,
487
- readText: false
488
- });
489
- return { count: result.sources.length, status: "available" };
490
- } catch {
491
- return { status: "available" };
492
- }
493
- },
494
- async handle(context, subpath) {
495
- const client = parseClientFilter(subpath.trim() || null);
496
- const result = await resolveAgents({
497
- folder: context.folder,
498
- client,
499
- homeDir: options.homeDir,
500
- linkedFolders: context.linkedFolders
501
- });
502
- return {
503
- kind: "available",
504
- data: {
505
- client,
506
- folder: result.folder,
507
- repositoryRoot: result.repositoryRoot,
508
- sources: result.sources,
509
- status: "available",
510
- warnings: result.warnings,
511
- chain: result.chain
512
- }
513
- };
514
- }
515
- };
516
- }
4
+ import { mkdir, stat as stat2, writeFile } from "node:fs/promises";
5
+ import { dirname, resolve as resolve2, sep as sep2 } from "node:path";
517
6
 
518
7
  // packages/plugins/dist/chunk-AX4A4GYF.js
519
8
  var FolderPluginFailure = class extends Error {
@@ -524,12 +13,19 @@ var FolderPluginFailure = class extends Error {
524
13
  };
525
14
 
526
15
  // packages/notes/src/server.ts
527
- import { readdir, stat as stat2 } from "node:fs/promises";
528
- import { basename as basename2, extname, relative, resolve as resolve2, sep } from "node:path";
16
+ import { readdir, stat } from "node:fs/promises";
17
+ import { basename, extname, relative, resolve, sep } from "node:path";
529
18
 
530
19
  // packages/notes/src/manifest.ts
531
20
  var notesManifest = {
532
21
  id: "notes",
22
+ icon: {
23
+ paths: [
24
+ "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8Z",
25
+ "M14 2v6h6",
26
+ "M8 13h8M8 17h6"
27
+ ]
28
+ },
533
29
  label: "Notes"
534
30
  };
535
31
 
@@ -542,7 +38,7 @@ async function listMarkdownFiles(folder) {
542
38
  for (const entry of entries) {
543
39
  if (entry.name === "node_modules" || entry.name.startsWith("."))
544
40
  continue;
545
- const path = resolve2(current, entry.name);
41
+ const path = resolve(current, entry.name);
546
42
  if (entry.isDirectory()) {
547
43
  await visit(path);
548
44
  continue;
@@ -550,12 +46,12 @@ async function listMarkdownFiles(folder) {
550
46
  if (!entry.isFile() || !markdownExtensions.has(extname(entry.name))) {
551
47
  continue;
552
48
  }
553
- const details = await stat2(path).catch(() => {
49
+ const details = await stat(path).catch(() => {
554
50
  return;
555
51
  });
556
52
  files.push({
557
53
  activityAt: details?.mtimeMs ?? 0,
558
- name: basename2(entry.name, extname(entry.name)),
54
+ name: basename(entry.name, extname(entry.name)),
559
55
  relativePath: relative(folder, path).split(sep).join("/")
560
56
  });
561
57
  }
@@ -608,16 +104,11 @@ function configuredFolderServerRegistry(registry, resolvedConfig) {
608
104
  ];
609
105
  return new Map(ids.map((id) => [id, registry.get(id)]));
610
106
  }
611
- function createFolderServerPlugins(options = {}) {
612
- return [
613
- createAgentsPlugin({
614
- homeDir: options.agentsHomeDir
615
- }),
616
- createNotesPlugin()
617
- ];
107
+ function createFolderServerPlugins() {
108
+ return [createNotesPlugin()];
618
109
  }
619
- function folderServerRegistry(options = {}) {
620
- return new Map(createFolderServerPlugins(options).map((plugin) => [plugin.id, plugin]));
110
+ function folderServerRegistry() {
111
+ return new Map(createFolderServerPlugins().map((plugin) => [plugin.id, plugin]));
621
112
  }
622
113
  function externalServerEntries() {
623
114
  const source = process.env.KENNEL_EXTERNAL_SERVER_ENTRIES;
@@ -637,14 +128,14 @@ function externalServerEntries() {
637
128
  return { id: item.id, module: item.module, symbol: item.symbol, trigger: item.trigger };
638
129
  });
639
130
  }
640
- async function folderServerRegistryAsync(options = {}) {
641
- const registry = folderServerRegistry(options);
131
+ async function folderServerRegistryAsync() {
132
+ const registry = folderServerRegistry();
642
133
  for (const entry of externalServerEntries()) {
643
134
  if (registry.has(entry.id))
644
135
  throw new Error(`External plugin id collides with core plugin: ${entry.id}`);
645
136
  const imported = await import(pathToFileURL(entry.module).href);
646
137
  const value = imported[entry.symbol];
647
- const plugin = typeof value === "function" ? value(options) : value;
138
+ const plugin = typeof value === "function" ? value() : value;
648
139
  if (!plugin || typeof plugin !== "object")
649
140
  throw new Error(`External plugin ${entry.id} did not export ${entry.symbol}`);
650
141
  const server = plugin;
@@ -656,7 +147,7 @@ async function folderServerRegistryAsync(options = {}) {
656
147
  ...server,
657
148
  async detect(context) {
658
149
  const detection = await server.detect(context);
659
- if (detection.status === "unavailable" && existsSync(resolve3(context.folder, entry.trigger))) {
150
+ if (detection.status === "unavailable" && existsSync(resolve2(context.folder, entry.trigger))) {
660
151
  return { status: "available" };
661
152
  }
662
153
  return detection;
@@ -694,8 +185,8 @@ async function externalApiHandlers() {
694
185
  return handlers;
695
186
  }
696
187
  async function scaffoldFolderPlugins(folder, options = {}) {
697
- const root = resolve3(folder);
698
- const registry = folderServerRegistry(options);
188
+ const root = resolve2(folder);
189
+ const registry = folderServerRegistry();
699
190
  const created = [];
700
191
  const skipped = [];
701
192
  const supported = [];
@@ -705,7 +196,7 @@ async function scaffoldFolderPlugins(folder, options = {}) {
705
196
  const context = { folder: root };
706
197
  const result = await plugin.init(context);
707
198
  const files = result.files.filter((file) => {
708
- const target = resolve3(root, file.path);
199
+ const target = resolve2(root, file.path);
709
200
  const contained = target === root || target.startsWith(root + sep2);
710
201
  return contained && file.path !== ".";
711
202
  });
@@ -714,15 +205,15 @@ async function scaffoldFolderPlugins(folder, options = {}) {
714
205
  files: files.map((file) => file.path)
715
206
  });
716
207
  for (const file of files) {
717
- const target = resolve3(root, file.path);
718
- const exists = await stat3(target).then(() => true).catch(() => false);
208
+ const target = resolve2(root, file.path);
209
+ const exists = await stat2(target).then(() => true).catch(() => false);
719
210
  if (exists && !options.force) {
720
211
  skipped.push({ path: file.path, plugin: plugin.id });
721
212
  continue;
722
213
  }
723
214
  if (options.write === false)
724
215
  continue;
725
- await mkdir(dirname2(target), { recursive: true });
216
+ await mkdir(dirname(target), { recursive: true });
726
217
  await writeFile(target, file.content);
727
218
  created.push({ path: file.path, plugin: plugin.id });
728
219
  }
@@ -22,7 +22,6 @@
22
22
  "@lexical/markdown": "0.49.0",
23
23
  "@lexical/react": "0.49.0",
24
24
  "@lexical/rich-text": "0.49.0",
25
- "@raggle-ai/agents": "workspace:*",
26
25
  "kennel-plugins": "workspace:*",
27
26
  "@raggle-ai/kennel-api": "workspace:*",
28
27
  "@raggle-ai/kennel-preview": "workspace:*",
@@ -1,5 +1,4 @@
1
1
  @import "tailwindcss";
2
- @source "../../../packages/agents/src";
3
2
  @source "../../../packages/ui/src";
4
3
  @source "./";
5
4