@cabane/companion 0.6.207 → 0.6.209

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
@@ -1,37 +1,16 @@
1
1
  # cabane
2
2
 
3
- The Cabane Companion runs your Cabane agents on your own device. Install it, paste one setup line, and the agents you assign to this device answer in Cabane while the model, the shell and the files stay on your device. Only the reply crosses back.
3
+ The Cabane Companion runs your Cabane agents on a device you choose. It receives their work from Cabane, starts a harness on the device and streams replies back. The harness calls its configured model provider; agents use the local files, tools and credentials available to their environment.
4
4
 
5
- It drives a **harness** you already have signed in: [Claude Code](https://www.npmjs.com/package/@anthropic-ai/claude-code), [Codex](https://developers.openai.com/codex/cli) or [OpenCode](https://opencode.ai). The Companion never installs a harness and never runs a sign-in; it finds the ones that are usable and reports them.
5
+ It uses **Claude Code**, **Codex** or **OpenCode**. The package includes Claude Code and Codex execution binaries, but setup does not run a vendor CLI installer or sign you in. OpenCode needs its own running server.
6
6
 
7
- Step-by-step guides with screenshots are at [cabane.ai/docs](https://cabane.ai/docs): [Connect your computer](https://cabane.ai/docs/connect-your-computer) to install and pair, [Create an agent](https://cabane.ai/docs/create-an-agent) to give an agent a device, and [When an agent doesn't answer](https://cabane.ai/docs/when-an-agent-doesnt-answer) when one stays silent. This README is the reference for the device side.
7
+ Start with [Introduction to the Companion](https://cabane.ai/docs/what-the-companion-does), then [Mac setup](https://cabane.ai/docs/on-a-mac), [Windows setup](https://cabane.ai/docs/on-windows) or [Server and VPS setup](https://cabane.ai/docs/on-a-server). [FAQ and Help](https://cabane.ai/docs/faq) covers sign-in and troubleshooting. This README is the device-side reference: commands, configuration and local state.
8
8
 
9
- ## The model
10
-
11
- Three things, one relation each.
12
-
13
- - **A device** is a machine running the Companion. It belongs to your account and can be joined to any of your workspaces. Cabane shows it as online, offline or deactivated.
14
- - **A harness** is a coding tool on the device with a login behind it. The Companion detects each one and reports its state: connected, needs sign-in, limited, problem, off or gone. A device offers exactly the harnesses it has.
15
- - **An agent** is assigned to one device and runs through one of that device's harnesses, with a model from it. Assign in as many workspaces as you like: one Companion serves them all.
16
-
17
- **Cabane decides what an agent is; the device decides what it can touch.** Everything about the agent lives on its page in Cabane and is delivered with each turn, so an edit there lands on the next reply with no restart: its charter, its harness and model, its MCP servers and its starting folder. The device holds only what can't travel from a server: the device token, your secrets, and local overrides for this device.
18
-
19
- How a turn runs, top to bottom:
20
-
21
- | Layer | Holds |
22
- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
23
- | **Cabane** | The agent: its charter, harness and model, the folder it starts in and its MCP servers. Who can edit it decides who changes them; an agent never does, and a conversation can't. |
24
- | **Companion** | The listener on the device. Holds the pairing and the harness logins. |
25
- | **Runner** | A child process per turn with a one-turn credential. |
26
- | **Harness** | Claude Code, Codex or OpenCode with its normal tools and your own settings. Nothing asks for permission mid-task. |
27
-
28
- > **An agent on this device reaches the whole device, with no approval prompts.** It runs the device's harness with its tools and the files there, and nothing waits for a click: nobody is at the screen, and approvals would hold the work to a person's pace. For almost everyone, the recommendation is to run the Companion and its harness together in a container or VM; running directly, with the harness's own sandbox set, is the alternative, and that sandbox restricts particular tools (see Isolation). An agent that reads untrusted input (public web, inbound mail, outside members) runs on a Companion that is isolated, whatever the device.
29
-
30
- **No account password or full-account token ever touches the device.** The setup code delivers a device token (`cabdev_…`) good only for pulling this device's assignments and reporting liveness. Each assigned agent gets its own workspace-bound credential, delivered once. Renaming, deactivating, removing a device and rotating its token happen in Cabane.
9
+ Pairing supplies a device token, not your Cabane password or a full-account token. The device token is for this device's assignments and liveness; assigned agents receive workspace-bound credentials. The [trust guide](https://cabane.ai/docs/what-the-companion-does) explains the layers, records and access.
31
10
 
32
11
  ## Install
33
12
 
34
- In a workspace, open **Settings → Devices** and choose **Add a device**. The page mints a setup line with a code in it, good for 15 minutes. Paste it in a terminal on the device. One of:
13
+ In a workspace, open **Settings → Devices** and choose **Set up a new device**. The page mints a setup line with a code in it, good for 15 minutes. Paste it in a terminal on the device. One of:
35
14
 
36
15
  ```sh
37
16
  curl -fsSL https://cabane.ai/install.sh | bash -s -- CODE
@@ -43,7 +22,9 @@ The script brings its own Node (checksum-checked, into `~/.cabane`) and needs no
43
22
  npm i -g @cabane/companion && cabane setup CODE
44
23
  ```
45
24
 
46
- Either way `cabane setup CODE` pairs the device to your account, joins it to that workspace, starts the Companion in the background, waits for its first check-in, and ends with the device's state in Cabane's words. No confirm, no name screen, no browser on the device. The same line on a device that is already paired joins it to the workspace and mints nothing.
25
+ `cabane setup CODE` pairs the device to your account and joins it to that workspace. From an interactive terminal, setup starts the Companion in the background, waits for its first check-in and reports the device's state. Without an interactive terminal, setup can stay attached to the running Companion. The same line on a device that is already paired joins it to the workspace and mints nothing.
26
+
27
+ If no harness is usable, interactive setup asks which one you want to set up. Follow the complete CLI installation and sign-in steps for [Mac setup](https://cabane.ai/docs/on-a-mac#3-sign-in-inside-the-environment), [Windows setup](https://cabane.ai/docs/on-windows#3-sign-in-inside-the-environment) or [Server and VPS setup](https://cabane.ai/docs/on-a-server#3-sign-in-without-a-browser), then check `cabane status`.
47
28
 
48
29
  ```
49
30
  ✓ Paired as "maya-mbp" with Acme.
@@ -60,37 +41,45 @@ Either way `cabane setup CODE` pairs the device to your account, joins it to tha
60
41
  In Cabane: https://app.cabane.ai/acme/settings/devices
61
42
  ```
62
43
 
63
- The device is online the moment the Companion checks in, before any harness is checked; Cabane shows it as **Checking harnesses…** until the first detection lands, then **Ready** or **Needs attention**. With nothing signed in, the device still pairs and the Companion still runs; the rows say which harness needs sign-in. Sign in, and the next check finds it: no restart. A harness that was signed in earlier in this run stays offered through a lapsed login, so a turn reaches the device, fails with the sign-in notice, and the first reply after you sign in again runs with no wait.
64
-
65
- Setup never installs the service. Run `cabane service install` when you want the Companion to start at login and keep itself updated; the closing block names it.
66
-
67
- A fresh device runs nothing yet. In a workspace, open an agent's page and assign it to the device; the Companion picks the assignment up on its next poll.
44
+ Setup never installs the service. On macOS or Linux, run `cabane service install` when you want the Companion to start at login and keep itself updated; the closing block names it. Native Windows uses the background process and has no service installer.
68
45
 
69
46
  If `cabane` isn't found afterwards, open a new terminal, or run the `source` line setup printed.
70
47
 
48
+ The [server guide](https://cabane.ai/docs/on-a-server) provides a Dockerfile and Compose example to build locally. Its Dockerfile installs the Companion and all three command-line tools; you sign in inside the container. Follow that guide for pairing and starting the Docker environment.
49
+
71
50
  ## Commands
72
51
 
73
- | Command | What it does |
74
- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
75
- | `setup [CODE]` | With a code: pair or join, detect harnesses, start. Without: a re-runnable checklist that reports harnesses and starts what isn't running. |
76
- | `start [--foreground]` | Run in the background. Never asks. Unpaired, it names `setup`. `--foreground` stays attached, for a supervisor of your own. |
77
- | `stop` | Stop a running Companion cleanly. Ends any turn in progress. |
78
- | `status` | Version and install, the paired device by its Cabane name, its state in Cabane's words and when it last checked in, each harness's state, where agents work, declared secret names, and local overrides. |
79
- | `update [--auto on\|off]` | Install the version Cabane names now; with `--auto`, set whether the Companion keeps itself up to date. |
80
- | `service install\|uninstall\|status` | Run as a systemd user service or a LaunchAgent that starts at boot and restarts if it stops; remove it; show its state. |
81
- | `logs [-n N] [-f]` | Recent log lines, or follow. |
82
- | `transcript [file] [--last] [-f]` | Read back a full agent turn, tool calls and results included. |
83
- | `logout [--purge]` | Remove the device token and cached agent credentials. Doesn't remove the device from Cabane. |
52
+ | Command | What it does |
53
+ | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
54
+ | `setup [CODE]` | With a code: pair or join, detect harnesses, start. Without: a re-runnable checklist that reports harnesses and starts what isn't running. |
55
+ | `start [--foreground]` | Start the Companion without prompts. From an interactive terminal, run in the background; noninteractive use may stay attached. Unpaired, it names `setup`. `--foreground` stays attached for your supervisor. |
56
+ | `stop` | Stop the Companion cleanly. Ends any turn in progress. |
57
+ | `status` | Version and install, the paired device by its Cabane name, its state in Cabane's words and when it last checked in, each harness's state, where agents work, declared secret names, and local overrides. |
58
+ | `update [--auto on\|off]` | Install the version Cabane names now; with `--auto`, set whether the Companion keeps itself up to date. |
59
+ | `service install\|uninstall\|status` | Run as a systemd user service or a LaunchAgent that starts at login and restarts if it stops; remove it; show its state. |
60
+ | `logs [-n N] [-f]` | Recent log lines, or follow. |
61
+ | `transcript [file] [--last] [-f]` | Read back a full agent turn, tool calls and results included. |
62
+ | `logout [--purge]` | Remove the device token and cached agent credentials. Doesn't remove the device from Cabane. |
84
63
 
85
64
  Anything else about a device is done in Cabane, on the device's page.
86
65
 
87
66
  ## Keeping it running
88
67
 
89
- Without the service, a reboot or a crash leaves the Companion stopped until the next `cabane start`, and the device shows **Offline** in Cabane. Under the service it restarts if it stops, comes back after a reboot, and follows the version Cabane names: it installs the new version under `~/.cabane/versions`, checks it starts, and swaps between turns. A version that can't start is rolled back by the boot guard. `cabane update --auto off` stops updates; without the service, `cabane update` installs and the next `cabane start` runs it.
68
+ For a direct installation, a reboot or a crash leaves the Companion stopped until the next `cabane start` unless you have installed its service. Under the service it restarts if it stops and starts with its user session (at login on macOS; enable linger on Linux for operation after logout), and follows the version Cabane names: it installs the new version under `~/.cabane/versions`, checks it starts, and swaps between turns. A version that can't start is rolled back by the boot guard. `cabane update --auto off` stops updates; without the service, `cabane update` installs and the next `cabane start` runs it.
69
+
70
+ On native Windows, check the background process with `cabane status` and run `cabane start` after a Windows restart. If you installed OpenCode outside Docker, keep its server running separately; the Companion's service does not supervise it.
71
+
72
+ For the Docker example, keep automatic Companion updates off and rebuild the local image to update the Companion and harness tools. Follow the [server guide's update steps](https://cabane.ai/docs/on-a-server#4-keep-it-running-and-update).
90
73
 
91
74
  Other supervisors: run `cabane start --foreground` with `CABANE_COMPANION_SUPERVISED=1` set, using the absolute paths `~/.cabane/node/bin/node` and `~/.cabane/current/dist/bin.js`, which don't move on an update.
92
75
 
93
- A device whose Companion has stopped shows **Offline** in Cabane about two minutes later. Deactivating a device in Cabane stops its Companion; reactivate there, then `cabane start` on the device. After **Rotate token**: `cabane stop`, replace `deviceToken` in `~/.cabane/config.json`, `cabane start`.
76
+ For a direct installation, after **Rotate token** in Cabane, apply the replacement on the device:
77
+
78
+ 1. Run `cabane stop`.
79
+ 2. In `~/.cabane/config.json`, replace `deviceToken` with the replacement token shown by Cabane.
80
+ 3. Run `cabane start`.
81
+
82
+ For Docker, follow [Rotate a Docker device's token](https://cabane.ai/docs/on-a-server#rotate-a-docker-devices-token).
94
83
 
95
84
  ## What's on this device
96
85
 
@@ -121,9 +110,9 @@ A device with no keychain or browser, such as a server or a container, can sign
121
110
  - `prepareHook`: a command that resolves the working directory before each turn; wins over both. A device-level hook applies to every agent that doesn't name its own. The hook gets `CABANE_DEFAULT_CWD`, the directory below, for a hook that only adds to it.
122
111
  - `root`: where agents work when nothing else says. Every agent gets a directory per conversation under it, `<root>/<workspace>/<agent>/<conversation>/`, made on the first turn and never removed by the Companion. Default `~/.cabane/work`; absolute, or `~/…`. An agent with no folder in Cabane, no `cwd` and no hook stands there; a folder or `cwd` that isn't an existing directory is passed over with a line in the log.
123
112
  - `harnesses`: an allowlist such as `["claude-code"]`; absent means all three.
124
- - `claudeCode.autoMemory`: Claude Code's local memory directory is off by default on every Companion, because notes belong in the workspace where others can read them. `true` hands it back.
113
+ - `claudeCode.autoMemory`: Claude Code's local memory directory is off by default in the Companion, because notes belong in the workspace where others can read them. `true` hands it back.
125
114
 
126
- A malformed block fails `cabane start` with the field named. A `runners` block, a row's `sandbox`, or a `prepareHook`'s `validateCached` or `failureReporter` from an older Companion is ignored, with one line in the log naming it.
115
+ A malformed block fails `cabane start` with the field named. A `runners` block, a row's `sandbox`, or a `prepareHook`'s `validateCached` or `failureReporter` from an older version of the Companion is ignored, with one line in the log naming it.
127
116
 
128
117
  Every turn's shell gets `CABANE_CONVERSATION_ID` and `CABANE_AGENT_ID`, so a script an agent runs can tell which conversation and agent it's working for.
129
118
 
@@ -145,28 +134,15 @@ What your command can rely on, and can set:
145
134
  | `CABANE_TRANSCRIPT_DIR` | Set: where the turn writes its transcript. A directory one level under `~/.cabane/transcripts/` lists in `cabane transcript`. |
146
135
  | `CABANE_WORK_ROOT_DEDICATED` | Set to `1` when the root is already this one conversation and agent's: the turn stands in it directly, with no per-conversation directory under it. |
147
136
 
148
- These names are a contract: a Companion that renamed one would break your command, so none changes without a note in the release.
149
-
150
- ### Isolation
151
-
152
- There are no tool approvals. Every agent runs the device's harness with its tools, settings and the files there, and nothing waits for a click: nobody is at the screen, and with the amount of work a person or a team puts through Cabane, approvals would hold it to a person's pace. The Companion approves Claude Code's tools through a hook, similar to `bypassPermissions` (it doesn't set that permission mode), and runs Codex with `approval_policy = "never"`.
153
-
154
- Cabane has no sandbox setting of its own. A harness's own sandbox settings restrict particular tools; they don't isolate the Companion and everything it launches. A container or VM contains the Companion and its child processes.
155
-
156
- So where agents run is your choice, and there are two ways:
157
-
158
- - **The Companion in a container or VM**, recommended for almost everyone: the Companion and the harness together in Docker, OrbStack or a VM, sharing only the folders and credentials they need. Agents keep a full shell to work and code in, still with no approvals, while the container or VM limits what they reach to what you put in, MCP servers, hooks and the harness process included. If you haven't set one up before, ask Claude to help; [Common device patterns](https://cabane.ai/docs/common-device-patterns) walks through one with Docker.
159
- - **Directly on your device**, with the harness's own sandbox set to taste. It restricts particular tools, and each harness draws a different line.
137
+ These names are a contract: changing one would break your command, so none changes without a note in the release.
160
138
 
161
- Running directly, confining agents is set in each harness's own file, and governs your own sessions there as well as every agent on the device:
139
+ ### Harness permissions
162
140
 
163
- - **Claude Code**, `~/.claude/settings.json`: `"sandbox": { "enabled": true, "allowUnsandboxedCommands": false, "failIfUnavailable": true }`. Commands can then write only in the agent's folder, the temp folder and the paths you add, and reach only the hosts you allow; reads stay open unless you deny them, and Claude's own file tools obey permission `deny` rules, not the sandbox. Set `allowUnsandboxedCommands: false`: when a sandboxed command fails the model can retry it unsandboxed, and on a Cabane turn there is nobody to ask, so the retry would be approved. `failIfUnavailable` stops commands running unsandboxed when bubblewrap is missing.
164
- - **Codex**, `~/.codex/config.toml` (or `$CODEX_HOME/config.toml`): set `sandbox_mode` and the Companion passes no sandbox flag, so the file governs; set nothing and turns run `danger-full-access`. `workspace-write` confines writes to the agent's folder, `/tmp` and your `writable_roots`, leaves reads open, turns command network off unless `[sandbox_workspace_write] network_access = true`, and runs each command in its own namespace, so a process it leaves running (a dev server, a background build) stops when the command returns. Docker doesn't work inside it.
165
- - **OpenCode** is your own `opencode serve`.
141
+ The Companion approves Claude Code's tools through a hook and approves OpenCode permission requests; no turn waits for a tool-approval dialog. For Codex it disables approvals and, when your configuration sets a top-level `sandbox_mode`, passes no sandbox flag; without that setting it uses `danger-full-access`. Choose where agents run using [Agent access](https://cabane.ai/docs/how-much-access-agents-get), and configure the tools through [Harness sandboxes](https://cabane.ai/docs/harness-sandboxes).
166
142
 
167
143
  ## Debugging a turn
168
144
 
169
- Cabane shows the reply, not how the agent got there. Every turn writes its full stream to `~/.cabane/transcripts/`: the tool list, every tool call and its result, the text, the outcome. A failed turn's log line names its transcript.
145
+ Cabane shows the conversation; the device also keeps a detailed local record. Every turn writes its full stream to `~/.cabane/transcripts/`: the tool list, every tool call and its result, the text, the outcome. A failed turn's log line names its transcript.
170
146
 
171
147
  ```sh
172
148
  cabane transcript --last # render the most recent turn
@@ -179,4 +155,4 @@ cabane logs -f # follow the log
179
155
 
180
156
  ## Not yet
181
157
 
182
- Windows has no service install and no self-update. There is no per-tool permissioning in Cabane: an agent on a device reaches the whole device, and the harness's own settings are the harness's.
158
+ Native Windows has no service install and no self-update. There is no per-tool permissioning in Cabane. Control agents' access through their environment and the harness's own settings.
package/dist/cli.js CHANGED
@@ -14566,7 +14566,7 @@ var CompanionSupervisor = class {
14566
14566
  this.detectTimer = setInterval(() => void this.detect(), DETECT_INTERVAL_MS);
14567
14567
  this.detectTimer.unref?.();
14568
14568
  if (!this.deviceApi || !this.config.deviceToken) {
14569
- this.log.warn("This device isn't paired. Get a setup line from Settings \u2192 Devices.");
14569
+ this.log.warn("This device isn't paired. Get a setup line from a workspace's Settings \u2192 Devices.");
14570
14570
  return;
14571
14571
  }
14572
14572
  this.deviceSub = new SseSubscriber({
@@ -17169,7 +17169,7 @@ async function logout(opts = {}) {
17169
17169
  return;
17170
17170
  }
17171
17171
  }
17172
- const serverNote = `the device remains registered server-side \u2014 remove it in Cabane (Settings \u2192 Devices) if you want it gone there too.`;
17172
+ const serverNote = `the device remains registered server-side \u2014 remove it in Cabane (Your settings \u2192 Devices) if you want it gone there too.`;
17173
17173
  if (opts.purge) {
17174
17174
  deleteConfig();
17175
17175
  clearCredentials();
package/dist/runtime.js CHANGED
@@ -10179,7 +10179,7 @@ var CompanionSupervisor = class {
10179
10179
  this.detectTimer = setInterval(() => void this.detect(), DETECT_INTERVAL_MS);
10180
10180
  this.detectTimer.unref?.();
10181
10181
  if (!this.deviceApi || !this.config.deviceToken) {
10182
- this.log.warn("This device isn't paired. Get a setup line from Settings \u2192 Devices.");
10182
+ this.log.warn("This device isn't paired. Get a setup line from a workspace's Settings \u2192 Devices.");
10183
10183
  return;
10184
10184
  }
10185
10185
  this.deviceSub = new SseSubscriber({
@@ -61,8 +61,8 @@
61
61
  <h2>Connected workspaces <span id="connected-count" class="count"></span></h2>
62
62
  <ul id="connected-list" class="ws-list"></ul>
63
63
  <p id="connected-empty" class="empty" hidden>
64
- No agents assigned yet. In a workspace, open Settings → Agents and assign an agent to a
65
- connector on this device.
64
+ No agents assigned yet. In a workspace, open an agent's page and choose this device under
65
+ Where they run.
66
66
  </p>
67
67
  </section>
68
68
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cabane/companion",
3
- "version": "0.6.207",
3
+ "version": "0.6.209",
4
4
  "type": "module",
5
5
  "description": "The Cabane Companion (headless): connect an agent on your machine to your Cabane workspace as a responder — drive work against your own codebase, files, and MCP servers without putting any of it in Cabane.",
6
6
  "license": "UNLICENSED",