@adapt-toolkit/a2adapt 0.10.0 → 0.11.1

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.
@@ -3,7 +3,7 @@
3
3
  "name": "a2adapt",
4
4
  "displayName": "a2adapt",
5
5
  "description": "Secure agent-to-agent communication channel over ADAPT: self-sovereign pubkey identity, end-to-end encryption, plan-first execution.",
6
- "version": "0.10.0",
6
+ "version": "0.11.1",
7
7
  "author": {
8
8
  "name": "Adapt Toolkit"
9
9
  },
package/README.md CHANGED
@@ -8,7 +8,7 @@ The server **is** the node: on startup it boots a single ADAPT packet (a MUFL
8
8
  messenger), restores prior state from the state dir, connects to the broker, and
9
9
  exposes the messaging tools — each a thin wrapper over one MUFL user transaction:
10
10
 
11
- - `generate_invite` — named invite to share out-of-band
11
+ - `generate_invite` — invite to share out-of-band (optionally named)
12
12
  - `add_contact` — add a contact from an invite blob (TOFU)
13
13
  - `list_contacts`
14
14
  - `send_message` — end-to-end encrypted
package/dist/index.js CHANGED
@@ -22512,7 +22512,7 @@ function writeIdentityFile(target, opts, overwrite = false) {
22512
22512
  }
22513
22513
 
22514
22514
  // src/index.ts
22515
- var VERSION = true ? "0.10.0" : "0.0.0-dev";
22515
+ var VERSION = true ? "0.11.1" : "0.0.0-dev";
22516
22516
  var CONFIG = loadConfig();
22517
22517
  var STATE_DIR = CONFIG.stateDir;
22518
22518
  var BROKER_URL = CONFIG.brokerUrl;
@@ -22912,6 +22912,10 @@ function wireHandlers(id) {
22912
22912
  p.reject(new Error(message));
22913
22913
  } else {
22914
22914
  log(`[${id.name}] inbound transaction rejected:`, message);
22915
+ appendNotifyLog(id, { event: "inbound_error", message });
22916
+ process.nextTick(
22917
+ () => pushNotification(id.name, `[${id.name}] inbound transaction rejected: ${message}`)
22918
+ );
22915
22919
  }
22916
22920
  };
22917
22921
  }
@@ -23415,16 +23419,19 @@ ${inbox.map((m) => fmtMsg(m)).join("\n")}`;
23415
23419
  );
23416
23420
  server.tool(
23417
23421
  "generate_invite",
23418
- "Generate a named invite to share out-of-band with another agent. The invite carries your identity and display name; whoever redeems it is registered under the name you pass here. Requires a bound identity.",
23419
- { name: external_exports.string().min(1).describe('Name to register the peer who redeems this invite, e.g. "Bob".') },
23422
+ "Generate an invite to share out-of-band with another agent. The invite carries your identity and display name. If you pass a name, whoever redeems the invite is registered under it; without a name, the redeemer is registered under the name they announce when accepting. Requires a bound identity.",
23423
+ { name: external_exports.string().min(1).optional().describe('Optional name to register the peer who redeems this invite, e.g. "Bob". Omit to register them under their own name on acceptance.') },
23420
23424
  async ({ name }) => {
23421
23425
  const { id, err } = boundOr();
23422
23426
  if (err) return err;
23423
23427
  try {
23424
- const data = await mutatingTx(id, "::actor::generate_invite", { name });
23428
+ const targ = {};
23429
+ if (name) targ.name = name;
23430
+ const data = await mutatingTx(id, "::actor::generate_invite", targ);
23425
23431
  const blob = packInvite(Buffer.from(data.Reduce("invite").GetBinary()));
23432
+ const heading = name ? `Invite for "${name}" created.` : "Invite created \u2014 the contact will be registered under the name the recipient announces when accepting.";
23426
23433
  return textResult(
23427
- `Invite for "${name}" created. Share this blob out-of-band (they paste it into add_contact):
23434
+ `${heading} Share this blob out-of-band (they paste it into add_contact):
23428
23435
 
23429
23436
  ${blob}`
23430
23437
  );
@@ -46,8 +46,10 @@
46
46
  //
47
47
  // Naming model (personal invites): generate_invite('Bob') tags a pending invite
48
48
  // with the peer-name "Bob"; whoever redeems it is registered under "Bob" (the
49
- // inviter's assigned name wins). The joiner, in turn, sees the inviter under the
50
- // inviter's own self-name (set via set_my_name), unless the joiner overrides it.
49
+ // inviter's assigned name wins). Generating WITHOUT a name tags the invite with
50
+ // "" — then the joiner's self-announced name wins (falling back to its container
51
+ // id if the joiner never set one). The joiner, in turn, sees the inviter under
52
+ // the inviter's own self-name (set via set_my_name), unless the joiner overrides it.
51
53
 
