From 542186aa49e766c3acfe285c00bdfeae902be748 Mon Sep 17 00:00:00 2001 From: Aiden Cline <63023139+rekram1-node@users.noreply.github.com> Date: Sun, 10 Aug 2025 08:00:44 -0500 Subject: [PATCH] feat: webfetch permission support (#1772) --- packages/opencode/src/config/config.ts | 1 + packages/opencode/src/tool/registry.ts | 3 +++ packages/opencode/src/tool/webfetch.ts | 17 +++++++++++++++++ .../web/src/content/docs/docs/permissions.mdx | 8 ++++++++ 4 files changed, 29 insertions(+) diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index c2491e8b..2ba82904 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -341,6 +341,7 @@ export namespace Config { .object({ edit: Permission.optional(), bash: z.union([Permission, z.record(z.string(), Permission)]).optional(), + webfetch: Permission.optional(), }) .optional(), experimental: z diff --git a/packages/opencode/src/tool/registry.ts b/packages/opencode/src/tool/registry.ts index 5b805ac6..c2fe5943 100644 --- a/packages/opencode/src/tool/registry.ts +++ b/packages/opencode/src/tool/registry.ts @@ -79,6 +79,9 @@ export namespace ToolRegistry { if (cfg?.permission?.bash === "deny") { result["bash"] = false } + if (cfg?.permission?.webfetch === "deny") { + result["webfetch"] = false + } return result } diff --git a/packages/opencode/src/tool/webfetch.ts b/packages/opencode/src/tool/webfetch.ts index 16bcf048..621421fe 100644 --- a/packages/opencode/src/tool/webfetch.ts +++ b/packages/opencode/src/tool/webfetch.ts @@ -2,6 +2,8 @@ import { z } from "zod" import { Tool } from "./tool" import TurndownService from "turndown" import DESCRIPTION from "./webfetch.txt" +import { Config } from "../config/config" +import { Permission } from "../permission" const MAX_RESPONSE_SIZE = 5 * 1024 * 1024 // 5MB const DEFAULT_TIMEOUT = 30 * 1000 // 30 seconds @@ -22,6 +24,21 @@ export const WebFetchTool = Tool.define("webfetch", { throw new Error("URL must start with http:// or https://") } + const cfg = await Config.get() + if (cfg.permission?.webfetch === "ask") + await Permission.ask({ + type: "webfetch", + sessionID: ctx.sessionID, + messageID: ctx.messageID, + callID: ctx.callID, + title: "Fetch content from: " + params.url, + metadata: { + url: params.url, + format: params.format, + timeout: params.timeout, + }, + }) + const timeout = Math.min((params.timeout ?? DEFAULT_TIMEOUT / 1000) * 1000, MAX_TIMEOUT) const controller = new AbortController() diff --git a/packages/web/src/content/docs/docs/permissions.mdx b/packages/web/src/content/docs/docs/permissions.mdx index a3de452d..2ac7b58a 100644 --- a/packages/web/src/content/docs/docs/permissions.mdx +++ b/packages/web/src/content/docs/docs/permissions.mdx @@ -13,6 +13,14 @@ The permissions system provides granular control to restrict what actions AI age Permissions are configured in your `opencode.json` file under the `permission` key. Here are the available options. +### Tool Permission Support + +| Tool | Description | +| ---------- | ------------------------------- | +| `edit` | Control file editing operations | +| `bash` | Control bash command execution | +| `webfetch` | Control web content fetching | + --- ### edit