feat(coding-agent): add --no-extensions flag to disable extension discovery

Adds --no-extensions CLI flag that skips automatic extension discovery
while still allowing explicit -e paths. Three modes now available:

1. Default: auto-discover + any -e additions
2. --no-extensions: no extensions at all
3. --no-extensions -e foo.js: only load explicit extensions

Useful for debugging or running subagent instances without auto-discovered
extensions.

closes #524
This commit is contained in:
Mario Zechner 2026-01-08 03:22:38 +01:00
commit 7f3fa417c4
6 changed files with 71 additions and 6 deletions

View file

@ -150,6 +150,26 @@ describe("parseArgs", () => {
});
});
describe("--no-extensions flag", () => {
test("parses --no-extensions flag", () => {
const result = parseArgs(["--no-extensions"]);
expect(result.noExtensions).toBe(true);
});
test("parses --no-extensions with explicit -e flags", () => {
const result = parseArgs(["--no-extensions", "-e", "foo.ts", "-e", "bar.ts"]);
expect(result.noExtensions).toBe(true);
expect(result.extensions).toEqual(["foo.ts", "bar.ts"]);
});
});
describe("--no-skills flag", () => {
test("parses --no-skills flag", () => {
const result = parseArgs(["--no-skills"]);
expect(result.noSkills).toBe(true);
});
});
describe("messages and file args", () => {
test("parses plain text messages", () => {
const result = parseArgs(["hello", "world"]);

View file

@ -443,4 +443,34 @@ describe("extensions discovery", () => {
expect(result.extensions).toHaveLength(1);
expect(result.extensions[0].flags.has("--my-flag")).toBe(true);
});
it("loadExtensions only loads explicit paths without discovery", async () => {
// Create discoverable extensions (would be found by discoverAndLoadExtensions)
fs.writeFileSync(path.join(extensionsDir, "discovered.ts"), extensionCodeWithTool("discovered"));
// Create explicit extension outside discovery path
const explicitPath = path.join(tempDir, "explicit.ts");
fs.writeFileSync(explicitPath, extensionCodeWithTool("explicit"));
// Use loadExtensions directly to skip discovery
const { loadExtensions } = await import("../src/core/extensions/loader.js");
const result = await loadExtensions([explicitPath], tempDir);
expect(result.errors).toHaveLength(0);
expect(result.extensions).toHaveLength(1);
expect(result.extensions[0].tools.has("explicit")).toBe(true);
expect(result.extensions[0].tools.has("discovered")).toBe(false);
});
it("loadExtensions with no paths loads nothing", async () => {
// Create discoverable extensions (would be found by discoverAndLoadExtensions)
fs.writeFileSync(path.join(extensionsDir, "discovered.ts"), extensionCode);
// Use loadExtensions directly with empty paths
const { loadExtensions } = await import("../src/core/extensions/loader.js");
const result = await loadExtensions([], tempDir);
expect(result.errors).toHaveLength(0);
expect(result.extensions).toHaveLength(0);
});
});