permissions disallow support (#1627)
Some checks are pending
deploy / deploy (push) Waiting to run

This commit is contained in:
Aiden Cline 2025-08-05 19:14:28 -05:00 committed by GitHub
parent 6b25b7e95e
commit a48274f82b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 29 additions and 14 deletions

View file

@ -224,7 +224,7 @@ export namespace Config {
})
export type Layout = z.infer<typeof Layout>
export const Permission = z.union([z.literal("ask"), z.literal("allow")])
export const Permission = z.union([z.literal("ask"), z.literal("allow"), z.literal("deny")])
export type Permission = z.infer<typeof Permission>
export const Info = z

View file

@ -728,7 +728,7 @@ export namespace Session {
const enabledTools = pipe(
mode.tools,
mergeDeep(ToolRegistry.enabled(input.providerID, input.modelID)),
mergeDeep(await ToolRegistry.enabled(input.providerID, input.modelID)),
mergeDeep(input.tools ?? {}),
)
for (const item of await ToolRegistry.tools(input.providerID, input.modelID)) {

View file

@ -93,7 +93,7 @@ export const BashTool = Tool.define("bash", {
// always allow cd if it passes above check
if (!needsAsk && command[0] !== "cd") {
const ask = (() => {
const action = (() => {
for (const [pattern, value] of Object.entries(permissions)) {
const match = Wildcard.match(node.text, pattern)
log.info("checking", { text: node.text.trim(), pattern, match })
@ -101,7 +101,12 @@ export const BashTool = Tool.define("bash", {
}
return "ask"
})()
if (ask === "ask") needsAsk = true
if (action === "deny") {
throw new Error(
"The user has specifically restricted access to this command, you are not allowed to execute it.",
)
}
if (action === "ask") needsAsk = true
}
}

View file

@ -11,6 +11,7 @@ import { TodoWriteTool, TodoReadTool } from "./todo"
import { WebFetchTool } from "./webfetch"
import { WriteTool } from "./write"
import { InvalidTool } from "./invalid"
import { Config } from "../config/config"
export namespace ToolRegistry {
const ALL = [
@ -65,11 +66,19 @@ export namespace ToolRegistry {
return result
}
export function enabled(_providerID: string, modelID: string): Record<string, boolean> {
export async function enabled(_providerID: string, modelID: string): Promise<Record<string, boolean>> {
const cfg = await Config.get()
const result: Record<string, boolean> = {}
if (cfg.permission?.edit === "deny") {
result["edit"] = false
result["patch"] = false
result["write"] = false
}
if (modelID.toLowerCase().includes("claude")) {
return {
patch: false,
}
result["patch"] = false
return result
}
if (
@ -79,13 +88,14 @@ export namespace ToolRegistry {
modelID.includes("o3") ||
modelID.includes("codex")
) {
return {
patch: false,
todowrite: false,
todoread: false,
}
result["patch"] = false
result["todowrite"] = false
result["todoread"] = false
return result
}
return {}
return result
}
function sanitizeGeminiParameters(schema: z.ZodTypeAny, visited = new Set()): z.ZodTypeAny {