@haven_ai/connect 0.8.1-alpha.0 → 0.10.0-alpha.0

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
@@ -47,7 +47,40 @@ Do not point it at a project repository, shared folder, or cloud-synced folder.
47
47
 
48
48
  Use `--ack-local-tools` with Haven-generated setup prompts. It prepares the
49
49
  local Haven tools acknowledgement during setup so Codex and Claude Code can load
50
- Haven after a normal restart.
50
+ Haven after a normal restart. It also works with `--repair`: when an upgrade
51
+ changes the signer's tool set, the stored acknowledgement no longer matches and
52
+ the new signer refuses to start — `--repair --ack-local-tools` re-acknowledges
53
+ consent for the signer the repair installs (printing the consent block), with
54
+ no setup token. With a bare `--doctor` the flag is refused: the doctor is
55
+ read-only. The token-free path, without a repair, is the recorded wrapper:
56
+ `<agent dir>/bin/haven-signer.mjs --ack < /dev/null`.
57
+
58
+ ## Updating an agent's own connector (#3799)
59
+
60
+ On a machine with several agents, an agent can update its own pair in one
61
+ command. `--doctor` and `--repair` accept `--name <slug>` and select the agent
62
+ directory by its recorded MCP pair (`haven-<slug>` / `haven-signer-<slug>`) —
63
+ the same rule `--rekey --name` and `--unwire --name` use. An unknown slug is
64
+ refused listing the slugs that exist; two live directories claiming one pair
65
+ are refused listing both; tombstoned directories never match. When several
66
+ agents exist and no `--name` or `--credentials-dir` is given, the multi-agent
67
+ refusal names, per directory, the agent id AND the pair it owns, and offers the
68
+ `--name <slug>` command for named pairs.
69
+
70
+ Two honesty rules worth knowing:
71
+
72
+ - On Claude Code, `--repair` writes no MCP config (the connector does not own
73
+ that runtime's registry). It re-points `<dir>/bin/haven-signer.mjs` at the
74
+ pinned signer runtime, and says exactly that — the entry that launches the
75
+ wrapper uses the new signer after a restart. `--doctor --runtime claude-code`
76
+ names the recorded pair and how to confirm it (`claude mcp get
77
+ haven-signer-<slug>`).
78
+ - When the stored consent does not match the pinned signer's tool set, a bare
79
+ `--repair` stops before writing anything and names the token-free
80
+ re-consent command; `--repair --ack-local-tools` performs the
81
+ re-acknowledgement with the installed signer during the repair. The stored
82
+ ack holds only a hash, so a mismatch is never reported as "the tools grew" —
83
+ a rekey or a chain change produces the same mismatch.
51
84
 
52
85
  ## Supported runtimes
53
86
 
@@ -78,7 +111,9 @@ spending authority.
78
111
  ### `--doctor` reports every agent, not just one (#1697)
79
112
 
80
113
  With several agents wired into one runtime (`--name`), the doctor enumerates
81
- every credential directory on the machine and classifies each one:
114
+ every credential directory on the machine and classifies each one. An agent can
115
+ also select its OWN directory with `--doctor --name <slug>` or
116
+ `--repair --name <slug>` — see [Updating an agent's own connector](#updating-an-agents-own-connector-3799):
82
117
 
83
118
  | Classification | Meaning |
84
119
  | --- | --- |
@@ -109,7 +144,7 @@ report stays `version: 1`; `level` is additive.
109
144
  | Level | Meaning | Example |
110
145
  | --- | --- | --- |
111
146
  | `ok` | Nothing to say. | The installed signer matches the connector's pin. |
112
- | `advisory` | Worth reading; nothing is broken. Exit 0. | `signer_runtime`: the install is intact but behind the pinned version ("intact, but outdated" — both versions named, `--repair` offered); `signer_runtime_unused` (#3123): runtime directories nothing references; `mcp_server_name_rebound` (#3122): two local binding records claim one server name. `superseded_agents` on a recognised runtime with no config file the connector can read (Claude Code, `other`): a second live key is reported, and the check says why "wired" cannot be verified from this machine. |
147
+ | `advisory` | Worth reading; nothing is broken. Exit 0. | `signer_runtime`: the install is intact but behind the pinned version ("intact, but outdated" — both versions named, `--repair` offered); `signer_runtime_unused` (#3123): runtime directories nothing references; `mcp_server_name_rebound` (#3122): two local binding records claim one server name. `superseded_agents` on a recognised runtime with no config file the connector can read (Claude Code, `other`): a second live key is reported, and the check — labelled "Other agent credentials (wiring not verifiable)" — says why "wired" cannot be verified from this machine. On Claude Code a pair named in `~/.claude.json` counts as wired (#3830), so only directories that file does not name reach this advisory, and the inventory row reads "not verified as wired" rather than "superseded"; a directory it upgrades runs the full per-agent checks and can fail the run. |
113
148
  | `failed` | A real failure with one repair action. Exit 1. | A stale or empty runtime directory; a live key in a directory the runtime's config demonstrably does not use. |
114
149
 
115
150
  What stays blocking is live spend authority: a directory whose stored key
@@ -161,8 +196,8 @@ minutes. Two rules follow:
161
196
  stderr log on every probe, and records it in `TOMBSTONE.json` for
162
197
  `--doctor` — with a copy in `~/.haven/tombstones/` (or `.tombstones/` inside
163
198
  a custom credentials root), so the retirement stays visible after the
164
- directory is deleted. It touches no key material and revokes nothing — revoke the
165
- agent on the Haven agent page yourself. Delete the tombstone only once every
199
+ directory is deleted. It touches no key material and revokes nothing — use **Remove
200
+ agent…** (or **Stop budget**) on the Haven agent page yourself. Delete the tombstone only once every
166
201
  long-lived host has been restarted.
167
202
 
168
203
  **Pass a real DIRECTORY, not an agent id.** A named agent lives at its wiring
@@ -219,7 +254,7 @@ backend change) and **refuses to destroy the key material on every answer**:
219
254
 
220
255
  | Probe | What it means | What `--unwire` does |
221
256
  | --- | --- | --- |
222
- | `ok` | The agent is still active: its key still spends. | Refuses; tells you to revoke on the Haven agent page (connect never revokes), then re-run. |
257
+ | `ok` | The agent is still active: its key still spends. | Refuses; tells you to use **Remove agent…** on the Haven agent page (connect never revokes), then re-run. |
223
258
  | `unauthorized` | The key no longer authenticates on normal routes (revoked, archived, paused, pending approval, rotated, or not a key the backend knows — it does not say which). | Refuses; says plainly that a stranded balance **may** exist and the connector **cannot check**; recover first (`haven_sweep_delegate`, or the agent page). |
224
259
  | `network_error` / `bad_response` | Could not verify. | Refuses: unknown is not "safe to delete". Retry. |
225
260
  | *(no stored API key + URL)* | Nothing the recovery routes would accept. | Proceeds, unprobed — the pre-#3123 shape. |
@@ -285,10 +320,10 @@ long-lived host afterwards, as with any retirement.
285
320
 
286
321
  Setup guards the **name slot** (a taken `--name`, the bare pair already wired
287
322
  — #2551 refuses or asks) but never the **wallet**: a machine can carry several
288
- agents with live keys, and until #3122 the "your previous agent(s) still exist
289
- with their own keys" heads-up was printed only after the credentials were
290
- written (that completion heads-up, #1688, is unchanged — this slice ADDS an
291
- earlier notice). Two things changed, both from local files only (no network call is
323
+ agents with live keys, and until #3122 the heads-up naming the other agent
324
+ directories was printed only after the credentials were written (that
325
+ completion heads-up, #1688, still prints — reworded by #3830, see below — and
326
+ this slice ADDS an earlier notice). Two things changed, both from local files only (no network call is
292
327
  added; the backend is not asked whether any key still authenticates):
293
328
 
294
329
  - **Before the key is minted or anything is written**, setup names every
@@ -383,21 +418,29 @@ deployment, so the two differing is intended topology, not an environment
383
418
  mismatch. It is non-secret: the same string goes into your own MCP config file,
384
419
  and the API key travels beside it in a header.
385
420
 
386
- `superseded_agent_ids` lists the other agent directories on this machine. A
387
- re-run mints a NEW agent, and without `--replace` retires nothing, so those
388
- older agents still hold live API and signing keys — revoke them on the Haven
389
- agent page if you meant to replace them. Empty on a clean first run; an empty
390
- list here is not a guarantee, since a scan that cannot read the credential root
391
- also yields one rather than failing a completed setup.
392
-
393
- **The dashboard offers the revoke, never the connector (#2561).** The same ids
394
- now ride the install-status report, so the Haven dashboard can put a
395
- revoke next to the setup that displaced them; it also ends the agent's budget
396
- with one owner signature (#3542). The connector does not
397
- and must not do it: `POST /agents/:id/revoke` is owner-authenticated, and an
398
- agent credential retiring a sibling agent is the "agent editing its own
399
- authority" the re-key routes refuse. Nothing is revoked automatically — the
400
- owner clicks, one agent at a time.
421
+ `superseded_agent_ids` lists the other agent directories on this machine —
422
+ every one, key-less and tombstoned included, on any backend. Despite the field
423
+ name it is **not** a replace set (#3830): since named pairs became the default
424
+ (#3737), a run without `--replace` adds its agent alongside the ones already
425
+ here and retires nothing, so most listed agents are simply other agents, many
426
+ of them wired and in use. Agents a `--replace` run actually retired are
427
+ `retired_agent_ids`. The completion heads-up names the list as "other agent
428
+ directories on this machine" and says this setup revoked none of them; if you
429
+ no longer use one, use **Remove agent…** on its Haven agent page. Empty on a
430
+ clean first run; an empty list here is not a guarantee, since a scan that
431
+ cannot read the credential root also yields one rather than failing a
432
+ completed setup.
433
+
434
+ **The dashboard lists them; revoking stays on each agent's page (#2561,
435
+ #3830).** The same ids ride the install-status report, and the connect modal's
436
+ completed state lists those that are the owner's agents and not revoked
437
+ (active, paused or still in setup), each linking to its agent page. It
438
+ does not call them replaced and offers no revoke there (owner decision,
439
+ 2026-10-09): the report cannot tell a coexisting agent
440
+ from a retired one. The connector never revokes either: `POST
441
+ /agents/:id/revoke` is owner-authenticated, and an agent credential retiring a
442
+ sibling agent is the "agent editing its own authority" the re-key routes
443
+ refuse.
401
444
 
402
445
  On the REPORT the field is a tri-state, unlike the `--json` outcome above: a
403
446
  list, `[]` when the scan ran and found none, and `null` when it could not run.
@@ -411,7 +454,12 @@ untouched — and `superseded_agents_retired_locally` is `true` when that
411
454
  retirement covered every collision entry (`false`: the install ended with an
412
455
  error code and the retirement was skipped, or one entry failed). Both fields
413
456
  are absent on any other run and say nothing about the backend, where nothing is
414
- revoked.
457
+ revoked. Separately, since #3772 a run that retired at least one directory tells
458
+ Haven which ones (`POST /agent-connection-setups/{setupId}/retired-agents`, with
459
+ the new agent's key, `retired_agent_ids` only), so a session still running as a
460
+ retired agent sees a `supersededBy` warning on its own `haven_get_agent` /
461
+ `haven_get_allowances`. That report is best-effort — an older backend's 404 is
462
+ ignored silently and any other failure is one log line — and it still pauses and revokes nothing.
415
463
 
416
464
  A `wiring_collision` refusal (a non-interactive bare setup over a live
417
465
  previous agent, #2551) carries `error.superseded_agent_ids` and
@@ -499,12 +547,24 @@ already-configured machine behaves as follows (characterized in
499
547
  consumed setup when Connect resolves it (or, in a rare concurrent-run race,
500
548
  at registration). The key pair minted for the attempt exists only in memory
501
549
  and is discarded. Start a fresh connection from the Haven dashboard instead.
502
- - **Running a fresh setup on a configured machine** writes the new agent's
503
- credentials into its own directory under `~/.haven/agents/<agent-id>/`,
550
+ - **Running a fresh setup on a configured machine writes the new agent's
551
+ credentials into its own directory under `~/.haven/agents/<slug-or-id>/`,
504
552
  alongside the previous agent's directory, which stays byte-identical.
505
- Nothing is rotated, revoked, or deleted locally.
553
+ Nothing is rotated, revoked, or deleted locally.**
554
+ - **A default setup names its pair from the agent's display name
555
+ ([#3737](https://github.com/d-hinders/Haven-AI/issues/3737)) and never
556
+ collides.** Without `--name`, `--bare` or `--replace`, the connector derives
557
+ the slug itself (`proposeServerSlug`: slugified display name, `agent`
558
+ fallback, numeric suffix when taken) and wires `haven-<slug>` /
559
+ `haven-signer-<slug>` — de-collided against **every** directory under the
560
+ credential root (retired and key-removed ones included, so a slug freed by
561
+ `--unwire` is never reused), and marked `-dev` on a non-production backend
562
+ (Base Sepolia or any chain that is not Base mainnet 8453; an explicit
563
+ `--name` is used verbatim and never altered). Nothing is displaced, so
564
+ nothing is asked. `--bare` opts back into the unnamed pair.
506
565
  - **A bare re-run over a live previous agent is a decision, not a default
507
- ([#2551](https://github.com/d-hinders/Haven-AI/issues/2551)).** Before
566
+ ([#2551](https://github.com/d-hinders/Haven-AI/issues/2551)).** Only a run
567
+ that targets the bare pair — `--bare`, or `--replace` — can collide; before
508
568
  minting a key or registering, Connect scans the credential root for a
509
569
  bare-pair directory that still holds a usable key — the same reading
510
570
  `--doctor` classifies as `wired` or `superseded`; `retired`, `orphaned`,
@@ -521,7 +581,9 @@ already-configured machine behaves as follows (characterized in
521
581
  flag itself. The setup prompt then permits one re-run with the flag the
522
582
  user picks (#3689), on top of `--json` and a `--runtime` retry.
523
583
  - **`--replace`** is the unattended answer "yes, replace". `--name <slug>`
524
- installs alongside. Passing both is a usage error — they contradict.
584
+ installs alongside. `--bare` is the human opt-in to the unnamed pair and
585
+ refuses with `--name`. Passing `--replace --name` is a usage error — they
586
+ contradict.
525
587
  - **Replacing re-points the bare pair, then retires the previous directory
526
588
  locally.** Connect owns the `haven` and `haven-signer` entries (and the
527
589
  managed Codex/Hermes equivalents) and re-points them at the new agent's
@@ -539,8 +601,9 @@ already-configured machine behaves as follows (characterized in
539
601
  [Running several agents in one runtime](#running-several-agents-in-one-runtime).
540
602
  - **The previous agent is not revoked by a re-run — with or without
541
603
  `--replace`.** Local retirement is local: its authority remains whatever
542
- its on-chain rules and the Haven agent page say. Revoke agents you no
543
- longer use from the Haven dashboard. Connect never calls revoke — that
604
+ its on-chain rules and the Haven agent page say. Use **Remove agent…** on
605
+ the Haven agent page for agents you no longer use (or the superseded-agents
606
+ revoke on the setup screen). Connect never calls revoke — that
544
607
  route is owner-authenticated, and an agent credential revoking a sibling
545
608
  agent would be an agent editing its own authority.
546
609
  - **A re-run never overwrites an existing credential file.** A write that would
@@ -567,15 +630,17 @@ As above, `<channel>` is a placeholder like the rest of this line: take the
567
630
  package from the setup response's `connector_package`
568
631
  and add `--name` to the command the dashboard gave you.
569
632
 
570
- | | Without `--name` | With `--name research` |
571
- |---|---|---|
572
- | MCP entries | `haven`, `haven-signer` | `haven-research`, `haven-signer-research` |
573
- | Credentials | `~/.haven/agents/<agent-id>/` | `~/.haven/agents/research/` |
633
+ | | Default (no `--name`) | `--name research` | `--bare` |
634
+ |---|---|---|---|
635
+ | MCP entries | `haven-<slug>`, `haven-signer-<slug>` (slug from the agent's display name, `-dev`-marked on a non-production backend) | `haven-research`, `haven-signer-research` | `haven`, `haven-signer` |
636
+ | Credentials | `~/.haven/agents/<slug>/` | `~/.haven/agents/research/` | `~/.haven/agents/<agent-id>/` |
574
637
 
575
638
  A writer only ever touches the pair it owns, so adding a named agent cannot
576
- disturb the bare pair or another named one. Omitting `--name` is byte-identical
577
- to how the connector behaved before named pairs existed, so nothing already
578
- wired needs changing.
639
+ disturb the bare pair or another named one. **`--bare` wires the bare pair
640
+ byte-identically to how the connector behaved before named pairs existed**, so
641
+ nothing already wired needs changing — it is the one flag (besides
642
+ `--replace`) that reaches the unnamed pair, and it cannot be combined with
643
+ `--name`.
579
644
 
580
645
  The slug is **1–32 lowercase letters, digits and single hyphens**, validated
581
646
  before anything is written, and **immutable once wired** — it is the server name
@@ -615,6 +680,14 @@ npx -y @haven_ai/connect@<channel> --rekey-finish --api-key sk_agent_... \
615
680
  --runtime claude-code [--name research]
616
681
  ```
617
682
 
683
+ **No `--name` needed when exactly one live agent is on the machine.** Since
684
+ [#3737](https://github.com/d-hinders/Haven-AI/issues/3737), `--rekey` without
685
+ `--name` selects the sole agent directory that still holds a stored API key —
686
+ tombstoned and key-removed directories left by `--unwire` do not count — and
687
+ the printed phase-two command carries that agent's exact `--name` when it has
688
+ one. With **several** live agents it refuses and lists them, so you must pass
689
+ `--name <slug>`; a bare agent needs no `--name`, exactly as before.
690
+
618
691
  **Phase one prints the exact phase-two command — prefer it over the line above.**
619
692
  Since [#2423](https://github.com/d-hinders/Haven-AI/issues/2423) the connector
620
693
  builds that command from the npm dist-tag **it** was published under, so a build
@@ -689,11 +762,12 @@ terminal and refuses everywhere else, so a `superseded` directory now means
689
762
  someone chose it — a `--replace` whose install failed, an older connector, or
690
763
  a directory this scan could not classify. A superseded directory
691
764
  whose key is still live is a FAILING check naming the agent id, with the
692
- repair spelled out: revoke it on the Haven agent page, then remove the
693
- directory. An already-revoked one reports as informational; an unreachable
765
+ repair spelled out: use **Remove agent…** on the Haven agent page, then remove
766
+ the directory. An already-revoked one reports as informational; an unreachable
694
767
  probe is a note, never a verdict. Connect never revokes or deletes
695
768
  credentials itself — it reports, you decide. The setup completion output
696
- names superseded agents the moment they are created, for the same reason.
769
+ names the other agent directories the moment the new agent is created, for
770
+ the same reason.
697
771
  One honest limit: "newest" is decided by file mtime, so a restored backup or
698
772
  a sync tool that rewrites timestamps can make doctor examine the wrong
699
773
  directory as current — before revoking anything, confirm the agent id