Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions docs/isolation.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,14 @@ A pane starts with your access: its program, an agent included, can read and wri
| Network | What the pane's programs get |
|---|---|
| Open | Your network, as you. |
| Only these providers | Only the hosts and ports that the agents you choose name in their manifests, through a proxy nerd runs for that pane alone. The agent must honour `HTTPS_PROXY`; one that does not gets no network. Agents whose manifests name different ports cannot share a pane. |
| Only these providers | Only the hosts and ports that the agents you choose name in their manifests, through a proxy nerd runs for that pane alone. For pi, **Choose providers…** narrows that to some of its providers. The agent must honour `HTTPS_PROXY`; one that does not gets no network. Agents whose manifests name different ports cannot share a pane. |
| None | No internet and no name lookups. Services on this Mac (`localhost`) stay reachable. |

The hosts in the agents' `plugin.json` are a starting point: check them against what your agent contacts. pi's names every provider pi ships with, except four you add yourself if you use them: Bedrock outside us-east-1 and eu-central-1, Vertex and Azure use addresses of your own account; Cloudflare (`api.cloudflare.com`, `gateway.ai.cloudflare.com`) can fetch any URL for an account token, so it would make the pane's network open. A pane's `~/.pi/agent/*.lock` is writable from every This-folder-only pane: one session can hold another pi session's lock, which only delays that session until the lock is deleted.
The hosts in the agents' `plugin.json` are a starting point: check them against what your agent contacts. pi's names every provider pi ships with, except four you add yourself if you use them: Bedrock outside us-east-1 and eu-central-1, Vertex and Azure use addresses of your own account; Cloudflare (`api.cloudflare.com`, `gateway.ai.cloudflare.com`) can fetch any URL for an account token, so it would make the pane's network open. In a pane set to Only these providers, Bedrock works with keys, not with SSO or profile login.

**Choose providers…** appears under the chips once pi is chosen and lists pi's providers, each with the hosts it opens: `deepseek` opens `api.deepseek.com`, `openai` opens `api.openai.com` and `auth.openai.com`, `github-copilot` opens GitHub's Copilot hosts and `github.com`, which pi also downloads its tools from. **all** is every provider, those added in a later version of pi included; a list of providers stays that list, so a provider added later stays closed. The pane is saved as `pi/deepseek`, one entry per provider; a pane saved before this choice existed is saved as `pi` and keeps every provider. A provider that a later nerd renames or removes stops the pane rather than opening more: it does not start, and the notice names the pane and the provider; the **Isolation** window shows it as no longer in pi's manifest and drops it on save. Only built-in agents name providers; a plugin's or your own agent manifest names its hosts as one list.

A pane's `~/.pi/agent/*.lock` is writable from every This-folder-only pane: one session can hold another pi session's lock, which only delays that session until the lock is deleted.

**This folder only** also keeps one session from planting code or instructions for another. Inside the places it may write, these stay read-only: shell, git and editor startup files, `~/.local/bin` and other folders ahead on `PATH`, agents' settings and memory, Claude Code's task list, Codex's shared databases, Qwen Code's workflow scripts, what agents source or run later from their own folders, and the caches package managers run code from (pnpm, uv, deno, Go, Playwright, Poetry, Yarn, node-gyp, pip, Cypress, SwiftPM, Copilot). When the pane's folder is your home folder, its dot files, `~/Library` and `~/bin` stay read-only too, except `~/Library/Caches` and the agents' session folders; choose a project folder for a real limit. The **Isolation** window lists what stops working.

