@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.
- package/README.md +51 -15
- package/dist/cli.js +1241 -358
- 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
|
-
**
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
`
|
|
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
|