@ashx-j/lunr 0.2.24 → 0.2.25

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 (104) hide show
  1. package/CHANGELOG.md +9 -1
  2. package/dist/gateway/adapters/discord.d.ts.map +1 -1
  3. package/dist/gateway/adapters/discord.js +2 -7
  4. package/dist/gateway/adapters/discord.js.map +1 -1
  5. package/dist/gateway/adapters/telegram.d.ts.map +1 -1
  6. package/dist/gateway/adapters/telegram.js +7 -0
  7. package/dist/gateway/adapters/telegram.js.map +1 -1
  8. package/dist/gateway/agent-bridge.d.ts +4 -1
  9. package/dist/gateway/agent-bridge.d.ts.map +1 -1
  10. package/dist/gateway/agent-bridge.js +57 -17
  11. package/dist/gateway/agent-bridge.js.map +1 -1
  12. package/dist/gateway/buttons.d.ts.map +1 -1
  13. package/dist/gateway/buttons.js +29 -19
  14. package/dist/gateway/buttons.js.map +1 -1
  15. package/dist/gateway/commands.d.ts +2 -0
  16. package/dist/gateway/commands.d.ts.map +1 -1
  17. package/dist/gateway/commands.js +39 -18
  18. package/dist/gateway/commands.js.map +1 -1
  19. package/dist/gateway/config.d.ts +1 -0
  20. package/dist/gateway/config.d.ts.map +1 -1
  21. package/dist/gateway/config.js +2 -0
  22. package/dist/gateway/config.js.map +1 -1
  23. package/dist/gateway/cron.d.ts +1 -1
  24. package/dist/gateway/cron.d.ts.map +1 -1
  25. package/dist/gateway/cron.js +2 -2
  26. package/dist/gateway/cron.js.map +1 -1
  27. package/dist/gateway/index.d.ts.map +1 -1
  28. package/dist/gateway/index.js +26 -26
  29. package/dist/gateway/index.js.map +1 -1
  30. package/dist/gateway/mobile-commands.d.ts.map +1 -1
  31. package/dist/gateway/mobile-commands.js +3 -3
  32. package/dist/gateway/mobile-commands.js.map +1 -1
  33. package/dist/gateway/presenter.d.ts +12 -1
  34. package/dist/gateway/presenter.d.ts.map +1 -1
  35. package/dist/gateway/presenter.js +146 -48
  36. package/dist/gateway/presenter.js.map +1 -1
  37. package/dist/gateway/router.d.ts +5 -5
  38. package/dist/gateway/router.d.ts.map +1 -1
  39. package/dist/gateway/router.js +95 -41
  40. package/dist/gateway/router.js.map +1 -1
  41. package/dist/gateway/service.d.ts.map +1 -1
  42. package/dist/gateway/service.js +13 -4
  43. package/dist/gateway/service.js.map +1 -1
  44. package/dist/gateway/setup.d.ts +5 -0
  45. package/dist/gateway/setup.d.ts.map +1 -1
  46. package/dist/gateway/setup.js +98 -42
  47. package/dist/gateway/setup.js.map +1 -1
  48. package/dist/gateway/stream.d.ts +6 -5
  49. package/dist/gateway/stream.d.ts.map +1 -1
  50. package/dist/gateway/stream.js +24 -11
  51. package/dist/gateway/stream.js.map +1 -1
  52. package/dist/node-runtime/{agent-session-services-IEF7LQWD.js → agent-session-services-YXXFCP5J.js} +7 -6
  53. package/dist/node-runtime/{builtin-extensions-EBAWTH4M.js → builtin-extensions-ZLAX7TUH.js} +1 -1
  54. package/dist/node-runtime/{chunk-OF7PWMG4.js → chunk-2HHLJWGD.js} +3 -87
  55. package/dist/node-runtime/{chunk-VWCE2HSZ.js → chunk-2HMIRK7W.js} +4 -4
  56. package/dist/node-runtime/{chunk-K5AGHH57.js → chunk-3XPLBUEM.js} +1 -1
  57. package/dist/node-runtime/{chunk-RORY2HMJ.js → chunk-6XL67VVY.js} +1 -1
  58. package/dist/node-runtime/chunk-7S3T6YEA.js +97 -0
  59. package/dist/node-runtime/{chunk-R3K2F5GI.js → chunk-B4HP6ZWM.js} +2 -0
  60. package/dist/node-runtime/{chunk-YVI6L6LU.js → chunk-E4D3IGP2.js} +38 -22
  61. package/dist/node-runtime/{chunk-5Q3EHOHI.js → chunk-IJIFHRTB.js} +14 -12
  62. package/dist/node-runtime/{chunk-Y73WPE6S.js → chunk-KWIYUUZK.js} +63 -37
  63. package/dist/node-runtime/{chunk-F4FLTQKV.js → chunk-LQP3RB67.js} +184 -1527
  64. package/dist/node-runtime/{chunk-FU6OODRZ.js → chunk-NRKGMJYU.js} +1 -1
  65. package/dist/node-runtime/{chunk-IGV54Q5V.js → chunk-QTU6AKNJ.js} +128 -63
  66. package/dist/node-runtime/{chunk-L3LX4SNR.js → chunk-RC7DMV45.js} +5 -5
  67. package/dist/node-runtime/{chunk-UWPJL22I.js → chunk-SLVOAQOY.js} +15 -4
  68. package/dist/node-runtime/{chunk-WHLRAGUQ.js → chunk-TORR5XBV.js} +6 -6
  69. package/dist/node-runtime/{chunk-UP2XBVH5.js → chunk-UOEDI7RP.js} +1 -1
  70. package/dist/node-runtime/{chunk-DE2JB6J5.js → chunk-VQFSUJJG.js} +2 -2
  71. package/dist/node-runtime/{chunk-QM43FEAE.js → chunk-WF7PGWRZ.js} +3 -3
  72. package/dist/node-runtime/chunk-YCUZEGJG.js +1361 -0
  73. package/dist/node-runtime/{command-7BG7VVTS.js → command-6WDOYKS6.js} +5 -5
  74. package/dist/node-runtime/{commands-QFDKNQTL.js → commands-QC6VUZJQ.js} +5 -5
  75. package/dist/node-runtime/{config-RORQUQFG.js → config-D4QUPAHX.js} +1 -1
  76. package/dist/node-runtime/{gateway-TWR3N65G.js → gateway-INAYBF4Q.js} +134 -78
  77. package/dist/node-runtime/index.js +15 -12
  78. package/dist/node-runtime/{install-cli-VAP6KBFN.js → install-cli-KL4UDDAD.js} +3 -3
  79. package/dist/node-runtime/{interactive-mode-6J5VZ2TT.js → interactive-mode-Z5M7WYYZ.js} +8 -7
  80. package/dist/node-runtime/{lunr-browser-J5ZZYVGM.js → lunr-browser-IR7TL3J7.js} +3 -3
  81. package/dist/node-runtime/{lunr-cron-CXOL37AL.js → lunr-cron-LWIZJM2N.js} +5 -5
  82. package/dist/node-runtime/main.js +12 -10
  83. package/dist/node-runtime/{mobile-commands-VTBM5DSZ.js → mobile-commands-J7OJEKFO.js} +4 -4
  84. package/dist/node-runtime/{package-manager-cli-ZLW5DZXF.js → package-manager-cli-VYZM5WHN.js} +10 -7
  85. package/dist/node-runtime/{pi-subagents-XPCLLKIM.js → pi-subagents-DNY7EAIG.js} +6 -6
  86. package/dist/node-runtime/rpc-entry.js +12 -10
  87. package/dist/node-runtime/{runtime-bridges-QYXUX2TG.js → runtime-bridges-VRDDR73P.js} +5 -5
  88. package/dist/node-runtime/{service-ISSP6VHE.js → service-MDQIPQ26.js} +1 -1
  89. package/dist/node-runtime/{settings-manager-WCQDUVQB.js → settings-manager-J4SPQPDJ.js} +4 -4
  90. package/dist/node-runtime/setup-CQ2NLVK5.js +214 -0
  91. package/dist/node-runtime/{subagent-executor-OTNISDQU.js → subagent-executor-KZZQGAKV.js} +5 -5
  92. package/dist/node-runtime/{update-cli-VBR2777K.js → update-cli-GTFJC7XK.js} +4 -4
  93. package/docs/features.md +4 -4
  94. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  95. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  96. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  97. package/examples/extensions/gondolin/package-lock.json +2 -2
  98. package/examples/extensions/gondolin/package.json +1 -1
  99. package/examples/extensions/sandbox/package-lock.json +2 -2
  100. package/examples/extensions/sandbox/package.json +1 -1
  101. package/examples/extensions/with-deps/package-lock.json +2 -2
  102. package/examples/extensions/with-deps/package.json +1 -1
  103. package/package.json +4 -4
  104. package/dist/node-runtime/setup-YRBKH2LD.js +0 -155
