@cabane/companion 0.6.145 → 0.6.147

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,13 +6,13 @@ The Companion runs your agents through a **harness** on your machine — **[Clau
6
6
 
7
7
  This is **v0**. It's a small CLI — install it from npm with one command, pair the machine once, and run. It talks to Cabane only over Cabane's public API.
8
8
 
9
- **The full story** — why you'd want the Companion, how it works, the privacy and tool-policy model, the diagram — lives at **[app.cabane.ai/docs/reference/connectors](https://app.cabane.ai/docs/reference/connectors)**. This README is the reference for _running_ the Companion.
9
+ **The step-by-step guides** — **Pair a device**, **Create an agent**, **Give an agent host access** — are in Cabane's docs, with screenshots: in Cabane, open the **Account menu** and choose **Docs**. This README is the reference for _running_ the Companion on the machine.
10
10
 
11
11
  ## The model in one paragraph
12
12
 
13
- The Companion runs on a **device you pair**, running **agents you assign to it**. Pair the device once with a short code, then `start` it. From then on it **pulls its assignments from Cabane at runtime** — every agent you've pointed at this device, across all your workspaces — and runs each one locally. Which agents to run, and how they're configured (mode, MCP servers, model), is owned by Cabane and delivered per turn. The machine only holds the bits that _must_ be local: the device token, each agent's working directory, and your secrets.
13
+ The Companion runs on a **device you pair**, running **agents you assign to it**. `cabane-companion start` pairs the device with a short code the first time, then runs. From then on it **pulls its assignments from Cabane at runtime** — every agent you've pointed at this device, across all your workspaces — and runs each one locally. Which agents to run, and how they're configured (host access, MCP servers, model), is owned by Cabane and delivered per turn. The machine only holds the bits that _must_ be local: the device token, your secrets, and any overrides you set for this machine.
14
14
 
15
- > **No account password or full-account token ever touches your machine.** The short-code pairing flow delivers a **device token** (`cabdev_…`) directly to the waiting CLI — good only for pulling this device's assignments and reporting liveness. Each agent the Companion runs gets its own **workspace-bound agent token**, delivered once when the agent is assigned and scoped to that one agent in that one workspace. Deactivating and removing a device — and assigning agents to it — all live in the Cabane app; the CLI only pairs the machine and runs the agents locally.
15
+ > **No account password or full-account token ever touches your machine.** The short-code pairing flow delivers a **device token** (`cabdev_…`) directly to the waiting CLI — good only for pulling this device's assignments and reporting liveness. Each agent the Companion runs gets its own **workspace-bound agent token**, delivered once when the agent is assigned and scoped to that one agent in that one workspace. Renaming, deactivating and removing a device, rotating its token, and assigning agents to it all live in Cabane; the CLI only pairs the machine and runs the agents locally.
16
16
 
17
17
  ## Prerequisites
18
18
 
@@ -34,11 +34,11 @@ Both halves are load-bearing, for different reasons:
34
34
 
35
35
  **Connect it.** Claude Code is an opt-in like the others: accept the offer from `cabane-companion start`, run `cabane-companion connect claude-code`, or add a `claudeCode` block to `~/.cabane/config.json`. A device exposes it only when you have connected it **and** the Agent SDK's bundled binary is installed — that binary arrives as an optional npm dependency, so a companion installed with optional dependencies omitted has none, and will tell you so with the command that fixes it.
36
36
 
37
- **Codex** — log in (`codex login`, or set `CODEX_API_KEY` in Codex's own environment — Cabane never sees the key), then opt in the same way: accept the offer from `cabane-companion start`, run `cabane-companion connect codex`, or add a one-line `codex` block in `~/.cabane/config.json`. As with Claude Code, the turn runs the SDK's own vendored `codex` binary rather than the CLI on your PATH. → [full setup](https://app.cabane.ai/docs/reference/connectors/chatgpt)
37
+ **Codex** — log in (`codex login`, or set `CODEX_API_KEY` in Codex's own environment — Cabane never sees the key), then opt in the same way: accept the offer from `cabane-companion start`, run `cabane-companion connect codex`, or add a one-line `codex` block in `~/.cabane/config.json`. As with Claude Code, the turn runs the SDK's own vendored `codex` binary rather than the CLI on your PATH.
38
38
 
39
- **opencode** — install it, authenticate a provider through its own flow, and start its server (`opencode serve`); the Companion addresses it at the URL you give it. → [full setup](https://app.cabane.ai/docs/reference/connectors/opencode)
39
+ **opencode** — install it, authenticate a provider through its own flow, and start its server and leave it running (`opencode serve --port 4096`). The Companion finds a server on that port by itself; for one anywhere else, connect it with `cabane-companion connect opencode --url <url>`.
40
40
 
41
- You also need **a Cabane account.** A device is registered under your user account; the agents it runs can live in any workspace you have access to.
41
+ You also need **a Cabane account.** A device belongs to your account, not to one workspace: once paired, it is available in every workspace the account is in.
42
42
 
43
43
  ## Install
44
44
 
@@ -50,37 +50,54 @@ That puts `cabane-companion` on your PATH. Confirm it with `cabane-companion --v
50
50
 
51
51
  ## First run
52
52
 
53
- On your machine, start the short-code pairing flow:
53
+ One command sets the machine up:
54
54
 
55
55
  ```sh
56
- cabane-companion pair
57
- # Enter this code at https://app.cabane.ai/settings/companions
58
- #
59
- # ABCD-EFGH
60
- #
61
- # Waiting for you to confirm it in cabane…
56
+ cabane-companion start
62
57
  ```
63
58
 
64
- Open the printed URL, enter the code in **Settings → Connectors**, give the device a label, and confirm. The waiting command receives its device token directly and finishes:
59
+ It names each coding agent it finds and asks whether to make it available in Cabane. Press Enter for yes, or type `n` to leave one out. Then it prints a pairing code and a link, and waits. The code is good for 15 minutes.
65
60
 
66
- ```sh
67
- # ✓ Paired this device "MacBook" with https://app.cabane.ai.
68
- # Run `cabane-companion start` — it will pull the agents assigned to this device and run them.
61
+ ```
62
+ We found Claude Code on this machine (2.1.287). Make it available in Cabane? [Y/n]
63
+ ✓ Claude Code — available once this device is paired.
69
64
 
70
- cabane-companion start
71
- # ✓ Cabane companion is running in the background.
72
- # Stop: cabane-companion stop Logs: cabane-companion logs (~/.cabane/companion.log)
65
+ Now let's pair this machine. Enter this code in Cabane:
66
+
67
+ 4HSP-FPWB
68
+
69
+ or, if Cabane isn’t open:
70
+
71
+ https://app.cabane.ai/pair/enter-code?code=4HSP-FPWB
72
+
73
+ Waiting for you to confirm in Cabane… (the code is good for 15 minutes)
74
+ ```
75
+
76
+ In Cabane, open the **Account menu** at the bottom left and choose **Settings**, then **Devices**, then **Pair a device** and **Enter pairing code**. Type the eight characters and choose **Pair device**. Or open the link from the terminal, which fills the code in. Any browser signed in to the account will do, so a headless machine needs no browser of its own. The device token is delivered straight to the waiting CLI. Nothing is copied or pasted.
77
+
78
+ The terminal finishes by itself:
79
+
80
+ ```
81
+ ✓ Paired to Maya Finch's account.
82
+ ✓ Claude Code connected.
83
+ ✓ Cabane companion is running in the background.
84
+ Stop: cabane-companion stop Logs: cabane-companion logs (~/.cabane/companion.log)
85
+
86
+ ! It won't restart on its own — after a reboot, or if it ever stops,
87
+ just run cabane-companion start again.
88
+
89
+ All set on this side. Finish up in Cabane.
73
90
  ```
74
91
 
75
- A headless machine needs no browser of its own: run `cabane-companion pair` on it, then open **Settings → Connectors** in any browser you're signed in to and enter the short code it printed. The device token is delivered straight to the waiting CLI over the pairing channel — nothing is ever copied or pasted.
92
+ Back in Cabane, **Name this device** asks for a **Device name**, which starts as the machine's hostname and can change later. Choose **Save and continue**. **What Runs on This Device** lists each coding agent on the device as a connector; choose **Continue**. The device is then listed under **Settings → Devices** as **Online**.
76
93
 
77
- A freshly paired device runs nothing yet — it has no agents. In **Workspace settings → Agents**, set an agent's **executor** to this device. The running Companion picks the assignment up within a minute (no restart), and the next time you address that agent — put it on a message's **To** line — the reply comes from your own machine. Assign agents in as many of your workspaces as you like — one running Companion serves them all.
94
+ A freshly paired device runs nothing yet: pairing doesn't put any agent on it. In a workspace, open **Settings**, then **Agents**, choose an agent, and under **Assignment** choose **Assign a device**, pick this device, and choose **Assign device**. Then, under **Execution**, choose its **Connector** and model and choose **Save execution settings**. Until those are saved, the agent's row in the list still says "Not configured". Only the device's own owner can assign an agent to it. The Create an agent guide in Cabane's docs walks these screens. Assign agents in as many workspaces as the account is in: one running Companion serves them all.
78
95
 
79
96
  ## Commands
80
97
 
81
98
  | Command | What it does |
82
99
  | ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
83
- | `pair [--server <url>]` | Pair this device using a short code confirmed in Settings → Connectors. `start` does this automatically when needed. |
100
+ | `pair [--server <url>]` | Pair this device with a short code entered in Cabane, without starting the Companion. `start` does this by itself when the device isn't paired, so `pair` is rarely needed. |
84
101
  | `start [--foreground] [--daemon]` | Pair if needed, offer detected coding harnesses, and run in the background. `--daemon` is an accepted compatibility alias for the default. `--foreground` stays attached for a terminal or external supervisor. A non-interactive `start` also stays attached. |
85
102
  | `connect <claude-code\|codex\|opencode>` | Connect a detected coding harness now or update the running Companion over its control socket. |
86
103
  | `stop` | Stop a foreground or detached Companion cleanly. Idempotent — "nothing running" is a success. |
@@ -90,7 +107,18 @@ A freshly paired device runs nothing yet — it has no agents. In **Workspace se
90
107
  | `logout [-y] [--purge]` | Remove the device token and cached agent credentials. `--purge` removes the whole local config. Neither removes the device from Cabane. |
91
108
  | `--version` / `-V` | Print the Companion version. |
92
109
 
93
- Lifecycle — **register / deactivate / remove** a device, and **assign agents** to it — lives in the Cabane app (Settings → Devices, and each workspace's Agents page), not the CLI.
110
+ Everything else about a device is done in Cabane, not the CLI: **rename**, **deactivate**, **rotate token** and **remove** are on the device's page under the account's **Settings → Devices**, and agents are assigned on each workspace's **Settings → Agents**.
111
+
112
+ ## Managing the device
113
+
114
+ Each of these starts in Cabane, on the device's page, and three of them need a command on the device afterwards.
115
+
116
+ - **After a reboot, or whenever the Companion has stopped**, run `cabane-companion start`. Running it while the Companion is already running changes nothing. In Cabane, a device whose Companion has stopped turns to **Offline** about two minutes later, and back to **Online** once it is up.
117
+ - **Deactivate** turns the device off without removing it. The Companion on the device exits. To bring it back, choose **Reactivate** in Cabane, then run `cabane-companion start` on the device. The Companion's log says to log out and pair again; that isn't needed.
118
+ - **Rotate token** shows a new device token (`cabdev_…`) once, and the old one stops working at once. On the device, run `cabane-companion stop`, replace the value of `deviceToken` in `~/.cabane/config.json` with the new token, then run `cabane-companion start`. Stop first: a Companion that is still running keeps the old token, and `start` does nothing while one is running.
119
+ - **Remove device** can't be undone. The Companion on the device exits. To pair the same machine again, run `cabane-companion logout`, then `cabane-companion start`.
120
+
121
+ If `cabane-companion start` says the Companion is running but the device stays **Offline**, the Companion may have exited straight after starting, which happens when Cabane no longer accepts the device. `cabane-companion status` and `cabane-companion logs` show which.
94
122
 
95
123
  ## Background and supervised operation
96
124
 
@@ -210,36 +238,40 @@ Run `cabane-companion start --foreground`. Configure the supervisor itself for r
210
238
 
211
239
  ## Configuring an agent: what's in Cabane vs. on this machine
212
240
 
213
- There's a deliberate split. **What the agent is** — its mode, MCP servers, model, reasoning, and charter — is configured in **Cabane** (Workspace settings → Agents) and delivered to the Companion per turn, so an edit in Cabane lands on the next turn with **no restart**. The Companion holds only the bits that can't travel from a server: the **working directory** an agent runs in (a path on _this_ machine) and your **secrets**.
241
+ There's a deliberate split. **What the agent is** — its host access, working directory, MCP servers, connector, model and charter — is configured in **Cabane** (a workspace's **Settings → Agents**) and delivered to the Companion per turn, so an edit in Cabane lands on the agent's next reply with **no restart**. One exception: a conversation given Custom execution settings keeps its own connector, model and tuning when the agent's defaults change. The Companion holds only the bits that can't travel from a server: your **secrets**, and machine-local overrides such as a prepare-hook.
214
242
 
215
- An agent can reach MCP servers two ways, and they don't overlap. **The agent's own MCP servers** are part of what the agent is: set on its Agents page, they go with it into every room. **Connections** belong to a person instead: you add one under Workspace settings → Connections (an endpoint and a pasted key, stored encrypted in Cabane), then add it to a room from the room's menu and pick which agents there may use it. On each turn in that room, Cabane attaches the room's connections for that agent and sends the key with the turn, into the harness's environment and never onto its command line. Nothing is configured on this machine. Replacing, disconnecting or deleting a key takes effect on the agent's next turn, and nothing is revoked at the service itself.
243
+ An agent can reach MCP servers two ways, and they don't overlap. **The agent's own MCP servers** are part of what the agent is: set on its Agents page, they go with it into every room. **Connections** belong to a person instead: you add one under a workspace's **Settings → Connections** (an endpoint and a pasted key, stored encrypted in Cabane), then add it to a room from the room's menu and pick which agents there may use it. On each turn in that room, Cabane attaches the room's connections for that agent and sends the key with the turn, into the harness's environment and never onto its command line. Nothing is configured on this machine. Replacing, disconnecting or deleting a key takes effect on the agent's next turn, and nothing is revoked at the service itself.
216
244
 
217
- ### Agent modes (set in Cabane)
245
+ ### Host access (set in Cabane)
218
246
 
219
- `mode` names the agent by what it _is_, not by how locked-down its tools are. You pick it on the workspace Agents page:
247
+ **Host access** is a setting in the agent's **Environment**, on its page under **Settings → Agents**. Only the owner of the agent's device can change it.
220
248
 
221
- | `mode` | What the agent is |
222
- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
223
- | `assistant` | A Cabane assistant — Cabane tools only (read/write workspace files, post messages). Local shell/filesystem tools are off. The cloud-safe default. |
224
- | `coding` | A full coding agent on your machine: all tools available, **with no permission prompts**, in the working directory you set below. **Companion-only.** ⚠️ |
225
- | `custom` | An explicit **allowlist** — Cabane's tools plus exactly the tools you list, and nothing else. |
249
+ | Host access | What the agent can do |
250
+ | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
251
+ | No | Work in the workspace: read and write the workspace's files and take part in conversations. No shell or file tools on the device. The default. |
252
+ | Yes | All of that, plus run shell commands and read and write files on the device, starting in its working directory. ⚠️ |
226
253
 
227
- > ⚠️ **`coding` mode is yolo — there is no permissioning yet.** It runs a coding agent on **your machine, with no approval prompts** — it can run any shell command and edit any file in its working directory. Only assign it where you trust it to operate, and treat it like Claude Code with permissions disabled. A future release adds real per-tool gating. Until then, `assistant` is the safe default.
254
+ > ⚠️ **An agent with host access acts on the device as the user account the Companion runs under, with no approval prompts.** With Claude Code as the connector, it runs every command and writes every file it is asked to, and it isn't restricted to its working directory. Turn it on for an agent whose work needs the device, on a device where that reach is acceptable. The [sandbox](#sandbox-set-on-this-machine) below limits what those tools can touch.
228
255
 
229
- ### Working directory + prepare-hook (set on this machine)
256
+ MCP servers in the agent's Environment don't depend on host access: a stdio server listed there runs on the device and gives the agent its tools either way.
230
257
 
231
- A `coding` agent needs a directory to run in — a path that only exists on your machine, so it lives in `~/.cabane/config.json`, not in Cabane. Add an `agents` map keyed by the agent's id, its `@username`, or `workspace-slug/username` (all three show up in `cabane-companion status`, copy-pasteable):
258
+ ### Working directory + prepare-hook
259
+
260
+ An agent with host access starts in its **Working directory**, set in Cabane in the same **Environment** dialog as host access. Left empty, or naming a folder that isn't on the device, the agent starts in the folder the Companion was started from; a missing folder is reported only in the Companion's log.
261
+
262
+ The machine can override it. A `cwd` in `~/.cabane/config.json` wins over the directory set in Cabane, and a prepare-hook wins over both. Add an `agents` map keyed by the agent's id, its `@username`, or `workspace-slug/username` (all three show up in `cabane-companion status`, copy-pasteable):
232
263
 
233
264
  ```jsonc
234
265
  {
235
- // …device identity, managed by `pair`; don't hand-edit those fields…
266
+ // …device identity, written when the device is paired. The one field to edit by
267
+ // hand is `deviceToken`, after rotating the token in Cabane…
236
268
 
237
269
  // Per-agent machine-local overrides. Only `cwd`, `prepareHook`, `claudeCode` and
238
- // `sandbox` live here — everything else about the agent (mode, MCP servers,
239
- // model) is set in Cabane.
270
+ // `sandbox` live here — everything else about the agent (host access, MCP
271
+ // servers, model) is set in Cabane.
240
272
  "agents": {
241
273
  "my-coding-agent": {
242
- "cwd": "/Users/you/code/project", // working directory the agent runs in
274
+ "cwd": "/Users/you/code/project", // overrides the working directory set in Cabane
243
275
  "prepareHook": { "command": "/Users/you/bin/prepare-turn" }, // optional: resolves the cwd before each turn
244
276
  },
245
277
  },
@@ -263,7 +295,7 @@ The agent's own entry wins when it names a hook; otherwise the device-level one
263
295
 
264
296
  ### Auto-memory (off by default)
265
297
 
266
- Claude Code's **auto-memory** — where the agent writes notes to a local `~/.claude` memory directory and recalls them on later turns — is **off by default** on every Companion. The stance is that memory-shaped things belong in your Cabane workspace (a shared, versioned `ABOUT.md`-style file or doc), not a private local directory that no one else can see. If you run your own Companion and want your normal Claude Code memory workflow back, set `claudeCode.autoMemory: true` on the agent — the Companion then stops overriding it and your own `~/.claude/settings.json` governs auto-memory as usual (this bites in `coding` mode, where your project settings are read):
298
+ Claude Code's **auto-memory** — where the agent writes notes to a local `~/.claude` memory directory and recalls them on later turns — is **off by default** on every Companion. The stance is that memory-shaped things belong in your Cabane workspace (a shared, versioned `ABOUT.md`-style file or doc), not a private local directory that no one else can see. If you run your own Companion and want your normal Claude Code memory workflow back, set `claudeCode.autoMemory: true` on the agent — the Companion then stops overriding it and your own `~/.claude/settings.json` governs auto-memory as usual (this matters for an agent with host access, where your project settings are read):
267
299
 
268
300
  ```jsonc
269
301
  {
@@ -364,25 +396,23 @@ A `gh auth login` session on the machine isn't used: `~/.config/gh` is unreadabl
364
396
 
365
397
  A **harness** is the local tool that runs a model — **[Claude Code](https://www.npmjs.com/package/@anthropic-ai/claude-code)**, **[Codex](https://developers.openai.com/codex/cli)**, or **[opencode](https://opencode.ai)** — together with the credential behind it. A harness connected to Cabane on this device is a **Connector**, and one device runs as many Connectors as it has harnesses. None is privileged: a device advertises exactly the harnesses it actually has.
366
398
 
367
- Which harness a turn uses follows the agent's **model**, set in Cabane (Workspace settings → Agents): a Claude model runs on Claude Code, an OpenAI model on Codex, an opencode model on opencode. A device only offers a harness's models — and only accepts its turns — once that harness is exposed, so set it up first, then pick a matching model for the agent. A turn is never routed to a harness the machine can't run.
399
+ Which harness a turn uses is the agent's **Connector**, chosen in Cabane under **Execution** on the agent's page (**Settings → Agents**), together with a model from that connector. The list holds the connectors on the agent's device, so set the harness up first, then choose it for the agent.
368
400
 
369
401
  What "exposed" means differs per harness, because each is discoverable in a different way. Bring your own install and your own login in all three cases — the Companion never installs a binary and never drives a login:
370
402
 
371
- | Harness | How the device exposes it | Setup |
372
- | --------------- | -------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
373
- | **Claude Code** | A `claudeCode` block in `~/.cabane/config.json`, **and** the Agent SDK's bundled binary installed. | [Claude](https://app.cabane.ai/docs/reference/connectors/claude) |
374
- | **Codex** | A `codex` block in `~/.cabane/config.json`, **and** the Codex SDK's vendored binary installed. | [ChatGPT (Codex)](https://app.cabane.ai/docs/reference/connectors/chatgpt) |
375
- | **opencode** | An `opencode.serverUrl` in `~/.cabane/config.json` pointing at a reachable `opencode serve`. | [opencode](https://app.cabane.ai/docs/reference/connectors/opencode) |
403
+ | Harness | How the device exposes it |
404
+ | --------------- | -------------------------------------------------------------------------------------------------- |
405
+ | **Claude Code** | A `claudeCode` block in `~/.cabane/config.json`, **and** the Agent SDK's bundled binary installed. |
406
+ | **Codex** | A `codex` block in `~/.cabane/config.json`, **and** the Codex SDK's vendored binary installed. |
407
+ | **opencode** | An `opencode.serverUrl` in `~/.cabane/config.json` pointing at a reachable `opencode serve`. |
376
408
 
377
409
  Claude Code and Codex each run a native binary their SDK ships, installed alongside the Companion as an optional npm dependency. Those are what a turn launches — not the `claude` / `codex` CLIs on your PATH, which are for setup and login. If one didn't install, the Companion says so on startup and on the device's page in Cabane, with the command that repairs it: `npm i -g @cabane/companion --include=optional`.
378
410
 
379
- Each harness has a full setup page in the docs — install, login, enable, verify — linked above; this section is just the shape of it and the config the Companion reads.
380
-
381
411
  **You usually don't hand-edit the config.** Interactive `cabane-companion start` offers each detected harness, and `cabane-companion connect codex` (or `claude-code` / `opencode`) can connect one later. Editing `~/.cabane/config.json` yourself is the fallback and what a headless device wants:
382
412
 
383
413
  ```jsonc
384
414
  {
385
- // …device identity, managed by `pair`; don't hand-edit those fields…
415
+ // …device identity, written when the device is paired…
386
416
  "claudeCode": { "enabled": true },
387
417
  "codex": { "enabled": true },
388
418
  "opencode": { "serverUrl": "http://127.0.0.1:4096" },
@@ -453,4 +483,4 @@ It renders the conversation step by step — `🔧 tool(input) → ok/ERROR: res
453
483
 
454
484
  ## What v0 doesn't do yet
455
485
 
456
- There's no OS-service install — an interactive `start` runs detached but doesn't survive logout/reboot or auto-restart on crash. A non-interactive `start` stays attached for a supervisor or provisioner. There's no per-tool permissioning for `coding` mode yet. And there's no self-update; re-run `npm i -g @cabane/companion@latest` to pick up a new version.
486
+ There's no OS-service install — an interactive `start` runs detached but doesn't survive logout/reboot or auto-restart on crash. A non-interactive `start` stays attached for a supervisor or provisioner. There's no per-tool permissioning for an agent with host access yet. And there's no self-update; re-run `npm i -g @cabane/companion@latest` to pick up a new version.