@oh-my-pi/pi-coding-agent 15.7.6 → 15.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +172 -198
- package/dist/types/async/job-manager.d.ts +3 -3
- package/dist/types/cli/args.d.ts +1 -0
- package/dist/types/cli/claude-trace-cli.d.ts +54 -0
- package/dist/types/cli/session-picker.d.ts +10 -3
- package/dist/types/cli/update-cli.d.ts +17 -0
- package/dist/types/commands/launch.d.ts +3 -0
- package/dist/types/config/keybindings.d.ts +10 -1
- package/dist/types/config/settings-schema.d.ts +2 -2
- package/dist/types/config/settings.d.ts +13 -0
- package/dist/types/edit/index.d.ts +6 -0
- package/dist/types/edit/streaming.d.ts +8 -0
- package/dist/types/eval/concurrency-bridge.d.ts +26 -0
- package/dist/types/eval/js/tool-bridge.d.ts +2 -1
- package/dist/types/export/ttsr.d.ts +9 -0
- package/dist/types/extensibility/plugins/legacy-pi-compat.d.ts +11 -0
- package/dist/types/main.d.ts +5 -0
- package/dist/types/mcp/transports/stdio.d.ts +19 -0
- package/dist/types/modes/components/custom-editor.d.ts +3 -1
- package/dist/types/modes/components/hook-selector.d.ts +3 -0
- package/dist/types/modes/components/session-selector.d.ts +32 -5
- package/dist/types/modes/components/tool-execution.d.ts +8 -0
- package/dist/types/modes/controllers/extension-ui-controller.d.ts +2 -2
- package/dist/types/modes/controllers/input-controller.d.ts +1 -0
- package/dist/types/modes/interactive-mode.d.ts +9 -2
- package/dist/types/modes/types.d.ts +4 -2
- package/dist/types/registry/agent-registry.d.ts +1 -1
- package/dist/types/sdk.d.ts +2 -2
- package/dist/types/session/agent-session.d.ts +4 -2
- package/dist/types/session/history-storage.d.ts +16 -1
- package/dist/types/session/session-manager.d.ts +4 -0
- package/dist/types/task/output-manager.d.ts +6 -15
- package/dist/types/tools/find.d.ts +0 -9
- package/dist/types/tools/index.d.ts +1 -1
- package/dist/types/tools/path-utils.d.ts +16 -0
- package/dist/types/tools/sqlite-reader.d.ts +25 -8
- package/dist/types/tools/write.d.ts +2 -0
- package/dist/types/utils/clipboard.d.ts +4 -0
- package/dist/types/utils/jj.d.ts +49 -0
- package/dist/types/web/kagi.d.ts +76 -0
- package/dist/types/web/search/providers/exa.d.ts +7 -1
- package/dist/types/web/search/providers/kagi.d.ts +1 -0
- package/package.json +9 -9
- package/src/async/job-manager.ts +3 -3
- package/src/cli/args.ts +6 -2
- package/src/cli/claude-trace-cli.ts +783 -0
- package/src/cli/session-picker.ts +36 -10
- package/src/cli/update-cli.ts +35 -2
- package/src/commands/launch.ts +3 -0
- package/src/config/keybindings.ts +14 -1
- package/src/config/model-registry.ts +18 -7
- package/src/config/settings-schema.ts +2 -2
- package/src/config/settings.ts +23 -0
- package/src/discovery/builtin-rules/index.ts +2 -0
- package/src/discovery/builtin-rules/ts-no-deprecated-leftovers.md +44 -0
- package/src/discovery/claude-plugins.ts +7 -9
- package/src/edit/index.ts +10 -0
- package/src/edit/streaming.ts +65 -0
- package/src/eval/__tests__/agent-bridge.test.ts +58 -4
- package/src/eval/concurrency-bridge.ts +34 -0
- package/src/eval/js/shared/prelude.txt +20 -17
- package/src/eval/js/tool-bridge.ts +5 -0
- package/src/eval/py/prelude.py +23 -15
- package/src/export/ttsr.ts +18 -1
- package/src/extensibility/custom-commands/bundled/review/index.ts +74 -45
- package/src/extensibility/plugins/legacy-pi-compat.ts +115 -131
- package/src/extensibility/skills.ts +0 -1
- package/src/internal-urls/docs-index.generated.ts +12 -11
- package/src/main.ts +92 -24
- package/src/mcp/transports/stdio.ts +55 -22
- package/src/modes/acp/acp-event-mapper.ts +54 -4
- package/src/modes/components/custom-editor.ts +10 -0
- package/src/modes/components/hook-selector.ts +89 -31
- package/src/modes/components/oauth-selector.ts +12 -6
- package/src/modes/components/session-selector.ts +179 -24
- package/src/modes/components/tool-execution.ts +16 -3
- package/src/modes/controllers/command-controller.ts +2 -11
- package/src/modes/controllers/extension-ui-controller.ts +3 -2
- package/src/modes/controllers/input-controller.ts +19 -1
- package/src/modes/controllers/selector-controller.ts +61 -21
- package/src/modes/interactive-mode.ts +125 -15
- package/src/modes/types.ts +5 -2
- package/src/prompts/agents/reviewer.md +2 -2
- package/src/prompts/review-request.md +1 -1
- package/src/prompts/system/empty-stop-retry.md +6 -0
- package/src/prompts/system/orchestrate-notice.md +5 -3
- package/src/prompts/system/workflow-notice.md +2 -2
- package/src/prompts/tools/eval.md +5 -5
- package/src/prompts/tools/find.md +1 -1
- package/src/prompts/tools/irc.md +6 -6
- package/src/prompts/tools/search-tool-bm25.md +9 -2
- package/src/prompts/tools/search.md +1 -1
- package/src/prompts/tools/task.md +1 -1
- package/src/registry/agent-registry.ts +1 -1
- package/src/sdk.ts +85 -31
- package/src/session/agent-session.ts +209 -54
- package/src/session/history-storage.ts +56 -12
- package/src/session/session-manager.ts +34 -0
- package/src/task/output-manager.ts +40 -48
- package/src/task/render.ts +3 -8
- package/src/tools/browser/tab-worker.ts +8 -5
- package/src/tools/find.ts +5 -29
- package/src/tools/index.ts +1 -1
- package/src/tools/path-utils.ts +144 -1
- package/src/tools/read.ts +47 -0
- package/src/tools/search-tool-bm25.ts +7 -1
- package/src/tools/search.ts +2 -27
- package/src/tools/sqlite-reader.ts +92 -9
- package/src/tools/write.ts +6 -0
- package/src/utils/clipboard.ts +38 -1
- package/src/utils/git.ts +19 -23
- package/src/utils/jj.ts +225 -0
- package/src/utils/open.ts +37 -2
- package/src/web/kagi.ts +168 -49
- package/src/web/search/providers/anthropic.ts +1 -1
- package/src/web/search/providers/exa.ts +20 -86
- package/src/web/search/providers/kagi.ts +4 -0
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import * as fs from "node:fs/promises";
|
|
2
|
-
import * as os from "node:os";
|
|
3
2
|
import * as path from "node:path";
|
|
4
3
|
import * as url from "node:url";
|
|
5
4
|
import { isCompiledBinary } from "@oh-my-pi/pi-utils";
|
|
@@ -45,8 +44,6 @@ const LEGACY_PI_IMPORT_SPECIFIER_REGEX = new RegExp(
|
|
|
45
44
|
`((?:from\\s+|import\\s*\\(\\s*)["'])(@(?:${PI_SCOPE_ALTERNATION})/(?:${PI_PACKAGE_ALTERNATION})(?:/[^"'()\\s]+)?)(["'])`,
|
|
46
45
|
"g",
|
|
47
46
|
);
|
|
48
|
-
const LEGACY_PI_FILE_PREFIX = "omp-legacy-pi-file:";
|
|
49
|
-
const LEGACY_PI_FILE_NAMESPACE = "omp-legacy-pi-file";
|
|
50
47
|
const resolvedSpecifierFallbacks = new Map<string, string>();
|
|
51
48
|
|
|
52
49
|
// Extensions that imported `@sinclair/typebox` directly used to resolve against a
|
|
@@ -56,7 +53,6 @@ const resolvedSpecifierFallbacks = new Map<string, string>();
|
|
|
56
53
|
// changes. Submodules like `@sinclair/typebox/compiler` are intentionally not
|
|
57
54
|
// remapped — those expose TypeBox-only APIs the shim does not provide and plugins
|
|
58
55
|
// relying on them must vendor `@sinclair/typebox` directly.
|
|
59
|
-
const TYPEBOX_SPECIFIER = "@sinclair/typebox";
|
|
60
56
|
const TYPEBOX_SPECIFIER_FILTER = /^@sinclair\/typebox$/;
|
|
61
57
|
|
|
62
58
|
// Compat shim and bundled-package paths used in compiled-binary mode. The shim
|
|
@@ -214,129 +210,146 @@ function rewriteLegacyPiImports(source: string): string {
|
|
|
214
210
|
} catch {
|
|
215
211
|
// Resolution failed — typically in compiled binary mode where
|
|
216
212
|
// Bun.resolveSync cannot walk up from /$bunfs/root to find the
|
|
217
|
-
// bundled node_modules.
|
|
218
|
-
//
|
|
219
|
-
// plugin's own installed peer deps instead.
|
|
213
|
+
// bundled node_modules. Leave the specifier unchanged so Bun
|
|
214
|
+
// resolves it natively against the extension's own peer deps.
|
|
220
215
|
return match;
|
|
221
216
|
}
|
|
222
217
|
},
|
|
223
218
|
);
|
|
224
219
|
}
|
|
225
220
|
|
|
226
|
-
// Match
|
|
227
|
-
|
|
228
|
-
//
|
|
229
|
-
const
|
|
230
|
-
|
|
231
|
-
/** Resolve bare imports against the extension directory before loading mirrored legacy Pi files. */
|
|
232
|
-
function isUrlLikeSpecifier(specifier: string): boolean {
|
|
233
|
-
// Windows drive-letter paths (e.g. `C:\foo` or `C:/foo`) also match the URL
|
|
234
|
-
// scheme shape `[A-Za-z][A-Za-z\d+.-]*:`. Treat them as filesystem paths so
|
|
235
|
-
// `toRewrittenImportSpecifier` converts them to `file://` URLs instead of
|
|
236
|
-
// emitting raw paths whose `\n`, `\U`, ... get eaten by TS string-literal
|
|
237
|
-
// escapes inside the mirrored extension file.
|
|
238
|
-
if (/^[a-zA-Z]:[\\/]/.test(specifier)) return false;
|
|
239
|
-
return /^[a-zA-Z][a-zA-Z\d+.-]*:/.test(specifier);
|
|
240
|
-
}
|
|
221
|
+
// Match the bare `@sinclair/typebox` import specifier (static + dynamic).
|
|
222
|
+
// Subpath imports like `@sinclair/typebox/compiler` are intentionally excluded —
|
|
223
|
+
// they expose TypeBox-only APIs the Zod-backed shim does not provide.
|
|
224
|
+
const TYPEBOX_IMPORT_SPECIFIER_REGEX = /((?:from\s+|import\s*\(\s*)["'])(@sinclair\/typebox)(["'])/g;
|
|
241
225
|
|
|
242
|
-
|
|
243
|
-
|
|
226
|
+
/**
|
|
227
|
+
* Rewrite the legacy specifiers a Pi extension may import — `@(scope)/pi-*` and
|
|
228
|
+
* the bare `@sinclair/typebox` root — to absolute `file://` URLs pointing at the
|
|
229
|
+
* bundled package or compat shim. Every other specifier (relative siblings, the
|
|
230
|
+
* extension's own bare dependencies) is left untouched so Bun resolves it
|
|
231
|
+
* natively from the extension's real on-disk location.
|
|
232
|
+
*/
|
|
233
|
+
function rewriteLegacyExtensionSource(source: string): string {
|
|
234
|
+
const withPi = rewriteLegacyPiImports(source);
|
|
235
|
+
return withPi.replace(
|
|
236
|
+
TYPEBOX_IMPORT_SPECIFIER_REGEX,
|
|
237
|
+
(_match, prefix: string, _specifier: string, suffix: string) => {
|
|
238
|
+
return `${prefix}${toImportSpecifier(TYPEBOX_SHIM_PATH)}${suffix}`;
|
|
239
|
+
},
|
|
240
|
+
);
|
|
244
241
|
}
|
|
245
242
|
|
|
246
|
-
function
|
|
247
|
-
return
|
|
243
|
+
function escapeRegExp(value: string): string {
|
|
244
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
248
245
|
}
|
|
249
246
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
if (shouldPreserveImportSpecifier(specifier)) {
|
|
255
|
-
return match;
|
|
256
|
-
}
|
|
257
|
-
if (specifier === TYPEBOX_SPECIFIER) {
|
|
258
|
-
return `${prefix}${toRewrittenImportSpecifier(TYPEBOX_SHIM_PATH)}${suffix}`;
|
|
259
|
-
}
|
|
260
|
-
try {
|
|
261
|
-
const resolved = Bun.resolveSync(specifier, importerDir);
|
|
262
|
-
return `${prefix}${toRewrittenImportSpecifier(resolved)}${suffix}`;
|
|
263
|
-
} catch {
|
|
264
|
-
return match;
|
|
265
|
-
}
|
|
266
|
-
});
|
|
267
|
-
}
|
|
247
|
+
// Match relative import specifiers (static `from "./…"` and dynamic
|
|
248
|
+
// `import("./…")`). Used to walk an extension's own module graph; bare and
|
|
249
|
+
// absolute specifiers are deliberately excluded.
|
|
250
|
+
const RELATIVE_IMPORT_SPECIFIER_REGEX = /(?:from\s+|import\s*\(\s*)["'](\.\.?\/[^"']+)["']/g;
|
|
268
251
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
252
|
+
// Extension entry realpaths that already have a load-time rewrite hook
|
|
253
|
+
// installed. Each `Bun.plugin()` registration is process-global and permanent,
|
|
254
|
+
// so we register at most one hook per entry.
|
|
255
|
+
const hookedExtensionEntries = new Set<string>();
|
|
273
256
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
257
|
+
/** Resolve symlinks in a path, falling back to the input if realpath fails. */
|
|
258
|
+
async function realpathOrSelf(p: string): Promise<string> {
|
|
259
|
+
try {
|
|
260
|
+
return await fs.realpath(p);
|
|
261
|
+
} catch {
|
|
262
|
+
return p;
|
|
263
|
+
}
|
|
278
264
|
}
|
|
279
265
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
266
|
+
/**
|
|
267
|
+
* Walk the extension's relative-import graph starting at `entryRealPath`,
|
|
268
|
+
* returning the realpath of every reachable source module. Only relative
|
|
269
|
+
* specifiers (`./`, `../`) are followed — bare and absolute imports are left to
|
|
270
|
+
* Bun's native resolver — so the set is exactly the extension's own source,
|
|
271
|
+
* wherever it physically lives (a `../src` sibling, a symlinked sub-tree, …).
|
|
272
|
+
* This mirrors the module set the old temp-dir mirror tracked, minus the copy.
|
|
273
|
+
*/
|
|
274
|
+
async function collectExtensionModules(entryRealPath: string): Promise<Set<string>> {
|
|
275
|
+
const modules = new Set<string>();
|
|
276
|
+
const queue = [entryRealPath];
|
|
277
|
+
while (queue.length > 0) {
|
|
278
|
+
const file = queue.pop();
|
|
279
|
+
if (!file || modules.has(file)) {
|
|
290
280
|
continue;
|
|
291
281
|
}
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
282
|
+
let source: string;
|
|
283
|
+
try {
|
|
284
|
+
source = await Bun.file(file).text();
|
|
285
|
+
} catch {
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
modules.add(file);
|
|
289
|
+
const dir = path.dirname(file);
|
|
290
|
+
for (const match of source.matchAll(RELATIVE_IMPORT_SPECIFIER_REGEX)) {
|
|
291
|
+
try {
|
|
292
|
+
const resolved = await realpathOrSelf(Bun.resolveSync(match[1], dir));
|
|
293
|
+
if (!modules.has(resolved)) {
|
|
294
|
+
queue.push(resolved);
|
|
295
|
+
}
|
|
296
|
+
} catch {
|
|
297
|
+
// Unresolvable relative import (e.g. a type-only path); skip it.
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
300
|
}
|
|
301
|
-
|
|
302
|
-
return source.replace(STATIC_IMPORT_SPECIFIER_REGEX, (match, prefix: string, specifier: string, suffix: string) => {
|
|
303
|
-
const replacement = replacements.get(specifier);
|
|
304
|
-
return replacement ? `${prefix}${replacement}${suffix}` : match;
|
|
305
|
-
});
|
|
301
|
+
return modules;
|
|
306
302
|
}
|
|
307
303
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
)
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
const resolvedPath = path.resolve(sourcePath);
|
|
320
|
-
const cached = state.seen.get(resolvedPath);
|
|
321
|
-
if (cached) {
|
|
322
|
-
return cached;
|
|
304
|
+
/**
|
|
305
|
+
* Install a `Bun.plugin()` `onLoad` hook scoped to exactly the modules in an
|
|
306
|
+
* extension's relative-import graph, so their legacy `@(scope)/pi-*` and bare
|
|
307
|
+
* `@sinclair/typebox` imports are rewritten at load time. A runtime `onLoad`
|
|
308
|
+
* cannot fall through (Bun requires a result object), so the filter is an
|
|
309
|
+
* exact-path alternation of the graph's realpaths — it never matches the host,
|
|
310
|
+
* other extensions, `node_modules` deps, or unrelated project source.
|
|
311
|
+
*/
|
|
312
|
+
async function ensureExtensionGraphHook(entryRealPath: string): Promise<void> {
|
|
313
|
+
if (hookedExtensionEntries.has(entryRealPath)) {
|
|
314
|
+
return;
|
|
323
315
|
}
|
|
316
|
+
hookedExtensionEntries.add(entryRealPath);
|
|
324
317
|
|
|
325
|
-
const
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
318
|
+
const modules = await collectExtensionModules(entryRealPath);
|
|
319
|
+
const alternation = [...modules].map(escapeRegExp).join("|");
|
|
320
|
+
const filter = new RegExp(`^(?:${alternation})$`);
|
|
321
|
+
Bun.plugin({
|
|
322
|
+
name: `omp:legacy-pi-ext:${Bun.hash(entryRealPath).toString(36)}`,
|
|
323
|
+
setup(build) {
|
|
324
|
+
build.onLoad({ filter, namespace: "file" }, async args => {
|
|
325
|
+
// Re-read on every load so a `?mtime` reload picks up edited source.
|
|
326
|
+
const raw = await Bun.file(args.path).text();
|
|
327
|
+
return { contents: rewriteLegacyExtensionSource(raw), loader: getLoader(args.path) };
|
|
328
|
+
});
|
|
329
|
+
},
|
|
330
|
+
});
|
|
332
331
|
}
|
|
333
332
|
|
|
333
|
+
/**
|
|
334
|
+
* Load a legacy Pi extension module from its real on-disk location.
|
|
335
|
+
*
|
|
336
|
+
* The extension runs in place, so its `import.meta.url` is the real source file
|
|
337
|
+
* and `__dirname`-relative `readFileSync` asset loads (HTML/CSS bundled next to
|
|
338
|
+
* the entry) resolve exactly as they do under the original Pi runtime — no
|
|
339
|
+
* temp-directory mirroring and no asset copying. An `onLoad` hook scoped to the
|
|
340
|
+
* entry's relative-import graph rewrites only the legacy `@(scope)/pi-*` and
|
|
341
|
+
* `@sinclair/typebox` imports in the extension's own source; everything else
|
|
342
|
+
* resolves natively.
|
|
343
|
+
*/
|
|
334
344
|
export async function loadLegacyPiModule(resolvedPath: string): Promise<unknown> {
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
345
|
+
// Bun reports the realpath of a loaded module to `onLoad` and exposes it as
|
|
346
|
+
// `import.meta.url`. Resolve symlinks here too (macOS `/var`→`/private/var`,
|
|
347
|
+
// `bun link`/pnpm installs) so the rewrite filter matches the path Bun
|
|
348
|
+
// actually hands the hook.
|
|
349
|
+
const entryRealPath = await realpathOrSelf(path.resolve(resolvedPath));
|
|
350
|
+
await ensureExtensionGraphHook(entryRealPath);
|
|
351
|
+
// `?mtime` busts Bun's module cache so repeat loads pick up edited source.
|
|
352
|
+
return import(`${toImportSpecifier(entryRealPath)}?mtime=${Date.now()}`);
|
|
340
353
|
}
|
|
341
354
|
|
|
342
355
|
function getLoader(path: string): "js" | "jsx" | "ts" | "tsx" {
|
|
@@ -396,36 +409,7 @@ export function installLegacyPiSpecifierShim(): void {
|
|
|
396
409
|
name: "omp:legacy-pi-shim",
|
|
397
410
|
setup(build) {
|
|
398
411
|
build.onResolve({ filter: LEGACY_PI_SPECIFIER_FILTER, namespace: "file" }, resolveLegacyPiSpecifier);
|
|
399
|
-
build.onResolve(
|
|
400
|
-
{ filter: LEGACY_PI_SPECIFIER_FILTER, namespace: LEGACY_PI_FILE_NAMESPACE },
|
|
401
|
-
resolveLegacyPiSpecifier,
|
|
402
|
-
);
|
|
403
|
-
|
|
404
412
|
build.onResolve({ filter: TYPEBOX_SPECIFIER_FILTER, namespace: "file" }, resolveTypeBoxSpecifier);
|
|
405
|
-
build.onResolve(
|
|
406
|
-
{ filter: TYPEBOX_SPECIFIER_FILTER, namespace: LEGACY_PI_FILE_NAMESPACE },
|
|
407
|
-
resolveTypeBoxSpecifier,
|
|
408
|
-
);
|
|
409
|
-
|
|
410
|
-
build.onResolve({ filter: /^omp-legacy-pi-file:/, namespace: "file" }, args => ({
|
|
411
|
-
path: args.path.slice(LEGACY_PI_FILE_PREFIX.length),
|
|
412
|
-
namespace: LEGACY_PI_FILE_NAMESPACE,
|
|
413
|
-
}));
|
|
414
|
-
|
|
415
|
-
build.onResolve({ filter: /^(?:\.{1,2}\/|\/)/, namespace: LEGACY_PI_FILE_NAMESPACE }, args => ({
|
|
416
|
-
path: args.path.startsWith("/") ? args.path : Bun.resolveSync(args.path, path.dirname(args.importer)),
|
|
417
|
-
namespace: LEGACY_PI_FILE_NAMESPACE,
|
|
418
|
-
}));
|
|
419
|
-
|
|
420
|
-
build.onLoad({ filter: /\.[cm]?[jt]sx?$/, namespace: LEGACY_PI_FILE_NAMESPACE }, async args => {
|
|
421
|
-
const raw = await Bun.file(args.path).text();
|
|
422
|
-
const withLegacyRemap = rewriteLegacyPiImports(raw);
|
|
423
|
-
const withBareResolved = rewriteBareImportsForLegacyExtension(withLegacyRemap, args.path);
|
|
424
|
-
return {
|
|
425
|
-
contents: withBareResolved,
|
|
426
|
-
loader: getLoader(args.path),
|
|
427
|
-
};
|
|
428
|
-
});
|
|
429
413
|
},
|
|
430
414
|
});
|
|
431
415
|
}
|
|
@@ -273,7 +273,6 @@ export async function loadSkills(options: LoadSkillsOptions = {}): Promise<LoadS
|
|
|
273
273
|
const skills = Array.from(skillMap.values());
|
|
274
274
|
// Deterministic ordering for prompt stability (case-insensitive, then exact name, then path).
|
|
275
275
|
skills.sort((a, b) => compareSkillOrder(a.name, a.filePath, b.name, b.filePath));
|
|
276
|
-
|
|
277
276
|
return {
|
|
278
277
|
skills,
|
|
279
278
|
warnings: [...(result.warnings ?? []).map(w => ({ skillPath: "", message: w })), ...collisionWarnings],
|