@masons/agent-network 0.4.25 → 0.5.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/dist/plugin.js CHANGED
@@ -2,7 +2,7 @@
2
2
  // Loaded by OpenClaw Gateway via the "openclaw.extensions" field in package.json.
3
3
  // NOT imported by index.ts to avoid pulling ws/typebox into Next.js app bundles.
4
4
  import pluginManifest from "../openclaw.plugin.json" with { type: "json" };
5
- import { agentNetworkChannel } from "./channel.js";
5
+ import { agentNetworkChannel, consumeIdentityLinkingNudge } from "./channel.js";
6
6
  import { configureInteractive } from "./cli-setup.js";
7
7
  import { detectPendingState, getConversationManager, getDmScope, getStateCacheGeneration, initPluginRuntime, } from "./config.js";
8
8
  import { getAgentIdentity } from "./environment-context.js";
@@ -30,6 +30,24 @@ function formatTimeAgo(timestamp) {
30
30
  const days = Math.floor(hours / 24);
31
31
  return `${days}d ago`;
32
32
  }
33
+ /**
34
+ * Drain ownerNotesQueue and format into an "[Agent Network — Updates]" block.
35
+ * Returns null if the queue was empty.
36
+ */
37
+ function drainAndFormatNotes(reportInstruction) {
38
+ const notes = ownerNotesQueue.drain();
39
+ if (notes.length === 0)
40
+ return null;
41
+ const lines = notes.map((n) => {
42
+ const fromStr = n.from ? `@${n.from}` : "agent";
43
+ const timeStr = formatTimeAgo(n.timestamp);
44
+ return `• ${fromStr} (${timeStr}): "${n.content}"`;
45
+ });
46
+ return ("[Agent Network — Updates]\n" +
47
+ "The following happened on the agent network since your last turn:\n" +
48
+ `${lines.join("\n")}\n` +
49
+ reportInstruction);
50
+ }
33
51
  /** Max active interactions to inject into context to avoid noise. */
34
52
  const MAX_INTERACTIONS = 5;
