agent-comms 9.0.11 → 9.0.13

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 (172) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +12 -6
  4. package/dist/account-cli.d.ts.map +1 -1
  5. package/dist/account-cli.js +4 -1
  6. package/dist/account-cli.js.map +1 -1
  7. package/dist/bridges/user/web/dist/bundle.js +1 -1
  8. package/dist/bridges/user/web/dist/index.html +1 -7
  9. package/dist/bridges/user/web/dist/mesh-worker.js +4 -4
  10. package/dist/bridges/user/web/dist/sw.js +1 -1
  11. package/dist/bridges/user/web/hosted-dashboard.d.ts +10 -0
  12. package/dist/bridges/user/web/hosted-dashboard.d.ts.map +1 -0
  13. package/dist/bridges/user/web/hosted-dashboard.js +10 -0
  14. package/dist/bridges/user/web/hosted-dashboard.js.map +1 -0
  15. package/dist/bridges/user/web/web-access.d.ts +0 -2
  16. package/dist/bridges/user/web/web-access.d.ts.map +1 -1
  17. package/dist/bridges/user/web/web-access.js +1 -2
  18. package/dist/bridges/user/web/web-access.js.map +1 -1
  19. package/dist/cli-main.d.ts.map +1 -1
  20. package/dist/cli-main.js +9 -12
  21. package/dist/cli-main.js.map +1 -1
  22. package/dist/core/account-bundle.d.ts +1 -1
  23. package/dist/core/account-bundle.d.ts.map +1 -1
  24. package/dist/core/account-bundle.js +26 -19
  25. package/dist/core/account-bundle.js.map +1 -1
  26. package/dist/core/account-join.d.ts.map +1 -1
  27. package/dist/core/account-join.js +5 -2
  28. package/dist/core/account-join.js.map +1 -1
  29. package/dist/core/account-ledger-crypto.d.ts.map +1 -1
  30. package/dist/core/account-ledger-crypto.js +4 -1
  31. package/dist/core/account-ledger-crypto.js.map +1 -1
  32. package/dist/core/account-ledger-store.d.ts +3 -1
  33. package/dist/core/account-ledger-store.d.ts.map +1 -1
  34. package/dist/core/account-ledger-store.js +6 -3
  35. package/dist/core/account-ledger-store.js.map +1 -1
  36. package/dist/core/account-ledger.d.ts +51 -4
  37. package/dist/core/account-ledger.d.ts.map +1 -1
  38. package/dist/core/account-ledger.js +102 -15
  39. package/dist/core/account-ledger.js.map +1 -1
  40. package/dist/core/bridge-mesh.d.ts.map +1 -1
  41. package/dist/core/bridge-mesh.js +3 -0
  42. package/dist/core/bridge-mesh.js.map +1 -1
  43. package/dist/core/bridge.d.ts.map +1 -1
  44. package/dist/core/bridge.js +16 -4
  45. package/dist/core/bridge.js.map +1 -1
  46. package/dist/core/capability-ask.d.ts.map +1 -1
  47. package/dist/core/capability-ask.js +10 -2
  48. package/dist/core/capability-ask.js.map +1 -1
  49. package/dist/core/connection-code-tool.d.ts +1 -1
  50. package/dist/core/connection-code-tool.js +2 -2
  51. package/dist/core/connection-code-tool.js.map +1 -1
  52. package/dist/core/connection-code.d.ts +5 -5
  53. package/dist/core/connection-code.d.ts.map +1 -1
  54. package/dist/core/connection-code.js +22 -6
  55. package/dist/core/connection-code.js.map +1 -1
  56. package/dist/core/device-membership.d.ts +8 -3
  57. package/dist/core/device-membership.d.ts.map +1 -1
  58. package/dist/core/device-membership.js +4 -4
  59. package/dist/core/device-membership.js.map +1 -1
  60. package/dist/core/dm-grant-actions.d.ts.map +1 -1
  61. package/dist/core/dm-grant-actions.js +7 -1
  62. package/dist/core/dm-grant-actions.js.map +1 -1
  63. package/dist/core/error-reporting.d.ts.map +1 -1
  64. package/dist/core/error-reporting.js +5 -0
  65. package/dist/core/error-reporting.js.map +1 -1
  66. package/dist/core/gateway-trust.d.ts +1 -1
  67. package/dist/core/gateway-trust.d.ts.map +1 -1
  68. package/dist/core/gateway-trust.js +4 -4
  69. package/dist/core/gateway-trust.js.map +1 -1
  70. package/dist/core/group-proofs.d.ts.map +1 -1
  71. package/dist/core/group-proofs.js +2 -2
  72. package/dist/core/group-proofs.js.map +1 -1
  73. package/dist/core/identity-store.d.ts +13 -9
  74. package/dist/core/identity-store.d.ts.map +1 -1
  75. package/dist/core/identity-store.js +122 -147
  76. package/dist/core/identity-store.js.map +1 -1
  77. package/dist/core/index.d.ts +1 -0
  78. package/dist/core/index.d.ts.map +1 -1
  79. package/dist/core/index.js +1 -0
  80. package/dist/core/index.js.map +1 -1
  81. package/dist/core/iso-timestamp.d.ts +10 -0
  82. package/dist/core/iso-timestamp.d.ts.map +1 -0
  83. package/dist/core/iso-timestamp.js +19 -0
  84. package/dist/core/iso-timestamp.js.map +1 -0
  85. package/dist/core/issuer-identity-file.d.ts +15 -0
  86. package/dist/core/issuer-identity-file.d.ts.map +1 -1
  87. package/dist/core/issuer-identity-file.js +69 -20
  88. package/dist/core/issuer-identity-file.js.map +1 -1
  89. package/dist/core/machine-identity.d.ts +1 -1
  90. package/dist/core/machine-identity.d.ts.map +1 -1
  91. package/dist/core/machine-identity.js +14 -11
  92. package/dist/core/machine-identity.js.map +1 -1
  93. package/dist/core/mesh-store.d.ts +2 -2
  94. package/dist/core/mesh-store.d.ts.map +1 -1
  95. package/dist/core/mesh-store.js.map +1 -1
  96. package/dist/core/peer-lifecycle.d.ts.map +1 -1
  97. package/dist/core/peer-lifecycle.js +8 -2
  98. package/dist/core/peer-lifecycle.js.map +1 -1
  99. package/dist/core/pid-lock-file.d.ts +27 -4
  100. package/dist/core/pid-lock-file.d.ts.map +1 -1
  101. package/dist/core/pid-lock-file.js +120 -11
  102. package/dist/core/pid-lock-file.js.map +1 -1
  103. package/dist/core/process-start.d.ts +10 -0
  104. package/dist/core/process-start.d.ts.map +1 -0
  105. package/dist/core/process-start.js +43 -0
  106. package/dist/core/process-start.js.map +1 -0
  107. package/dist/core/room-lifecycle.d.ts +3 -2
  108. package/dist/core/room-lifecycle.d.ts.map +1 -1
  109. package/dist/core/room-lifecycle.js +9 -8
  110. package/dist/core/room-lifecycle.js.map +1 -1
  111. package/dist/core/room-protocol.d.ts.map +1 -1
  112. package/dist/core/room-protocol.js +25 -3
  113. package/dist/core/room-protocol.js.map +1 -1
  114. package/dist/core/stale-agent-checker.d.ts.map +1 -1
  115. package/dist/core/stale-agent-checker.js +3 -1
  116. package/dist/core/stale-agent-checker.js.map +1 -1
  117. package/dist/core/store.d.ts +3 -0
  118. package/dist/core/store.d.ts.map +1 -1
  119. package/dist/core/store.js +42 -20
  120. package/dist/core/store.js.map +1 -1
  121. package/dist/core/tool.d.ts +5 -1
  122. package/dist/core/tool.d.ts.map +1 -1
  123. package/dist/core/tool.js +7 -1
  124. package/dist/core/tool.js.map +1 -1
  125. package/dist/core/types.d.ts +1 -1
  126. package/dist/core/types.d.ts.map +1 -1
  127. package/dist/core/types.js +8 -3
  128. package/dist/core/types.js.map +1 -1
  129. package/dist/core/user-identity.d.ts +5 -5
  130. package/dist/core/user-identity.d.ts.map +1 -1
  131. package/dist/core/user-identity.js +59 -45
  132. package/dist/core/user-identity.js.map +1 -1
  133. package/package.json +1 -1
  134. package/src/account-cli.ts +4 -1
  135. package/src/bridges/user/web/dist/bundle.js +1 -1
  136. package/src/bridges/user/web/dist/index.html +1 -7
  137. package/src/bridges/user/web/dist/mesh-worker.js +4 -4
  138. package/src/bridges/user/web/dist/sw.js +1 -1
  139. package/src/bridges/user/web/hosted-dashboard.ts +11 -0
  140. package/src/bridges/user/web/web-access.ts +1 -3
  141. package/src/cli-main.ts +10 -12
  142. package/src/core/account-bundle.ts +36 -25
  143. package/src/core/account-join.ts +5 -2
  144. package/src/core/account-ledger-crypto.ts +4 -1
  145. package/src/core/account-ledger-store.ts +11 -3
  146. package/src/core/account-ledger.ts +142 -20
  147. package/src/core/bridge-mesh.ts +4 -0
  148. package/src/core/bridge.ts +24 -4
  149. package/src/core/capability-ask.ts +16 -1
  150. package/src/core/connection-code-tool.ts +2 -2
  151. package/src/core/connection-code.ts +34 -8
  152. package/src/core/device-membership.ts +12 -8
  153. package/src/core/dm-grant-actions.ts +7 -1
  154. package/src/core/error-reporting.ts +5 -0
  155. package/src/core/gateway-trust.ts +4 -4
  156. package/src/core/group-proofs.ts +5 -2
  157. package/src/core/identity-store.ts +182 -191
  158. package/src/core/index.ts +1 -0
  159. package/src/core/iso-timestamp.ts +21 -0
  160. package/src/core/issuer-identity-file.ts +87 -23
  161. package/src/core/machine-identity.ts +15 -12
  162. package/src/core/mesh-store.ts +2 -1
  163. package/src/core/peer-lifecycle.ts +9 -4
  164. package/src/core/pid-lock-file.ts +139 -11
  165. package/src/core/process-start.ts +45 -0
  166. package/src/core/room-lifecycle.ts +12 -9
  167. package/src/core/room-protocol.ts +23 -3
  168. package/src/core/stale-agent-checker.ts +3 -1
  169. package/src/core/store.ts +48 -23
  170. package/src/core/tool.ts +14 -1
  171. package/src/core/types.ts +9 -3
  172. package/src/core/user-identity.ts +65 -51
