// SPDX-License-Identifier: AGPL-3.0-only // SPDX-FileCopyrightText: Copyright (C) 2026 Catcrafts® export module Crafter.Review:Tools; import std; // The tool lists every pass is started with: what is denied whatever the // allowlist says, the read-only git verbs, the base allowlist, and the // Playwright MCP server's tools by name. A leaf of its own: the config checks // its extra tools against DENY and the pool builds every command line from // these, so with the lists in either of them the two would import each // other. export namespace Crafter::Review::Tools { // The Playwright MCP server, as --mcp-config names it. constexpr std::string_view McpServer = "playwright"; constexpr std::array McpTools = { "browser_navigate", "browser_navigate_back", "browser_snapshot", "browser_click", "browser_type", "browser_fill_form", "browser_select_option", "browser_press_key", "browser_hover", "browser_drag", "browser_drop", "browser_handle_dialog", "browser_wait_for", "browser_take_screenshot", "browser_console_messages", "browser_network_requests", "browser_network_request", "browser_evaluate", "browser_tabs", "browser_resize", "browser_close", "browser_find", "browser_emulate_media", "browser_file_upload", }; // browser_run_code_unsafe runs arbitrary Node code in the server's // process. constexpr std::array McpDenied = {"browser_run_code_unsafe"}; // mcp__playwright__ for each. std::vector McpToolNames(); std::vector McpDeniedToolNames(); // Never, whatever the allowlist says: writes, the network beyond the // browser, the agent tools, package managers, stacks, a database client // that commits (psql: the supabase environment's helper is the one way // in, every call rolled back). const std::vector& Deny(); constexpr std::array GitReadOnly = { "diff", "log", "show", "grep", "blame", "ls-tree", "ls-files", "cat-file", "rev-parse", "rev-list", "hash-object", "describe", "merge-base", "name-rev", "shortlog", "for-each-ref", "branch", "tag", "status", "worktree list", "remote", "count-objects", }; const std::vector& BaseAllow(); // Does Deny() override this allowlist entry? `Bash(psql -h x:*)` falls // under `Bash(psql:*)`, `Bash(psqlx:*)` does not. bool Denied(std::string_view tool); }