@sailorbridge/client 0.2.4 → 0.2.6

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
@@ -17,6 +17,11 @@ writable and its `bin` directory is on `PATH`. Prefer a user-owned Node install
17
17
  from tools such as nvm/asdf over `sudo npm install -g`. Linux and macOS are the
18
18
  supported targets; Windows packaging support is deferred.
19
19
 
20
+ The host service records the PATH of the shell that installed it, because no
21
+ systemd user unit or launchd agent inherits one. After changing where your tools
22
+ live — an nvm/asdf version switch, a new Homebrew prefix — re-run
23
+ `sailorbridge host service install` so the service picks up the new PATH.
24
+
20
25
  Upgrade an npm-installed client and reload a running managed host daemon in one
21
26
  step:
22
27
 
@@ -80,7 +85,34 @@ sailorbridge login
80
85
  host pairing code, waits for console/mobile approval, writes a 0600 credentials
81
86
  file at `~/.sailorbridge/credentials.json`, and then installs and starts the
82
87
  host service so the console can start workers and agents on this machine without
83
- a second command.
88
+ a second command. A pending pairing is also stored with mode 0600: restarting
89
+ `login` within the 10-minute code lifetime resumes the same code. Transient
90
+ 429/5xx/network failures use capped exponential backoff until that deadline;
91
+ an expired/rejected code or 401/403 fails immediately and tells you to run
92
+ `sailorbridge login` for a new code.
93
+
94
+ Before pairing, `login` asks what the host is for and prints one preflight
95
+ checklist for that answer, so a missing prerequisite surfaces while the user is
96
+ still at the keyboard instead of when their first member fails to start:
97
+
98
+ | Requirement | Dev-pair host | Worker-only host |
99
+ | --- | --- | --- |
100
+ | Node.js >= 20 | required | required |
101
+ | `git` executable | required | not used |
102
+ | tmux | required | not used |
103
+ | `claude` or `codex` CLI, logged in | required (either one) | not used |
104
+
105
+ Pass `--worker-only` (or `SAILORBRIDGE_WORKER_ONLY=1`) to skip the dev-pair
106
+ items; an interactive login asks once, and a non-interactive login checks the
107
+ full dev-pair list. The login preflight checks that git is installed but does
108
+ not inspect the current directory; the repository is named when a team is
109
+ created. Workers advertise `podman`, `git`, `kubectl`,
110
+ `perf` and `bpftrace` as capabilities when present; none are required.
111
+
112
+ A failing item never blocks pairing — the report prints the exact command that
113
+ fixes it. tmux can be installed with consent (the exact command is shown first);
114
+ engine CLIs and their logins are always left to the user, since the credential
115
+ is theirs.
84
116
 
85
117
  Common commands:
86
118
 
@@ -89,10 +121,13 @@ sailorbridge --help
89
121
  sailorbridge login
90
122
  sailorbridge upgrade
91
123
  sailorbridge workflow
92
- sailorbridge mailbox peek "$SAILORBRIDGE_AGENT_NAME"
93
- sailorbridge mailbox ack MESSAGE_ID --lease-token LEASE_TOKEN
124
+ sailorbridge mailbox peek
125
+ sailorbridge mailbox claim
126
+ sailorbridge reply --in-reply-to MESSAGE_ID REPLY --body-file ./reply.txt
127
+ sailorbridge mailbox ack MESSAGE_ID --lease-token-file ./lease-token
94
128
  printf '%s\n' 'hello $USER `date` $(pwd)' | sailorbridge mailbox send --to-agents ab_hand --tag BTW
95
- sailorbridge mailbox send --to-roles reviewer --session ab --tag PLAN-REVIEW --body-file ./plan.txt
129
+ sailorbridge mailbox send --to-roles reviewer --tag PLAN-REVIEW --body-file ./plan.txt
130
+ sailorbridge mailbox send --to-agents captain --tag REPORT --body-file ./report.txt
96
131
  sailorbridge enrollment --session ab --agent ab_hand --roles operator
97
132
  sailorbridge host register
98
133
  sailorbridge host consume --once --dry-run-start
@@ -101,8 +136,8 @@ sailorbridge host service status
101
136
  sailorbridge worker list
102
137
  sailorbridge worker run --worker dev-1 -- uname -s
