MCPcopy Create free account
hub / github.com/agentforce314/clawcodex / _bash_call

Function _bash_call

src/tool_system/tools/bash/bash_tool.py:234–465  ·  view source on GitHub ↗
(tool_input: dict[str, Any], context: ToolContext)

Source from the content-addressed store, hash-verified

232
233
234def _bash_call(tool_input: dict[str, Any], context: ToolContext) -> ToolResult:
235 command = tool_input["command"]
236 if not isinstance(command, str) or not command.strip():
237 raise ToolInputError("command must be a non-empty string")
238 if "\x00" in command:
239 raise ToolInputError("command contains NUL byte")
240
241 # Defense-in-depth: block obviously dangerous commands even when called
242 # directly (bypassing the registry's check_permissions flow).
243 for pat in _HARDCODED_DANGEROUS_PATTERNS:
244 if pat.search(command):
245 raise ToolPermissionError("refusing to run potentially dangerous command")
246
247 explicit_cwd = tool_input.get("cwd")
248 if explicit_cwd is not None:
249 if not isinstance(explicit_cwd, str) or not explicit_cwd.startswith("/"):
250 raise ToolInputError("cwd must be an absolute path when provided")
251 cwd = context.ensure_allowed_path(explicit_cwd)
252 else:
253 cwd = context.cwd or context.workspace_root
254
255 # ``run_in_background: true`` detaches the command so the agent can keep
256 # coordinating while a long-running job (dev server, build, long test
257 # suite, ...) makes progress. Mirrors
258 # ``typescript/src/tools/BashTool/BashTool.tsx`` ``spawnBackgroundTask``
259 # behaviour: we return immediately with a task id and let the model poll
260 # the output via ``TaskOutput``.
261 if tool_input.get("run_in_background"):
262 bg_output = spawn_background_bash(
263 command=command,
264 cwd=cwd,
265 description=tool_input.get("description"),
266 context=context,
267 )
268 return ToolResult(name=BASH_TOOL_NAME, output=bg_output)
269
270 cd_target = _try_extract_cd(command)
271 if (
272 cd_target is not None
273 and command.strip().startswith("cd ")
274 and len(command.strip().splitlines()) == 1
275 ):
276 if not cd_target.is_absolute():
277 next_dir = (cwd / cd_target).expanduser().resolve()
278 else:
279 next_dir = cd_target.expanduser().resolve()
280 next_dir = context.ensure_allowed_path(next_dir)
281 if not next_dir.exists() or not next_dir.is_dir():
282 return ToolResult(
283 name=BASH_TOOL_NAME,
284 output={"error": f"directory does not exist: {next_dir}"},
285 is_error=True,
286 )
287 context.cwd = next_dir
288 return ToolResult(
289 name=BASH_TOOL_NAME,
290 output={"cwd": str(context.cwd), "stdout": "", "stderr": ""},
291 )

Calls 15

format_durationFunction · 0.90
ToolInputErrorClass · 0.85
ToolPermissionErrorClass · 0.85
spawn_background_bashFunction · 0.85
ToolResultClass · 0.85
_try_extract_cdFunction · 0.85
get_max_timeout_msFunction · 0.85
get_default_timeout_msFunction · 0.85
_run_bash_with_abortFunction · 0.85
_get_abort_signalFunction · 0.85
truncate_outputFunction · 0.85
interpret_command_resultFunction · 0.85