@primusclaw/connector 0.1.1 → 0.1.3
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 +71 -13
- package/dist/cli.js +877 -176
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -71,15 +71,22 @@ CLAW_CONNECTOR_KEY='replace-with-your-claw-api-key' claw-connector login --serve
|
|
|
71
71
|
|
|
72
72
|
The key is stored as it is in `credentials.json` (mode 0600) and is for trying things out; the device sign-in is the normal way.
|
|
73
73
|
|
|
74
|
-
**4.
|
|
74
|
+
**4. Keep it running**
|
|
75
75
|
|
|
76
76
|
```sh
|
|
77
|
-
claw-connector
|
|
77
|
+
claw-connector service install
|
|
78
|
+
claw-connector service status
|
|
78
79
|
```
|
|
79
80
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
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
|
+
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.
|
|
83
|
+
It uses `systemd --user` on Linux and launchd on macOS. On Linux, run `loginctl enable-linger $USER` once (`service install` says so
|
|
84
|
+
when it is needed) so it also runs while you are logged out. In a container without systemd, `service install` starts a small
|
|
85
|
+
supervisor and writes `keepalive.sh`; have the container's startup command and a 5-minute cron job run that script (it does nothing
|
|
86
|
+
when the supervisor is up) so a restarted container comes back by itself. See [Keeping it running](#keeping-it-running).
|
|
87
|
+
|
|
88
|
+
To try it in the foreground instead, `claw-connector run` prints `connecting claude to https://claw.example.com/claw-api as
|
|
89
|
+
"<machine name>"` and stays up until Ctrl-C, which stops it and every agent it started.
|
|
83
90
|
|
|
84
91
|
**5. See it in Clawy**
|
|
85
92
|
|
|
@@ -157,6 +164,23 @@ unattended while Cursor keeps asking. For that agent the connector then:
|
|
|
157
164
|
`mode_update` carry `unattended`, so a client can always show whether a session asks. `status` and the line `run` prints
|
|
158
165
|
at start-up name the agents without per-step approval.
|
|
159
166
|
|
|
167
|
+
**Before the first phone session, check which way your Claude settings go.** When `permissions.defaultMode` is
|
|
168
|
+
`bypassPermissions` in your user `settings.json` (`$CLAUDE_CONFIG_DIR`, else `~/.claude`) or in Claude's managed settings,
|
|
169
|
+
every session of a `claude` agent without `approval = "never"` is closed with `mode_not_enforced` (a `claude-attach`
|
|
170
|
+
agent accepts the warning while it takes a conversation over, so it is not affected).
|
|
171
|
+
`claw-connector status` and the start-up line of `run` say so for each such agent:
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
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
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Choose one: `approval = "never"` on that agent (knowing the risk below), or another `defaultMode` in that file. The check
|
|
178
|
+
reads the two files from which the Claude adapter takes `bypassPermissions` (it ignores that value in a repository's
|
|
179
|
+
`.claude/settings.json` and `.claude/settings.local.json`), and only the exact spelling counts, as for the adapter; root
|
|
180
|
+
without `IS_SANDBOX` cannot use bypass, and `permissions.disableBypassPermissionsMode = "disable"` turns it off. It applies
|
|
181
|
+
to every agent that runs `claude-agent-acp` except `claude-attach`. Codex and Cursor have no equivalent: their own
|
|
182
|
+
settings are replaced by the mode the connector sets and reads back.
|
|
183
|
+
|
|
160
184
|
**The risk, in one sentence:** an agent without per-step approval acts on whatever it is told, including text it read in
|
|
161
185
|
a file or a web page, with everything your account can do inside its roots (and `--force` or full access reach outside the
|
|
162
186
|
sandbox the adapter would otherwise keep), and nobody is asked first.
|
|
@@ -307,8 +331,9 @@ session stops the agent process; it never deletes the conversation.
|
|
|
307
331
|
| `init [--approval ask\|never \| AGENT=ask\|never] [--no-hooks]` | Write a sample `agents.toml`; an existing file is never touched. `--approval never` turns per-step approval off (see above). Also installs the Claude Code session hooks (`--no-hooks` skips that). |
|
|
308
332
|
| `hooks install\|uninstall\|status` | The `SessionStart`/`SessionEnd` hooks alone; `--config-dir DIR` names the Claude config directory (default: those of the `claude-attach` agents, else `$CLAUDE_CONFIG_DIR` or `~/.claude`). |
|
|
309
333
|
| `login` | Device sign-in. `--key <api key>` (or `CLAW_CONNECTOR_KEY`) is for development only. After a revocation, run it again: it connects this machine as a new connector. |
|
|
310
|
-
| `run` | Connect and serve. Exit code
|
|
311
|
-
| `status [--
|
|
334
|
+
| `run [--supervised]` | Connect and serve. Exit code 78 means starting it again will not help: the connector was revoked, Claw or the identity service refused the sign-in (at start, or for two minutes in a row while running), or there is no usable `agents.toml` or sign-in; the reason is kept in `needs-login.json`, and until `login` removes it `run` exits 78 at once without contacting Claw. `--supervised` marks a run the service started. Any other non-zero exit is worth a restart. A unit written by hand for 0.1.2 and older (`RestartPreventExitStatus=3`): replace it with `claw-connector service install`, which writes the same file. |
|
|
335
|
+
| `service install\|uninstall\|status [--supervisor systemd\|launchd\|script] [--env NAME ...]` | Keep `run` up (see [Keeping it running](#keeping-it-running)). `install` stops a `run` started by hand so the service takes over; `status` also lists the last five disconnects and why. |
|
|
336
|
+
| `status [--json]` | Running or not, paused, signed in, agents, adapter processes, the last disconnect and its reason (`last down:`), a `problem:` line when a new sign-in is needed, and a `warning:` line for each agent whose sessions will be refused because Claude's own settings default to `bypassPermissions` (see [Running without per-step approval](#running-without-per-step-approval)). |
|
|
312
337
|
| `pause` / `resume` | Stop every agent within a second and stay offline, or undo that. |
|
|
313
338
|
| `stop` | Stop the running connector and every agent it started. |
|
|
314
339
|
| `logout` | Stop, ask the identity service to revoke the sign-in, delete it from this machine. The stored connector id stays, so the next sign-in reuses the same connector. |
|
|
@@ -325,7 +350,38 @@ the connector sees it within a heartbeat, stops every agent and exits without re
|
|
|
325
350
|
refused). `~/.local/state/claw-connector/` (or `$XDG_STATE_HOME/claw-connector/`): `connector.json` (the connector's identity and the
|
|
326
351
|
commands handled), `sessions.json`, `outbox/` (events not yet acknowledged by Claw), `audit.jsonl` (spawn, directory
|
|
327
352
|
decisions, every command received, every permission request and answer, every automatic approval, mode changes),
|
|
328
|
-
`logs/`, `children.json`, `connector.pid
|
|
353
|
+
`logs/`, `children.json`, `connector.pid`, `disconnects.jsonl`, `needs-login.json` (only after a run that needs a new sign-in), and with
|
|
354
|
+
the script supervisor `supervisor.pid`, `keepalive.sh` and `run.log`. `CLAW_CONNECTOR_HOME=/some/dir` keeps all of it under one directory.
|
|
355
|
+
|
|
356
|
+
## Keeping it running
|
|
357
|
+
|
|
358
|
+
`service install` picks the supervisor (override with `--supervisor`):
|
|
359
|
+
|
|
360
|
+
- **systemd** (Linux, when systemd is the machine's init): `~/.config/systemd/user/claw-connector.service` with `Restart=on-failure`,
|
|
361
|
+
`RestartSec=5`, `RestartPreventExitStatus=78` and no start limit. Logs: `journalctl --user -u claw-connector`.
|
|
362
|
+
- **launchd** (macOS): `~/Library/LaunchAgents/com.primusclaw.connector.plist` (mode 0600) with `KeepAlive` on any unclean exit. launchd cannot
|
|
363
|
+
exempt one exit code, so a run it started exits 0 instead of 78.
|
|
364
|
+
Log: `run.log` in the state directory.
|
|
365
|
+
- **script** (a container without systemd; an `systemctl` that answers "Running in chroot" counts as none): `claw-connector supervise`
|
|
366
|
+
runs in the background and restarts the connector 5 seconds after it dies; `keepalive.sh` in the state directory starts that
|
|
367
|
+
supervisor unless it is alive (recorded pid and start time) or a sign-in is needed. Nothing restarts the supervisor after the container
|
|
368
|
+
restarts, so call `keepalive.sh` from the container's startup command and from a 5-minute cron job. Log: `run.log`.
|
|
369
|
+
|
|
370
|
+
A successful `login` starts an installed service again, so after a revocation or a refused key signing in is the whole fix.
|
|
371
|
+
`keepalive.sh` and the script supervisor start nothing while only a person can help (no `agents.toml`, not signed in,
|
|
372
|
+
`needs-login.json`); under launchd every exit 78 is turned into a clean exit, which launchd does not restart. The service
|
|
373
|
+
installed for a state directory is recorded in its `service.json`.
|
|
374
|
+
|
|
375
|
+
The unit carries `PATH` (so the agents are found), `CLAW_CONNECTOR_HOME`, `XDG_CONFIG_HOME`, `XDG_STATE_HOME`, `CLAUDE_CONFIG_DIR`,
|
|
376
|
+
`CODEX_HOME`, the CA and proxy variables and `LANG` from the shell that ran `install` (a proxy URL with a password in it only when named with `--env`, e.g. `--env HTTPS_PROXY`); `--env NAME` adds another, except a name that looks
|
|
377
|
+
like a credential (`KEY`, `TOKEN`, `SECRET`, `PASSWORD`, `CREDENTIAL`), which is never written into a unit. Run `install` again after
|
|
378
|
+
changing any of them, or after moving Node. With a service installed, `claw-connector stop` stops the connector until the next login,
|
|
379
|
+
boot or keep-alive check; to stay offline use `pause`, or `service uninstall`.
|
|
380
|
+
|
|
381
|
+
**Why it went down.** Every disconnect is appended to `disconnects.jsonl` in the state directory: `server_closed` (a Claw release or
|
|
382
|
+
restart, `superseded` by another run, `token_expired`; reconnected at once), `stream_lost` (the network, with the error), `stopped`,
|
|
383
|
+
`revoked`, `auth_failed`, `failed`, and `process_died` (the previous run never shut down: killed, crashed or the machine restarted;
|
|
384
|
+
dated by its last heartbeat). `status` shows the latest, `service status` the last five.
|
|
329
385
|
|
|
330
386
|
## Restarts and crashes
|
|
331
387
|
|
|
@@ -399,21 +455,23 @@ workflow, fails if the workflow file stops having that shape, or if its environm
|
|
|
399
455
|
|
|
400
456
|
1. Set the new version in `package.json` and `src/version.ts` (`scripts/check-pack.mjs` fails if they disagree) and merge that to `main`.
|
|
401
457
|
2. Write the release notes from the PR descriptions, not from commit subjects: every change states in its PR what a user will now observe.
|
|
402
|
-
For the PRs that touched `connector/` since the previous release (`prev` is
|
|
403
|
-
|
|
458
|
+
For the PRs that touched `connector/` since the previous release (`prev` is the newest `connector-v*` tag, the previous release's;
|
|
459
|
+
`next` is the version merged in step 1, read from `package.json` on `main`):
|
|
404
460
|
```sh
|
|
405
|
-
prev=connector-v0.1.0
|
|
406
461
|
git fetch origin main --tags
|
|
462
|
+
prev=$(git tag --list 'connector-v*' --sort=-version:refname | head -n 1)
|
|
463
|
+
next=$(git show origin/main:connector/package.json | node -p 'JSON.parse(require("fs").readFileSync(0, "utf8")).version')
|
|
464
|
+
[ "$prev" != "connector-v$next" ] || echo "connector-v$next is already released: step 1 is not merged yet" >&2
|
|
407
465
|
for n in $(git log --first-parent --format=%s "$prev"..origin/main -- connector/ | grep -o '(#[0-9]*)$' | tr -d '(#)'); do
|
|
408
466
|
gh pr view "$n" --repo AMD-AGI/PrimusClaw --json number,title,body --jq '"## #\(.number) \(.title)\n\n\(.body)\n"'
|
|
409
467
|
done > notes.md
|
|
410
468
|
```
|
|
411
469
|
Edit `notes.md` into the notes a user of the package wants to read.
|
|
412
470
|
3. Publish the release on the merged commit (not as a pre-release):
|
|
413
|
-
`gh release create connector-
|
|
471
|
+
`gh release create "connector-v$next" --target <sha-on-main> --title "claw-connector $next" --notes-file notes.md`
|
|
414
472
|
4. The `package` job runs and writes a summary: the commit, whether the release workflow at that commit equals the one on `main`, and the
|
|
415
473
|
tarball's name, sha256 and files. A reviewer opens the run, checks that the tagged commit is the reviewed one on `main` and that the
|
|
416
474
|
workflow file is `main`'s (if the summary says it is different, read the diff first), and approves `publish`. The job then attests the
|
|
417
475
|
tarball, attaches it to the release and publishes it.
|
|
418
|
-
5. Check it: `npm view @primusclaw/connector version`, and `gh attestation verify primusclaw-connector
|
|
476
|
+
5. Check it: `npm view @primusclaw/connector version`, and `gh attestation verify "primusclaw-connector-$next.tgz" --repo AMD-AGI/PrimusClaw`
|
|
419
477
|
on the tarball attached to the release.
|