From 6b8edc77b1b18e8f93c626847eafa48685f4e9a3 Mon Sep 17 00:00:00 2001 From: Aaron Trowbridge Date: Sat, 11 Jul 2026 15:29:13 -0400 Subject: [PATCH] =?UTF-8?q?fix(config):=20allow=20the=20skill=20tool=20?= =?UTF-8?q?=E2=80=94=20staged=20set=20is=20already=20curated?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The skill tool routes every load through a per-name permission ask by default. Our staged set is surface+entitlement filtered, so the ask is friction without a boundary — and hangs headless sessions, same class as the external_directory default. Co-Authored-By: Claude Fable 5 --- packages/extension/src/opencode_config.ts | 5 +++++ packages/extension/test/opencode_config.test.ts | 3 +++ 2 files changed, 8 insertions(+) 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", () => {