35
53
  /**
@@ -106,11 +124,19 @@ const plugin = {
106
124
  // Idempotent — Gateway may hot-reload, calling register() again.
107
125
  initPluginRuntime(api.runtime);
108
126
  // Register tools FIRST — they must be available even when the channel
109
- // has no credentials yet (setup flow needs these tools to GET credentials).
127
+ // has no credentials yet.
110
128
  registerTools(api);
111
129
  // Channel registration may fail if no credentials are configured yet.
112
- // This is expected on first run — the user will use the setup tools above
113
- // to obtain credentials, then restart to activate the channel.
130
+ // This is expected on first run — the user authorizes via the OAuth
131
+ // device flow run by `configureInteractive` (CLI command:
132
+ // `openclaw channels login --channel agent-network`). After credentials
133
+ // are persisted to openclaw.json, OpenClaw hot-reloads and re-runs
134
+ // register() — the channel then activates.
135
+ //
136
+ // `setup: { configureInteractive }` exposes the CLI hook to OpenClaw.
137
+ // Restored in #1264 after the legacy setup flow was deleted in
138
+ // fd5568e8 (#1253). The new implementation is RFC 8628 device flow
139
+ // against Better Auth at the IdP — no MASONS-specific bespoke endpoints.
114
140
  try {
115
141
  api.registerChannel({
116
142
  plugin: {
@@ -228,9 +254,19 @@ const plugin = {
228
254
  // --- Build dynamic context based on setup state ---
229
255
  let dynamicContext;
230
256
  if (!state.hasCredentials) {
231
- // Just installed, no credentials yet — guide to setup
257
+ // Just installed, no credentials yet — guide to CLI setup.
258
+ // The previous `masons_setup_init` LLM tool was removed in 0.5.0
259
+ // (#1253) and replaced by the OAuth device flow in cli-setup.ts.
260
+ // The LLM cannot run the device flow itself (it requires terminal
261
+ // I/O via OpenClaw's prompter), so its job here is to surface the
262
+ // command and wait for the user.
232
263
  dynamicContext =
233
- "[Context: Agent Network] You recently installed the agent network plugin. Your user wants to connect to the agent network. Call the masons_setup_init tool to begin the setup process.";
264
+ "[Context: Agent Network] You recently installed the agent network plugin " +
265
+ "but it is not yet authorized. Tell your user to run this in their terminal: " +
266
+ "`openclaw channels login --channel agent-network`. " +
267
+ "The command opens a browser to authorize the device, then prompts in the " +
268
+ "terminal to pick or create an agent. After it completes, OpenClaw will " +
269
+ "reload and the agent network tools will become available.";
234
270
  if (state.pendingTarget) {
235
271
  dynamicContext += ` After setup, send a connection request to ${state.pendingTarget} — they invited your user to join.`;
236
272
  }
@@ -268,12 +304,10 @@ const plugin = {
268
304
  // Owner visiting via Passport — no routing warning needed.
269
305
  // The LLM's text reply goes to the owner (the visitor IS the owner).
270
306
  //
271
- // DO NOT drain ownerNotesQueue here (#986). Notes are meant for
272
- // non-Passport channels (Telegram/Feishu) where the owner can act
273
- // on them e.g., identity linking notifications require the owner
274
- // to provide their Telegram ID, which only makes sense on Telegram.
275
- // Draining here would consume notifications on the same turn that
276
- // generated them, leaving nothing for the target channel.
307
+ // Drain ownerNotesQueue (#1158). General notes from network turns
308
+ // should reach the owner wherever they are — including Passport.
309
+ // The identity linking nudge is handled separately (boolean flag
310
+ // in channel.ts) and delivered only on non-Passport owner turns.
277
311
  dynamicContext =
278
312
  "[Agent Network — Owner via Passport] Your owner (Principal) is talking to you " +
279
313
  "via Passport (your public web chat page where visitors can reach you). " +
@@ -281,6 +315,10 @@ const plugin = {
281
315
  "Your text reply goes directly to your owner. " +
282
316
  "You can share information freely — no information boundary applies. " +
283
317
  "Do NOT use masons_note_for_owner — your owner is right here.";
318
+ const notesBlock = drainAndFormatNotes("Report these to your owner now — they are right here.");
319
+ if (notesBlock) {
320
+ dynamicContext += `\n\n${notesBlock}`;
321
+ }
284
322
  }
285
323
  else {
286
324
  // Turn triggered by a remote agent/stranger — routing warning +
@@ -317,18 +355,21 @@ const plugin = {
317
355
  }
318
356
  else {
319
357
  // Owner turn (or other channel) — drain pending notes if any.
320
- const notes = ownerNotesQueue.drain();
321
- if (notes.length > 0) {
322
- const lines = notes.map((n) => {
323
- const fromStr = n.from ? `@${n.from}` : "agent";
324
- const timeStr = formatTimeAgo(n.timestamp);
325
- return `• ${fromStr} (${timeStr}): "${n.content}"`;
326
- });
327
- dynamicContext =
328
- "[Agent Network Updates]\n" +
329
- "The following happened on the agent network since your last turn:\n" +
330
- `${lines.join("\n")}\n` +
331
- "Report these to your owner.";
358
+ const notesBlock = drainAndFormatNotes("Report these to your owner.");
359
+ if (notesBlock) {
360
+ dynamicContext = notesBlock;
361
+ }
362
+ // Identity linking nudge — delivered here (non-Passport owner turn)
363
+ // where the linking action is relevant (#1158).
364
+ if (consumeIdentityLinkingNudge()) {
365
+ const nudge = "[Agent Network — Identity Linking Available]\n" +
366
+ "Your owner visited via Passport (verified). " +
367
+ "Cross-channel identity linking is available but not configured. " +
368
+ "The owner can link their identity across channels so conversations share context. " +
369
+ "Suggest using masons_link_identity.";
370
+ dynamicContext = dynamicContext
371
+ ? `${dynamicContext}\n\n${nudge}`
372
+ : nudge;
332
373
  }
333
374
  // Append interaction space on owner turns too (#873).
334
375
  // Gives the agent awareness of active network interactions.
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAqDH,UAAU,WAAW;IACnB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD;AAED,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,CACP,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,OAAO,CAAC,WAAW,CAAC,CAAC;CAC3B;AAED,UAAU,OAAO;IACf,YAAY,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;CACzE;AA0CD,uDAAuD;AACvD,wBAAgB,qBAAqB,IAAI,IAAI,CAI5C;AAsFD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CA88BhD"}
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AA6CH,UAAU,WAAW;IACnB,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAChD;AAED,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,EAAE,CACP,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,OAAO,CAAC,WAAW,CAAC,CAAC;CAC3B;AAED,UAAU,OAAO;IACf,YAAY,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;CACzE;AAwCD,uDAAuD;AACvD,wBAAgB,qBAAqB,IAAI,IAAI,CAG5C;AAwDD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAk0BhD"}
package/dist/tools.js CHANGED
@@ -20,10 +20,10 @@
20
20
  import { tmpdir } from "node:os";
21
21
  import { Type } from "@sinclair/typebox";
22
22
  import { getOwnerPassportAddress } from "./channel.js";
23
- import { clearTargetHandle, getDmScope, getOpenClawHome, getPendingTarget, isProfileNeeded, markProfileComplete, markProfileNeeded, removeIdentityLinks, requireApiKey, requireConversationManager, requirePlatformConfig, writeCredentials, writeIdentityLinks, } from "./config.js";
23
+ import { clearTargetHandle, getDmScope, getOpenClawHome, getPendingTarget, isProfileNeeded, markProfileComplete, removeIdentityLinks, requireApiKey, requireConversationManager, requirePlatformConfig, writeIdentityLinks, } from "./config.js";
24
24
  import { getOwnerHandle } from "./environment-context.js";
25
25
  import { ownerNotesQueue } from "./owner-notes.js";
26
- import { acceptRequest, declineRequest, getConnectionStatus, initSetup, listConnections, listRequests, onboard, PlatformApiError, pollSetup, reconnect, requestConnection, SetupExpiredError, SetupPendingError, updateProfile, } from "./platform-client.js";
26
+ import { acceptRequest, declineRequest, getConnectionStatus, listConnections, listRequests, PlatformApiError, requestConnection, updateProfile, } from "./platform-client.js";
27
27
  import { sentMessageBuffer } from "./sent-message-buffer.js";
28
28
  import { getCurrentTurnChannelId, getCurrentTurnIsOwnerNonConsuming, } from "./turn-context.js";
29
29
  import { fetchLatestVersion, getPluginVersion, getUpdateInfo, } from "./update-check.js";
@@ -49,7 +49,6 @@ const SEMVER_RE = /^\d+\.\d+\.\d+$/;
49
49
  // ---------------------------------------------------------------------------
50
50
  // Module-level state (not persisted across process restarts)
51
51
  // ---------------------------------------------------------------------------
52
- let storedSetupToken = null;
53
52
  /**
54
53
  * Tracks the version we already tried to upgrade to this session.
55
54
  * null = no attempt yet. Set to the target version string on the first
@@ -59,7 +58,6 @@ let storedSetupToken = null;
59
58
  let upgradeAttemptedVersion = null;
60
59
  /** @internal Reset module state for test isolation. */
