fix(coding-agent): prefer explicit -e extensions closes #1896
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
- Fixed custom tool collapsed/expanded rendering in HTML exports. Custom tools that define different collapsed vs expanded displays now render correctly in exported HTML, with expandable sections when both states differ and direct display when only expanded exists ([#1934](https://github.com/badlogic/pi-mono/pull/1934) by [@aliou](https://github.com/aliou))
|
||||
- Fixed tmux startup guidance and keyboard setup warnings for modified key handling, including Ghostty `shift+enter=text:\n` remap guidance and tmux `extended-keys-format` detection ([#1872](https://github.com/badlogic/pi-mono/issues/1872))
|
||||
- Fixed z.ai context overflow recovery so `model_context_window_exceeded` errors trigger auto-compaction instead of surfacing as unhandled stop reason failures ([#1937](https://github.com/badlogic/pi-mono/issues/1937))
|
||||
- Fixed explicit `pi -e <path>` extensions losing command and tool conflicts to discovered extensions by giving CLI-loaded extensions higher precedence ([#1896](https://github.com/badlogic/pi-mono/issues/1896))
|
||||
|
||||
## [0.57.0] - 2026-03-07
|
||||
|
||||
|
||||
@@ -376,7 +376,7 @@ export class DefaultResourceLoader implements ResourceLoader {
|
||||
|
||||
const extensionPaths = this.noExtensions
|
||||
? cliEnabledExtensions
|
||||
: this.mergePaths(enabledExtensions, cliEnabledExtensions);
|
||||
: this.mergePaths(cliEnabledExtensions, enabledExtensions);
|
||||
|
||||
const extensionsResult = await loadExtensions(extensionPaths, this.cwd, this.eventBus);
|
||||
const inlineExtensions = await this.loadExtensionFactories(extensionsResult.runtime);
|
||||
|
||||
@@ -483,5 +483,73 @@ export default function(pi: ExtensionAPI) {
|
||||
const { errors } = loader.getExtensions();
|
||||
expect(errors.some((e) => e.error.includes("duplicate-tool") && e.error.includes("conflicts"))).toBe(true);
|
||||
});
|
||||
|
||||
it("should prefer explicit CLI extensions over discovered extensions when commands and tools conflict", async () => {
|
||||
const globalExtDir = join(agentDir, "extensions");
|
||||
mkdirSync(globalExtDir, { recursive: true });
|
||||
const explicitExtPath = join(tempDir, "explicit-extension.ts");
|
||||
|
||||
writeFileSync(
|
||||
join(globalExtDir, "global.ts"),
|
||||
`
|
||||
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
||||
import { Type } from "@sinclair/typebox";
|
||||
export default function(pi: ExtensionAPI) {
|
||||
pi.registerTool({
|
||||
name: "duplicate-tool",
|
||||
description: "global tool",
|
||||
parameters: Type.Object({}),
|
||||
execute: async () => ({ result: "global" }),
|
||||
});
|
||||
pi.registerCommand("deploy", {
|
||||
description: "global command",
|
||||
handler: async () => {},
|
||||
});
|
||||
}`,
|
||||
);
|
||||
|
||||
writeFileSync(
|
||||
explicitExtPath,
|
||||
`
|
||||
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
||||
import { Type } from "@sinclair/typebox";
|
||||
export default function(pi: ExtensionAPI) {
|
||||
pi.registerTool({
|
||||
name: "duplicate-tool",
|
||||
description: "explicit tool",
|
||||
parameters: Type.Object({}),
|
||||
execute: async () => ({ result: "explicit" }),
|
||||
});
|
||||
pi.registerCommand("deploy", {
|
||||
description: "explicit command",
|
||||
handler: async () => {},
|
||||
});
|
||||
}`,
|
||||
);
|
||||
|
||||
const loader = new DefaultResourceLoader({
|
||||
cwd,
|
||||
agentDir,
|
||||
additionalExtensionPaths: [explicitExtPath],
|
||||
});
|
||||
await loader.reload();
|
||||
|
||||
const extensionsResult = loader.getExtensions();
|
||||
expect(extensionsResult.extensions[0]?.path).toBe(explicitExtPath);
|
||||
|
||||
const sessionManager = SessionManager.inMemory();
|
||||
const authStorage = AuthStorage.create(join(tempDir, "auth-explicit.json"));
|
||||
const modelRegistry = new ModelRegistry(authStorage);
|
||||
const runner = new ExtensionRunner(
|
||||
extensionsResult.extensions,
|
||||
extensionsResult.runtime,
|
||||
cwd,
|
||||
sessionManager,
|
||||
modelRegistry,
|
||||
);
|
||||
|
||||
expect(runner.getCommand("deploy")?.description).toBe("explicit command");
|
||||
expect(runner.getToolDefinition("duplicate-tool")?.description).toBe("explicit tool");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user