@@ -15,7 +15,7 @@
15
15
  "source": "url",
16
16
  "url": "https://github.com/ExaDev/agent-comms.git"
17
17
  },
18
- "version": "9.0.11"
18
+ "version": "9.0.13"
19
19
  }
20
20
  ]
21
21
  }
@@ -17,5 +17,5 @@
17
17
  },
18
18
  "name": "agent-comms",
19
19
  "repository": "https://github.com/ExaDev/agent-comms",
20
- "version": "9.0.11"
20
+ "version": "9.0.13"
21
21
  }
package/README.md CHANGED
@@ -88,7 +88,7 @@ Beacons and probes go to a multicast group joined on the loopback interface (239
88
88
 
89
89
  ### Identity
90
90
 
91
- Each bridge derives its peer ID from the device-id of its own keypair (SHA-256 of the raw public key): ECDSA P-256, self-signed, generated locally. The key material persists per bridge slot (`~/.agent-comms/identity-<harness>--<cwd>.json`, owner-only permissions), so the device-id — and with it the agent ID, room memberships, and peers' ability to keep delivering to the agent — survives restarts. Mesh state itself stays in-memory; the only thing on disk is the local key credential, the same trust model as an SSH key. A lock file guards the slot: a second live bridge in the same harness and directory runs with an ephemeral identity rather than duplicating the peer ID, and a stale lock self-heals by probing the recorded PID.
91
+ Each bridge derives its peer ID from the device-id of its own keypair (SHA-256 of the raw public key): ECDSA P-256, self-signed, generated locally. The key material persists per bridge slot (`~/.agent-comms/identity-<harness>--<cwd>.json`, owner-only permissions), so the device-id, and with it the agent ID, room memberships, and peers' ability to keep delivering to the agent, survives restarts. Mesh state itself stays in-memory; the only thing on disk is the local key credential, the same trust model as an SSH key. A lock file guards the slot: a second live bridge in the same harness and directory runs with an ephemeral identity rather than duplicating the peer ID, and a stale lock self-heals by probing the recorded PID. The tokens an ephemeral bridge holds are bound to its throw-away key, so it keeps them in memory for the life of the process and never reads or writes the slot file. A slot file that exists but cannot be used (damaged, unreadable, or holding a key that cannot be certified again) is never replaced: the bridge stops with an error naming the file and why, and leaves it untouched, since a new key would change the peer ID for everyone who knows it and discard its room and group tokens. Restore the file from a backup, or move it aside to start a new identity.
92
92
 
93
93
  Two more keys sit beside the slot files, each generated locally on first use and never derived from anything about the hardware. `~/.agent-comms/user-identity.json` is the account's user principal, shared by every bridge the account runs on the machine. `~/.agent-comms/machine-identity.json` is the machine, shared by every bridge the account runs on the host. Because it lives in the account's home directory, another OS account on the same host mints a machine key of its own and shows up as a separate machine, and until the principal can span hosts ([#344](https://github.com/ExaDev/agent-comms/issues/344)) the two keys have the same scope; one machine key for every account on a host is tracked in [#367](https://github.com/ExaDev/agent-comms/issues/367). Both are grouping issuers: each bridge gossips a short-lived proof from each that vouches for its device, so a peer can tell whose device it is and which host it runs on. `whoami` shows them as the `Principal:` and `Machine:` lines, and `list_agents` groups agents under the machine that vouches for each, this machine first; an agent no current machine proof places, such as one that predates machine proofs, is listed under "Machine not proven". Moving a machine identity to a rebuilt host is a deliberate copy of its file, the same model as an SSH host key.
94
94
 
@@ -103,7 +103,11 @@ Environment and explicit directories must be absolute paths. Relative paths, lit
103
103
  Library callers can set `dataDir` on `IdentitySlot`, which is also used by the identity loaders and lock helpers:
104
104
 
105
105
  ```ts
106
- const slot = { harness: "my-bridge", cwd: process.cwd(), dataDir: config.dataDir };
106
+ const slot = {
107
+ harness: "my-bridge",
108
+ cwd: process.cwd(),
109
+ dataDir: config.dataDir,
110
+ };
107
111
  const { store, tool } = await createBridgeMesh(slot);
108
112
  ```
109
113
 
@@ -319,6 +323,8 @@ Any bridge that starts a web server (`npx agent-comms chat`, or any other comman
319
323
 
320
324
  A bridge's web server binds the first free TCP port from 19877 to 19886, so several bridges on one machine each get a port of their own in that range, and takes a port the operating system picks only when all ten are taken. The hosted dashboard looks for a bridge on those same ports, which is how it finds one without being told a port. The address a bridge prints, and the `web_url` action returns, is the port it actually holds.
321
325
 
326
+ The dashboard page carries a content security policy (a meta tag, since a static host sets no headers): it denies everything by default, allows script only from its own origin, and allows connections only to its own origin and to `127.0.0.1` and `localhost`. The policy binds the page. The shared worker that holds the bridge connection takes its policy from its own script's response headers, which a static host does not set, so the worker is not bound by it; and a policy in a meta tag cannot forbid the page being framed, which needs a response header. Its service worker answers a page navigation from the network while the host is reachable and from its cache only when the host cannot be reached, so a redirect the host answers is always followed. The origin the hosted dashboard is served from is defined once, in `src/bridges/user/web/hosted-dashboard.ts`.
327
+
322
328
  Two independent transports sit inside that dashboard, both built on [oRPC](https://orpc.unnoq.com/), a contract-first RPC layer with Zod-validated inputs and outputs and native support for streaming procedures:
323
329
 
324
330
  - **Worker ↔ server**, over a real WebSocket at `/ws/mesh`. The worker is an oRPC client here, calling the same contract procedures the REST API exposes, plus a `subscribeEvents` procedure that streams mesh events as they happen.
@@ -543,7 +549,7 @@ ConnectionCode {
543
549
  }
544
550
  ```
545
551
 
546
- `code`/`expiresAt` are the always-checked half: proof that whoever redeems this was on the other end of this exact exchange, recently. `signature` is optional and answers a different question — this claim was made by whoever holds a specific long-lived PGP key. It's checked only when present, and never required: a device with no PGP identity still generates and redeems a bare code.
552
+ `code`/`expiresAt` are the always-checked half: proof that whoever redeems this was on the other end of this exact exchange, recently. `expiresAt` must be an ISO 8601 timestamp, and a code whose expiry does not parse is refused. `signature` is optional and answers a different question: this claim was made by whoever holds a specific long-lived PGP key. A device with no PGP identity still generates and redeems a bare code, but a bare code is a bearer hint, not authentication: redeeming it trusts whatever device-id its text names, whoever wrote it, so it is no way to establish trust in a stranger. A redeemer who supplies a public key or a fingerprint is asking for the issuer to be authenticated, so a code without a signature is then refused.
547
553
 
548
554
  ```
549
555
  # Generate a code vouching for this device, unsigned
@@ -566,7 +572,7 @@ agent_comms({
566
572
  })
567
573
  ```
568
574
 
569
- The fingerprint is never a trust anchor supplied by the keyserver — it's the thing the redeemer already independently trusts (from a business card, a prior verification, wherever), and the redeemer's own check is that the key actually fetched or pasted verifies to that exact fingerprint, not merely that _some_ key was found. Redemption never calls back to whoever generated the code: the whole point is bootstrapping trust before any connection between the two devices exists.
575
+ Supplying `publicKey` or `fingerprint` also requires `signature`: an unsigned code, or a signed one whose signature has been removed, is refused rather than redeemed without the check. The fingerprint is never a trust anchor supplied by the keyserver: it's the thing the redeemer already independently trusts (from a business card, a prior verification, wherever), and the redeemer's own check is that the key actually fetched or pasted verifies to that exact fingerprint, not merely that _some_ key was found. Redemption never calls back to whoever generated the code: the whole point is bootstrapping trust before any connection between the two devices exists.
570
576
 
571
577
  ### One account on several machines
572
578
 
@@ -583,7 +589,7 @@ npx agent-comms account join # on the new machine; paste the invite at the p
583
589
 
584
590
  Both are commands you run, not `agent_comms` tool actions: an invite is the account key to whoever redeems it first, and a join replaces the account the machine holds, so nothing an agent is told can do either, and the invite is printed only to your terminal, never into an agent's transcript. `join` reads the invite at a prompt that does not echo, so it stays out of shell history.
585
591
 
586
- `account invite` runs a store of its own and keeps it up until the invite is redeemed or expires, since the issuing device keeps invites only in memory and answers each one once and never after it expires. An invite is valid for as long as a connection code, and can be made shorter with `--ttl-minutes <n>` but not longer. Redeeming it trusts the issuing device, exactly as `gateway_redeem_connection_code` does, then asks that device for the account key over the mesh's end-to-end authenticated request path, directly or relayed by the hub; the key comes back sealed under a key derived from the invite, which only its holder can open. A join the issuing device refuses or never answers withdraws that trust again, so a failed join leaves the new machine trusting no one it did not trust before. An invite can be PGP-signed with `--sign-key <armored private key file>`, and a signed one is checked on `join` against `--public-key <file>`, pinned to `--fingerprint <hex>` when you give one. Issuing an invite also trusts your own principal on the issuing machine, and joining trusts it on the new one, so the two list each other's devices from then on. The account the new machine held before is kept beside it as `user-identity.replaced-<id>.json`, since its key is still the only one that can revoke what it issued, and the machine's running bridges pick up the account when they restart.
592
+ `account invite` runs a store of its own and keeps it up until the invite is redeemed or expires, since the issuing device keeps invites only in memory and answers each one once and never after it expires. An invite is valid for as long as a connection code, and can be made shorter with `--ttl-minutes <n>` but not longer. Redeeming it trusts the issuing device, exactly as `gateway_redeem_connection_code` does, then asks that device for the account key over the mesh's end-to-end authenticated request path, directly or relayed by the hub; the key comes back sealed under a key derived from the invite, which only its holder can open. A join the issuing device refuses or never answers withdraws that trust again, so a failed join leaves the new machine trusting no one it did not trust before. An invite can be PGP-signed with `--sign-key <armored private key file>`, and a signed one is checked on `join` against `--public-key <file>`, pinned to `--fingerprint <hex>` when you give one. Giving either on `join` refuses an unsigned invite. An unsigned invite is a bearer hint: the joining machine trusts whatever device it names, so carry it only over a channel you trust. Issuing an invite also trusts your own principal on the issuing machine, and joining trusts it on the new one, so the two list each other's devices from then on. The account the new machine held before is kept beside it as `user-identity.replaced-<id>.json`, since its key is still the only one that can revoke what it issued, and the machine's running bridges pick up the account when they restart.
587
593
 
588
594
  To copy the account without the mesh, export it to a passphrase-sealed file and import that on the other machine. The key is never printed; the passphrase is read from `AGENT_COMMS_ACCOUNT_PASSPHRASE` or asked for without echo, and the file is written owner-only and never over an existing one:
589
595
 
@@ -594,4 +600,4 @@ npx agent-comms account import ~/account.bundle # on the other machine, then d
594
600
 
595
601
  Copy the account this way or by joining, never by copying `~/.agent-comms` between machines: each machine keeps a writer id of its own for the grant ledger below, and two machines sharing one would corrupt it.
596
602
 
597
- Every grant your account issues, and every revocation of one, is recorded in a replicated ledger rather than on the machine that minted it: each machine appends to a data-domain log of its own (wire-mesh's replicated issuer grant ledger pattern, `spec/PATTERNS.md`), and the logs replicate to every machine holding the account, so `dm_revoke` on any of them finds and revokes a grant another one issued. Entries are sealed under a key derived from the account key, so a device that stores or relays them without holding the account sees only ciphertext, and writing to the ledger still needs the account's private key. The ledger replicates over direct peer connections (the local mesh, or machines that reach each other directly) and between machines that meet only through the relay hub, over a relay pairing sealed end to end between the two devices so the hub carries ciphertext; either way a log is offered only to a device whose membership proof names this account, and a hub-reachable device of any other account is never offered it. A revocation itself is also announced to every connected peer the moment it is made. Grants a build before the ledger recorded in `user-identity.json` are moved into it the first time a bridge starts, with nothing to do by hand.
603
+ Every grant your account issues, and every revocation of one, is recorded in a replicated ledger rather than on the machine that minted it: each machine appends to a data-domain log of its own (wire-mesh's replicated issuer grant ledger pattern, `spec/PATTERNS.md`), and the logs replicate to every machine holding the account, so `dm_revoke` on any of them finds and revokes a grant another one issued. Entries are sealed under a key derived from the account key, so a device that stores or relays them without holding the account sees only ciphertext, and writing to the ledger still needs the account's private key. The ledger replicates over direct peer connections (the local mesh, or machines that reach each other directly) and between machines that meet only through the relay hub, over a relay pairing sealed end to end between the two devices so the hub carries ciphertext; either way a log is offered only to a device whose membership proof names this account, and a hub-reachable device of any other account is never offered it. A revocation itself is also announced to every connected peer the moment it is made. Grants a build before the ledger recorded in `user-identity.json` are moved into it the first time a bridge starts, with nothing to do by hand. A ledger entry that cannot be read does not stop the rest of it being read, so listing and revoking a device's grants still work. Each unreadable entry is reported once, naming its log and position, and is listed by `whoami`. It may hold a grant or a revocation: a grant recorded only in it is not revoked, and a revocation recorded only in it is not applied on this machine, until the entry is repaired or replaced from another machine's replica of the account. A removal or a `dm_revoke` that skipped one says so and is reported as incomplete, never as a clean success, and a bridge that starts with one reports that revocations may be missing.
@@ -1 +1 @@
1
- {"version":3,"file":"account-cli.d.ts","sourceRoot":"","sources":["../src/account-cli.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAIL,KAAK,mBAAmB,EACzB,MAAM,yBAAyB,CAAC;AAEjC,mEAAmE;AACnE,eAAO,MAAM,sBAAsB,mCAAmC,CAAC;AAKvE,eAAO,MAAM,aAAa,QAKd,CAAC;AAEb,MAAM,WAAW,YAAY;IAC3B,mEAAmE;IACnE,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAChD,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IAClD,4GAA4G;IAC5G,SAAS,EAAE,MAAM,OAAO,CAAC,eAAe,CAAC,CAAC;CAC3C;AAmBD,gSAAgS;AAChS,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,EAAE,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC1B,mBAAmB,GAAE,QAAQ,CAAC,mBAAmB,CAAM,GACtD,OAAO,CAAC,IAAI,CAAC,CA+Cf;AAED,2DAA2D;AAC3D,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AASxC,6aAA6a;AAC7a,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,GAChB,cAAc,CA0BhB;AAED,sPAAsP;AACtP,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAoCpE"}
1
+ {"version":3,"file":"account-cli.d.ts","sourceRoot":"","sources":["../src/account-cli.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,EAGL,KAAK,eAAe,EACrB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAIL,KAAK,mBAAmB,EACzB,MAAM,yBAAyB,CAAC;AAEjC,mEAAmE;AACnE,eAAO,MAAM,sBAAsB,mCAAmC,CAAC;AAKvE,eAAO,MAAM,aAAa,QAQd,CAAC;AAEb,MAAM,WAAW,YAAY;IAC3B,mEAAmE;IACnE,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAChD,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IAClD,4GAA4G;IAC5G,SAAS,EAAE,MAAM,OAAO,CAAC,eAAe,CAAC,CAAC;CAC3C;AAmBD,gSAAgS;AAChS,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,EAAE,EAAE,QAAQ,CAAC,YAAY,CAAC,EAC1B,mBAAmB,GAAE,QAAQ,CAAC,mBAAmB,CAAM,GACtD,OAAO,CAAC,IAAI,CAAC,CA+Cf;AAED,2DAA2D;AAC3D,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AASxC,6aAA6a;AAC7a,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,GAChB,cAAc,CA0BhB;AAED,sPAAsP;AACtP,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAoCpE"}
@@ -15,6 +15,9 @@ export const ACCOUNT_USAGE = [
15
15
  " agent-comms account import <file>",
16
16
  " agent-comms account invite [--ttl-minutes <n>] [--sign-key <file>]",
17
17
  " agent-comms account join [--public-key <file>] [--fingerprint <hex>] [--label <name>]",
18
+ "",
19
+ "An invite without --sign-key is a bearer hint, not authentication: the machine that joins with it trusts whatever device the invite names, whoever wrote it, so carry it only over a channel you trust.",
20
+ "--public-key and --fingerprint on join require a signed invite and refuse an unsigned one.",
18
21
  ].join("\n");
19
22
  async function passphrase(io, confirm) {
20
23
  const fromEnv = io.env[ACCOUNT_PASSPHRASE_ENV];
@@ -58,7 +61,7 @@ export async function runAccountCommand(args, io, userIdentityOptions = {}) {
58
61
  }
59
62
  if (subcommand === "import") {
60
63
  const contents = openAccountBundle(fs.readFileSync(file, "utf-8"), await passphrase(io, false));
61
- const { identity, replacedFile } = importAccountKey(userIdentityOptions, contents);
64
+ const { identity, replacedFile } = await importAccountKey(userIdentityOptions, contents);
62
65
  io.log(`This machine now holds account ${principalOf(identity)}.`);
63
66
  if (replacedFile !== undefined) {
64
67
  io.log(`The account it held before was moved to ${replacedFile}; it is still the only key that can revoke what that account issued.`);
@@ -1 +1 @@
1
- {"version":3,"file":"account-cli.js","sourceRoot":"","sources":["../src/account-cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"account-cli.js","sourceRoot":"","sources":["../src/account-cli.ts"],"names":[],"mappings":"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"}