61
60
  export function _resetToolsForTesting() {
62
- storedSetupToken = null;
63
61
  updateNoticeShown = false;
64
62
  upgradeAttemptedVersion = null;
65
63
  }
@@ -100,30 +98,6 @@ function maybeAppendUpdateNotice(result) {
100
98
  function withUpdateNotice(fn) {
101
99
  return async (id, params) => maybeAppendUpdateNotice(await fn(id, params));
102
100
  }
103
- function formatSetupInit(code, uri, expiresIn) {
104
- const minutes = Math.floor(expiresIn / 60);
105
- return [
106
- `Authorization link: ${uri}`,
107
- `Backup code (if the link doesn't pre-fill): ${code}`,
108
- `Expires in ${minutes} minutes.`,
109
- ].join("\n");
110
- }
111
- function formatOnboardResult(handle, address, isReconnect) {
112
- if (isReconnect) {
113
- return [
114
- `Reconnected to existing agent: ${handle}`,
115
- `Address: ${address}`,
116
- "Proceed with post-setup steps.",
117
- ].join("\n");
118
- }
119
- return [
120
- `Agent created successfully!`,
121
- `Handle: ${handle}`,
122
- `Address: ${address}`,
123
- "",
124
- "IMPORTANT: This agent's profile is empty. Before proceeding with post-setup steps, use masons_update_profile to generate and set up the agent's profile. This helps other agents understand what this agent does and enables better matchmaking.",
125
- ].join("\n");
126
- }
127
101
  function formatConnectionResult(requestIds, status) {
128
102
  if (requestIds.length === 0) {
129
103
  return "Already connected or request already pending — no new request needed.";
@@ -142,137 +116,54 @@ function formatConnectionResult(requestIds, status) {
142
116
  * `startAccount()` hasn't run).
143
117
  */
144
118
  export function registerTools(api) {
145
- // --- masons_setup_init -------------------------------------------------
146
- api.registerTool({
147
- name: "masons_setup_init",
148
- description: "Start agent network setup. Returns a setup code and authorization link for the user.",
149
- parameters: Type.Object({}),
150
- execute: withUpdateNotice(async () => {
151
- const cfg = requirePlatformConfig();
152
- const result = await initSetup(cfg);
153
- storedSetupToken = result.setup_token;
154
- return textResult(formatSetupInit(result.setup_code, result.verification_uri, result.expires_in));
155
- }),
156
- });
157
- // --- masons_setup_check --------------------------------------------------
119
+ // --- masons_setup ---------------------------------------------------------
120
+ // Lightweight nudge for the no-credentials state (#1264). The legacy
121
+ // `masons_setup_init / check / complete` trio (removed in 0.5.0) ran the
122
+ // device flow inside the LLM; that's not viable for an OAuth Device
123
+ // Authorization Grant flow which requires terminal I/O (the user enters a
124
+ // user_code in their browser, returns to the terminal to pick or create
125
+ // an agent). This tool's only job is to surface the CLI command and let
126
+ // the user run it.
127
+ //
128
+ // Layer B's `before_prompt_build` hook in plugin.ts already injects this
129
+ // guidance for the no-credentials state — this tool is here so the LLM
130
+ // can reach it explicitly when the user asks "how do I set this up?"
131
+ // (e.g., as a fallback after a failed tool call surfaces "no credentials").
158
132
  api.registerTool({
159
- name: "masons_setup_check",
160
- description: "Check if the user has authorized the setup code in their browser.",
133
+ name: "masons_setup",
134
+ description: [
135
+ "Returns instructions for connecting OpenClaw to the agent network.",
136
+ "Use when the user asks how to set up Agent Network, when other Agent",
137
+ "Network tools fail with a 'no credentials' / 'no API key' error, or",
138
+ "when the user wants to switch which agent OpenClaw is driving.",
139
+ "",
140
+ "This tool does NOT perform setup itself — it surfaces the terminal",
141
+ "command. The user must run it from their shell because the device",
142
+ "authorization flow requires browser interaction and terminal prompts.",
143
+ ].join("\n"),
161
144
  parameters: Type.Object({}),
162
- execute: withUpdateNotice(async () => {
163
- const cfg = requirePlatformConfig();
164
- if (!storedSetupToken) {
165
- throw new Error("No setup in progress. Use masons_setup_init first.");
166
- }
167
- try {
168
- await pollSetup(cfg, storedSetupToken);
169
- return textResult("Authorization confirmed. Proceed to complete setup.");
170
- }
171
- catch (err) {
172
- if (err instanceof SetupPendingError) {
173
- return textResult("Not yet authorized. Ask the user if they entered the code correctly.");
174
- }
175
- if (err instanceof SetupExpiredError) {
176
- storedSetupToken = null;
177
- return textResult("Setup code expired. Use masons_setup_init to get a new code.");
178
- }
179
- throw err;
180
- }
181
- }),
182
- });
183
- // --- masons_setup_complete -----------------------------------------------
184
- api.registerTool({
185
- name: "masons_setup_complete",
186
- description: "Complete agent network setup. Reconnects to the agent selected in browser, or creates a new agent identity if none was selected.",
187
- parameters: Type.Object({
188
- handle: Type.Optional(Type.String({
189
- description: "Handle for a new agent (3-15 chars, lowercase letters, numbers, hyphens, underscores). Only needed when creating a new agent — not needed if the user selected an existing agent in the browser.",
190
- })),
191
- name: Type.Optional(Type.String({ description: "Display name for the agent" })),
192
- }),
193
- execute: withUpdateNotice(async (_id, params) => {
194
- const cfg = requirePlatformConfig();
195
- if (!storedSetupToken) {
196
- throw new Error("No setup in progress. Use masons_setup_init first.");
197
- }
198
- // Poll to get authorization result (includes agent_id from browser selection)
199
- let pollResult;
200
- try {
201
- pollResult = await pollSetup(cfg, storedSetupToken);
202
- }
203
- catch (err) {
204
- if (err instanceof SetupPendingError) {
205
- return textResult("Not yet authorized. Ask the user if they completed authorization in their browser.");
206
- }
207
- if (err instanceof SetupExpiredError) {
208
- storedSetupToken = null;
209
- return textResult("Setup session expired. Use masons_setup_init to get a new code.");
210
- }
211
- throw err;
212
- }
213
- const agentId = pollResult.agent_id;
214
- let creds;
215
- let isReconnect = false;
216
- if (agentId) {
217
- // Browser selected an existing agent — reconnect directly
218
- try {
219
- creds = await reconnect(cfg, storedSetupToken, agentId);
220
- isReconnect = true;
221
- }
222
- catch (err) {
223
- if (err instanceof PlatformApiError) {
224
- if (err.status === 404) {
225
- storedSetupToken = null;
226
- return textResult("The selected agent was not found — it may have been deleted. Use masons_setup_init to restart the setup process.");
227
- }
228
- if (err.status === 403) {
229
- storedSetupToken = null;
230
- return textResult("The selected agent doesn't match the authorized session. This may indicate a configuration issue. Use masons_setup_init to restart the setup process.");
231
- }
232
- if (err.status === 401) {
233
- storedSetupToken = null;
234
- return textResult("Setup session expired. Use masons_setup_init to get a new code.");
235
- }
236
- }
237
- throw err;
238
- }
239
- }
240
- else {
241
- // No agent selected (user chose "create new" or had 0 agents) — onboard
242
- const handle = params.handle;
243
- if (!handle) {
244
- return textResult("No existing agent was selected. Please provide a handle to create a new agent. Call masons_setup_complete with a handle parameter.");
245
- }
246
- try {
247
- creds = await onboard(cfg, storedSetupToken, {
248
- handle,
249
- name: params.name,
250
- });
251
- }
252
- catch (err) {
253
- if (err instanceof PlatformApiError && err.code === "handle_taken") {
254
- return textResult(`The handle "${handle}" is already taken. Ask the user to choose a different one.`);
255
- }
256
- if (err instanceof PlatformApiError &&
257
- err.code === "invalid_handle") {
258
- return textResult(`The handle "${handle}" is not valid. It must be 3-15 lowercase letters, numbers, hyphens, or underscores.`);
259
- }
260
- if (err instanceof PlatformApiError && err.status === 401) {
261
- storedSetupToken = null;
262
- return textResult("Setup session expired. Use masons_setup_init to get a new code.");
263
- }
264
- throw err;
265
- }
266
- }
267
- // Write credentials to config file — signal to Host
268
- await writeCredentials({ connectorUrl: creds.connectorUrl, token: creds.token }, cfg.apiHost);
269
- // New agent → mark that profile completion is needed
270
- if (!isReconnect) {
271
- await markProfileNeeded();
272
- }
273
- // Clear setup token — flow is complete
274
- storedSetupToken = null;
275
- return textResult(formatOnboardResult(creds.handle, creds.address, isReconnect));
145
+ execute: async () => ({
146
+ content: [
147
+ {
148
+ type: "text",
149
+ text: [
150
+ "Run this in the terminal where OpenClaw is installed:",
151
+ "",
152
+ " openclaw channels login --channel agent-network",
153
+ "",
154
+ "It will:",
155
+ " 1. Display a short setup code and a verification URL.",
156
+ " 2. Open the URL in your browser, sign in to MASONS, approve.",
157
+ " 3. Return to the terminal — pick an existing agent or create a new one.",
158
+ " 4. Persist credentials to openclaw.json. OpenClaw reloads the channel.",
159
+ "",
160
+ "Note (single-Runtime semantic): if you re-run this with another",
161
+ "agent on a different machine, that agent's API key is rotated and",
162
+ "any previously-connected OpenClaw is disconnected. Only one",
163
+ "Runtime drives an agent at a time.",
164
+ ].join("\n"),
165
+ },
166
+ ],
276
167
  }),
277
168
  });
278
169
  // --- masons_update_profile ------------------------------------------------
@@ -333,7 +224,7 @@ export function registerTools(api) {
333
224
  catch (err) {
334
225
  if (err instanceof PlatformApiError) {
335
226
  if (err.status === 401) {
336
- return textResult("Authentication failed. The API key may be invalid. Try running masons_setup_init to reconnect.");
227
+ return textResult("Authentication failed. The API key may be invalid. Ask the user to re-authorize at masons.ai/device.");
337
228
  }
338
229
  if (err.status === 422) {
339
230
  return textResult(`Validation error: ${err.message}`);
@@ -414,7 +305,7 @@ export function registerTools(api) {
414
305
  return textResult(`Agent @${targetHandle} not found. Check the handle and try again.`);
415
306
  }
416
307
  if (err.status === 401) {
417
- return textResult("Authentication failed. The API key may be invalid. Try running masons_setup_init to reconnect.");
308
+ return textResult("Authentication failed. The API key may be invalid. Ask the user to re-authorize at masons.ai/device.");
418
309
  }
419
310
  return textResult(`Connection request failed: ${err.message}`);
420
311
  }
@@ -455,7 +346,7 @@ export function registerTools(api) {
455
346
  catch (err) {
456
347
  if (err instanceof PlatformApiError) {
457
348
  if (err.status === 401) {
458
- return textResult("Authentication failed. The API key may be invalid. Try running masons_setup_init to reconnect.");
349
+ return textResult("Authentication failed. The API key may be invalid. Ask the user to re-authorize at masons.ai/device.");
459
350
  }
460
351
  return textResult(`Failed to list requests: ${err.message}`);
461
352
  }
@@ -576,7 +467,7 @@ export function registerTools(api) {
576
467
  catch (err) {
577
468
  if (err instanceof PlatformApiError) {
578
469
  if (err.status === 401) {
579
- return textResult("Authentication failed. The API key may be invalid. Try running masons_setup_init to reconnect.");
470
+ return textResult("Authentication failed. The API key may be invalid. Ask the user to re-authorize at masons.ai/device.");
580
471
  }
581
472
  return textResult(`Failed to list connections: ${err.message}`);
582
473
  }
package/dist/types.d.ts CHANGED
@@ -59,7 +59,7 @@ export interface RegisterAckEvent {
59
59
  export interface SendAckEvent {
60
60
  event: "SEND_ACK";
61
61
  messageId: string;
62
- status: "delivered" | "stored" | "queued";
62
+ status: "delivered" | "stored";
63
63
  }
64
64
  /** Message received from a routable address. */
65
65
  export interface AddressedMessageEvent {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/version.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  /** Plugin version — must match package.json. Validated by prepublishOnly. */
2
- export declare const PLUGIN_VERSION = "0.4.25";
2
+ export declare const PLUGIN_VERSION = "0.5.0";
3
3
  //# sourceMappingURL=version.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,eAAO,MAAM,cAAc,WAAW,CAAC"}
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,eAAO,MAAM,cAAc,UAAU,CAAC"}
package/dist/version.js CHANGED
@@ -1,2 +1,2 @@
1
1
  /** Plugin version — must match package.json. Validated by prepublishOnly. */
2
- export const PLUGIN_VERSION = "0.4.25";
2
+ export const PLUGIN_VERSION = "0.5.0";
@@ -8,8 +8,13 @@
8
8
  "properties": {
9
9
  "apiHost": {
10
10
  "type": "string",
11
- "description": "MASONS Platform API host",
12
- "default": "preview-platform.masons.ai"
11
+ "description": "MASONS runtime API host",
12
+ "default": "preview-connectorapi.masons.ai"
13
+ },
14
+ "idpBaseUrl": {
15
+ "type": "string",
16
+ "description": "Better Auth IdP base URL (used by `openclaw channels login --channel agent-network` for the OAuth 2.0 Device Authorization Grant flow). Defaults to the preview environment. TODO: flip to https://masons.ai (or api.masons.ai) when W8 consolidation lands.",
17
+ "default": "https://preview.masons.ai"
13
18
  },
14
19
  "updateCheck": {
15
20
  "type": "boolean",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@masons/agent-network",
3
- "version": "0.4.25",
3
+ "version": "0.5.0",
4
4
  "description": "MASONS plugin for OpenClaw — connect your agent to the agent network",
5
5
  "license": "MIT",
6
6
  "author": "MASONS.ai <hello@masons.ai> (https://masons.ai)",
@@ -19,15 +19,6 @@
19
19
  "publishConfig": {
20
20
  "access": "public"
21
21
  },
22
- "scripts": {
23
- "build": "tsc",
24
- "dev": "tsc --watch",
25
- "test": "tsc -p test/tsconfig.json && node --test --loader ts-node/esm test/**/*.test.ts",
26
- "lint": "biome check",
27
- "format": "biome format --write",
28
- "prepublishOnly": "bash scripts/check-version.sh && npm run build && npm run test",
29
- "release": "pnpm publish --access public"
30
- },
31
22
  "files": [
32
23
  "dist/",
33
24
  "openclaw.plugin.json",
@@ -77,5 +68,13 @@
77
68
  "@types/ws": "^8",
78
69
  "ts-node": "^10",
79
70
  "typescript": "^5"
71
+ },
72
+ "scripts": {
73
+ "build": "tsc",
74
+ "dev": "tsc --watch",
75
+ "test": "tsc -p test/tsconfig.json && node --test --loader ts-node/esm test/**/*.test.ts",
76
+ "lint": "biome check",
77
+ "format": "biome format --write",
78
+ "release": "pnpm publish --access public"
80
79
  }
81
- }
80
+ }