Expand Down
5 changes: 5 additions & 0 deletions docs/menus.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ Every window except a context menu is drawn through `chrome::dialog`, and `chrom
exact delivery" when the pane's agent delivers through a hook that is not this build's. Then **Isolation…** as
the pane's own tool. **Rename pane…** refuses a name another pane holds and asks keep or drop for a name with
routes or waiting messages from before.
- In the Isolation window, once an agent with providers (pi) is chosen under Only these providers, a line under the
chips says which (`pi: all`, `pi: deepseek, openai`) beside **[Choose providers…]**. It opens the view **Choose
providers** inside the window: a row **all** with its host count, then a row per provider with its hosts. A click
ticks a row (all clears the providers; a provider clears all); **[Enter] done** writes the choice back, **[Esc] back**
returns unchanged; done with nothing ticked stays and says so.
- Tab menu and space menu: **Isolation for new panes…**, with "as the space" or "as nerd's default".
- Settings → Messages: Messaging, Programs in panes may stop or update nerd, Set up a topology…, Accounts…. The
server stores them in policy.json, not in config.json.
Expand Down
2 changes: 1 addition & 1 deletion docs/privacy-and-security.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Each way out starts from something you do or approved, and writes a line to `dae
| <!-- egress:git-fetch --> `git` | You add a plugin, update it or check for updates, or refresh the catalog (**Plugins…**, `nerd --plugin-add`, `--plugin-update`, `--plugin-catalog`). Never in the background. | The public GitHub address shown in the window. | git's own requests for that repository, from a `git` run with none of your git config, no home folder, no credentials and no proxy settings. | `git clone …` |
| <!-- egress:ssh --> `ssh` | You connect to another computer (**Connect to another computer…**, `nerd --remote`). | The host you named in `remotes`, reached through your own `~/.ssh/config`, keys and agent, so a `ProxyJump` there decides the path. | nerd's protocol to the nerd on that machine, including what you type and what its panes print. | `remote: ssh …` |
| <!-- egress:plugin-network --> A plugin with network | A plugin you installed with a network permission runs; approving it at install is what lets it reach the network later. | `"localhost"`: services on this Mac only, and whatever they pass on. Hosts and ports: only those hosts on those ports, through a proxy nerd runs for that plugin alone in a sandbox of its own; the plugin itself reaches only that proxy's port on this Mac's addresses and looks up no name. A name is reached at whatever public address its owner gives it, never this Mac or a network it is on; an IP address in the manifest is reached as written, and one on your local network or this Mac is named so when you are asked. The plugin must honour `HTTPS_PROXY`; plain `http://` does not work. | Anything the plugin can read, the command line and environment of your other programs included (macOS lets any of your processes read those). | `plugin … started: network …`; each connection and refusal as `plugin … proxy: …` |
| <!-- egress:pane-network --> A pane set to Only these providers | You choose **Isolation…** → Network: Only these providers for a pane, and its program starts. | Only the hosts and ports the chosen agents' manifests name, through a proxy nerd runs for that pane alone in a sandbox of its own; the pane's programs reach only that proxy's port on this Mac and look up no names. The agent must honour `HTTPS_PROXY`; one that does not gets no network. | Anything the pane's programs send. | `pane N proxy: …` |
| <!-- egress:pane-network --> A pane set to Only these providers | You choose **Isolation…** → Network: Only these providers for a pane, and its program starts. | Only the chosen agents' or chosen providers' hosts, on the ports their manifests name, through a proxy nerd runs for that pane alone in a sandbox of its own; the pane's programs reach only that proxy's port on this Mac and look up no names. The agent must honour `HTTPS_PROXY`; one that does not gets no network. | Anything the pane's programs send. | `pane N proxy: …` |
| <!-- egress:link --> A link or a file | You open a link in a pane, or a file with **Open in its app**. | `http(s)` in your browser, `mailto:` in your mail app, a file in its app. Files that hold an address of their own (`.webloc`, `.inetloc`, `.url`, `.fileloc`, `.ftploc`, `.afploc`, `.vncloc`, `.mailloc`) are not opened; a page opened in the browser may still load addresses of its own, and a file opened in its app runs as that app does (a `.command` or an app runs code as you). | The address. | `link opened …`, with the host for `http(s)` and only the kind otherwise |
| <!-- egress:clipboard --> The clipboard | You copy. | The macOS clipboard, and through OSC 52 the terminal you run nerd in, which may be on another machine over `ssh`. | The text you copied. | `copied N characters` |
| <!-- egress:agent-inbox --> Claude Code's inbox | A message from another pane, or from you, is delivered to a Claude Code pane whose session reported its inbox socket. | That session's own socket on this Mac, used only after nerd has checked that a process of that pane listens on it. | The message, its first line naming the sender: `[message from <name> via nerd, id <id>; …]`. | `message … via inbox: delivered` |
Expand Down
42 changes: 41 additions & 1 deletion plugins/pi/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,46 @@
"flag": ["--continue", "-c", "--resume", "-r", "--no-session"]
},
"data": ["~/.pi/agent/sessions", "~/.pi/agent/*.lock"],
"network": { "hosts": ["ai-gateway.vercel.sh", "api.ant-ling.com", "api.anthropic.com", "api.business.githubcopilot.com", "api.cerebras.ai", "api.deepseek.com", "api.enterprise.githubcopilot.com", "api.fireworks.ai", "api.github.com", "api.githubcopilot.com", "api.groq.com", "api.individual.githubcopilot.com", "api.kimi.com", "api.meta.ai", "api.minimax.io", "api.minimaxi.com", "api.mistral.ai", "api.moonshot.ai", "api.moonshot.cn", "api.openai.com", "api.together.ai", "api.typesafe.ai", "api.x.ai", "api.xiaomimimo.com", "api.z.ai", "auth.kimi.com", "auth.meta.com", "auth.openai.com", "auth.x.ai", "bedrock-runtime.eu-central-1.amazonaws.com", "bedrock-runtime.us-east-1.amazonaws.com", "chatgpt.com", "claude.ai", "console.anthropic.com", "generativelanguage.googleapis.com", "github.com", "inference.baseten.co", "integrate.api.nvidia.com", "open.bigmodel.cn", "opencode.ai", "openrouter.ai", "platform.claude.com", "radius.pi.dev", "router.huggingface.co", "token-plan-ams.xiaomimimo.com", "token-plan-cn.xiaomimimo.com", "token-plan-sgp.xiaomimimo.com", "token-plan.ap-southeast-1.maas.aliyuncs.com", "token-plan.cn-beijing.maas.aliyuncs.com", "us.openrouter.ai"], "ports": [443] }
"network": {
"providers": {
"amazon-bedrock": ["bedrock-runtime.eu-central-1.amazonaws.com", "bedrock-runtime.us-east-1.amazonaws.com"],
"ant-ling": ["api.ant-ling.com"],
"anthropic": ["api.anthropic.com", "claude.ai", "platform.claude.com"],
"baseten": ["inference.baseten.co"],
"cerebras": ["api.cerebras.ai"],
"deepseek": ["api.deepseek.com"],
"fireworks": ["api.fireworks.ai"],
"github-copilot": ["api.business.githubcopilot.com", "api.enterprise.githubcopilot.com", "api.github.com", "api.individual.githubcopilot.com", "github.com"],
"google": ["generativelanguage.googleapis.com"],
"groq": ["api.groq.com"],
"huggingface": ["router.huggingface.co"],
"kimi-coding": ["api.kimi.com", "auth.kimi.com"],
"meta": ["api.meta.ai", "auth.meta.com"],
"minimax": ["api.minimax.io"],
"minimax-cn": ["api.minimaxi.com"],
"mistral": ["api.mistral.ai"],
"moonshotai": ["api.moonshot.ai"],
"moonshotai-cn": ["api.moonshot.cn"],
"nvidia": ["integrate.api.nvidia.com"],
"openai": ["api.openai.com", "auth.openai.com"],
"openai-codex": ["auth.openai.com", "chatgpt.com"],
"opencode": ["opencode.ai"],
"openrouter": ["openrouter.ai", "us.openrouter.ai"],
"qwen-token-plan": ["token-plan.ap-southeast-1.maas.aliyuncs.com"],
"qwen-token-plan-cn": ["token-plan.cn-beijing.maas.aliyuncs.com"],
"radius": ["radius.pi.dev"],
"together": ["api.together.ai"],
"typesafe": ["api.typesafe.ai"],
"vercel-ai-gateway": ["ai-gateway.vercel.sh"],
"xai": ["api.x.ai", "auth.x.ai"],
"xiaomi": ["api.xiaomimimo.com"],
"xiaomi-token-plan-ams": ["token-plan-ams.xiaomimimo.com"],
"xiaomi-token-plan-cn": ["token-plan-cn.xiaomimimo.com"],
"xiaomi-token-plan-sgp": ["token-plan-sgp.xiaomimimo.com"],
"zai": ["api.z.ai"],
"zai-coding-cn": ["open.bigmodel.cn"]
},
"ports": [443]
}
}
}
Loading
Loading