# How Apache Maka's Bash Tool Works: A Deep Dive into Shell Execution

> Explore how Apache Maka's Bash tool executes shell commands foreground or background. Learn about PTY allocation, sandbox enforcement, and customizable hooks for efficient shell management.

- Repository: [The Apache Software Foundation/maka](https://github.com/apache/maka)
- Tags: deep-dive
- Published: 2026-08-29

---

**Apache Maka's Bash tool is a configurable managed tool that executes shell commands either foreground (blocking with optional timeout) or background (non-blocking as a runtime task), with built-in support for PTY allocation, sandbox boundary enforcement, and host-customizable hooks.**

The Bash tool sits at the core of Maka's ability to let AI agents interact with the underlying operating system. In [`packages/runtime/src/shell-tools.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/shell-tools.ts), the `buildManagedBashTool` factory constructs a `MakaTool` instance that bridges high-level tool calls from the model to concrete shell process execution. This article breaks down the complete execution flow, parameter schema, timeout handling, and extension points you need to understand to work with or extend Maka's Bash capabilities.

## Tool Definition and Parameter Schema

Maka defines the Bash tool programmatically rather than through static configuration. The `buildManagedBashTool` function creates a tool named **Bash** with activity kind `command` and a Zod-validated parameter schema.

### Core Parameters

The parameter schema in [`shell-tools.ts`](https://github.com/apache/maka/blob/main/shell-tools.ts) lines 31-36 accepts:

- **`command`** (string, required): The shell command to execute
- **`timeout_ms`** (number, optional): Explicit timeout in milliseconds
- **`run_in_background`** (boolean, optional): Run as non-blocking background task
- **`pty`** (boolean, optional): Allocate pseudo-terminal (PTY mode)
- **`boundary_intent`** and **`required_boundary`** (conditional): Sandbox boundary declarations when `declareSandboxBoundary` is enabled

Validation enforces that PTY mode requires `run_in_background=true`, and foreground timeouts are clamped to `MAX_FOREGROUND_BASH_TIMEOUT_MS`.

```typescript
// From shell-tools.ts L31-L36 - the Zod schema structure
const bashParamsSchema = z.object({
  command: z.string(),
  timeout_ms: z.number().optional(),
  run_in_background: z.boolean().optional(),
  pty: z.boolean().optional(),
  // boundary fields added conditionally based on host configuration
});

```

## Execution Flow: From Tool Call to Shell Process

When a model invokes the Bash tool, the runtime follows a predictable dispatch pipeline in [`shell-tools.ts`](https://github.com/apache/maka/blob/main/shell-tools.ts) lines 88-133:

1. **Parameter extraction** – Parse and validate incoming arguments
2. **Sandbox resolution** – Resolve declared boundary via `preflightDeclaredSandboxBoundary`
3. **Command transformation** – Apply optional `transformCommand` hook
4. **Timeout calculation** – Clamp to host and built-in limits
5. **Execution dispatch** – Route to `runForegroundBash` or `runBackgroundBash`
6. **Result processing** – Emit output, invoke `afterResult` hook, convert to model format

### Timeout Handling Logic

The timeout calculation in [`shell-tools.ts`](https://github.com/apache/maka/blob/main/shell-tools.ts) lines 102-108 implements tiered defaults:

```typescript
// Foreground: use explicit, or host default, or built-in default
// Then clamp to MAX_FOREGROUND_BASH_TIMEOUT_MS
const effectiveTimeout = Math.min(
  params.timeout_ms ?? host.defaultTimeoutMs?.(params.command) ?? DEFAULT_BASH_TIMEOUT_MS,
  MAX_FOREGROUND_BASH_TIMEOUT_MS
);

// Background: no default timeout unless explicitly provided
// If provided, clamp to MAX_SHELL_RUN_TIMEOUT_MS

```

These constants are defined in [`packages/runtime/src/shell-run-contract.js`](https://github.com/apache/maka/blob/main/packages/runtime/src/shell-run-contract.js).

## Foreground vs. Background Execution

Maka's Bash tool supports two fundamentally different execution modes, selected by the `run_in_background` parameter.

### Foreground Execution (`runForegroundBash`)

- **Blocking**: Returns only after command completion
- **Timeout enforced**: Hard limit via `MAX_FOREGROUND_BASH_TIMEOUT_MS`
- **Simpler result**: Direct terminal output, no task reference

### Background Execution (`runBackgroundBash`)

- **Non-blocking**: Returns immediately with a task reference like `maka://runtime/background-tasks/abc123`
- **PTY support**: Required for interactive programs (editors, REPLs)
- **Lifecycle management**: Tracked by `ShellRunLauncher`, completion via `onCompletion` callback

The background task completion handler in [`shell-tools.ts`](https://github.com/apache/maka/blob/main/shell-tools.ts) lines 55-64 attaches a one-time callback:

```typescript
// Simplified from shell-tools.ts L55-L64
const onCompletion = (result: ShellRunResult) => {
  const success = result.exitCode === 0;
  reportBackgroundTaskCompletion(taskRef, success, result);
};

```

## PTY Mode and Interactive Shell Sessions

The `pty` parameter triggers pseudo-terminal allocation, essential for programs that require termcap detection or raw terminal I/O. Key constraints enforced by the schema:

- PTY requires `run_in_background=true` (enforced at validation)
- Background PTY tasks can be interacted with via subsequent **WriteStdin** and **Read** tool calls
- The task reference returned allows multi-turn session management

Example background PTY invocation:

```json
{
  "type": "tool_call",
  "toolName": "Bash",
  "args": {
    "command": "vim /tmp/file.txt",
    "run_in_background": true,
    "pty": true
  }
}

```

## Sandbox Boundary Enforcement

When the host enables `declareSandboxBoundary`, the schema expands to include `boundary_intent` and `required_boundary` fields. The runtime validates these through two helper functions:

- **`preprocessBashBoundaryDeclaration`** – Initial validation and normalization
- **`refineBashBoundaryDeclaration`** – Final resolution before execution

The resolved boundary is passed to the shell runner, enabling hosts to implement filesystem, network, or resource isolation policies without modifying core Maka code.

## Result Conversion and Model Output

Raw terminal output contains fields unsuitable for durable model context—particularly the original `cmd` string which may include secrets or excessive length. The `bashToolResultToModelOutput` function in [`packages/runtime/src/bash-model-output.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/bash-model-output.ts) lines 24-42 sanitizes results:

```typescript
// From bash-model-output.ts L24-L42
export function bashToolResultToModelOutput(result: TerminalResult): ModelBashOutput {
  // Strip 'cmd' field, preserve stdout/stderr/exitCode
  const { cmd, ...safeFields } = result;
  return {
    ...safeFields,
    // Additional normalization for model consumption
  };
}

```

This ensures that:
- Command history in context windows stays compact
- Potentially sensitive command arguments aren't persisted
- The model receives canonical, structured output

## Host Customization Hooks

The `buildManagedBashTool` factory accepts configuration options that let hosts inject policy without forking:

| Hook/Option | Purpose | Called When |
|-------------|---------|-------------|
| `defaultTimeoutMs` | Per-command timeout fallback | Timeout not explicitly specified |
| `transformCommand` | Modify command before execution | After validation, before dispatch |
| `afterResult` | Post-execution side effects | After result conversion |
| `declareSandboxBoundary` | Enable boundary schema fields | Tool construction |

Example host configuration:

```typescript
import { buildManagedBashTool } from '@maka/runtime/src/shell-tools.js';

export const bash = buildManagedBashTool(launcher, {
  declareSandboxBoundary: true,
  
  defaultTimeoutMs: (cmd) => {
    // Longer timeout for known slow commands
    if (cmd.includes('npm install')) return 300_000;
    if (cmd.includes('git clone')) return 180_000;
    return 60_000;
  },
  
  afterResult: async (input, result, ctx) => {
    await auditLog.record({
      command: input.command,
      exitCode: result.exitCode,
      duration: result.durationMs,
      sessionId: ctx.sessionId,
    });
  },
});

```

## Registration and Built-in Integration

The Bash tool is registered alongside other built-ins in [`packages/runtime/src/builtin-tools.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/builtin-tools.ts). This registration layer connects the managed tool implementation to Maka's runtime initialization, ensuring the **Bash** tool name resolves correctly in tool calls from the model.

## Key Source Files Reference

| File | Lines | Responsibility |
|------|-------|----------------|
| [`packages/runtime/src/shell-tools.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/shell-tools.ts) | 77-88 | `buildManagedBashTool` factory |
| [`packages/runtime/src/shell-tools.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/shell-tools.ts) | 31-36 | Parameter schema definition |
| [`packages/runtime/src/shell-tools.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/shell-tools.ts) | 88-100 | Option handling and transformation |
| [`packages/runtime/src/shell-tools.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/shell-tools.ts) | 102-108 | Timeout calculation logic |
| [`packages/runtime/src/shell-tools.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/shell-tools.ts) | 109-114 | Execution dispatch |
| [`packages/runtime/src/shell-tools.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/shell-tools.ts) | 115-133 | Result handling pipeline |
| [`packages/runtime/src/shell-tools.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/shell-tools.ts) | 55-64 | Background completion callback |
| [`packages/runtime/src/shell-tools.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/shell-tools.ts) | 71-86 | Sandbox boundary processing |
| [`packages/runtime/src/bash-model-output.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/bash-model-output.ts) | 24-42 | Result sanitization |
| [`packages/runtime/src/shell-run-contract.js`](https://github.com/apache/maka/blob/main/packages/runtime/src/shell-run-contract.js) | — | Timeout constants |
| [`packages/runtime/src/builtin-tools.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/builtin-tools.ts) | — | Tool registration |
| [`packages/runtime/src/shell-run-detect.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/shell-run-detect.ts) | — | Model guidance strings |

## Summary

- **Apache Maka's Bash tool** is implemented via `buildManagedBashTool` in [`shell-tools.ts`](https://github.com/apache/maka/blob/main/shell-tools.ts), creating a configurable bridge between model tool calls and operating system shell execution.
- **Two execution modes**: Foreground (blocking, timeout-capped) and background (non-blocking, PTY-capable, referenced for lifecycle management).
- **Parameter schema** validates `command`, optional `timeout_ms`, `run_in_background`, `pty`, and conditional sandbox boundary fields with strict enforcement of PTY-background coupling.
- **Timeout handling** applies tiered defaults and clamps to `MAX_FOREGROUND_BASH_TIMEOUT_MS` or `MAX_SHELL_RUN_TIMEOUT_MS` depending on execution mode.
- **Result sanitization** via `bashToolResultToModelOutput` strips the original command for safe, compact model context while preserving execution output.
- **Host extensibility** through `defaultTimeoutMs`, `transformCommand`, and `afterResult` hooks without core code modification.

## Frequently Asked Questions

### What is the maximum timeout for foreground Bash commands in Maka?

Foreground Bash commands are clamped to `MAX_FOREGROUND_BASH_TIMEOUT_MS` as defined in [`packages/runtime/src/shell-run-contract.js`](https://github.com/apache/maka/blob/main/packages/runtime/src/shell-run-contract.js). Even if the host's `defaultTimeoutMs` or an explicit `timeout_ms` parameter exceeds this value, the runtime enforces this hard ceiling for blocking operations.

### Can I run interactive programs like vim or node repl through Maka's Bash tool?

Yes, but you must set both `run_in_background: true` and `pty: true`. PTY allocation requires background mode because interactive programs need persistent process state across multiple turns. The runtime returns a task reference that subsequent **WriteStdin** and **Read** tools use to interact with the session.

### How does Maka prevent sensitive commands from persisting in model context?

The `bashToolResultToModelOutput` function in [`packages/runtime/src/bash-model-output.ts`](https://github.com/apache/maka/blob/main/packages/runtime/src/bash-model-output.ts) deliberately removes the `cmd` field from terminal results before they enter durable storage or model context. This prevents accidental exposure of passwords, tokens, or verbose command strings while preservingstdout, stderr, and exit status for model reasoning.

### What happens if I declare a sandbox boundary but the command violates it?

The runtime validates `boundary_intent` and `required_boundary` through `preprocessBashBoundaryDeclaration` and `refineBashBoundaryDeclaration` before execution. Actual enforcement depends on the host's `ShellRunLauncher` implementation—these declarations provide structured policy input that the host's execution layer can use to apply filesystem, network, or resource constraints.