103
138
  sailorbridge worker job JOB_ID
104
- sailorbridge worker serve --worker dev-1 --workdir "$PWD"
105
- sailorbridge supervise --agent ab_hand --cli codex --cwd "$PWD" --i-own-this-agent
139
+ sailorbridge worker serve
140
+ sailorbridge supervise --cli codex --cwd "$PWD" --i-own-this-agent
106
141
  ```
107
142
 
108
143
  `worker list`, `worker run`, and `worker job` are member-runtime commands;
@@ -132,7 +167,7 @@ The package installs a `sailorbridge` bin after build:
132
167
  ```bash
133
168
  bun run build
134
169
  node dist/src/cli.js workflow
135
- node dist/src/cli.js mailbox peek "$SAILORBRIDGE_AGENT_NAME"
170
+ node dist/src/cli.js mailbox peek
136
171
  ```
137
172
 
138
173
  Build a native standalone binary for the current host:
@@ -164,7 +199,7 @@ SAILORBRIDGE_CAPTAIN_ID=100
164
199
  SAILORBRIDGE_SESSION=session
165
200
  SAILORBRIDGE_HOST_ID=mac
166
201
  SAILORBRIDGE_HOST_DISPLAY_NAME="Mac"
167
- SAILORBRIDGE_HOST_WORKSPACES=~/project-a:~/project-b
202
+ SAILORBRIDGE_HOST_CONFIG_FILE=~/.sailorbridge/host-config.json
168
203
  SAILORBRIDGE_API_URL=https://www.sailorbridge.com
169
204
  SAILORBRIDGE_CREDENTIALS_FILE=~/.sailorbridge/credentials.json
170
205
  SAILORBRIDGE_WORKER_NAME=dev-1
@@ -185,14 +220,42 @@ the token, captain id, and session. Agent routing uses the separate
185
220
  `SAILORBRIDGE_HOST_ID` and `SAILORBRIDGE_HOST_DISPLAY_NAME` identify the
186
221
  captain-scoped local host for Tier 6 console start-request polling. When omitted,
187
222
  host commands default both values from the OS hostname.
188
- `SAILORBRIDGE_HOST_WORKSPACES` is an explicit opt-in inventory list for host
189
- daemon reporting, split by the platform path delimiter (`:` on Linux/macOS). The
190
- daemon reports only those declared git workspaces, including `remote.origin.url`
191
- and the current branch, so the console can queue an isolated clone from that
192
- origin. It does not scan home directories.
193
-
194
- Every 6 hours the host daemon also runs a scratch sweep over each declared
195
- workspace, reaping `<root>/.agent/tmp/` (a git-ignored scratch directory): it
223
+ A host keeps no list of "its" repositories: a repository belongs to a team, and
224
+ its absolute path on the host is named per team (`create ... --repo-path`, or the
225
+ path field in the console's team wizard). The daemon never scans or reports the
226
+ directories on a host.
227
+
228
+ `SAILORBRIDGE_HOST_CONFIG_FILE` redirects the local host config
229
+ (`~/.sailorbridge/host-config.json` by default) that `host account` writes and
230
+ the daemon reads.
231
+
232
+ ## Running members on more than one engine account
233
+
234
+ By default every member on a host uses that host's own engine directory
235
+ (`CLAUDE_CONFIG_DIR`/`CODEX_HOME`, else `~/.claude`/`~/.codex`) — one account,
236
+ zero configuration. To run members on several logins, register each login
237
+ directory under a name of your choosing and point members at it:
238
+
239
+ ```bash
240
+ sailorbridge host account add C1 ~/.claude-accounts/C1
241
+ sailorbridge host account add C2 ~/.claude-accounts/C2
242
+ sailorbridge host account set alice C1
243
+ sailorbridge host account set bob C2
244
+ sailorbridge host account list
245
+ ```
246
+
247
+ `add` refuses a directory that holds no engine credential, so an account nothing
248
+ could start on is rejected while you are still at the keyboard. A member with no
249
+ pointer keeps using the host default directory. Moving a member is
250
+ `host account set MEMBER ACCOUNT` (or `default` to clear it); it takes effect on
251
+ that member's **next start or relaunch**, because the engine reads its credential
252
+ at boot. Members sharing an account share one physical credential file, so a
253
+ token refresh in any of their sessions is visible to all of them. SailorBridge
254
+ stores only the pointer — the credential never enters product storage, logs, or
255
+ the relay, and the console shows the account NAME read-only.
256
+
257
+ Every 6 hours the host daemon also runs a scratch sweep over each member
258
+ worktree it owns, reaping `<root>/.agent/tmp/` (a git-ignored scratch directory): it
196
259
  deletes git-untracked files older than 7 days, then evicts oldest-first until the
197
260
  directory total is under 512 MiB. It only ever touches untracked files inside that
198
261
  directory, never follows symlinks, and skips (with a log) any workspace whose
@@ -226,7 +289,9 @@ status never completes a SailorBridge task lifecycle.
226
289
 
227
290
  `sailorbridge login` creates a host pairing against
228
291
  `https://www.sailorbridge.com`. The command displays the one-time code and
