> ## Documentation Index
> Fetch the complete documentation index at: https://hub.hcompany.ai/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> H Platform has three products: the Agents API (managed computer-use agents, base URL https://agp.eu.hcompany.ai/api/v2 or https://agp.hcompany.ai/api/v2 for the US), the Models API (OpenAI-compatible Holo vision-language models at https://api.hcompany.ai/v1), and HoloTab (a free no-code Chrome extension that runs Holo in the user's browser, with recordable routines and schedules). The `holo` CLI (`pip install "hai-agents[cli]"`) runs Agents API agents from a terminal, drives the user's own desktop with `-a h/holo-desktop`, and serves coding agents through `holo mcp`.
> Authenticate with a bearer API key from the HAI_API_KEY environment variable. SDKs: `pip install hai-agents` (Python, `from hai_agents import Client`) and `npm install hai-agents` (TypeScript, `import { HaiAgentsClient } from "hai-agents"`). CLI: `holo`.
> Agents do work in a browser or on a desktop; describe the task as an imperative instruction. To run a task quickly, prefer the pre-built agent `h/web-surfer-flash`. Read results from the session's `latest_answer` after it reaches a terminal status.
> Sessions are the unit of work; wait for a terminal status (completed, failed, timed_out, interrupted) before reading the answer. Use webhooks or the `changes` long-poll endpoint to follow progress.

# Shell mode

> Let an agent drive your desktop with commands: run them, edit files, and write code.

## Run a session