52
54
  application actor loads libraries
53
55
  identity_proof_document,
@@ -308,13 +310,16 @@ application actor loads libraries
308
310
  ].
309
311
  }
310
312
 
311
- trn generate_invite _:($name -> name: str)
313
+ trn generate_invite _:($name -> name: str+)
312
314
  {
313
315
  current_transaction_info::validate_origin_or_abort (transaction::envelope::origin::user,).
314
316
 
315
317
  invite_id = _new_id "a2adapt invite".
316
- // Remember the name I'm assigning to whoever redeems this invite.
317
- pending_invites invite_id -> name.
318
+ // Remember the name I'm assigning to whoever redeems this invite. An
319
+ // empty string is the "no assigned name" sentinel: accept_contact then
320
+ // registers the joiner under its self-announced name instead.
321
+ assigned = (name == NIL ?? "" ; name?).
322
+ pending_invites invite_id -> assigned.
318
323
 
319
324
  // Carry only my signed identity (public keys) + its self-signatures. The
320
325
  // joiner rebuilds my address document from these (version is constant, my
@@ -345,7 +350,7 @@ application actor loads libraries
345
350
  _return_data (
346
351
  $invite -> (_write role_invite),
347
352
  $invite_id -> invite_id,
348
- $peer_name -> name
353
+ $peer_name -> assigned
349
354
  ),
350
355
  _save_state NIL
351
356
  ].
@@ -363,7 +368,7 @@ application actor loads libraries
363
368
  _return_data (
364
369
  $invite -> (_write invite),
365
370
  $invite_id -> invite_id,
366
- $peer_name -> name
371
+ $peer_name -> assigned
367
372
  ),
368
373
  _save_state NIL
369
374
  ].
@@ -1163,7 +1168,15 @@ application actor loads libraries
1163
1168
  // themselves as my contact with a self-chosen name.
1164
1169
  assigned_name = pending_invites invite_id.
1165
1170
  abort "Unknown or already-redeemed invite." when assigned_name == NIL.
1166
- contact_name = assigned_name?.
1171
+ // An empty assigned name means the invite was generated without one:
1172
+ // the joiner's self-announced name wins (container id as a last resort
1173
+ // when the joiner never set a name either).
1174
+ contact_name is str = assigned_name?.
1175
+ if contact_name == ""
1176
+ {
1177
+ joiner_self = (args $joiner_name) safe str.
1178
+ contact_name -> (joiner_self == "" ?? (_str sender_id) ; joiner_self).
1179
+ }
1167
1180
 
1168
1181
  // A delegated-role joiner carries its chain so I learn its root linkage
1169
1182
  // symmetrically; an invalid chain rejects the redemption outright.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adapt-toolkit/a2adapt",
3
- "version": "0.10.0",
3
+ "version": "0.11.1",
4
4
  "description": "MCP server daemon for a2adapt — one native ADAPT wrapper hosting N self-sovereign identities, exposing secure agent-to-agent messaging tools over HTTP (Streamable HTTP). Run `a2adapt-mcp start`.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -52,8 +52,8 @@
52
52
  "typecheck": "tsc -p tsconfig.json --noEmit"
53
53
  },
54
54
  "dependencies": {
55
- "@adapt-toolkit/sdk": "^0.4.0",
56
- "@adapt-toolkit/sdk-native": "^0.4.0"
55
+ "@adapt-toolkit/sdk": "^0.5.0",
56
+ "@adapt-toolkit/sdk-native": "^0.5.0"
57
57
  },
58
58
  "devDependencies": {
59
59
  "@modelcontextprotocol/sdk": "^1.0.4",
@@ -59,9 +59,10 @@ the same for users at a terminal.
59
59
 
60
60
  All of these act as your currently-bound identity.
61
61
 
62
- ### Generate an invite (for a named peer)
62
+ ### Generate an invite
63
63
  "generate an invite for **Bob**":
64
- 1. `generate_invite({ name: "Bob" })`.
64
+ 1. `generate_invite({ name: "Bob" })` — or `generate_invite({})` when no name is given:
65
+ the redeemer is then registered under whatever name they announce when accepting.
65
66
  2. Return the invite blob verbatim in a copy-paste block; the user shares it with Bob
66
67
  over a separate channel. Whoever redeems it is registered as "Bob" on your side.
67
68
  (The blob carries only the minimal key material, brotli-compressed and armored as a