---
title: Web terminal — the Agent J host's command line in a computer browser
nav: Web terminal
summary: A time-limited terminal on the Agent J host, used from a computer browser like a cloud console; off by default, switched on from Settings → Safety with Face ID and the computer password, not available on a phone; Face ID on every open; `!` commands from the chat and a computer password filled in with Face ID.
order: 50
---
# Web terminal — the Agent J host's command line in a computer browser

The web terminal gives you the command line of the Agent J host (the computer Agent J is installed on) in a computer browser, like the web console of a cloud service: you type a line in the browser, the host runs it and the output shows in the browser. It lives in Settings → Safety → Web terminal.

It works only in a computer browser, that is, a remote opened in a browser on a computer. A phone shows one sentence only: **For safety and convenience, the web terminal can only be used from a computer browser.**

It is off by default. Switching it on takes you in person: Face ID plus the Agent J host's login password in a computer browser, or one command run at the host. The Agent, scheduled tasks and scripts cannot. Every open needs Face ID, lasts at most 15 minutes by default and is recorded in full.

Once it is on, you can also run a command straight from the chat by starting the message with `!` ([details](#bang)), let the computer remember its password so Face ID fills it in, on the Agent's admin-command cards too ([details](#computer-password)), and let the Agent open the terminal with a command filled in or read what it printed ([details](#agent)).

## Where to find it {#where}

Open Settings → Safety. The **Web terminal** row is always there and tells you the next step:

- **A computer browser, the terminal off or this browser not allowed yet**: tap **Switch on and open**; see [Switch it on in a computer browser](#enable-browser). Below it, **Or run this line on the Agent J host:** shows `agentj terminal enable` with a button to copy it ([details](#enable)).
- **A phone**: it says only **For safety and convenience, the web terminal can only be used from a computer browser.** There are no buttons.
- **The Agent J host runs Windows (not inside WSL)**: it says this system is not supported yet and the next version will be. Today it works on Linux, macOS and Windows' WSL.
- **This device has no Face ID yet**: tap **Set up Face ID** first.
- **Only a command line, no switch-on button**: this remote did not record at pairing whether it is a computer or a phone (it was paired long ago, for example). Pair this remote again to switch it on right here, or run the line shown at the Agent J host; see [Who can use it](#who).
- **Switched on and this browser may use it**: tap **Open web terminal**.

## Switch it on in a computer browser {#enable-browser}

1. Open the remote in a computer browser and go to Settings → Safety → Web terminal. Tap **Switch on and open**.
2. Confirm with Face ID.
3. Type the Agent J host's login password once — the password you use to log in to that computer and for sudo. The host checks it with sudo. Switching on always takes a typed password, never a remembered one.
4. When the password is right, the web terminal is switched on for this browser and opens straight away: you leave Settings and use it full screen in this window. The ✕ at the top right collapses it ([details](#full-screen)).

Every remote then gets a notice naming the device it was switched on from. When that device is a web-version remote, the notice also says: if this was not you, run `agentj terminal disable` on the Agent J host now.

The browser's guess of computer or phone only takes you to the right place. The Agent J host also checks, by the device type recorded at pairing, and refuses to open or switch on the terminal for a remote that paired as a phone. What really protects you are the locks: the signature, Face ID, the computer login password, the full recording and the time limits.

## Switch it on at the Agent J host {#enable}

The other way: in the Agent J host's own terminal, run:

```bash
agentj terminal enable
```

1. The host prints a 6-digit match code, and every paired remote (phones included) gets a card naming the devices that may use the terminal, the minutes per session and the same match code.
2. Check that the digits match, then allow it on a remote that has Face ID set up and confirm with Face ID. If nobody confirms within 5 minutes, nothing changes.
3. The computer browser on the list now shows **Open web terminal** under Settings → Safety.

What it needs:

- At least one paired computer browser with Face ID (or a fingerprint — a passkey). If none has it yet, tap **Set up Face ID** under Settings → Safety → Web terminal in that browser first.
- It runs on Linux, macOS and Windows' WSL; native Windows comes in the next version. A Mac has a few extra points: see [On a Mac](#macos).
- Your computer account must be able to use sudo, and sudo must ask for a password. With a sudo that needs no password (NOPASSWD), or an account that is not an administrator, `agentj terminal enable` refuses and says why: the web terminal uses your computer login password as a second lock.

Only you, typing in your own terminal, can run this. The Agent, scheduled tasks, scripts and the web terminal itself cannot. A remote can only switch it on for itself with **Switch on and open**, which also takes Face ID and the computer login password; a phone cannot.

With several computer browsers that have Face ID, pick one with `--device` (repeatable; a remote that paired as a phone cannot be picked). Change the minutes per session with `--minutes` (default 15, at most 60):

```bash
agentj terminal enable --device <device> --minutes 30
```

`agentj terminal status` lists the switch, the devices on the list and whether each one has a remembered computer password.

## On a Mac {#macos}

When the Agent J host is a Mac, the web terminal works as on Linux: switched on only by you, Face ID on every open, a time limit, a recording of everything, a second confirmation for risky commands, and what you type is masked before it is recorded. What differs:

- Three more things before it can be switched on, and you are told which one is missing: your Mac account is an administrator (System Settings → Users & Groups says Admin); sudo does not use Touch ID or Apple Watch, or sudo would wait for a fingerprint on the Mac's own screen, which never comes when you are away; and the Command Line Tools are installed (run `xcode-select --install` on the Mac), so that sudo in the web terminal can use the remembered computer password safely. Without them the terminal still works, but sudo says why and does not run.
- The terminal uses your login shell: zsh by default, or the system's bash when your login shell is bash. It does not read start-up files such as `~/.zshrc` or `~/.bash_profile`, so their aliases and functions are not there; the usual paths (including Homebrew's `/opt/homebrew/bin`) are on the PATH, and text is shown as UTF-8.
- The command history is kept only in Agent J's data folder, never in `~/.zsh_history`. Lines that look like a password, key or token, and lines starting with a space, never go into it.
- A Mac has no isolated space like Linux's. The terminal runs as you — not as the Agent, and outside the Agent's fence; the gates above are what protect it.

## Who can use it {#who}

Only devices on the list can open the web terminal. The one chosen at `enable`, or the browser that switched it on for itself, is yours.

When a friend (an engineer, say) helps you, do not hand over your device. Let them pair a browser on their own computer as a remote, with their own Face ID, then allow that remote for a while at the Agent J host:

```bash
agentj terminal allow <device> --hours 2
```

`--hours` takes 1 to 24 (default 2); the permission ends by itself. A device allowed for a while never gets a remembered computer password: it types it on every open. `agentj terminal deny <device>` takes it off the list early. A remote that paired as a phone cannot be allowed.

A **web-version remote** also needs `--allow-web`. On such a device the Web terminal row says it is the web version. The reason: a tampered web page could borrow your Face ID. The confirmation card says so too.

```bash
agentj terminal allow <device> --allow-web
```

## Opening it and the password {#open}

1. In a computer browser, go to Settings → Safety → Web terminal, tap **Open web terminal**, then **Confirm with Face ID**. **Every open needs Face ID**, even if you just used it.
2. The first time on a device (unless Face ID can already fill it in, see [below](#computer-password)), the terminal page asks you to **Type your computer login password** — the password you use to log in to the Agent J host and for sudo. It is encrypted in the browser before it leaves and only the Agent J host can open it; it is never shown or kept on this device. Tap **Send with Face ID**.
3. The host checks it and opens the terminal. The top shows the current folder, the time left and **Recording**.

Wrong passwords: 3 in a row on one device lock it for 15 minutes; 10 within an hour on the whole host lock it for an hour. Every wrong password is a notice on every remote. The computer's own system may count these failures toward its own lockout as well (pam_faillock on Linux, for example), so too many can also lock the computer's normal login for a while.

### How the computer keeps the password {#password-modes}

The computer keeps it in one of three ways; the Settings row says which in plain words:

| Way | What Settings says | When |
|---|---|---|
| Unlocked by your Face ID | Your computer password is stored encrypted; only your Face ID can unlock it. | This device's Face ID (passkey) supports it (preferred) |
| Encrypted on the computer | Your computer password is stored encrypted on the computer; it is used only after your Face ID. | The device does not support the first way, Isolated sandbox is on and Session mode is independent |
| This session only | You type the computer password each time you open it; it is cleared when you finish. | Everything else, and every device allowed for a while |

What each protects against:

- The first two: **they protect against backups, offline copies and the Agent reading the disk directly; they do not protect against a program that can change Agent J's code or your user services.** The stored password is encrypted: a copy or a backup cannot open it, and the Agent reading the file directly sees no plain text. But a program on the same computer that can change Agent J's own code or your user services could catch the password at the moment it is used.
- Encrypted on the computer is allowed only while Isolated sandbox is on and Session mode is independent. The moment you switch isolation off or move to a shared session, that copy is deleted and you type the password again next time.
- This session only: the password stays only in Agent J's memory on the computer and is cleared when the terminal closes; nothing is written to disk.

To make the computer forget the password for this device, tap **Clear on this device** under Settings → Safety → **Computer password**; to delete every remembered copy, run `agentj terminal forget` at the computer. After you change your login password, the old copy is deleted the next time sudo rejects it; type the new one at the next open.

## The computer password: type it once, then Face ID {#computer-password}

The first way above is a small password vault. Your computer password is stored only in encrypted form on the computer, never on a remote. Each device unlocks it with its own Face ID or fingerprint.

- **The first time on a device**, type the password once (in the terminal, or on an admin-command card). After that, Face ID on that device fills it in.
- **Another device:** open Settings → Safety → **Computer password** on it and tap **Use it on this device too**. Confirm with Face ID, then, within 2 minutes, tap **Agree with Face ID** on a device that can already use it. That card shows the new device's name, ID, passkey, pairing date and type: agree only if you know the device. Every remote gets a notice afterwards. You can also simply type the password once on the new device.
- **The Agent's admin-command cards (sudo):** tap **Fill in the computer password with Face ID**. Or tap **Or type the computer password** and tick **Remember it with Face ID (next time, just scan your face)**. The password is used for that one command only; the Agent gets the command's output, not the password. This works on a phone's admin-command cards too.
- A device whose Face ID cannot do this (Settings says so), or a device allowed only for a while, types the password each time.
- If you changed the password, the card says **The remembered computer password no longer works (it may have changed). Type it once.** This does not count as a wrong password.

It protects against the same things as above: **backups, offline copies and the Agent reading the files; not against a program that can change Agent J's code or your user services.**

The **Computer password** row in Settings says whether this device can use it. **Clear on this device** removes only this device's access.

## Typing commands: line mode {#line-mode}

Version 1 is **line mode**: you write a whole line in the browser and tap **Send**; only then does the host run it.

- A line is at most 4096 bytes, with no Tab and no line break. There is no Tab completion.
- There are two control keys only: Ctrl+C (interrupt the running program) and Ctrl+\ (force-quit it). No Ctrl+D, no Ctrl+Z.
- Full-screen programs such as `vim`, `top` or `less` do not work. Use `cat`, `head` or `tail` to read a file.
- Some programs notice they are not writing to a screen and hold their output until a large block is ready, so they look stuck. Put `stdbuf -oL` in front of the command to make it print line by line.
- Error output and normal output arrive together, in order. Colours and other control codes are removed, and anything that looks like a password or key is hidden on the host before it reaches the browser. When output comes too fast, the excess is left out with a note of how many bytes.
- The browser keeps the output in memory only; it is gone when you close the terminal and is never saved on this device.

### Never type passwords into the terminal {#no-passwords}

The web terminal is not a real screen. When a program asks for a password (`ssh`, `git` asking for credentials, `passwd`), it reads the next whole line you send, **as plain text**. So **do not type any password here**. The note under the input box says the same.

`sudo` is the exception: when you use `sudo` in the terminal, the page shows **Allow sudo with Face ID** with the command sudo will really run and the line you typed, and warns you when the two differ. **Allow with Face ID** hands the remembered password to this one sudo; **Don't allow** makes sudo fail, and so does no answer within 60 seconds. The password never appears in a line you send.

A line you send while a program is running goes to that program. The recording keeps only a placeholder for such a line, not its text, and it does not enter the command history.

The web terminal keeps its own command history on the host, readable only by you. A line that starts with a space, a repeat of the line before, and any line that looks like it sets a key or password (such as `TOKEN=…`, `--password=…`, `Bearer …`, `https://user:password@…`) is not kept. The history of your usual terminal is never read or copied in.

### Risky lines are confirmed again {#confirm}

The host looks at every line before it runs. High-risk commands such as deleting files, and lines that start a new shell or interpreter, run a script file, or use `ssh`, `su`, `source` or `eval`, first show **This line needs your OK** with the reason. They run only after you tap **Run** and confirm with Face ID; without that, or after 120 seconds, they do not run. Only the device using the terminal can answer, and no automatic approval applies.

To be honest: **this step only catches slips; it does not stop someone who already holds the session.** A command can be put together across several lines — a variable, a file written and then run — and the host will not always recognise it. What really protects you are the locks before it: switching on takes you in person, the list, Face ID on every open, the time limits and the full recording.

## When it closes by itself {#limits}

The terminal closes, and stops everything still running in it, when:

- the time limit is reached (15 minutes by default; set with `--minutes` when you switch it on at the host, at most 60);
- no line has been sent for 5 minutes;
- the browser has been on another tab or minimised for more than 60 seconds;
- the connection drops;
- you tap Stop everything, or Agent J on the host stops;
- you run `agentj terminal disable` at the host, or take this device off the list with `deny`;
- you tap **End**.

Every remote gets a notice when it opens and when it closes, with the reason and the minutes used. Only one device can use the web terminal at a time.

## Full screen, collapse, copy and screenshot {#full-screen}

The terminal opens full screen: light text on a dark background. When you open it from Settings, you leave Settings and use it full screen in this window. (The page is full screen; full-screen programs such as `vim` still do not work.)

- **Collapse it:** click the ✕ at the top right, press Esc, or drag the handle at the top down. Double-clicking does nothing, so it never disturbs a running program.
- **Collapsing does not end it.** The session keeps running with the same time limits, and a chip above the message box shows **Terminal · N min left**; tap **Open** to go back. A sudo or confirmation card brings the terminal back by itself.
- **Copy output** copies the output on the page.
- **Screenshot to chat** turns the visible output into a picture and puts it in your attachments. It is sent only when you send the message.
- Tap **End** to close it.

## Run a command from the chat with `!` {#bang}

In the message box in a computer browser, type `!` and then the command, for example `!df -h`, and send. It is not sent to Agent J as chat: it runs as one line in the web terminal.

1. If the terminal is not open on this device, you are first asked to open it with Face ID. It then stays collapsed in the background.
2. A result card in the chat shows the output; **Show all** opens long output.
3. The command and its output then go to Agent J, which carries on from there.

Everything above applies: risky lines are confirmed, sudo asks for Face ID, the time limits and the recording stay the same. One `!` command runs at a time. If the output is not finished after 120 seconds, the card shows the output so far.

If the terminal is off or this device is not on the list, a card explains how to switch it on; on a phone, the card says the web terminal can only be used from a computer browser. To send an ordinary message that starts with `!`, put a space before it. `!` works only in the Agent J app and web page, not in Telegram or e-mail.

### What reaches the AI {#what-the-ai-sees}

The output of a `!` command, and what the Agent reads with `agentj terminal output`, go into the Agent's conversation, so they are sent to your AI model provider. Before that, the computer hides more: the value after names such as KEY, TOKEN, SECRET or PASS, the word after `-p` or `--password`, and passwords inside links. The card says how many items it hid, for example **3 items that look like passwords or keys are hidden**.

The hiding is not perfect. It also hides some harmless things (in `mkdir -p dir`, `dir` is hidden), and it can miss a secret in an unusual format. So **do not print passwords or keys in the terminal** (no `cat .env`).

## The recording {#recording}

Every session is recorded: the output, already masked, and each line you sent, masked the same way. The recording stays on the host in Agent J's data folder, readable only by your computer account, and is deleted after 30 days. It is never uploaded anywhere and never goes into a support report. The activity log also notes which device opened and closed it and when, plus the risky lines and sudo calls you confirmed — as fingerprints only, never the command text.

To see the recent log and the recording files at the host:

```bash
agentj terminal logs
```

## It is not a way in when the connection is down {#not-a-fallback}

The web terminal uses the same encrypted connection between the remote and the Agent J host. When that connection is down, the terminal is down too. When a remote cannot reach the host:

- Use Emergency repair on the remote, ① then ②.
- Run `agentj doctor --reconnect` at the host.
- Ask someone at the host to run `curl -fsSL https://agentj.app/rescue | sh`.

See [Phone grey or disconnected?](/docs/reconnect/).

Under Emergency repair → Commands on the Agent J host, each command also gets **Open in terminal** while the terminal is on and this device is on the list: it puts the command into the web terminal, and it runs only when you press Enter.

## Switching it off {#turn-off}

- Switch the whole feature off and delete every remembered password:

```bash
agentj terminal disable
```

- Take one device off the list:

```bash
agentj terminal deny <device>
```

- Delete only the remembered computer passwords and keep the list:

```bash
agentj terminal forget
```

Unpairing a remote, or removing its Face ID, also takes it off the list and deletes its remembered password.

## Borrowing a friend's computer in an emergency {#borrowed-computer}

You cannot carry the Agent J host around, but there is a browser everywhere. When you urgently need a few commands on the host, borrow a computer's browser for a while and unbind it afterwards:

1. **Pair by scanning**: on the borrowed computer, open the remote web page in a browser and let it show its pairing QR code; scan it with your paired phone, check that both 6-digit match codes are the same, and confirm. See [Be scanned](/docs/phone/#be-scanned-the-new-device-shows-a-code-a-paired-phone-scans-it).
2. **Set up Face ID**: tap **Set up Face ID** in that browser. If your friend's computer has no fingerprint reader, follow the browser's prompt to confirm with your phone instead.
3. **Switch on and open**: in that browser go to Settings → Safety → Web terminal, tap **Switch on and open**, confirm with Face ID and type the Agent J host's login password once. See [Switch it on in a computer browser](#enable-browser).
4. **Use it**, and tap **End** when you are done.
5. **Unbind**: on your phone, open **Remotes** and **Unbind** this one. The moment you do, its open web terminal closes and every command still running in it stops; it leaves the list and its remembered computer password is deleted; from then on that browser cannot open the web terminal at all — it would have to be paired again.

Before you hand the computer back, clear this browser's site data for the remote web page, and do not let the browser save the Agent J host's password.

## What the Agent can do {#agent}

The Agent can never type into the terminal, send a line or switch the terminal on. It can do two things:

- **Open it for you with a command filled in.** When you need to run something yourself (a sudo command, say), the Agent can bring up the terminal on your allowed devices that are online (never on a remote that paired as a phone), with the line already in the input box: **Agent J filled in a command. Check it, then press Enter to run it.** A closed terminal still needs your Face ID to open. If you had already typed something, the Agent's line waits in a chip until you tap it. When you send the Agent's line without changing it, the page always asks again, **This command was filled in by the Agent**, with Face ID.
- **Read the output.** Instead of asking you to paste it, the Agent can read the lines and output of the current session, or of the last one for up to 30 minutes after it closed. This is kept only in memory on the host, hidden the same way as in [What reaches the AI](#what-the-ai-sees). A line you type into a running program is not included, and nor is the session of a device allowed only for a while. The terminal page says so: **Agent J can read the output here; passwords and keys are hidden.**

Neither works while the Agent is handling a message that did not come from you (a group, a forwarded message, a friend). If the Agent asks you, through a key card, for your computer login password or sudo password, that request is refused.

More commands and options: [agentj command reference](/docs/cli/). Other remote settings: [User guide](/docs/manual/).
