diff --git a/packages/extension/src/opencode_config.ts b/packages/extension/src/opencode_config.ts index c91e181b..495caf27 100644 --- a/packages/extension/src/opencode_config.ts +++ b/packages/extension/src/opencode_config.ts @@ -400,6 +400,11 @@ export function buildOpencodeConfigContent( permission: { bash: "allow", edit: "allow", + // The staged skill set is already curated by us (surface: product + + // entitlement filter), so the skill tool's default per-name "ask" adds + // friction without a security boundary — and hangs headless sessions, + // same class as the external_directory default documented above. + skill: "allow", external_directory: { [templatePath]: "allow", // exact template file the agent reads [`${templatesDir}/**`]: "allow", // (belt-and-suspenders for the dir) diff --git a/packages/extension/test/opencode_config.test.ts b/packages/extension/test/opencode_config.test.ts index 0e1c1fee..d8ece98a 100644 --- a/packages/extension/test/opencode_config.test.ts +++ b/packages/extension/test/opencode_config.test.ts @@ -56,6 +56,9 @@ describe("buildOpencodeConfigContent", () => { expect(ed["/home/u/.amico/runs/default/**"]).toBe("allow"); expect(cfg.permission.bash).toBe("allow"); // runs amico-run (compound launch) expect(cfg.permission.edit).toBe("allow"); // fills the FILL-IN block + // The staged skill set is curated by us — a per-name "ask" on the skill + // tool is friction without a boundary, and hangs headless sessions. + expect(cfg.permission.skill).toBe("allow"); expect(cfg.permission.webfetch).toBeUndefined(); // unused by the solve flow — dropped }); it("registers the amicode_* plugin by ABSOLUTE default path — and the file actually exists", () => {