229
- polls until approval. The stored credential contains a host-scoped relay key
292
+ polls until approval. Deploy-time 429/5xx/network interruptions do not replace
293
+ an unexpired code, and restarting the command resumes its pending pairing.
294
+ The stored credential contains a host-scoped relay key
230
295
  (`key_scope: "host"` plus `host_id`) and is used as a fallback when
231
296
  `SAILORBRIDGE_RELAY_URL` or `SAILORBRIDGE_TOKEN` are not set. Worker data
232
297
  commands reject this host-scoped fallback before any relay request. Raw host
@@ -286,6 +351,12 @@ Claude uses `$CLAUDE_CONFIG_DIR/.credentials.json` when set, otherwise
286
351
  `~/.claude/.credentials.json`.
287
352
  The per-agent sandbox links to that single host auth file; missing engine auth
288
353
  fails fast instead of starting a CLI that will prompt for credentials.
354
+ The host daemon also reads the default Claude subscription OAuth credential
355
+ once per day to list provider model metadata. It sends one `GET /v1/models`
356
+ request with a 10-second timeout and no retry, then reports model ids only to
357
+ the relay. The OAuth token stays in the provider request header and never
358
+ enters relay payloads, logs, errors, or argv. API-key-only and Codex-only hosts
359
+ skip this probe; Codex has no machine-readable subscription catalog source.
289
360
 
290
361
  Worker commands implement both sides of the relay worker contract from
291
362
  `engine/PROTOCOL.md`: register, heartbeat, pull, stream upload, result posting,
@@ -298,11 +369,19 @@ non-destructive command. Add `--lease` to a claim only to include rows already
298
369
  leased by this client. A supervisor peek leaves workflow-obligation messages
299
370
  queued and claimable after it surfaces the body-free doorbell. The bound agent's
300
371
  first `mailbox claim` leases them, then the agent completes the required action.
301
- Direct workflow messages are acknowledged with the lease token returned by the
302
- claim. Durable task sources are acknowledged by their successful task
303
- transition, while task terminal replies and `UNPARKED` are auto-acked after
304
- delivery. Ordinary and control messages keep their existing acknowledgement
305
- behavior.
372
+ Plain claims expose every lease token. `HUMAN` and `MAIL` stay leased so
373
+ `reply --in-reply-to` can infer the sender and atomically record the reply plus
374
+ source ACK; untagged peer mail is shown and handled as `MAIL`. If the exact
375
+ source cannot be reclaimed, the CLI identifies whether it is missing, settled,
376
+ addressed to another agent, or a transcript-only row and prints the next action.
377
+ `--no-ack` leaves the source leased. Other direct workflow messages
378
+ retain their manual ACK or durable-transition settlement.
379
+ ACK lease tokens must stay out of argv: store the surfaced token in a private
380
+ file and use `mailbox ack MESSAGE_ID --lease-token-file PATH`, or pipe exactly
381
+ the token to `mailbox ack MESSAGE_ID --lease-token-file -`. Empty input, a TTY,
382
+ duplicate token sources, and piped input unused by a file path are rejected.
383
+ `--lease-token TOKEN` is deprecated for one release and exists only for
384
+ compatibility.
306
385
 
307
386
  Mailbox send is footgun-free by construction: message bodies are read only from
308
387
  piped stdin or `--body-file`, never from positional argv. Every `--body-file` and
