/** * Which built-in agent tools touch the host workspace jail. * No Bare imports — unit-testable on Node. */ const HOST_WORKSPACE_TOOLS = [ 'read_file', 'write_file', 'search_replace', 'grep', 'list_dir', 'run_terminal_cmd', 'memory_search', 'memory_get', 'memory_write', ]; const HOST_WORKSPACE_SET = new Set(HOST_WORKSPACE_TOOLS); const ALWAYS_RESERVED = ['image_gen', 'image_edit', 'image_to_video', 'deploy_app']; const ALWAYS_BUILTIN_RESERVED = [ 'todo_write', 'web_search', 'web_fetch', 'enter_plan_mode', 'exit_plan_mode', 'ask_user_question', 'update_goal', 'memory_write', 'task', 'send_subagent_message', 'get_task_output', 'wait_tasks', 'kill_task', 'search_tool', 'use_tool', ]; function parseHostWorkspace(opts) { opts = opts || {}; if (opts.hostWorkspace === false || opts.hostTools === false) return false; return true; } function filterBuiltinSchemas(schemas, opts) { opts = opts || {}; const hostWorkspace = parseHostWorkspace(opts); let list = Array.isArray(schemas) ? schemas.slice() : []; if (!hostWorkspace) { list = list.filter((t) => !HOST_WORKSPACE_SET.has(t.name)); } if (opts.builtinTools === false) { list = []; } else if (Array.isArray(opts.builtinTools)) { const allow = new Set(opts.builtinTools.map(String)); list = list.filter((t) => allow.has(t.name)); } if (opts.planMode) { // Keep write_file / search_replace so the model can edit plan.md; gate other writes at execute. list = list.filter((t) => t.name !== 'run_terminal_cmd'); } if (opts.webFetch !== true) { list = list.filter((t) => t.name !== 'web_fetch'); } return list; } function isHostWorkspaceTool(name) { return HOST_WORKSPACE_SET.has(name); } module.exports = { HOST_WORKSPACE_TOOLS, ALWAYS_RESERVED, ALWAYS_BUILTIN_RESERVED, parseHostWorkspace, filterBuiltinSchemas, isHostWorkspaceTool, };