@@ -0,0 +1,1361 @@
1
+ import { createRequire as __lunrRequire } from "node:module"; const require = __lunrRequire(import.meta.url);
2
+ import {
3
+ DefaultPackageManager,
4
+ require_ignore
5
+ } from "./chunk-LQP3RB67.js";
6
+ import {
7
+ parseFrontmatter
8
+ } from "./chunk-QFWG2RVL.js";
9
+ import {
10
+ SettingsManager
11
+ } from "./chunk-6XL67VVY.js";
12
+ import {
13
+ getGlobalInstructionsPath,
14
+ loadSelectedUserInstructions
15
+ } from "./chunk-M3LZLQW2.js";
16
+ import {
17
+ measureStartup,
18
+ resetTimings
19
+ } from "./chunk-PVCDKGR6.js";
20
+ import {
21
+ loadThemeFromPath
22
+ } from "./chunk-RDDAZOMU.js";
23
+ import {
24
+ CONFIG_DIR_NAME,
25
+ canonicalizePath,
26
+ getAgentDir,
27
+ isBunBinary,
28
+ isLocalPath,
29
+ isNodeBundle,
30
+ resolvePath,
31
+ waitForChildProcess
32
+ } from "./chunk-FQMM2EZ2.js";
33
+ import {
34
+ __toESM
35
+ } from "./chunk-BRJX2PRC.js";
36
+
37
+ // packages/coding-agent/dist/core/event-bus.js
38
+ import { EventEmitter } from "node:events";
39
+ function createEventBus() {
40
+ let emitter = new EventEmitter();
41
+ return {
42
+ emit: (channel, data) => {
43
+ emitter.emit(channel, data);
44
+ },
45
+ on: (channel, handler) => {
46
+ let safeHandler = async (data) => {
47
+ try {
48
+ await handler(data);
49
+ } catch (err) {
50
+ console.error(`Event handler error (${channel}):`, err);
51
+ }
52
+ };
53
+ return emitter.on(channel, safeHandler), () => emitter.off(channel, safeHandler);
54
+ },
55
+ clear: () => {
56
+ emitter.removeAllListeners();
57
+ }
58
+ };
59
+ }
60
+
61
+ // packages/coding-agent/dist/core/source-info.js
62
+ function createSourceInfo(path2, metadata) {
63
+ return {
64
+ path: path2,
65
+ source: metadata.source,
66
+ scope: metadata.scope,
67
+ origin: metadata.origin,
68
+ baseDir: metadata.baseDir
69
+ };
70
+ }
71
+ function createSyntheticSourceInfo(path2, options) {
72
+ return {
73
+ path: path2,
74
+ source: options.source,
75
+ scope: options.scope ?? "temporary",
76
+ origin: options.origin ?? "top-level",
77
+ baseDir: options.baseDir
78
+ };
79
+ }
80
+
81
+ // packages/coding-agent/dist/core/extensions/loader.js
82
+ import * as fs from "node:fs";
83
+ import { createRequire } from "node:module";
84
+ import * as path from "node:path";
85
+ import { fileURLToPath } from "node:url";
86
+
87
+ // packages/coding-agent/dist/core/exec.js
88
+ import { spawn } from "node:child_process";
89
+ async function execCommand(command, args, cwd, options) {
90
+ return new Promise((resolve5) => {
91
+ let proc = spawn(command, args, {
92
+ cwd,
93
+ shell: !1,
94
+ stdio: ["ignore", "pipe", "pipe"]
95
+ }), stdout = "", stderr = "", killed = !1, timeoutId, killProcess = () => {
96
+ killed || (killed = !0, proc.kill("SIGTERM"), setTimeout(() => {
97
+ proc.killed || proc.kill("SIGKILL");
98
+ }, 5e3));
99
+ };
100
+ options?.signal && (options.signal.aborted ? killProcess() : options.signal.addEventListener("abort", killProcess, { once: !0 })), options?.timeout && options.timeout > 0 && (timeoutId = setTimeout(() => {
101
+ killProcess();
102
+ }, options.timeout)), proc.stdout?.on("data", (data) => {
103
+ stdout += data.toString();
104
+ }), proc.stderr?.on("data", (data) => {
105
+ stderr += data.toString();
106
+ }), waitForChildProcess(proc).then((code) => {
107
+ timeoutId && clearTimeout(timeoutId), options?.signal && options.signal.removeEventListener("abort", killProcess), resolve5({ stdout, stderr, code: code ?? 0, killed });
108
+ }).catch((_err) => {
109
+ timeoutId && clearTimeout(timeoutId), options?.signal && options.signal.removeEventListener("abort", killProcess), resolve5({ stdout, stderr, code: 1, killed });
110
+ });
111
+ });
112
+ }
113
+
114
+ // packages/coding-agent/dist/core/extensions/loader.js
115
+ var bunExtensionHost, createJitiFn;
116
+ var require2 = createRequire(new URL("../core/extensions/loader.js", import.meta.url).href), _aliases = null;
117
+ function getAliases() {
118
+ if (_aliases)
119
+ return _aliases;
120
+ let __dirname = path.dirname(fileURLToPath(new URL("../core/extensions/loader.js", import.meta.url).href)), packageIndex = path.resolve(__dirname, "../..", isNodeBundle ? "node-runtime/index.js" : "index.js"), typeboxEntry = require2.resolve("typebox"), typeboxCompileEntry = require2.resolve("typebox/compile"), typeboxValueEntry = require2.resolve("typebox/value"), packagesRoot = path.resolve(__dirname, "../../../../"), resolveWorkspaceOrImport = (workspaceRelativePath, specifier) => {
121
+ let workspacePath = path.join(packagesRoot, workspaceRelativePath);
122
+ return fs.existsSync(workspacePath) ? workspacePath : fileURLToPath(import.meta.resolve(specifier));
123
+ }, piCodingAgentEntry = packageIndex, piAgentCoreEntry = resolveWorkspaceOrImport("agent/dist/index.js", "@ashx-j/lunr-agent"), piTuiEntry = resolveWorkspaceOrImport("tui/dist/index.js", "@ashx-j/lunr-tui"), piAiCompatEntry = resolveWorkspaceOrImport("ai/dist/compat.js", "@ashx-j/lunr-ai/compat"), piAiOauthEntry = resolveWorkspaceOrImport("ai/dist/oauth.js", "@ashx-j/lunr-ai/oauth"), piAiProvidersEntry = resolveWorkspaceOrImport("ai/dist/providers/all.js", "@ashx-j/lunr-ai/providers/all");
124
+ return _aliases = {
125
+ "@ashx-j/lunr": piCodingAgentEntry,
126
+ "@ashx-j/lunr-agent": piAgentCoreEntry,
127
+ "@ashx-j/lunr-tui": piTuiEntry,
128
+ "@ashx-j/lunr-ai/providers/all": piAiProvidersEntry,
129
+ "@ashx-j/lunr-ai/compat": piAiCompatEntry,
130
+ "@ashx-j/lunr-ai/oauth": piAiOauthEntry,
131
+ "@ashx-j/lunr-ai": piAiCompatEntry,
132
+ "@ashx-j/lunr": piCodingAgentEntry,
133
+ "@ashx-j/lunr-agent": piAgentCoreEntry,
134
+ "@ashx-j/lunr-tui": piTuiEntry,
135
+ "@ashx-j/lunr-ai/providers/all": piAiProvidersEntry,
136
+ "@ashx-j/lunr-ai/compat": piAiCompatEntry,
137
+ "@ashx-j/lunr-ai/oauth": piAiOauthEntry,
138
+ "@ashx-j/lunr-ai": piAiCompatEntry,
139
+ "@mariozechner/pi-coding-agent": piCodingAgentEntry,
140
+ "@mariozechner/pi-agent-core": piAgentCoreEntry,
141
+ "@mariozechner/pi-tui": piTuiEntry,
142
+ "@mariozechner/pi-ai/providers/all": piAiProvidersEntry,
143
+ "@mariozechner/pi-ai/compat": piAiCompatEntry,
144
+ "@mariozechner/pi-ai/oauth": piAiOauthEntry,
145
+ "@mariozechner/pi-ai": piAiCompatEntry,
146
+ typebox: typeboxEntry,
147
+ "typebox/compile": typeboxCompileEntry,
148
+ "typebox/value": typeboxValueEntry,
149
+ "@sinclair/typebox": typeboxEntry,
150
+ "@sinclair/typebox/compile": typeboxCompileEntry,
151
+ "@sinclair/typebox/value": typeboxValueEntry
152
+ }, _aliases;
153
+ }
154
+ var extensionCacheCwd, extensionCacheGeneration = 0, extensionCache = /* @__PURE__ */ new Map();
155
+ function clearExtensionCache() {
156
+ extensionCache.clear(), extensionCacheCwd = void 0, extensionCacheGeneration++;
157
+ }
158
+ function useExtensionCacheCwd(cwd) {
159
+ let resolvedCwd = resolvePath(cwd);
160
+ return extensionCacheCwd !== void 0 && extensionCacheCwd !== resolvedCwd && clearExtensionCache(), extensionCacheCwd = resolvedCwd, { cwd: resolvedCwd, generation: extensionCacheGeneration };
161
+ }
162
+ function createExtensionRuntime() {
163
+ let notInitialized = () => {
164
+ throw new Error("Extension runtime not initialized. Action methods cannot be called during extension loading.");
165
+ }, state = {}, runtime = {
166
+ sendMessage: notInitialized,
167
+ sendUserMessage: notInitialized,
168
+ appendEntry: notInitialized,
169
+ setSessionName: notInitialized,
170
+ getSessionName: notInitialized,
171
+ setLabel: notInitialized,
172
+ getActiveTools: notInitialized,
173
+ getAllTools: notInitialized,
174
+ setActiveTools: notInitialized,
175
+ // registerTool() is valid during extension load; refresh is only needed post-bind.
176
+ refreshTools: () => {
177
+ },
178
+ getCommands: notInitialized,
179
+ setModel: () => Promise.reject(new Error("Extension runtime not initialized")),
180
+ getThinkingLevel: notInitialized,
181
+ setThinkingLevel: notInitialized,
182
+ flagValues: /* @__PURE__ */ new Map(),
183
+ pendingProviderRegistrations: [],
184
+ assertActive: () => {
185
+ if (state.staleMessage)
186
+ throw new Error(state.staleMessage);
187
+ },
188
+ invalidate: (message) => {
189
+ state.staleMessage ??= message ?? "This extension ctx is stale after session replacement or reload. Do not use a captured pi or command ctx after ctx.newSession(), ctx.fork(), ctx.switchSession(), or ctx.reload(). For newSession, fork, and switchSession, move post-replacement work into withSession and use the ctx passed to withSession. For reload, do not use the old ctx after await ctx.reload().";
190
+ },
191
+ // Pre-bind: queue registrations so bindCore() can flush them once the
192
+ // model registry is available. bindCore() replaces both with direct calls.
193
+ registerProvider: (name, config, extensionPath = "<unknown>") => {
194
+ runtime.pendingProviderRegistrations.push({ name, config, extensionPath });
195
+ },
196
+ unregisterProvider: (name) => {
197
+ runtime.pendingProviderRegistrations = runtime.pendingProviderRegistrations.filter((r) => r.name !== name);
198
+ }
199
+ };
200
+ return runtime;
201
+ }
202
+ function createExtensionAPI(extension, runtime, cwd, eventBus) {
203
+ return {
204
+ // Registration methods - write to extension
205
+ on(event, handler) {
206
+ runtime.assertActive();
207
+ let list = extension.handlers.get(event) ?? [];
208
+ list.push(handler), extension.handlers.set(event, list);
209
+ },
210
+ registerTool(tool) {
211
+ runtime.assertActive(), extension.tools.set(tool.name, {
212
+ definition: tool,
213
+ sourceInfo: extension.sourceInfo
214
+ }), runtime.refreshTools();
215
+ },
216
+ registerCommand(name, options) {
217
+ runtime.assertActive(), extension.commands.set(name, {
218
+ name,
219
+ sourceInfo: extension.sourceInfo,
220
+ ...options
221
+ });
222
+ },
223
+ registerShortcut(shortcut, options) {
224
+ runtime.assertActive(), extension.shortcuts.set(shortcut, { shortcut, extensionPath: extension.path, ...options });
225
+ },
226
+ registerFlag(name, options) {
227
+ runtime.assertActive(), extension.flags.set(name, { name, extensionPath: extension.path, ...options }), options.default !== void 0 && !runtime.flagValues.has(name) && runtime.flagValues.set(name, options.default);
228
+ },
229
+ registerMessageRenderer(customType, renderer) {
230
+ runtime.assertActive(), extension.messageRenderers.set(customType, renderer);
231
+ },
232
+ registerEntryRenderer(customType, renderer) {
233
+ runtime.assertActive(), extension.entryRenderers ??= /* @__PURE__ */ new Map(), extension.entryRenderers.set(customType, renderer);
234
+ },
235
+ // Flag access - checks extension registered it, reads from runtime
236
+ getFlag(name) {
237
+ if (runtime.assertActive(), !!extension.flags.has(name))
238
+ return runtime.flagValues.get(name);
239
+ },
240
+ // Action methods - delegate to shared runtime
241
+ sendMessage(message, options) {
242
+ runtime.assertActive(), runtime.sendMessage(message, options);
243
+ },
244
+ sendUserMessage(content, options) {
245
+ runtime.assertActive(), runtime.sendUserMessage(content, options);
246
+ },
247
+ appendEntry(customType, data) {
248
+ runtime.assertActive(), runtime.appendEntry(customType, data);
249
+ },
250
+ setSessionName(name) {
251
+ runtime.assertActive(), runtime.setSessionName(name);
252
+ },
253
+ getSessionName() {
254
+ return runtime.assertActive(), runtime.getSessionName();
255
+ },
256
+ setLabel(entryId, label) {
257
+ runtime.assertActive(), runtime.setLabel(entryId, label);
258
+ },
259
+ exec(command, args, options) {
260
+ return runtime.assertActive(), execCommand(command, args, options?.cwd ?? cwd, options);
261
+ },
262
+ getActiveTools() {
263
+ return runtime.assertActive(), runtime.getActiveTools();
264
+ },
265
+ getAllTools() {
266
+ return runtime.assertActive(), runtime.getAllTools();
267
+ },
268
+ setActiveTools(toolNames) {
269
+ runtime.assertActive(), runtime.setActiveTools(toolNames);
270
+ },
271
+ getCommands() {
272
+ return runtime.assertActive(), runtime.getCommands();
273
+ },
274
+ setModel(model) {
275
+ return runtime.assertActive(), runtime.setModel(model);
276
+ },
277
+ getThinkingLevel() {
278
+ return runtime.assertActive(), runtime.getThinkingLevel();
279
+ },
280
+ setThinkingLevel(level) {
281
+ runtime.assertActive(), runtime.setThinkingLevel(level);
282
+ },
283
+ registerProvider(name, config) {
284
+ runtime.assertActive(), runtime.registerProvider(name, config, extension.path);
285
+ },
286
+ unregisterProvider(name) {
287
+ runtime.assertActive(), runtime.unregisterProvider(name, extension.path);
288
+ },
289
+ events: eventBus
290
+ };
291
+ }
292
+ function isCurrentCacheToken(cacheToken) {
293
+ return cacheToken !== void 0 && extensionCacheCwd === cacheToken.cwd && extensionCacheGeneration === cacheToken.generation;
294
+ }
295
+ async function ensureExtensionHost() {
296
+ if (createJitiFn)
297
+ return createJitiFn;
298
+ if (isBunBinary && bunExtensionHost)
299
+ return bunExtensionHost.createJiti;
300
+ let { createJiti } = await import("jiti/static");
301
+ return createJitiFn = createJiti, createJiti;
302
+ }
303
+ async function loadExtensionModule(extensionPath, cacheToken) {
304
+ if (isCurrentCacheToken(cacheToken)) {
305
+ let cachedFactory = extensionCache.get(extensionPath);
306
+ if (cachedFactory)
307
+ return cachedFactory;
308
+ }
309
+ let factory = await (await ensureExtensionHost())(new URL("../core/extensions/loader.js", import.meta.url).href, {
310
+ moduleCache: !1,
311
+ // In Bun binary: use virtualModules for bundled packages (no filesystem resolution)
312
+ // Also disable tryNative so jiti handles ALL imports (not just the entry point)
313
+ // In Node.js/dev: use aliases to resolve to node_modules paths
314
+ ...isBunBinary ? { virtualModules: bunExtensionHost?.virtualModules, tryNative: !1 } : { alias: getAliases() }
315
+ }).import(extensionPath, { default: !0 });
316
+ if (typeof factory == "function")
317
+ return isCurrentCacheToken(cacheToken) && extensionCache.set(extensionPath, factory), factory;
318
+ }
319
+ function createExtension(extensionPath, resolvedPath) {
320
+ let source = extensionPath.startsWith("<") && extensionPath.endsWith(">") ? extensionPath.slice(1, -1).split(":")[0] || "temporary" : "local", baseDir = extensionPath.startsWith("<") ? void 0 : path.dirname(resolvedPath);
321
+ return {
322
+ path: extensionPath,
323
+ resolvedPath,
324
+ sourceInfo: createSyntheticSourceInfo(extensionPath, { source, baseDir }),
325
+ handlers: /* @__PURE__ */ new Map(),
326
+ tools: /* @__PURE__ */ new Map(),
327
+ messageRenderers: /* @__PURE__ */ new Map(),
328
+ entryRenderers: /* @__PURE__ */ new Map(),
329
+ commands: /* @__PURE__ */ new Map(),
330
+ flags: /* @__PURE__ */ new Map(),
331
+ shortcuts: /* @__PURE__ */ new Map()
332
+ };
333
+ }
334
+ async function loadExtension(extensionPath, cwd, eventBus, runtime, cacheToken) {
335
+ let resolvedPath = resolvePath(extensionPath, cwd, { normalizeUnicodeSpaces: !0 });
336
+ try {
337
+ let factory = await measureStartup(`${extensionPath} module import`, () => loadExtensionModule(resolvedPath, cacheToken));
338
+ if (!factory)
339
+ return { extension: null, error: `Extension does not export a valid factory function: ${extensionPath}` };
340
+ let extension = createExtension(extensionPath, resolvedPath), api = createExtensionAPI(extension, runtime, cwd, eventBus);
341
+ return await measureStartup(`${extensionPath} factory`, () => factory(api)), { extension, error: null };
342
+ } catch (err) {
343
+ return { extension: null, error: `Failed to load extension: ${err instanceof Error ? err.message : String(err)}` };
344
+ }
345
+ }
346
+ async function loadExtensionFromFactory(factory, cwd, eventBus, runtime, extensionPath = "<inline>") {
347
+ let extension = createExtension(extensionPath, extensionPath), resolvedCwd = resolvePath(cwd), api = createExtensionAPI(extension, runtime, resolvedCwd, eventBus);
348
+ return await measureStartup(`${extensionPath} factory`, () => factory(api)), extension;
349
+ }
350
+ async function loadExtensionsInternal(paths, cwd, eventBus, runtime, useCache = !1) {
351
+ let extensions = [], errors = [], cacheToken = useCache ? useExtensionCacheCwd(cwd) : void 0, resolvedCwd = cacheToken?.cwd ?? resolvePath(cwd), resolvedEventBus = eventBus ?? createEventBus(), resolvedRuntime = runtime ?? createExtensionRuntime();
352
+ for (let extPath of paths) {
353
+ let { extension, error } = await loadExtension(extPath, resolvedCwd, resolvedEventBus, resolvedRuntime, cacheToken);
354
+ if (error) {
355
+ errors.push({ path: extPath, error });
356
+ continue;
357
+ }
358
+ extension && extensions.push(extension);
359
+ }
360
+ return {
361
+ extensions,
362
+ errors,
363
+ runtime: resolvedRuntime
364
+ };
365
+ }
366
+ async function loadExtensions(paths, cwd, eventBus, runtime) {
367
+ return loadExtensionsInternal(paths, cwd, eventBus, runtime);
368
+ }
369
+ async function loadExtensionsCached(paths, cwd, eventBus, runtime) {
370
+ return loadExtensionsInternal(paths, cwd, eventBus, runtime, !0);
371
+ }
372
+ function readPiManifest(packageJsonPath) {
373
+ try {
374
+ let content = fs.readFileSync(packageJsonPath, "utf-8"), pkg = JSON.parse(content);
375
+ return pkg.pi && typeof pkg.pi == "object" ? pkg.pi : null;
376
+ } catch {
377
+ return null;
378
+ }
379
+ }
380
+ function isExtensionFile(name) {
381
+ return name.endsWith(".ts") || name.endsWith(".js");
382
+ }
383
+ function resolveExtensionEntries(dir) {
384
+ let packageJsonPath = path.join(dir, "package.json");
385
+ if (fs.existsSync(packageJsonPath)) {
386
+ let manifest = readPiManifest(packageJsonPath);
387
+ if (manifest?.extensions?.length) {
388
+ let entries = [];
389
+ for (let extPath of manifest.extensions) {
390
+ let resolvedExtPath = path.resolve(dir, extPath);
391
+ fs.existsSync(resolvedExtPath) && entries.push(resolvedExtPath);
392
+ }
393
+ if (entries.length > 0)
394
+ return entries;
395
+ }
396
+ }
397
+ let indexTs = path.join(dir, "index.ts"), indexJs = path.join(dir, "index.js");
398
+ return fs.existsSync(indexTs) ? [indexTs] : fs.existsSync(indexJs) ? [indexJs] : null;
399
+ }
400
+ function discoverExtensionsInDir(dir) {
401
+ if (!fs.existsSync(dir))
402
+ return [];
403
+ let discovered = [];
404
+ try {
405
+ let entries = fs.readdirSync(dir, { withFileTypes: !0 });
406
+ for (let entry of entries) {
407
+ let entryPath = path.join(dir, entry.name);
408
+ if ((entry.isFile() || entry.isSymbolicLink()) && isExtensionFile(entry.name)) {
409
+ discovered.push(entryPath);
410
+ continue;
411
+ }
412
+ if (entry.isDirectory() || entry.isSymbolicLink()) {
413
+ let entries2 = resolveExtensionEntries(entryPath);
414
+ entries2 && discovered.push(...entries2);
415
+ }
416
+ }
417
+ } catch {
418
+ return [];
419
+ }
420
+ return discovered;
421
+ }
422
+ async function discoverAndLoadExtensions(configuredPaths, cwd, agentDir = getAgentDir(), eventBus) {
423
+ let resolvedCwd = resolvePath(cwd), resolvedAgentDir = resolvePath(agentDir), allPaths = [], seen = /* @__PURE__ */ new Set(), addPaths = (paths) => {
424
+ for (let p of paths) {
425
+ let resolved = path.resolve(p);
426
+ seen.has(resolved) || (seen.add(resolved), allPaths.push(p));
427
+ }
428
+ }, localExtDir = path.join(resolvedCwd, CONFIG_DIR_NAME, "extensions");
429
+ addPaths(discoverExtensionsInDir(localExtDir));
430
+ let globalExtDir = path.join(resolvedAgentDir, "extensions");
431
+ addPaths(discoverExtensionsInDir(globalExtDir));
432
+ for (let p of configuredPaths) {
433
+ let resolved = resolvePath(p, resolvedCwd, { normalizeUnicodeSpaces: !0 });
434
+ if (fs.existsSync(resolved) && fs.statSync(resolved).isDirectory()) {
435
+ let entries = resolveExtensionEntries(resolved);
436
+ if (entries) {
437
+ addPaths(entries);
438
+ continue;
439
+ }
440
+ addPaths(discoverExtensionsInDir(resolved));
441
+ continue;
442
+ }
443
+ addPaths([resolved]);
444
+ }
445
+ return loadExtensions(allPaths, resolvedCwd, eventBus);
446
+ }
447
+
448
+ // packages/coding-agent/dist/core/skills.js
449
+ var import_ignore = __toESM(require_ignore(), 1);
450
+ import { existsSync as existsSync2, readdirSync as readdirSync2, readFileSync as readFileSync2, statSync as statSync2 } from "fs";
451
+ import { basename, dirname as dirname2, join as join2, relative, resolve as resolve2, sep } from "path";
452
+ var MAX_NAME_LENGTH = 64, MAX_DESCRIPTION_LENGTH = 1024, IGNORE_FILE_NAMES = [".gitignore", ".ignore", ".fdignore"];
453
+ function toPosixPath(p) {
454
+ return p.split(sep).join("/");
455
+ }
456
+ function prefixIgnorePattern(line, prefix) {
457
+ let trimmed = line.trim();
458
+ if (!trimmed || trimmed.startsWith("#") && !trimmed.startsWith("\\#"))
459
+ return null;
460
+ let pattern = line, negated = !1;
461
+ pattern.startsWith("!") ? (negated = !0, pattern = pattern.slice(1)) : pattern.startsWith("\\!") && (pattern = pattern.slice(1)), pattern.startsWith("/") && (pattern = pattern.slice(1));
462
+ let prefixed = prefix ? `${prefix}${pattern}` : pattern;
463
+ return negated ? `!${prefixed}` : prefixed;
464
+ }
465
+ function addIgnoreRules(ig, dir, rootDir) {
466
+ let relativeDir = relative(rootDir, dir), prefix = relativeDir ? `${toPosixPath(relativeDir)}/` : "";
467
+ for (let filename of IGNORE_FILE_NAMES) {
468
+ let ignorePath = join2(dir, filename);
469
+ if (existsSync2(ignorePath))
470
+ try {
471
+ let patterns = readFileSync2(ignorePath, "utf-8").split(/\r?\n/).map((line) => prefixIgnorePattern(line, prefix)).filter((line) => !!line);
472
+ patterns.length > 0 && ig.add(patterns);
473
+ } catch {
474
+ }
475
+ }
476
+ }
477
+ function validateName(name) {
478
+ let errors = [];
479
+ return name.length > MAX_NAME_LENGTH && errors.push(`name exceeds ${MAX_NAME_LENGTH} characters (${name.length})`), /^[a-z0-9-]+$/.test(name) || errors.push("name contains invalid characters (must be lowercase a-z, 0-9, hyphens only)"), (name.startsWith("-") || name.endsWith("-")) && errors.push("name must not start or end with a hyphen"), name.includes("--") && errors.push("name must not contain consecutive hyphens"), errors;
480
+ }
481
+ function validateDescription(description) {
482
+ let errors = [];
483
+ return !description || description.trim() === "" ? errors.push("description is required") : description.length > MAX_DESCRIPTION_LENGTH && errors.push(`description exceeds ${MAX_DESCRIPTION_LENGTH} characters (${description.length})`), errors;
484
+ }
485
+ function createSkillSourceInfo(filePath, baseDir, source) {
486
+ switch (source) {
487
+ case "user":
488
+ return createSyntheticSourceInfo(filePath, {
489
+ source: "local",
490
+ scope: "user",
491
+ baseDir
492
+ });
493
+ case "project":
494
+ return createSyntheticSourceInfo(filePath, {
495
+ source: "local",
496
+ scope: "project",
497
+ baseDir
498
+ });
499
+ case "path":
500
+ return createSyntheticSourceInfo(filePath, {
501
+ source: "local",
502
+ baseDir
503
+ });
504
+ default:
505
+ return createSyntheticSourceInfo(filePath, { source, baseDir });
506
+ }
507
+ }
508
+ function loadSkillsFromDir(options) {
509
+ let { dir, source } = options;
510
+ return loadSkillsFromDirInternal(dir, source, !0);
511
+ }
512
+ function loadSkillsFromDirInternal(dir, source, includeRootFiles, ignoreMatcher, rootDir) {
513
+ let skills = [], diagnostics = [];
514
+ if (!existsSync2(dir))
515
+ return { skills, diagnostics };
516
+ let root = rootDir ?? dir, ig = ignoreMatcher ?? (0, import_ignore.default)();
517
+ addIgnoreRules(ig, dir, root);
518
+ try {
519
+ let entries = readdirSync2(dir, { withFileTypes: !0 });
520
+ for (let entry of entries) {
521
+ if (entry.name !== "SKILL.md")
522
+ continue;
523
+ let fullPath = join2(dir, entry.name), isFile = entry.isFile();
524
+ if (entry.isSymbolicLink())
525
+ try {
526
+ isFile = statSync2(fullPath).isFile();
527
+ } catch {
528
+ continue;
529
+ }
530
+ let relPath = toPosixPath(relative(root, fullPath));
531
+ if (!isFile || ig.ignores(relPath))
532
+ continue;
533
+ let result = loadSkillFromFile(fullPath, source);
534
+ return result.skill && skills.push(result.skill), diagnostics.push(...result.diagnostics), { skills, diagnostics };
535
+ }
536
+ for (let entry of entries) {
537
+ if (entry.name.startsWith(".") || entry.name === "node_modules")
538
+ continue;
539
+ let fullPath = join2(dir, entry.name), isDirectory = entry.isDirectory(), isFile = entry.isFile();
540
+ if (entry.isSymbolicLink())
541
+ try {
542
+ let stats = statSync2(fullPath);
543
+ isDirectory = stats.isDirectory(), isFile = stats.isFile();
544
+ } catch {
545
+ continue;
546
+ }
547
+ let relPath = toPosixPath(relative(root, fullPath)), ignorePath = isDirectory ? `${relPath}/` : relPath;
548
+ if (ig.ignores(ignorePath))
549
+ continue;
550
+ if (isDirectory) {
551
+ let subResult = loadSkillsFromDirInternal(fullPath, source, !1, ig, root);
552
+ skills.push(...subResult.skills), diagnostics.push(...subResult.diagnostics);
553
+ continue;
554
+ }
555
+ if (!isFile || !includeRootFiles || !entry.name.endsWith(".md"))
556
+ continue;
557
+ let result = loadSkillFromFile(fullPath, source);
558
+ result.skill && skills.push(result.skill), diagnostics.push(...result.diagnostics);
559
+ }
560
+ } catch {
561
+ }
562
+ return { skills, diagnostics };
563
+ }
564
+ function loadSkillFromFile(filePath, source) {
565
+ let diagnostics = [];
566
+ try {
567
+ let rawContent = readFileSync2(filePath, "utf-8"), { frontmatter } = parseFrontmatter(rawContent), skillDir = dirname2(filePath), parentDirName = basename(skillDir), descErrors = validateDescription(frontmatter.description);
568
+ for (let error of descErrors)
569
+ diagnostics.push({ type: "warning", message: error, path: filePath });
570
+ let name = frontmatter.name || parentDirName, nameErrors = validateName(name);
571
+ for (let error of nameErrors)
572
+ diagnostics.push({ type: "warning", message: error, path: filePath });
573
+ return !frontmatter.description || frontmatter.description.trim() === "" ? { skill: null, diagnostics } : {
574
+ skill: {
575
+ name,
576
+ description: frontmatter.description,
577
+ filePath,
578
+ baseDir: skillDir,
579
+ sourceInfo: createSkillSourceInfo(filePath, skillDir, source),
580
+ disableModelInvocation: frontmatter["disable-model-invocation"] === !0
581
+ },
582
+ diagnostics
583
+ };
584
+ } catch (error) {
585
+ let message = error instanceof Error ? error.message : "failed to parse skill file";
586
+ return diagnostics.push({ type: "warning", message, path: filePath }), { skill: null, diagnostics };
587
+ }
588
+ }
589
+ function formatSkillsForPrompt(skills) {
590
+ let visibleSkills = skills.filter((s) => !s.disableModelInvocation);
591
+ if (visibleSkills.length === 0)
592
+ return "";
593
+ let lines = [
594
+ `
595
+
596
+ The following skills provide specialized instructions for specific tasks.`,
597
+ "Use the read tool to load a skill's file when the task matches its description.",
598
+ "When a skill file references a relative path, resolve it against the skill directory (parent of SKILL.md / dirname of the path) and use that absolute path in tool commands.",
599
+ "",
600
+ "<available_skills>"
601
+ ];
602
+ for (let skill of visibleSkills)
603
+ lines.push(" <skill>"), lines.push(` <name>${escapeXml(skill.name)}</name>`), lines.push(` <description>${escapeXml(skill.description)}</description>`), lines.push(` <location>${escapeXml(skill.filePath)}</location>`), lines.push(" </skill>");
604
+ return lines.push("</available_skills>"), lines.join(`
605
+ `);
606
+ }
607
+ function escapeXml(str) {
608
+ return str.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
609
+ }
610
+ function loadSkills(options) {
611
+ let { agentDir, skillPaths, includeDefaults } = options, resolvedCwd = resolvePath(options.cwd), resolvedAgentDir = resolvePath(agentDir ?? getAgentDir()), skillMap = /* @__PURE__ */ new Map(), realPathSet = /* @__PURE__ */ new Set(), allDiagnostics = [], collisionDiagnostics = [];
612
+ function addSkills(result) {
613
+ allDiagnostics.push(...result.diagnostics);
614
+ for (let skill of result.skills) {
615
+ let realPath = canonicalizePath(skill.filePath);
616
+ if (realPathSet.has(realPath))
617
+ continue;
618
+ let existing = skillMap.get(skill.name);
619
+ existing ? collisionDiagnostics.push({
620
+ type: "collision",
621
+ message: `name "${skill.name}" collision`,
622
+ path: skill.filePath,
623
+ collision: {
624
+ resourceType: "skill",
625
+ name: skill.name,
626
+ winnerPath: existing.filePath,
627
+ loserPath: skill.filePath
628
+ }
629
+ }) : (skillMap.set(skill.name, skill), realPathSet.add(realPath));
630
+ }
631
+ }
632
+ includeDefaults && (addSkills(loadSkillsFromDirInternal(join2(resolvedAgentDir, "skills"), "user", !0)), addSkills(loadSkillsFromDirInternal(resolve2(resolvedCwd, CONFIG_DIR_NAME, "skills"), "project", !0)));
633
+ let userSkillsDir = join2(resolvedAgentDir, "skills"), projectSkillsDir = resolve2(resolvedCwd, CONFIG_DIR_NAME, "skills"), isUnderPath = (target, root) => {
634
+ let normalizedRoot = resolve2(root);
635
+ if (target === normalizedRoot)
636
+ return !0;
637
+ let prefix = normalizedRoot.endsWith(sep) ? normalizedRoot : `${normalizedRoot}${sep}`;
638
+ return target.startsWith(prefix);
639
+ }, getSource = (resolvedPath) => {
640
+ if (!includeDefaults) {
641
+ if (isUnderPath(resolvedPath, userSkillsDir))
642
+ return "user";
643
+ if (isUnderPath(resolvedPath, projectSkillsDir))
644
+ return "project";
645
+ }
646
+ return "path";
647
+ };
648
+ for (let rawPath of skillPaths) {
649
+ let resolvedPath = resolvePath(rawPath, resolvedCwd, { trim: !0 });
650
+ if (!existsSync2(resolvedPath)) {
651
+ allDiagnostics.push({ type: "warning", message: "skill path does not exist", path: resolvedPath });
652
+ continue;
653
+ }
654
+ try {
655
+ let stats = statSync2(resolvedPath), source = getSource(resolvedPath);
656
+ if (stats.isDirectory())
657
+ addSkills(loadSkillsFromDirInternal(resolvedPath, source, !0));
658
+ else if (stats.isFile() && resolvedPath.endsWith(".md")) {
659
+ let result = loadSkillFromFile(resolvedPath, source);
660
+ result.skill ? addSkills({ skills: [result.skill], diagnostics: result.diagnostics }) : allDiagnostics.push(...result.diagnostics);
661
+ } else
662
+ allDiagnostics.push({ type: "warning", message: "skill path is not a markdown file", path: resolvedPath });
663
+ } catch (error) {
664
+ let message = error instanceof Error ? error.message : "failed to read skill path";
665
+ allDiagnostics.push({ type: "warning", message, path: resolvedPath });
666
+ }
667
+ }
668
+ return {
669
+ skills: Array.from(skillMap.values()),
670
+ diagnostics: [...allDiagnostics, ...collisionDiagnostics]
671
+ };
672
+ }
673
+
674
+ // packages/coding-agent/dist/core/resource-loader.js
675
+ import { existsSync as existsSync4, readdirSync as readdirSync4, readFileSync as readFileSync4, statSync as statSync4 } from "node:fs";
676
+ import { dirname as dirname4, join as join4, resolve as resolve4, sep as sep3 } from "node:path";
677
+ import chalk from "chalk";
678
+
679
+ // packages/coding-agent/dist/core/prompt-templates.js
680
+ import { existsSync as existsSync3, readdirSync as readdirSync3, readFileSync as readFileSync3, statSync as statSync3 } from "fs";
681
+ import { basename as basename2, dirname as dirname3, join as join3, resolve as resolve3, sep as sep2 } from "path";
682
+ function parseCommandArgs(argsString) {
683
+ let args = [], current = "", inQuote = null;
684
+ for (let i = 0; i < argsString.length; i++) {
685
+ let char = argsString[i];
686
+ inQuote ? char === inQuote ? inQuote = null : current += char : char === '"' || char === "'" ? inQuote = char : /\s/.test(char) ? current && (args.push(current), current = "") : current += char;
687
+ }
688
+ return current && args.push(current), args;
689
+ }
690
+ function substituteArgs(content, args) {
691
+ let allArgs = args.join(" ");
692
+ return content.replace(/\$\{(\d+):-([^}]*)\}|\$\{@:(\d+)(?::(\d+))?\}|\$(ARGUMENTS|@|\d+)/g, (_match, defaultNum, defaultValue, sliceStart, sliceLength, simple) => {
693
+ if (defaultNum) {
694
+ let index2 = parseInt(defaultNum, 10) - 1, value = args[index2];
695
+ return value || defaultValue;
696
+ }
697
+ if (sliceStart) {
698
+ let start = parseInt(sliceStart, 10) - 1;
699
+ if (start < 0 && (start = 0), sliceLength) {
700
+ let length = parseInt(sliceLength, 10);
701
+ return args.slice(start, start + length).join(" ");
702
+ }
703
+ return args.slice(start).join(" ");
704
+ }
705
+ if (simple === "ARGUMENTS" || simple === "@")
706
+ return allArgs;
707
+ let index = parseInt(simple, 10) - 1;
708
+ return args[index] ?? "";
709
+ });
710
+ }
711
+ function loadTemplateFromFile(filePath, sourceInfo) {
712
+ try {
713
+ let rawContent = readFileSync3(filePath, "utf-8"), { frontmatter, body } = parseFrontmatter(rawContent), name = basename2(filePath).replace(/\.md$/, ""), description = frontmatter.description || "";
714
+ if (!description) {
715
+ let firstLine = body.split(`
716
+ `).find((line) => line.trim());
717
+ firstLine && (description = firstLine.slice(0, 60), firstLine.length > 60 && (description += "..."));
718
+ }
719
+ return {
720
+ name,
721
+ description,
722
+ ...frontmatter["argument-hint"] && { argumentHint: frontmatter["argument-hint"] },
723
+ content: body,
724
+ sourceInfo,
725
+ filePath
726
+ };
727
+ } catch {
728
+ return null;
729
+ }
730
+ }
731
+ function loadTemplatesFromDir(dir, getSourceInfo) {
732
+ let templates = [];
733
+ if (!existsSync3(dir))
734
+ return templates;
735
+ try {
736
+ let entries = readdirSync3(dir, { withFileTypes: !0 });
737
+ for (let entry of entries) {
738
+ let fullPath = join3(dir, entry.name), isFile = entry.isFile();
739
+ if (entry.isSymbolicLink())
740
+ try {
741
+ isFile = statSync3(fullPath).isFile();
742
+ } catch {
743
+ continue;
744
+ }
745
+ if (isFile && entry.name.endsWith(".md")) {
746
+ let template = loadTemplateFromFile(fullPath, getSourceInfo(fullPath));
747
+ template && templates.push(template);
748
+ }
749
+ }
750
+ } catch {
751
+ return templates;
752
+ }
753
+ return templates;
754
+ }
755
+ function loadPromptTemplates(options) {
756
+ let resolvedCwd = resolvePath(options.cwd), resolvedAgentDir = resolvePath(options.agentDir), promptPaths = options.promptPaths, includeDefaults = options.includeDefaults, templates = [], globalPromptsDir = join3(resolvedAgentDir, "prompts"), projectPromptsDir = resolve3(resolvedCwd, CONFIG_DIR_NAME, "prompts"), isUnderPath = (target, root) => {
757
+ let normalizedRoot = resolve3(root);
758
+ if (target === normalizedRoot)
759
+ return !0;
760
+ let prefix = normalizedRoot.endsWith(sep2) ? normalizedRoot : `${normalizedRoot}${sep2}`;
761
+ return target.startsWith(prefix);
762
+ }, getSourceInfo = (resolvedPath) => isUnderPath(resolvedPath, globalPromptsDir) ? createSyntheticSourceInfo(resolvedPath, {
763
+ source: "local",
764
+ scope: "user",
765
+ baseDir: globalPromptsDir
766
+ }) : isUnderPath(resolvedPath, projectPromptsDir) ? createSyntheticSourceInfo(resolvedPath, {
767
+ source: "local",
768
+ scope: "project",
769
+ baseDir: projectPromptsDir
770
+ }) : createSyntheticSourceInfo(resolvedPath, {
771
+ source: "local",
772
+ baseDir: statSync3(resolvedPath).isDirectory() ? resolvedPath : dirname3(resolvedPath)
773
+ });
774
+ includeDefaults && (templates.push(...loadTemplatesFromDir(globalPromptsDir, getSourceInfo)), templates.push(...loadTemplatesFromDir(projectPromptsDir, getSourceInfo)));
775
+ for (let rawPath of promptPaths) {
776
+ let resolvedPath = resolvePath(rawPath, resolvedCwd, { trim: !0 });
777
+ if (existsSync3(resolvedPath))
778
+ try {
779
+ let stats = statSync3(resolvedPath);
780
+ if (stats.isDirectory())
781
+ templates.push(...loadTemplatesFromDir(resolvedPath, getSourceInfo));
782
+ else if (stats.isFile() && resolvedPath.endsWith(".md")) {
783
+ let template = loadTemplateFromFile(resolvedPath, getSourceInfo(resolvedPath));
784
+ template && templates.push(template);
785
+ }
786
+ } catch {
787
+ }
788
+ }
789
+ return templates;
790
+ }
791
+ function expandPromptTemplate(text, templates) {
792
+ if (!text.startsWith("/"))
793
+ return text;
794
+ let match = text.match(/^\/([^\s]+)(?:\s+([\s\S]*))?$/);
795
+ if (!match)
796
+ return text;
797
+ let templateName = match[1], argsString = match[2] ?? "", template = templates.find((t) => t.name === templateName);
798
+ if (template) {
799
+ let args = parseCommandArgs(argsString);
800
+ return substituteArgs(template.content, args);
801
+ }
802
+ return text;
803
+ }
804
+
805
+ // packages/coding-agent/dist/core/resource-loader.js
806
+ function inlineExtensionPath(input, index) {
807
+ return `<inline:${typeof input != "function" ? input.name : index + 1}>`;
808
+ }
809
+ function resolvePromptInput(input, description) {
810
+ if (input) {
811
+ if (existsSync4(input))
812
+ try {
813
+ return readFileSync4(input, "utf-8");
814
+ } catch (error) {
815
+ return console.error(chalk.yellow(`Warning: Could not read ${description} file ${input}: ${error}`)), input;
816
+ }
817
+ return input;
818
+ }
819
+ }
820
+ function loadContextFileFromDir(dir) {
821
+ let candidates = ["AGENTS.md", "AGENTS.MD", "CLAUDE.md", "CLAUDE.MD"];
822
+ for (let filename of candidates) {
823
+ let filePath = join4(dir, filename);
824
+ if (existsSync4(filePath))
825
+ try {
826
+ return {
827
+ path: filePath,
828
+ content: readFileSync4(filePath, "utf-8")
829
+ };
830
+ } catch (error) {
831
+ console.error(chalk.yellow(`Warning: Could not read ${filePath}: ${error}`));
832
+ }
833
+ }
834
+ return null;
835
+ }
836
+ function loadProjectContextFiles(options) {
837
+ let resolvedCwd = resolvePath(options.cwd), resolvedAgentDir = resolvePath(options.agentDir), contextFiles = [], seenPaths = /* @__PURE__ */ new Set(), userContexts = options.settingsManager ? loadSelectedUserInstructions({ agentDir: resolvedAgentDir, settingsManager: options.settingsManager }) : [getGlobalInstructionsPath(resolvedAgentDir)].map((path2) => loadContextFileFromDir(dirname4(path2))).filter((file) => file !== null);
838
+ for (let userContext of userContexts)
839
+ contextFiles.push(userContext), seenPaths.add(userContext.path);
840
+ let ancestorContextFiles = [], currentDir = resolvedCwd;
841
+ for (; ; ) {
842
+ let contextFile = loadContextFileFromDir(currentDir);
843
+ contextFile && !seenPaths.has(contextFile.path) && (ancestorContextFiles.unshift(contextFile), seenPaths.add(contextFile.path));
844
+ let parentDir = dirname4(currentDir);
845
+ if (parentDir === currentDir)
846
+ break;
847
+ currentDir = parentDir;
848
+ }
849
+ return contextFiles.push(...ancestorContextFiles), contextFiles;
850
+ }
851
+ var DefaultResourceLoader = class {
852
+ cwd;
853
+ agentDir;
854
+ settingsManager;
855
+ eventBus;
856
+ packageManager;
857
+ additionalExtensionPaths;
858
+ additionalSkillPaths;
859
+ additionalPromptTemplatePaths;
860
+ additionalThemePaths;
861
+ extensionFactories;
862
+ noExtensions;
863
+ noSkills;
864
+ noPromptTemplates;
865
+ noThemes;
866
+ noContextFiles;
867
+ systemPromptSource;
868
+ appendSystemPromptSource;
869
+ extensionsOverride;
870
+ skillsOverride;
871
+ promptsOverride;
872
+ themesOverride;
873
+ agentsFilesOverride;
874
+ systemPromptOverride;
875
+ appendSystemPromptOverride;
876
+ extensionsResult;
877
+ skills;
878
+ skillDiagnostics;
879
+ prompts;
880
+ promptDiagnostics;
881
+ themes;
882
+ themeDiagnostics;
883
+ agentsFiles;
884
+ systemPrompt;
885
+ appendSystemPrompt;
886
+ lastSkillPaths;
887
+ extensionSkillSourceInfos;
888
+ extensionPromptSourceInfos;
889
+ extensionThemeSourceInfos;
890
+ lastPromptPaths;
891
+ lastThemePaths;
892
+ loaded;
893
+ constructor(options) {
894
+ this.cwd = resolvePath(options.cwd), this.agentDir = resolvePath(options.agentDir), this.settingsManager = options.settingsManager ?? SettingsManager.create(this.cwd, this.agentDir), this.eventBus = options.eventBus ?? createEventBus(), this.packageManager = new DefaultPackageManager({
895
+ cwd: this.cwd,
896
+ agentDir: this.agentDir,
897
+ settingsManager: this.settingsManager
898
+ }), this.additionalExtensionPaths = options.additionalExtensionPaths ?? [], this.additionalSkillPaths = options.additionalSkillPaths ?? [], this.additionalPromptTemplatePaths = options.additionalPromptTemplatePaths ?? [], this.additionalThemePaths = options.additionalThemePaths ?? [], this.extensionFactories = options.extensionFactories ?? [], this.noExtensions = options.noExtensions ?? !1, this.noSkills = options.noSkills ?? !1, this.noPromptTemplates = options.noPromptTemplates ?? !1, this.noThemes = options.noThemes ?? !1, this.noContextFiles = options.noContextFiles ?? !1, this.systemPromptSource = options.systemPrompt, this.appendSystemPromptSource = options.appendSystemPrompt, this.extensionsOverride = options.extensionsOverride, this.skillsOverride = options.skillsOverride, this.promptsOverride = options.promptsOverride, this.themesOverride = options.themesOverride, this.agentsFilesOverride = options.agentsFilesOverride, this.systemPromptOverride = options.systemPromptOverride, this.appendSystemPromptOverride = options.appendSystemPromptOverride, this.extensionsResult = { extensions: [], errors: [], runtime: createExtensionRuntime() }, this.skills = [], this.skillDiagnostics = [], this.prompts = [], this.promptDiagnostics = [], this.themes = [], this.themeDiagnostics = [], this.agentsFiles = [], this.appendSystemPrompt = [], this.lastSkillPaths = [], this.extensionSkillSourceInfos = /* @__PURE__ */ new Map(), this.extensionPromptSourceInfos = /* @__PURE__ */ new Map(), this.extensionThemeSourceInfos = /* @__PURE__ */ new Map(), this.lastPromptPaths = [], this.lastThemePaths = [], this.loaded = !1;
899
+ }
900
+ getExtensions() {
901
+ return this.extensionsResult;
902
+ }
903
+ getSkills() {
904
+ return { skills: this.skills, diagnostics: this.skillDiagnostics };
905
+ }
906
+ getPrompts() {
907
+ return { prompts: this.prompts, diagnostics: this.promptDiagnostics };
908
+ }
909
+ getThemes() {
910
+ return { themes: this.themes, diagnostics: this.themeDiagnostics };
911
+ }
912
+ getAgentsFiles() {
913
+ return { agentsFiles: this.agentsFiles };
914
+ }
915
+ contextFilesEnabled() {
916
+ return !this.noContextFiles;
917
+ }
918
+ getSystemPrompt() {
919
+ return this.systemPrompt;
920
+ }
921
+ getAppendSystemPrompt() {
922
+ return this.appendSystemPrompt;
923
+ }
924
+ async attachInlineExtensions(factories) {
925
+ let loaded = new Set(this.extensionsResult.extensions.map((extension) => extension.path)), pending = factories.filter((factory, index) => {
926
+ let path2 = inlineExtensionPath(factory, this.extensionFactories.length + index);
927
+ return !loaded.has(path2);
928
+ });
929
+ if (pending.length === 0)
930
+ return { extensions: [], errors: [], runtime: this.extensionsResult.runtime };
931
+ let attached = await this.loadExtensionFactories(this.extensionsResult.runtime, pending);
932
+ return this.extensionFactories.push(...pending), this.extensionsResult.extensions.push(...attached.extensions), this.extensionsResult.errors.push(...attached.errors), this.addExtensionConflictDiagnostics(this.extensionsResult), {
933
+ extensions: attached.extensions,
934
+ errors: attached.errors,
935
+ runtime: this.extensionsResult.runtime
936
+ };
937
+ }
938
+ extendResources(paths) {
939
+ let skillPaths = this.normalizeExtensionPaths(paths.skillPaths ?? []), promptPaths = this.normalizeExtensionPaths(paths.promptPaths ?? []), themePaths = this.normalizeExtensionPaths(paths.themePaths ?? []);
940
+ for (let entry of skillPaths)
941
+ this.extensionSkillSourceInfos.set(entry.path, createSourceInfo(entry.path, entry.metadata));
942
+ for (let entry of promptPaths)
943
+ this.extensionPromptSourceInfos.set(entry.path, createSourceInfo(entry.path, entry.metadata));
944
+ for (let entry of themePaths)
945
+ this.extensionThemeSourceInfos.set(entry.path, createSourceInfo(entry.path, entry.metadata));
946
+ skillPaths.length > 0 && (this.lastSkillPaths = this.mergePaths(this.lastSkillPaths, skillPaths.map((entry) => entry.path)), this.updateSkillsFromPaths(this.lastSkillPaths)), promptPaths.length > 0 && (this.lastPromptPaths = this.mergePaths(this.lastPromptPaths, promptPaths.map((entry) => entry.path)), this.updatePromptsFromPaths(this.lastPromptPaths)), themePaths.length > 0 && (this.lastThemePaths = this.mergePaths(this.lastThemePaths, themePaths.map((entry) => entry.path)), this.updateThemesFromPaths(this.lastThemePaths));
947
+ }
948
+ resolveOnMissing(skipMissingPackageInstall) {
949
+ if (skipMissingPackageInstall)
950
+ return async () => "skip";
951
+ }
952
+ async loadProjectTrustExtensions(options) {
953
+ return this.settingsManager.setProjectTrusted(!1), await this.settingsManager.reload(), this.loadCurrentExtensionSet({
954
+ includeInlineFactories: !0,
955
+ skipMissingPackageInstall: options?.skipMissingPackageInstall
956
+ });
957
+ }
958
+ async reload(options) {
959
+ resetTimings("extensions"), this.loaded && clearExtensionCache();
960
+ let preTrustExtensions;
961
+ if (options?.resolveProjectTrust) {
962
+ preTrustExtensions = await this.loadProjectTrustExtensions(options);
963
+ let projectTrusted = await options.resolveProjectTrust({ extensionsResult: preTrustExtensions });
964
+ this.settingsManager.setProjectTrusted(projectTrusted);
965
+ }
966
+ await this.settingsManager.reload();
967
+ let resolvedPaths = await this.packageManager.resolve(this.resolveOnMissing(options?.skipMissingPackageInstall)), cliExtensionPaths = await this.packageManager.resolveExtensionSources(this.additionalExtensionPaths, {
968
+ temporary: !0
969
+ }), metadataByPath = /* @__PURE__ */ new Map();
970
+ this.extensionSkillSourceInfos = /* @__PURE__ */ new Map(), this.extensionPromptSourceInfos = /* @__PURE__ */ new Map(), this.extensionThemeSourceInfos = /* @__PURE__ */ new Map();
971
+ let getEnabledResources = (resources) => {
972
+ for (let r of resources)
973
+ metadataByPath.has(r.path) || metadataByPath.set(r.path, r.metadata);
974
+ return resources.filter((r) => r.enabled);
975
+ }, getEnabledPaths = (resources) => getEnabledResources(resources).map((r) => r.path), enabledExtensions = getEnabledPaths(resolvedPaths.extensions), enabledSkillResources = getEnabledResources(resolvedPaths.skills), enabledPrompts = getEnabledPaths(resolvedPaths.prompts), enabledThemes = getEnabledPaths(resolvedPaths.themes), enabledSkills = enabledSkillResources.map((resource) => this.mapSkillPath(resource, metadataByPath));
976
+ for (let r of cliExtensionPaths.extensions)
977
+ metadataByPath.has(r.path) || metadataByPath.set(r.path, { source: "cli", scope: "temporary", origin: "top-level" });
978
+ for (let r of cliExtensionPaths.skills)
979
+ metadataByPath.has(r.path) || metadataByPath.set(r.path, { source: "cli", scope: "temporary", origin: "top-level" });
980
+ let cliEnabledExtensions = getEnabledPaths(cliExtensionPaths.extensions), cliEnabledSkills = getEnabledPaths(cliExtensionPaths.skills), cliEnabledPrompts = getEnabledPaths(cliExtensionPaths.prompts), cliEnabledThemes = getEnabledPaths(cliExtensionPaths.themes), extensionPaths = this.noExtensions ? cliEnabledExtensions : this.mergePaths(cliEnabledExtensions, enabledExtensions), extensionsResult = await this.loadFinalExtensionSet(extensionPaths, preTrustExtensions);
981
+ for (let p of this.additionalExtensionPaths)
982
+ if (isLocalPath(p)) {
983
+ let resolved = this.resolveResourcePath(p);
984
+ existsSync4(resolved) || extensionsResult.errors.push({ path: resolved, error: `Extension path does not exist: ${resolved}` });
985
+ }
986
+ this.extensionsResult = this.extensionsOverride ? this.extensionsOverride(extensionsResult) : extensionsResult, this.applyExtensionSourceInfo(this.extensionsResult.extensions, metadataByPath);
987
+ let skillPaths = this.noSkills ? this.mergePaths(cliEnabledSkills, this.additionalSkillPaths) : this.mergePaths([...cliEnabledSkills, ...enabledSkills], this.additionalSkillPaths);
988
+ this.lastSkillPaths = skillPaths, this.updateSkillsFromPaths(skillPaths, metadataByPath);
989
+ for (let p of this.additionalSkillPaths)
990
+ if (isLocalPath(p)) {
991
+ let resolved = this.resolveResourcePath(p);
992
+ !existsSync4(resolved) && !this.skillDiagnostics.some((d) => d.path === resolved) && this.skillDiagnostics.push({ type: "error", message: "Skill path does not exist", path: resolved });
993
+ }
994
+ let promptPaths = this.noPromptTemplates ? this.mergePaths(cliEnabledPrompts, this.additionalPromptTemplatePaths) : this.mergePaths([...cliEnabledPrompts, ...enabledPrompts], this.additionalPromptTemplatePaths);
995
+ this.lastPromptPaths = promptPaths, this.updatePromptsFromPaths(promptPaths, metadataByPath);
996
+ for (let p of this.additionalPromptTemplatePaths)
997
+ if (isLocalPath(p)) {
998
+ let resolved = this.resolveResourcePath(p);
999
+ !existsSync4(resolved) && !this.promptDiagnostics.some((d) => d.path === resolved) && this.promptDiagnostics.push({
1000
+ type: "error",
1001
+ message: "Prompt template path does not exist",
1002
+ path: resolved
1003
+ });
1004
+ }
1005
+ let themePaths = this.noThemes ? this.mergePaths(cliEnabledThemes, this.additionalThemePaths) : this.mergePaths([...cliEnabledThemes, ...enabledThemes], this.additionalThemePaths);
1006
+ this.lastThemePaths = themePaths, this.updateThemesFromPaths(themePaths, metadataByPath);
1007
+ for (let p of this.additionalThemePaths) {
1008
+ let resolved = this.resolveResourcePath(p);
1009
+ !existsSync4(resolved) && !this.themeDiagnostics.some((d) => d.path === resolved) && this.themeDiagnostics.push({ type: "error", message: "Theme path does not exist", path: resolved });
1010
+ }
1011
+ let agentsFiles = {
1012
+ agentsFiles: this.noContextFiles ? [] : loadProjectContextFiles({
1013
+ cwd: this.cwd,
1014
+ agentDir: this.agentDir,
1015
+ settingsManager: this.settingsManager
1016
+ })
1017
+ }, resolvedAgentsFiles = this.agentsFilesOverride ? this.agentsFilesOverride(agentsFiles) : agentsFiles;
1018
+ this.agentsFiles = resolvedAgentsFiles.agentsFiles;
1019
+ let baseSystemPrompt = resolvePromptInput(this.systemPromptSource ?? this.discoverSystemPromptFile(), "system prompt");
1020
+ this.systemPrompt = this.systemPromptOverride ? this.systemPromptOverride(baseSystemPrompt) : baseSystemPrompt;
1021
+ let baseAppend = (this.appendSystemPromptSource ?? (this.discoverAppendSystemPromptFile() ? [this.discoverAppendSystemPromptFile()] : [])).map((s) => resolvePromptInput(s, "append system prompt")).filter((s) => s !== void 0);
1022
+ this.appendSystemPrompt = this.appendSystemPromptOverride ? this.appendSystemPromptOverride(baseAppend) : baseAppend, this.loaded = !0;
1023
+ }
1024
+ async loadCurrentExtensionSet(options) {
1025
+ let resolvedPaths = await this.packageManager.resolve(this.resolveOnMissing(options.skipMissingPackageInstall)), cliExtensionPaths = await this.packageManager.resolveExtensionSources(this.additionalExtensionPaths, {
1026
+ temporary: !0
1027
+ }), enabledExtensions = resolvedPaths.extensions.filter((r) => r.enabled).map((r) => r.path), cliEnabledExtensions = cliExtensionPaths.extensions.filter((r) => r.enabled).map((r) => r.path), extensionPaths = this.noExtensions ? cliEnabledExtensions : this.mergePaths(cliEnabledExtensions, enabledExtensions), extensionsResult = await loadExtensionsCached(extensionPaths, this.cwd, this.eventBus);
1028
+ if (!options.includeInlineFactories)
1029
+ return extensionsResult;
1030
+ let inlineExtensions = await this.loadExtensionFactories(extensionsResult.runtime);
1031
+ return extensionsResult.extensions.push(...inlineExtensions.extensions), extensionsResult.errors.push(...inlineExtensions.errors), extensionsResult;
1032
+ }
1033
+ resolveExtensionLoadPath(path2) {
1034
+ return resolvePath(path2, this.cwd, { normalizeUnicodeSpaces: !0 });
1035
+ }
1036
+ async loadFinalExtensionSet(extensionPaths, preTrustExtensions) {
1037
+ if (!preTrustExtensions) {
1038
+ let extensionsResult2 = await loadExtensionsCached(extensionPaths, this.cwd, this.eventBus), inlineExtensions2 = await this.loadExtensionFactories(extensionsResult2.runtime);
1039
+ return extensionsResult2.extensions.push(...inlineExtensions2.extensions), extensionsResult2.errors.push(...inlineExtensions2.errors), this.addExtensionConflictDiagnostics(extensionsResult2), extensionsResult2;
1040
+ }
1041
+ let preloadedByPath = new Map(preTrustExtensions.extensions.filter((extension) => !extension.path.startsWith("<inline:")).map((extension) => [extension.resolvedPath, extension])), failedPreloadPaths = new Set(preTrustExtensions.errors.map((error) => this.resolveExtensionLoadPath(error.path))), remainingPaths = extensionPaths.filter((path2) => {
1042
+ let resolvedPath = this.resolveExtensionLoadPath(path2);
1043
+ return !preloadedByPath.has(resolvedPath) && !failedPreloadPaths.has(resolvedPath);
1044
+ }), remainingExtensions = await loadExtensionsCached(remainingPaths, this.cwd, this.eventBus, preTrustExtensions.runtime), loadedByPath = new Map(preloadedByPath);
1045
+ for (let extension of remainingExtensions.extensions)
1046
+ loadedByPath.set(extension.resolvedPath, extension);
1047
+ let inlineExtensions = preTrustExtensions.extensions.filter((extension) => extension.path.startsWith("<inline:")), orderedExtensions = extensionPaths.map((path2) => loadedByPath.get(this.resolveExtensionLoadPath(path2))).filter((extension) => extension !== void 0);
1048
+ orderedExtensions.push(...inlineExtensions);
1049
+ let extensionsResult = {
1050
+ extensions: orderedExtensions,
1051
+ errors: [...preTrustExtensions.errors, ...remainingExtensions.errors],
1052
+ runtime: preTrustExtensions.runtime
1053
+ };
1054
+ return this.addExtensionConflictDiagnostics(extensionsResult), extensionsResult;
1055
+ }
1056
+ addExtensionConflictDiagnostics(extensionsResult) {
1057
+ let conflicts = this.detectExtensionConflicts(extensionsResult.extensions);
1058
+ for (let conflict of conflicts)
1059
+ extensionsResult.errors.push({ path: conflict.path, error: conflict.message });
1060
+ }
1061
+ mapSkillPath(resource, metadataByPath) {
1062
+ if (resource.metadata.source !== "auto" && resource.metadata.origin !== "package")
1063
+ return resource.path;
1064
+ try {
1065
+ if (!statSync4(resource.path).isDirectory())
1066
+ return resource.path;
1067
+ } catch {
1068
+ return resource.path;
1069
+ }
1070
+ let skillFile = join4(resource.path, "SKILL.md");
1071
+ return existsSync4(skillFile) ? (metadataByPath.has(skillFile) || metadataByPath.set(skillFile, resource.metadata), skillFile) : resource.path;
1072
+ }
1073
+ normalizeExtensionPaths(entries) {
1074
+ return entries.map((entry) => {
1075
+ let metadata = entry.metadata.baseDir ? { ...entry.metadata, baseDir: this.resolveResourcePath(entry.metadata.baseDir) } : entry.metadata;
1076
+ return {
1077
+ path: this.resolveResourcePath(entry.path),
1078
+ metadata
1079
+ };
1080
+ });
1081
+ }
1082
+ updateSkillsFromPaths(skillPaths, metadataByPath) {
1083
+ let skillsResult;
1084
+ this.noSkills && skillPaths.length === 0 ? skillsResult = { skills: [], diagnostics: [] } : skillsResult = loadSkills({
1085
+ cwd: this.cwd,
1086
+ agentDir: this.agentDir,
1087
+ skillPaths,
1088
+ includeDefaults: !1
1089
+ });
1090
+ let resolvedSkills = this.skillsOverride ? this.skillsOverride(skillsResult) : skillsResult;
1091
+ this.skills = resolvedSkills.skills.map((skill) => ({
1092
+ ...skill,
1093
+ sourceInfo: this.findSourceInfoForPath(skill.filePath, this.extensionSkillSourceInfos, metadataByPath) ?? skill.sourceInfo ?? this.getDefaultSourceInfoForPath(skill.filePath)
1094
+ })), this.skillDiagnostics = resolvedSkills.diagnostics;
1095
+ }
1096
+ updatePromptsFromPaths(promptPaths, metadataByPath) {
1097
+ let promptsResult;
1098
+ if (this.noPromptTemplates && promptPaths.length === 0)
1099
+ promptsResult = { prompts: [], diagnostics: [] };
1100
+ else {
1101
+ let allPrompts = loadPromptTemplates({
1102
+ cwd: this.cwd,
1103
+ agentDir: this.agentDir,
1104
+ promptPaths,
1105
+ includeDefaults: !1
1106
+ });
1107
+ promptsResult = this.dedupePrompts(allPrompts);
1108
+ }
1109
+ let resolvedPrompts = this.promptsOverride ? this.promptsOverride(promptsResult) : promptsResult;
1110
+ this.prompts = resolvedPrompts.prompts.map((prompt) => ({
1111
+ ...prompt,
1112
+ sourceInfo: this.findSourceInfoForPath(prompt.filePath, this.extensionPromptSourceInfos, metadataByPath) ?? prompt.sourceInfo ?? this.getDefaultSourceInfoForPath(prompt.filePath)
1113
+ })), this.promptDiagnostics = resolvedPrompts.diagnostics;
1114
+ }
1115
+ updateThemesFromPaths(themePaths, metadataByPath) {
1116
+ let themesResult;
1117
+ if (this.noThemes && themePaths.length === 0)
1118
+ themesResult = { themes: [], diagnostics: [] };
1119
+ else {
1120
+ let loaded = this.loadThemes(themePaths, !1), deduped = this.dedupeThemes(loaded.themes);
1121
+ themesResult = { themes: deduped.themes, diagnostics: [...loaded.diagnostics, ...deduped.diagnostics] };
1122
+ }
1123
+ let resolvedThemes = this.themesOverride ? this.themesOverride(themesResult) : themesResult;
1124
+ this.themes = resolvedThemes.themes.map((theme) => {
1125
+ let sourcePath = theme.sourcePath;
1126
+ return theme.sourceInfo = sourcePath ? this.findSourceInfoForPath(sourcePath, this.extensionThemeSourceInfos, metadataByPath) ?? theme.sourceInfo ?? this.getDefaultSourceInfoForPath(sourcePath) : theme.sourceInfo, theme;
1127
+ }), this.themeDiagnostics = resolvedThemes.diagnostics;
1128
+ }
1129
+ applyExtensionSourceInfo(extensions, metadataByPath) {
1130
+ for (let extension of extensions) {
1131
+ extension.sourceInfo = this.findSourceInfoForPath(extension.path, void 0, metadataByPath) ?? this.getDefaultSourceInfoForPath(extension.path);
1132
+ for (let command of extension.commands.values())
1133
+ command.sourceInfo = extension.sourceInfo;
1134
+ for (let tool of extension.tools.values())
1135
+ tool.sourceInfo = extension.sourceInfo;
1136
+ }
1137
+ }
1138
+ findSourceInfoForPath(resourcePath, extraSourceInfos, metadataByPath) {
1139
+ if (!resourcePath)
1140
+ return;
1141
+ if (resourcePath.startsWith("<"))
1142
+ return this.getDefaultSourceInfoForPath(resourcePath);
1143
+ let normalizedResourcePath = resolve4(resourcePath);
1144
+ if (extraSourceInfos)
1145
+ for (let [sourcePath, sourceInfo] of extraSourceInfos.entries()) {
1146
+ let normalizedSourcePath = resolve4(sourcePath);
1147
+ if (normalizedResourcePath === normalizedSourcePath || normalizedResourcePath.startsWith(`${normalizedSourcePath}${sep3}`))
1148
+ return { ...sourceInfo, path: resourcePath };
1149
+ }
1150
+ if (metadataByPath) {
1151
+ let exact = metadataByPath.get(normalizedResourcePath) ?? metadataByPath.get(resourcePath);
1152
+ if (exact)
1153
+ return createSourceInfo(resourcePath, exact);
1154
+ for (let [sourcePath, metadata] of metadataByPath.entries()) {
1155
+ let normalizedSourcePath = resolve4(sourcePath);
1156
+ if (normalizedResourcePath === normalizedSourcePath || normalizedResourcePath.startsWith(`${normalizedSourcePath}${sep3}`))
1157
+ return createSourceInfo(resourcePath, metadata);
1158
+ }
1159
+ }
1160
+ }
1161
+ getDefaultSourceInfoForPath(filePath) {
1162
+ if (filePath.startsWith("<") && filePath.endsWith(">"))
1163
+ return {
1164
+ path: filePath,
1165
+ source: filePath.slice(1, -1).split(":")[0] || "temporary",
1166
+ scope: "temporary",
1167
+ origin: "top-level"
1168
+ };
1169
+ let normalizedPath = resolve4(filePath), agentRoots = [
1170
+ join4(this.agentDir, "skills"),
1171
+ join4(this.agentDir, "prompts"),
1172
+ join4(this.agentDir, "themes"),
1173
+ join4(this.agentDir, "extensions")
1174
+ ], projectRoots = [
1175
+ join4(this.cwd, CONFIG_DIR_NAME, "skills"),
1176
+ join4(this.cwd, CONFIG_DIR_NAME, "prompts"),
1177
+ join4(this.cwd, CONFIG_DIR_NAME, "themes"),
1178
+ join4(this.cwd, CONFIG_DIR_NAME, "extensions")
1179
+ ];
1180
+ for (let root of agentRoots)
1181
+ if (this.isUnderPath(normalizedPath, root))
1182
+ return { path: filePath, source: "local", scope: "user", origin: "top-level", baseDir: root };
1183
+ for (let root of projectRoots)
1184
+ if (this.isUnderPath(normalizedPath, root))
1185
+ return { path: filePath, source: "local", scope: "project", origin: "top-level", baseDir: root };
1186
+ return {
1187
+ path: filePath,
1188
+ source: "local",
1189
+ scope: "temporary",
1190
+ origin: "top-level",
1191
+ baseDir: statSync4(normalizedPath).isDirectory() ? normalizedPath : resolve4(normalizedPath, "..")
1192
+ };
1193
+ }
1194
+ mergePaths(primary, additional) {
1195
+ let merged = [], seen = /* @__PURE__ */ new Set();
1196
+ for (let p of [...primary, ...additional]) {
1197
+ let resolved = this.resolveResourcePath(p), canonicalPath = canonicalizePath(resolved);
1198
+ seen.has(canonicalPath) || (seen.add(canonicalPath), merged.push(resolved));
1199
+ }
1200
+ return merged;
1201
+ }
1202
+ resolveResourcePath(p) {
1203
+ return resolvePath(p, this.cwd, { trim: !0 });
1204
+ }
1205
+ loadThemes(paths, includeDefaults = !0) {
1206
+ let themes = [], diagnostics = [];
1207
+ if (includeDefaults) {
1208
+ let defaultDirs = [join4(this.agentDir, "themes"), join4(this.cwd, CONFIG_DIR_NAME, "themes")];
1209
+ for (let dir of defaultDirs)
1210
+ this.loadThemesFromDir(dir, themes, diagnostics);
1211
+ }
1212
+ for (let p of paths) {
1213
+ let resolved = this.resolveResourcePath(p);
1214
+ if (!existsSync4(resolved)) {
1215
+ diagnostics.push({ type: "warning", message: "theme path does not exist", path: resolved });
1216
+ continue;
1217
+ }
1218
+ try {
1219
+ let stats = statSync4(resolved);
1220
+ stats.isDirectory() ? this.loadThemesFromDir(resolved, themes, diagnostics) : stats.isFile() && resolved.endsWith(".json") ? this.loadThemeFromFile(resolved, themes, diagnostics) : diagnostics.push({ type: "warning", message: "theme path is not a json file", path: resolved });
1221
+ } catch (error) {
1222
+ let message = error instanceof Error ? error.message : "failed to read theme path";
1223
+ diagnostics.push({ type: "warning", message, path: resolved });
1224
+ }
1225
+ }
1226
+ return { themes, diagnostics };
1227
+ }
1228
+ loadThemesFromDir(dir, themes, diagnostics) {
1229
+ if (existsSync4(dir))
1230
+ try {
1231
+ let entries = readdirSync4(dir, { withFileTypes: !0 });
1232
+ for (let entry of entries) {
1233
+ let isFile = entry.isFile();
1234
+ if (entry.isSymbolicLink())
1235
+ try {
1236
+ isFile = statSync4(join4(dir, entry.name)).isFile();
1237
+ } catch {
1238
+ continue;
1239
+ }
1240
+ isFile && entry.name.endsWith(".json") && this.loadThemeFromFile(join4(dir, entry.name), themes, diagnostics);
1241
+ }
1242
+ } catch (error) {
1243
+ let message = error instanceof Error ? error.message : "failed to read theme directory";
1244
+ diagnostics.push({ type: "warning", message, path: dir });
1245
+ }
1246
+ }
1247
+ loadThemeFromFile(filePath, themes, diagnostics) {
1248
+ try {
1249
+ themes.push(loadThemeFromPath(filePath));
1250
+ } catch (error) {
1251
+ let message = error instanceof Error ? error.message : "failed to load theme";
1252
+ diagnostics.push({ type: "warning", message, path: filePath });
1253
+ }
1254
+ }
1255
+ async loadExtensionFactories(runtime, factories = this.extensionFactories) {
1256
+ let extensions = [], errors = [];
1257
+ for (let [index, input] of factories.entries()) {
1258
+ let factory = typeof input != "function" ? input.factory : input, extensionPath = inlineExtensionPath(input, index);
1259
+ try {
1260
+ let extension = await loadExtensionFromFactory(factory, this.cwd, this.eventBus, runtime, extensionPath);
1261
+ extensions.push(extension);
1262
+ } catch (error) {
1263
+ let message = error instanceof Error ? error.message : "failed to load extension";
1264
+ errors.push({ path: extensionPath, error: message });
1265
+ }
1266
+ }
1267
+ return { extensions, errors };
1268
+ }
1269
+ dedupePrompts(prompts) {
1270
+ let seen = /* @__PURE__ */ new Map(), diagnostics = [];
1271
+ for (let prompt of prompts) {
1272
+ let existing = seen.get(prompt.name);
1273
+ existing ? diagnostics.push({
1274
+ type: "collision",
1275
+ message: `name "/${prompt.name}" collision`,
1276
+ path: prompt.filePath,
1277
+ collision: {
1278
+ resourceType: "prompt",
1279
+ name: prompt.name,
1280
+ winnerPath: existing.filePath,
1281
+ loserPath: prompt.filePath
1282
+ }
1283
+ }) : seen.set(prompt.name, prompt);
1284
+ }
1285
+ return { prompts: Array.from(seen.values()), diagnostics };
1286
+ }
1287
+ dedupeThemes(themes) {
1288
+ let seen = /* @__PURE__ */ new Map(), diagnostics = [];
1289
+ for (let t of themes) {
1290
+ let name = t.name ?? "unnamed", existing = seen.get(name);
1291
+ existing ? diagnostics.push({
1292
+ type: "collision",
1293
+ message: `name "${name}" collision`,
1294
+ path: t.sourcePath,
1295
+ collision: {
1296
+ resourceType: "theme",
1297
+ name,
1298
+ winnerPath: existing.sourcePath ?? "<builtin>",
1299
+ loserPath: t.sourcePath ?? "<builtin>"
1300
+ }
1301
+ }) : seen.set(name, t);
1302
+ }
1303
+ return { themes: Array.from(seen.values()), diagnostics };
1304
+ }
1305
+ discoverSystemPromptFile() {
1306
+ let projectPath = join4(this.cwd, CONFIG_DIR_NAME, "SYSTEM.md");
1307
+ if (this.settingsManager.isProjectTrusted() && existsSync4(projectPath))
1308
+ return projectPath;
1309
+ let globalPath = join4(this.agentDir, "SYSTEM.md");
1310
+ if (existsSync4(globalPath))
1311
+ return globalPath;
1312
+ }
1313
+ discoverAppendSystemPromptFile() {
1314
+ let projectPath = join4(this.cwd, CONFIG_DIR_NAME, "APPEND_SYSTEM.md");
1315
+ if (this.settingsManager.isProjectTrusted() && existsSync4(projectPath))
1316
+ return projectPath;
1317
+ let globalPath = join4(this.agentDir, "APPEND_SYSTEM.md");
1318
+ if (existsSync4(globalPath))
1319
+ return globalPath;
1320
+ }
1321
+ isUnderPath(target, root) {
1322
+ let normalizedRoot = resolve4(root);
1323
+ if (target === normalizedRoot)
1324
+ return !0;
1325
+ let prefix = normalizedRoot.endsWith(sep3) ? normalizedRoot : `${normalizedRoot}${sep3}`;
1326
+ return target.startsWith(prefix);
1327
+ }
1328
+ detectExtensionConflicts(extensions) {
1329
+ let conflicts = [], toolOwners = /* @__PURE__ */ new Map(), flagOwners = /* @__PURE__ */ new Map();
1330
+ for (let ext of extensions) {
1331
+ for (let toolName of ext.tools.keys()) {
1332
+ let existingOwner = toolOwners.get(toolName);
1333
+ existingOwner && existingOwner !== ext.path ? conflicts.push({
1334
+ path: ext.path,
1335
+ message: `Tool "${toolName}" conflicts with ${existingOwner}`
1336
+ }) : toolOwners.set(toolName, ext.path);
1337
+ }
1338
+ for (let flagName of ext.flags.keys()) {
1339
+ let existingOwner = flagOwners.get(flagName);
1340
+ existingOwner && existingOwner !== ext.path ? conflicts.push({
1341
+ path: ext.path,
1342
+ message: `Flag "--${flagName}" conflicts with ${existingOwner}`
1343
+ }) : flagOwners.set(flagName, ext.path);
1344
+ }
1345
+ }
1346
+ return conflicts;
1347
+ }
1348
+ };
1349
+
1350
+ export {
1351
+ createEventBus,
1352
+ createSyntheticSourceInfo,
1353
+ createExtensionRuntime,
1354
+ discoverAndLoadExtensions,
1355
+ expandPromptTemplate,
1356
+ loadSkillsFromDir,
1357
+ formatSkillsForPrompt,
1358
+ loadSkills,
1359
+ loadProjectContextFiles,
1360
+ DefaultResourceLoader
1361
+ };