MCPcopy
hub / github.com/coder/mux / createBashTool

Function createBashTool

src/node/services/tools/bash.ts:875–1570  ·  view source on GitHub ↗
(config: ToolConfiguration)

Source from the content-addressed store, hash-verified

873 * @param config Required configuration including working directory
874 */
875export const createBashTool: ToolFactory = (config: ToolConfiguration) => {
876 // Select limits based on overflow policy
877 // truncate = IPC calls (generous limits for UI features, no line limit, no per-line limit)
878 // tmpfile = AI agent calls (conservative limits for LLM context)
879 const overflowPolicy = config.overflow_policy ?? "tmpfile";
880 const maxTotalBytes =
881 overflowPolicy === "truncate" ? BASH_TRUNCATE_MAX_TOTAL_BYTES : BASH_MAX_TOTAL_BYTES;
882 const maxFileBytes =
883 overflowPolicy === "truncate" ? BASH_TRUNCATE_MAX_FILE_BYTES : BASH_MAX_FILE_BYTES;
884 const maxLines = overflowPolicy === "truncate" ? Infinity : BASH_HARD_MAX_LINES;
885 const maxLineBytes = overflowPolicy === "truncate" ? Infinity : BASH_MAX_LINE_BYTES;
886
887 return tool({
888 description: buildBashToolDescription(config.cwd, config.projects ?? []),
889 inputSchema: TOOL_DEFINITIONS.bash.schema,
890 execute: async (
891 { script, timeout_secs, run_in_background, display_name, monitor },
892 { abortSignal, toolCallId }
893 ): Promise<BashToolResult> => {
894 // Validate script input
895
896 // Treat display_name as untrusted input: it ends up in filesystem paths.
897 const safeDisplayName = resolveBashDisplayName(script, display_name);
898 const validationError = validateScript(script, config);
899 if (validationError) return validationError;
900
901 // Warn when the model appears to be reading files via bash output (cat/rg/grep).
902 // Reading files via bash output is fragile (may be truncated or auto-filtered);
903 // file_read supports paging and avoids silent context loss.
904 const fileReadNotice =
905 detectCatFileRead(script) || detectRipgrepFileDump(script) || detectGrepFileDump(script)
906 ? CAT_FILE_READ_NOTICE
907 : undefined;
908
909 // Look up .mux/tool_env to source before script (for direnv, nvm, venv, etc.)
910 // Skip for untrusted projects — tool_env is repo-controlled code
911 const toolEnvPath =
912 config.trusted && config.runtime ? await getToolEnvPath(config.runtime, config.cwd) : null;
913 const toolEnvPrelude = buildToolEnvPrelude(toolEnvPath);
914
915 // Neutralize git hooks for untrusted projects — prevent repository-controlled
916 // hooks from executing when the model runs git subcommands (for example,
917 // `git commit` or `git am`) through this bash tool.
918 const hooksEnv = config.trusted !== true ? GIT_NO_HOOKS_ENV : {};
919
920 // On Windows, models sometimes emit cmd.exe-style `>nul` / `2>nul` redirections.
921 // Since the bash tool runs via bash, `nul` becomes a real file in the workspace.
922 // Only rewrite for local Windows runtimes so non-Windows scripts keep their semantics.
923 const shouldRewriteNullRedirects =
924 process.platform === "win32" && config.runtime instanceof LocalBaseRuntime;
925 const nulRedirectRewrite = shouldRewriteNullRedirects
926 ? rewriteWindowsNullRedirects(script)
927 : { script, didRewrite: false };
928 const scriptWithEnv = toolEnvPrelude + nulRedirectRewrite.script;
929
930 const nulRedirectNote = nulRedirectRewrite.didRewrite
931 ? "Rewrote `>nul`/`2>nul` → `/dev/null` (bash tool runs in bash; use `/dev/null` to discard output)."
932 : undefined;

Calls 15

resolveBashDisplayNameFunction · 0.90
getToolEnvPathFunction · 0.90
getErrorMessageFunction · 0.90
toBashTaskIdFunction · 0.90
migrateToBackgroundFunction · 0.90
buildBashToolDescriptionFunction · 0.85
validateScriptFunction · 0.85
detectCatFileReadFunction · 0.85
detectRipgrepFileDumpFunction · 0.85
detectGrepFileDumpFunction · 0.85
buildToolEnvPreludeFunction · 0.85

Tested by 2

createTestBashToolFunction · 0.72