feat(multimodal-looker): restrict to read-only tool access

Use createAgentToolAllowlist to allow only 'read' tool for multimodal-looker agent.
Previously denied write/edit/bash but allowed other tools.
Now uses wildcard deny pattern (*: deny) with explicit read allow.

- Add createAgentToolAllowlist function for allowlist-based restrictions
- Support legacy fallback for older OpenCode versions
- Add 4 test cases covering both permission systems
This commit is contained in:
justsisyphus
2026-01-16 15:02:55 +09:00
parent 27ef9fa8df
commit ede9abceb3
5 changed files with 150 additions and 23 deletions
+63
View File
@@ -30,6 +30,69 @@ export function createAgentToolRestrictions(
}
}
/**
* Common tools that should be denied when using allowlist approach.
* Used for legacy fallback when `*: deny` pattern is not supported.
*/
const COMMON_TOOLS_TO_DENY = [
"write",
"edit",
"bash",
"task",
"sisyphus_task",
"call_omo_agent",
"webfetch",
"glob",
"grep",
"lsp_diagnostics",
"lsp_prepare_rename",
"lsp_rename",
"ast_grep_search",
"ast_grep_replace",
"session_list",
"session_read",
"session_search",
"session_info",
"background_output",
"background_cancel",
"skill",
"skill_mcp",
"look_at",
"todowrite",
"todoread",
"interactive_bash",
] as const
/**
* Creates tool restrictions that ONLY allow specified tools.
* All other tools are denied by default.
*
* Uses `*: deny` pattern for new permission system,
* falls back to explicit deny list for legacy systems.
*/
export function createAgentToolAllowlist(
allowTools: string[]
): VersionAwareRestrictions {
if (supportsNewPermissionSystem()) {
return {
permission: {
"*": "deny" as const,
...Object.fromEntries(
allowTools.map((tool) => [tool, "allow" as const])
),
},
}
}
// Legacy fallback: explicitly deny common tools except allowed ones
const allowSet = new Set(allowTools)
const denyTools = COMMON_TOOLS_TO_DENY.filter((tool) => !allowSet.has(tool))
return {
tools: Object.fromEntries(denyTools.map((tool) => [tool, false])),
}
}
export function migrateToolsToPermission(
tools: Record<string, boolean>
): Record<string, PermissionValue> {