A [`desktop` environment](https://hub.hcompany.ai/agents-api/your-desktop) has two modes. Both act on the same machine, and differ in how the agent drives it.

| Mode | The agent | Reaches |
| - | - | - |
| `visual`, the default | Looks at the screen, clicks, and types. | Anything on screen. |
| `shell` | Runs commands. | The same apps and your Chrome, through a command line, and also files, scripts, git, and installs. |

In shell mode, the agent gets a shell on your machine, running as you. It runs commands, reads and edits files, installs what a task needs, and starts tests and servers. When a result only shows in a window, it drives the screen and your Chrome from the same shell.

Two guards bound what it does. It [asks before a command](#approve-commands) you have not allowed, and its commands run in a [sandbox](#sandbox) that writes in one folder and cannot read your credentials. The sandbox is on by default on macOS. On Linux and Windows it is off until you [install it](#linux-and-windows), so require approval there.

[Stop it](https://hub.hcompany.ai/holo-cli/introduction.md#drive-your-desktop) with Esc twice, or `holo local stop` in any terminal, which stops every session driving this machine.

```bash Install theme={"system"}
pip install "hai-agents[cli,workstation]"
```

It works on macOS, Linux, and Windows (with [Git for Windows](https://git-scm.com/download/win), whose bash runs the commands). Create an agent with a `desktop` environment in `shell` mode, once:

```python Python theme={"system"}
from hai_agents import Client

client = Client()

client.agents.create_agent(
    name="laptop-coder",
    description="Runs commands and edits files on my machine.",
    environments=[{
        "id": "my-laptop",
        "kind": "desktop",
        "mode": {"type": "shell", "command_approval": "required"},
    }],
)
```

```bash cURL theme={"system"}
curl -X POST https://agp.eu.hcompany.ai/api/v2/agents \
  -H "Authorization: Bearer $HAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "laptop-coder",
    "description": "Runs commands and edits files on my machine.",
    "environments": [{
      "id": "my-laptop",
      "kind": "desktop",
      "mode": {"type": "shell", "command_approval": "required"}
    }]
  }'
```

Then run it from the folder it should work in:

```bash CLI theme={"system"}
cd ~/Projects/app
HAI_SHELL_WORKSPACE=. holo -a laptop-coder "Run the tests and fix the one that fails"
```

`holo` connects your machine, prints each step, and [asks you](https://hub.hcompany.ai/holo-cli/reference.md#approvals) before a command that needs approval. From Python, [answer in code](#answer-from-code).

On macOS, the first session asks for the [desktop permissions](https://hub.hcompany.ai/holo-cli/introduction.md#desktop-permissions) the agent needs to see and drive the screen, and stops with an error until you grant them.

## What the agent can do

| It can | How |
| - | - |
| Run commands | Each with a timeout. A long one, such as a server or a watcher, keeps running in the background while the agent goes on. |
| Read, write, and edit files | With its file tools, or with commands. |
| Look at an image or a screenshot | It loads the file into its context. |
| Drive apps, dialogs, and your signed-in Chrome | With `cua`, a command line it runs in the shell. It works in a tab it opens, and leaves yours alone. |
| Send you a file | As an [attachment](https://hub.hcompany.ai/agents-api/observe-and-steer.md#get-the-files-the-agent-sends). The file is also on your disk, where the agent says. |
| Search and read the web | As any agent does. |

The agent is told to stay in its folder unless the task names another place, to install tools there and not system-wide, and to leave your windows and processes as it found them. These are instructions. The limits are the two guards.

## Where it works

The agent starts in its workspace, the folder its file tools act in.

| You set | Workspace |
| - | - |
| Nothing | A new folder under `~/hai/`, one per session. |
| `HAI_SHELL_WORKSPACE=<folder>` | That folder, such as your project. A relative path starts from where you run `holo` or Python. |

* Files you [attach to a message](https://hub.hcompany.ai/agents-api/sessions/send-messages.md#param-files) land in `files/` in the workspace.
* With a guard on, the file tools act in the workspace only, and never inside a `.git` folder. Commands go where the [sandbox](#sandbox) lets them, when it is on.
* With no guard on, commands and file tools reach whatever you can.

## Approve commands

With `"command_approval": "required"`, a command waits for your decision unless it starts with an allowed one. A command is allowed by:

* The agent's `allowed_commands`, such as `["git status", "npm test"]`.
* What you chose to always allow on this machine, kept in `~/.config/hai/allowed-commands`. It starts with `cua`, which drives your screen.

An allowed command covers every command that starts with it: `git status` covers `git status --short`, and not `git stash`. In a line that chains commands with `&&`, `;`, or `|`, each one must be covered. Some syntax always waits, because the words do not say what runs: `$(...)`, backticks, subshells, and redirection to a file.

A held command shows in [`pending_approvals`](https://hub.hcompany.ai/agents-api/sessions/status#param-pending-approvals) with the command and the reason, and the session waits on `awaiting_tool_results`. An approval runs that command once. A denial tells the agent why, so it can try another way.

| You run the session from | You answer |
| - | - |
| `holo` in a terminal | At the [prompt](https://hub.hcompany.ai/holo-cli/reference.md#approvals): `y` approves, `a` approves and always allows, `n` denies. |
| Python | With `approve` and `deny`, [below](#answer-from-code). |
| Anything else | With [Send tool approvals](https://hub.hcompany.ai/agents-api/sessions/tool-approvals.md). |

Where nobody can answer, the run ends: `holo` with `--json` or `--quiet`, a pipe, or a [coding agent](https://hub.hcompany.ai/agents-api/coding-agents.md#local-server). A call still held when a session ends is denied.

### Answer from code

`wait_for_completion` returns when the agent holds a call. Decide each one, then wait again:

```python Python theme={"system"}
session = client.start_session(
    agent="laptop-coder",
    messages="Run the tests and fix the one that fails",
)
result = session.wait_for_completion()

while result.pending_approvals:
    for held in result.pending_approvals:
        command = held.tool_req.args["command"]
        if command.startswith(("pytest", "git diff")):
            session.approve(held.tool_req.id)
        else:
            session.deny(held.tool_req.id, "Only run tests and read diffs.")
    result = session.wait_for_completion(from_index=result.next_from_index)

print(result.status, result.answer)
```

Python reads `HAI_SHELL_WORKSPACE` too: set it before you start the session.

## Sandbox

On macOS, every command runs inside Anthropic's [sandbox-runtime](https://github.com/anthropics/sandbox-runtime). The SDK downloads it on your first session in shell mode, 41 MB under `~/.hai/sandbox-runtime`. If the download fails, commands run as you, with a warning at each session.

| A command can | Built-in rules |
| - | - |
| Write | The workspace, and its own temp and cache folders. |
| Read | Everything else you can, except the row below. |
| Not read | SSH, cloud, npm, pip, and GitHub CLI credentials, the keychain, Chrome's profile, shell history, and environment variables that look like tokens. |
| Reach | `pypi.org`, `files.pythonhosted.org`, `registry.npmjs.org`. |
| Use git | In an existing repository. `git init`, `git clone`, and config changes are refused. |

An agent asks for more in its [mode](#mode-fields): `allowed_domains` to reach other hosts, `writable_folders` to write elsewhere. What was added is printed when the session starts.

```python theme={"system"}
mode = {
    "type": "shell",
    "command_approval": "required",
    "allowed_commands": ["git status", "npm test"],
    "allowed_domains": ["github.com"],
}
```

* With `github.com` allowed, commands read public repositories over HTTPS. Your SSH keys and stored git credentials stay unreadable, so the agent commits and you push.
* `"sandbox": "required"` runs no command on a machine that cannot confine it.
* Your own rules go in `~/.config/hai/sandbox.json`, in sandbox-runtime's [settings format](https://github.com/anthropics/sandbox-runtime#configuration). The file replaces the built-in rules.
* `HAI_SHELL_SANDBOX=0` turns the sandbox off: commands then run as you.
* The sandbox confines commands. It does not confine `cua`: what the agent does with your mouse and keyboard can do whatever you can.

### Linux and Windows

There the sandbox is off until you install it and turn it on: with `HAI_SHELL_SANDBOX=1`, a `sandbox.json`, or an agent that requires it.

| System | Install once |
| - | - |
| Linux | `npm install -g --omit=optional @anthropic-ai/sandbox-runtime` (Node 22.12+), with `bubblewrap`, `socat`, and `ripgrep`. On Ubuntu 24.04 and later, `sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0`. On 25.04 and later, also `sudo apparmor_parser -R /etc/apparmor.d/bwrap-userns-restrict`. |
| Windows (alpha) | The same `npm install`, then `srt windows-install` once, as an administrator. |

* A command made only of `cua` calls runs outside the sandbox: that is how the agent sees and drives your screen. Mixed with anything else, `cua` stays inside and cannot reach it.
* On Windows, commands run as a separate `srt-sandbox` user. Each takes several seconds, and `curl` cannot open HTTPS. `git`, `pip`, and `node` can. sandbox-runtime lists its [known limitations](https://github.com/anthropics/sandbox-runtime#known-limitations).

## Mode fields

The `mode` of the [`desktop` environment](https://hub.hcompany.ai/agents-api/your-desktop#fields), with `"type": "shell"`.

| Field | Default | Description |
| - | - | - |
| `command_approval` | `"not_required"` | `"required"` holds each command until you [approve](#approve-commands) it, unless it starts with one of `allowed_commands`. |
| `allowed_commands` | `[]` | Commands that run without approval, each with any arguments after it, such as `"git status"`. |
| `sandbox` | `"if_available"` | Commands run in the [sandbox](#sandbox) on a machine that has it, and as you on one that does not. `"required"` runs no command on a machine without it. |
| `allowed_domains` | `[]` | Hosts commands may reach besides the Python and npm registries, such as `"github.com"` or `"*.example.com"`. |
| `writable_folders` | `[]` | Folders commands may write besides the workspace, absolute or under `~/`, such as `"~/Projects/lib"`. |

What your machine sets itself wins:

* With `HAI_SHELL_POLICY=<file>`, that allowlist alone decides which commands wait, whatever the agent's `command_approval`. `allowed_commands` is not added to it.
* With a `~/.config/hai/sandbox.json`, your file alone decides what commands reach and write. `allowed_domains` and `writable_folders` are not added to it.
* With `HAI_SHELL_SANDBOX=0`, an agent that requires the sandbox does not start.

## Behavior and limits

When a session starts, the SDK opens a connection inside your process. It receives the agent's commands, runs them on your machine, and ties the session to it. [Watch and steer](https://hub.hcompany.ai/agents-api/observe-and-steer.md) and [changes](https://hub.hcompany.ai/agents-api/sessions/changes.md) work as in the cloud.

* One agent drives this machine at a time, and a run stops after 150 steps or 30 minutes by default, as on [your desktop](https://hub.hcompany.ai/holo-cli/introduction.md#drive-your-desktop).
* With a guard on, each command runs in a shell of its own: nothing carries from one to the next but the files.
* Commands, their output, and the files the agent reads go to H with the session, as [What H receives](https://hub.hcompany.ai/holo-cli/introduction.md#what-h-receives) lays out.
* The [session file endpoints](https://hub.hcompany.ai/agents-api/sessions/list-files.md) serve cloud browsers. Here the files are on your disk.
* The connection closes when your process exits, and the sessions it served are cancelled.

### Connect from elsewhere

The Python SDK and `holo` connect your machine for you, for an inline agent and for one referenced by name. For a session started from TypeScript, the H Platform, or another machine, serve the shell yourself and set the `session_id` it prints on the agent's `desktop` environment:

```bash CLI theme={"system"}
holo local desktop --shell --workspace ~/Projects/app
```

[`holo local`](https://hub.hcompany.ai/holo-cli/reference#holo-local) lists its flags.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.