@primusclaw/connector 0.1.4 → 0.1.5

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.
Files changed (3) hide show
  1. package/README.md +51 -15
  2. package/dist/cli.js +1241 -358
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -41,8 +41,12 @@ If npm answers `EACCES`, point its global prefix at a directory you own (`npm co
41
41
  ```sh
42
42
  claw-connector init # writes agents.toml and prints where: ~/.config/claw-connector/agents.toml unless XDG_CONFIG_HOME or CLAW_CONNECTOR_HOME is set
43
43
  claw-connector status # after you edit it: prints a "problem:" line if the file is wrong
44
+ claw-connector doctor # starts each agent's adapter, opens a session (no prompt) and checks the modes it offers
44
45
  ```
45
46
 
47
+ `init` runs the same check as `doctor` at the end. `doctor` says `ok` for an agent whose phone sessions will open, and otherwise a
48
+ `problem:` line with the fix, for example an agent whose sessions would be refused with `mode_unavailable`.
49
+
46
50
  By default every agent asks before it writes a file or runs a command, and your phone answers each question. To let phone sessions run
47
51
  like your terminal instead, run `claw-connector init --approval never` (or set `approval = "never"` on an agent later); see
48
52
  [Running without per-step approval](#running-without-per-step-approval).
@@ -80,6 +84,8 @@ claw-connector service status
80
84
 
81
85
  This starts the connector now and keeps it up: at login and after a reboot, and again 5 seconds after it dies for any reason, except
82
86
  one that only you can fix (the connector was revoked, or Claw refused the sign-in), which leaves it stopped until you run `login` again.
87
+ Only `claw-connector stop` (or stopping the service) stops it for good: a `kill` of the connector's process from anywhere else ends it
88
+ with exit 75, and it is started again.
83
89
  It uses `systemd --user` on Linux and launchd on macOS. On Linux, run `loginctl enable-linger $USER` once (`service install` says so
84
90
  when it is needed) so it also runs while you are logged out. In a container without systemd, `service install` starts a small
85
91
  supervisor and writes `keepalive.sh`; have the container's startup command and a 5-minute cron job run that script (it does nothing
@@ -136,6 +142,16 @@ Presets and the adapter versions they pin (override `command` and `args` to move
136
142
  | `codex` | `npx @agentclientprotocol/codex-acp@2.3.0` | `read-only` | `read-only` | `agent-full-access` |
137
143
  | `cursor` | `agent acp` (the Cursor CLI) | `ask` | `ask`, `plan` | `agent`, started as `agent --force acp` |
138
144
 
145
+ The pinned adapters (the `npx -y <package>@<version>` presets above) are installed once into the connector's state
146
+ directory (`adapters/<package>@<version>`), by `init`, by `service install` and in the background when `run` starts, and are
147
+ then started from there with the connector's own Node.js: a session does not wait for npx to look the package up in a
148
+ registry (about 70 seconds when the registry cannot be reached) or download it (Claude's adapter takes about 350 MB on
149
+ disk with its dependencies), and a repository's own `.npmrc` cannot pick the registry. The install uses `npm install` with your npm
150
+ settings (`~/.npmrc`, `npm_config_*`, an `npm_config_registry` in the agent's `env`). A session that opens while its
151
+ adapter is still being installed waits for it; if the install failed, the agent's npx command runs as before, in the
152
+ connector's state directory, and the install is tried again in the background ten minutes later. An agent with its own
153
+ `command` or `args` is started exactly as written.
154
+
139
155
  `claude-attach` does not start new conversations: it takes over Claude Code conversations that already exist on this
140
156
  machine (see [Taking over an existing conversation](#taking-over-an-existing-conversation)).
141
157
 
@@ -165,23 +181,20 @@ unattended while Cursor keeps asking. For that agent the connector then:
165
181
  `mode_update` carry `unattended`, so a client can always show whether a session asks. `status` and the line `run` prints
166
182
  at start-up name the agents without per-step approval.
167
183
 
168
- **Before the first phone session, check which way your Claude settings go.** When `permissions.defaultMode` is
169
- `bypassPermissions` in your user `settings.json` (`$CLAUDE_CONFIG_DIR`, else `~/.claude`) or in Claude's managed settings,
170
- every session of a `claude` agent without `approval = "never"` is closed with `mode_not_enforced` (a `claude-attach`
171
- agent accepts the warning while it takes a conversation over, so it is not affected).
172
- `claw-connector status` and the start-up line of `run` say so for each such agent:
173
-
174
- ```
175
- warning: claude: sessions will be refused (mode_not_enforced): Claude defaults to bypassPermissions here (permissions.defaultMode in /home/me/.claude/settings.json); set approval = "never" on this agent or change defaultMode
176
- ```
177
-
178
- Choose one: `approval = "never"` on that agent (knowing the risk below), or another `defaultMode` in that file. The check
179
- reads the two files from which the Claude adapter takes `bypassPermissions` (it ignores that value in a repository's
180
- `.claude/settings.json` and `.claude/settings.local.json`), and only the exact spelling counts, as for the adapter; root
181
- without `IS_SANDBOX` cannot use bypass, and `permissions.disableBypassPermissionsMode = "disable"` turns it off. It applies
182
- to every agent that runs `claude-agent-acp` except `claude-attach`. Codex and Cursor have no equivalent: their own
184
+ **Your own Claude settings may default to `bypassPermissions`** (`permissions.defaultMode` in your user `settings.json`,
185
+ `$CLAUDE_CONFIG_DIR` or `~/.claude`, or in Claude's managed settings). For a `claude` agent that asks (no
186
+ `approval = "never"`), the connector tells the adapter to leave that mode out (`allowDangerouslySkipPermissions: false`),
187
+ so its sessions start in `default` and ask; before 0.1.5 each of them was closed with `mode_not_enforced`. An agent with
188
+ `approval = "never"` runs in `bypassPermissions` either way. A `claude-attach` agent takes over a conversation in the mode
189
+ its terminal chose and accepts the adapter's warning while it starts. Codex and Cursor have no equivalent: their own
183
190
  settings are replaced by the mode the connector sets and reads back.
184
191
 
192
+ **Root.** Claude Code offers `bypassPermissions` to root only when `IS_SANDBOX` is set. For an agent that runs
193
+ `claude-agent-acp` with `approval = "never"` (or `allow_unsafe_modes = true`), the connector sets `IS_SANDBOX=1` in that
194
+ agent's adapter environment when it runs as root, and `run` prints a `note:` line saying so; nothing else gets it. Without
195
+ that, every phone session of such an agent was refused with `mode_unavailable`. To keep it off, set `IS_SANDBOX` yourself
196
+ in the agent's `[agents.env]` (an empty value is kept as it is; `status` then warns that sessions will be refused).
197
+
185
198
  **The risk, in one sentence:** an agent without per-step approval acts on whatever it is told, including text it read in
186
199
  a file or a web page, with everything your account can do inside its roots (and `--force` or full access reach outside the
187
200
  sandbox the adapter would otherwise keep), and nobody is asked first.
@@ -258,6 +271,17 @@ reference, title, directory, last activity, and whether anything holds it open),
258
271
  chat client can offer a choice; `session.new` then names the chosen one (`resume_ref`). Claw and the chat client know no
259
272
  product: the agent's `kind` is the label `attach`.
260
273
 
274
+ **You do not have to add this agent.** Every agent made from the `claude` preset brings one with the same roots, adapter,
275
+ approval and environment, named `<id>-sessions`, so the conversations already on the machine show up on the phone by
276
+ themselves. `existing_sessions = false` on the `claude` agent turns that off; an explicit `claude-attach` agent reading the same
277
+ Claude config directory replaces it.
278
+
279
+ Each entry also says, for a conversation a terminal holds open, what Claude Code says that terminal is doing (`activity`:
280
+ `working`, `waiting` for the person at it, or `idle`; with `waiting`, `waiting_for` in its words, such as "input needed"). The
281
+ connector looks at Claude Code's session registry and projects directory every 10 seconds (file names and times only; nothing
282
+ is started) and reports a change at once instead of at the next heartbeat, so a conversation a terminal has just opened, or one
283
+ that starts waiting, reaches the phone within seconds.
284
+
261
285
  ```toml
262
286
  [[agents]]
263
287
  id = "claude-attach"
@@ -319,6 +343,18 @@ A transcript written within the last 10 seconds is refused too (a terminal that
319
343
  `session_live`, `recently_written` and `twin_check_failed`; the agent that this connector itself started for the conversation
320
344
  is not mistaken for a twin.
321
345
 
346
+ A conversation that a terminal has open when the phone asks for it is not refused but watched, read-only. Nothing is
347
+ started: the connector reads the transcript the terminal writes, from its end (opened read-only; nothing is ever written to it),
348
+ and sends each new line as the update an adapter would have sent (the user's words, the agent's words, the steps it starts
349
+ and how they end; thinking and sub-agents are left out), scrubbed for credentials like every event and marked `read_only`.
350
+ The last twenty updates already there are sent first, marked `replay`. `session_started` says `read_only: true` and
351
+ `read_only_reason: "session_live"`. A prompt, a mode change or a decision sent to it is refused with
352
+ `read_only_live_session` and reaches nothing that could write to the transcript; the server refuses them too
353
+ (`session_read_only`). The heartbeat still reports the conversation as `live`, and an attach agent's capabilities say `watch_live: true`, so a
354
+ client offers the watch only where the connector can do it. When the terminal no longer has it open the
355
+ watch ends (`session_closed`, reason `terminal_closed`), and taking it over is then a new session, through every check
356
+ above. A watched session stays read-only across a restart of the connector.
357
+
322
358
  The ask mode still applies: a conversation keeps the mode it was left in, often one that never asks (`bypassPermissions`),
323
359
  and the adapter says so while it sets the session up. That warning describes the mode that is about to be replaced, so it is
324
360
  set aside until the ask mode (`default`) is locked and read back from the adapter; a warning that comes after that, or a mode