@@ -312,8 +391,9 @@ that another selected source would discard is rejected instead of silently
312
391
  ignored; commands without a stdin contract reject it before any relay request.
313
392
  This prevents the local
314
393
  shell from expanding `$VARS`, backticks, or `$()` before the client starts. A
315
- single `--to-agents A` sends directly to that agent even when `--session` is also
316
- present. Multiple explicit agents use the session mailbox endpoint. `--to-agents`
394
+ single `--to-agents A` sends directly to that agent, except reserved `captain`,
395
+ which uses the session transcript endpoint. Multiple explicit agents use the
396
+ session mailbox endpoint. `--to-agents`
317
397
  is mutually exclusive with `--to-roles` and `--to-host`; combine roles and host
318
398
  when filtering registered agents. An empty pipe sends an empty string body; an
319
399
  interactive TTY with no pipe fails fast instead of waiting for typed input.
@@ -341,10 +421,10 @@ interactive pane. Host-started agents use readable session names such as
341
421
  `sb-<team>-<role>` and append the captain number only when that default already
342
422
  exists on the host.
343
423
 
344
- Tmux launch environment is passed through tmux process mechanisms (`-e` and the
345
- child process environment), never as `KEY=value command` text typed into the
346
- pane. That still has the normal short-lived process-list exposure of command
347
- arguments; cleaner secret delivery belongs to a later transport release.
424
+ Tmux launch environment is handed directly to the new pane through a private,
425
+ one-shot FIFO. The pane imports it immediately before `exec`; bearer values
426
+ never enter tmux argv, the tmux environment store, pane input, or a regular
427
+ credential file.
348
428
 
349
429
  SDK drivers are optional implementation code and are release-gated from the
350
430
  public Phase 1 CLI. A base install or tmux-only caller does not need to
@@ -391,6 +471,29 @@ channel must have one owner, otherwise mailbox leases can be stolen. Use
391
471
  `sailorbridge supervise` only for agents not already driven by another
392
472
  listener/supervisor.
393
473
 
474
+ Context auto-checkpoint (tmux transport, claude/codex): the supervisor reads
475
+ the context percentage from the pane every ~20s and, at or above the agent's
476
+ configured `context_checkpoint_percent` (console setting; `0` disables,
477
+ default 75), posts one self-addressed `SAVE-CONTEXT`. The mailbox loop then
478
+ cues the `save_ctx` skill, waits for `SAVE-CONTEXT-DONE`, and replays
479
+ `/clear` plus the `resume_ctx` cue. Threshold changes made in the console
480
+ take effect live through the `reload_context_autopilot` resolve command.
481
+ Semantics match the engine listener's autopilot (same thresholds, same
482
+ armed-below/fire-once water-mark).
483
+
484
+ Idle pre-save (tmux transport, claude by default): the same loop watches for a
485
+ member that has gone quiet. Once the pane is visibly idle and the newest real
486
+ mailbox activity is older than `idle_presave_min` (console setting; `0`
487
+ disables, empty takes the engine default — claude 50 minutes, codex off) but
488
+ still younger than the engine's prompt-cache TTL, the supervisor re-samples pane
489
+ and activity and then posts one `SAVE-CONTEXT` carrying
490
+ `source=listener-idle-presave`. That checkpoint is **ACK-only**: the handoff is
491
+ written, but nothing clears, resumes, or relaunches — a member that merely sat
492
+ idle keeps its live context. One archive per span of activity, a 30-minute
493
+ cooldown after each attempt, and every unknown (capture failure, busy pane,
494
+ missing or future activity timestamps) is a no-op. Tables are pinned against the
495
+ engine listener by `tooling/e2e/idle-presave-parity.test.ts`.
496
+
394
497
  Default transport selection:
395
498
 
396
499
  | CLI | Default transport | Default command |
@@ -448,7 +551,7 @@ message. Persistent relay errors back off instead of spinning.
448
551
  The CLI entrypoint is explicit about ownership:
449
552
 
450
553
  ```bash
451
- sailorbridge supervise --agent A --cli codex --cwd /repo --i-own-this-agent
554
+ sailorbridge supervise --cli codex --cwd /repo --i-own-this-agent
452
555
  ```
453
556
 
454
557
  `--i-own-this-agent` is required as a runtime collision guard. For tmux launches,