@masons/agent-network 0.5.0 → 0.5.11
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/cli-setup.d.ts +54 -33
- package/dist/cli-setup.d.ts.map +1 -1
- package/dist/cli-setup.js +111 -40
- package/dist/config.d.ts +8 -4
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +13 -4
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +20 -14
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -1
package/dist/cli-setup.d.ts
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* CLI
|
|
2
|
+
* CLI Login Path — OAuth 2.0 Device Authorization Grant (RFC 8628).
|
|
3
3
|
*
|
|
4
|
-
* Implements `
|
|
5
|
-
*
|
|
4
|
+
* Implements `login()` hook for OpenClaw's 2026.4.x channel-plugin contract:
|
|
5
|
+
* api.registerChannel({ plugin: { ..., auth: { login } } })
|
|
6
|
+
*
|
|
7
|
+
* Invoked by `openclaw channels login --channel agent-network`. CLI dispatch
|
|
8
|
+
* at `dist/channels-cli-Cc40S0aS.js:85` reads `plugin.auth?.login` and throws
|
|
9
|
+
* `"Channel ... does not support login"` if absent. See WhatsApp + Feishu
|
|
10
|
+
* bundled extensions for reference implementations of the same contract.
|
|
6
11
|
*
|
|
7
12
|
* Flow:
|
|
8
13
|
* 1. POST {idpBaseUrl}/api/auth/device/code with client_id + scope
|
|
@@ -11,45 +16,61 @@
|
|
|
11
16
|
* → handles `expired_token`, `authorization_pending`, `slow_down`
|
|
12
17
|
* 3. POST {apiHost}/runtime/v1/onboard with Bearer access_token
|
|
13
18
|
* → list / select existing agent / create new (terminal prompter)
|
|
14
|
-
* 4.
|
|
19
|
+
* 4. Persist credentials directly via `writeCredentials()` into
|
|
20
|
+
* `openclaw.json`. (The CLI does NOT auto-persist after login returns —
|
|
21
|
+
* unlike the legacy `configureInteractive` contract — so the plugin
|
|
22
|
+
* owns the file write; see `runChannelLogin` in channels-cli source.)
|
|
15
23
|
*
|
|
16
|
-
* Pre-migration this file existed as a `setup_codes`-based bespoke
|
|
17
|
-
* (deleted in fd5568e8).
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
24
|
+
* History. Pre-migration this file existed as a `setup_codes`-based bespoke
|
|
25
|
+
* flow (deleted in fd5568e8). A device-flow re-implementation landed in 0.5.0
|
|
26
|
+
* under `configureInteractive` mounted at `plugin.setup.configureInteractive`
|
|
27
|
+
* — but that mount path is not read by any known OpenClaw version (neither
|
|
28
|
+
* 2026.3.x's top-level `plugin.configureInteractive` nor 2026.4.x's
|
|
29
|
+
* `plugin.auth.login`). 0.5.1 corrects the mount point and adopts the
|
|
30
|
+
* 2026.4.x `{cfg, accountId, runtime, verbose, channelInput}` signature.
|
|
21
31
|
*
|
|
22
|
-
* See #1264 for the design rationale (
|
|
23
|
-
*
|
|
24
|
-
* any previously-connected Runtime).
|
|
32
|
+
* See #1264 for the design rationale (single-driver Node semantic — re-running
|
|
33
|
+
* this flow rotates the api_key and evicts any previously-connected Runtime).
|
|
25
34
|
*/
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
prompter: Prompter;
|
|
39
|
-
options: Record<string, unknown>;
|
|
35
|
+
/**
|
|
36
|
+
* Minimal OpenClaw runtime surface passed to `auth.login`. Exposed as
|
|
37
|
+
* `defaultRuntime` in `openclaw/dist/runtime-Dx7oeLYq.js` — plugins get
|
|
38
|
+
* only the output/exit channel, not a prompter (plugins build their own
|
|
39
|
+
* via @clack/prompts, which is what OpenClaw CLI uses internally too).
|
|
40
|
+
*/
|
|
41
|
+
interface OpenClawRuntime {
|
|
42
|
+
log(...args: unknown[]): void;
|
|
43
|
+
error(...args: unknown[]): void;
|
|
44
|
+
writeStdout(value: string): void;
|
|
45
|
+
writeJson(value: unknown, space?: number): void;
|
|
46
|
+
exit(code: number): void;
|
|
40
47
|
}
|
|
41
|
-
|
|
48
|
+
/**
|
|
49
|
+
* Context passed by OpenClaw CLI to `plugin.auth.login`. Matches the call
|
|
50
|
+
* site at `dist/channels-cli-Cc40S0aS.js:89`:
|
|
51
|
+
* await login({ cfg, accountId, runtime, verbose, channelInput });
|
|
52
|
+
*/
|
|
53
|
+
interface AuthLoginContext {
|
|
42
54
|
cfg: Record<string, unknown>;
|
|
43
55
|
accountId?: string;
|
|
44
|
-
|
|
56
|
+
runtime: OpenClawRuntime;
|
|
57
|
+
verbose?: boolean;
|
|
58
|
+
channelInput?: string;
|
|
59
|
+
}
|
|
45
60
|
/**
|
|
46
|
-
*
|
|
61
|
+
* Channel login hook — invoked by `openclaw channels login --channel agent-network`.
|
|
47
62
|
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
63
|
+
* Unlike the legacy `configureInteractive` contract (which returned a config
|
|
64
|
+
* object for the CLI to persist), the 2026.4.x `auth.login` contract returns
|
|
65
|
+
* void and expects the plugin to persist any config changes itself. We use
|
|
66
|
+
* `writeCredentials()` in config.ts, which writes `openclaw.json` atomically
|
|
67
|
+
* and bumps the state-cache generation so Layer B's dynamic context re-reads
|
|
68
|
+
* on the next turn.
|
|
50
69
|
*
|
|
51
|
-
*
|
|
70
|
+
* Errors during device flow or onboarding are surfaced via `ctx.runtime.error`
|
|
71
|
+
* (not thrown) so OpenClaw CLI doesn't display a stack trace — matches the
|
|
72
|
+
* WhatsApp/Feishu pattern.
|
|
52
73
|
*/
|
|
53
|
-
export declare function
|
|
74
|
+
export declare function login(ctx: AuthLoginContext): Promise<void>;
|
|
54
75
|
export {};
|
|
55
76
|
//# sourceMappingURL=cli-setup.d.ts.map
|
package/dist/cli-setup.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-setup.d.ts","sourceRoot":"","sources":["../src/cli-setup.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"cli-setup.d.ts","sourceRoot":"","sources":["../src/cli-setup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAiCH;;;;;GAKG;AACH,UAAU,eAAe;IACvB,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC9B,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChC,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChD,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;;;GAIG;AACH,UAAU,gBAAgB;IACxB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,eAAe,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAobD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,KAAK,CAAC,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmDhE"}
|
package/dist/cli-setup.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* CLI
|
|
2
|
+
* CLI Login Path — OAuth 2.0 Device Authorization Grant (RFC 8628).
|
|
3
3
|
*
|
|
4
|
-
* Implements `
|
|
5
|
-
*
|
|
4
|
+
* Implements `login()` hook for OpenClaw's 2026.4.x channel-plugin contract:
|
|
5
|
+
* api.registerChannel({ plugin: { ..., auth: { login } } })
|
|
6
|
+
*
|
|
7
|
+
* Invoked by `openclaw channels login --channel agent-network`. CLI dispatch
|
|
8
|
+
* at `dist/channels-cli-Cc40S0aS.js:85` reads `plugin.auth?.login` and throws
|
|
9
|
+
* `"Channel ... does not support login"` if absent. See WhatsApp + Feishu
|
|
10
|
+
* bundled extensions for reference implementations of the same contract.
|
|
6
11
|
*
|
|
7
12
|
* Flow:
|
|
8
13
|
* 1. POST {idpBaseUrl}/api/auth/device/code with client_id + scope
|
|
@@ -11,18 +16,24 @@
|
|
|
11
16
|
* → handles `expired_token`, `authorization_pending`, `slow_down`
|
|
12
17
|
* 3. POST {apiHost}/runtime/v1/onboard with Bearer access_token
|
|
13
18
|
* → list / select existing agent / create new (terminal prompter)
|
|
14
|
-
* 4.
|
|
19
|
+
* 4. Persist credentials directly via `writeCredentials()` into
|
|
20
|
+
* `openclaw.json`. (The CLI does NOT auto-persist after login returns —
|
|
21
|
+
* unlike the legacy `configureInteractive` contract — so the plugin
|
|
22
|
+
* owns the file write; see `runChannelLogin` in channels-cli source.)
|
|
15
23
|
*
|
|
16
|
-
* Pre-migration this file existed as a `setup_codes`-based bespoke
|
|
17
|
-
* (deleted in fd5568e8).
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
24
|
+
* History. Pre-migration this file existed as a `setup_codes`-based bespoke
|
|
25
|
+
* flow (deleted in fd5568e8). A device-flow re-implementation landed in 0.5.0
|
|
26
|
+
* under `configureInteractive` mounted at `plugin.setup.configureInteractive`
|
|
27
|
+
* — but that mount path is not read by any known OpenClaw version (neither
|
|
28
|
+
* 2026.3.x's top-level `plugin.configureInteractive` nor 2026.4.x's
|
|
29
|
+
* `plugin.auth.login`). 0.5.1 corrects the mount point and adopts the
|
|
30
|
+
* 2026.4.x `{cfg, accountId, runtime, verbose, channelInput}` signature.
|
|
21
31
|
*
|
|
22
|
-
* See #1264 for the design rationale (
|
|
23
|
-
*
|
|
24
|
-
* any previously-connected Runtime).
|
|
32
|
+
* See #1264 for the design rationale (single-driver Node semantic — re-running
|
|
33
|
+
* this flow rotates the api_key and evicts any previously-connected Runtime).
|
|
25
34
|
*/
|
|
35
|
+
import { cancel, confirm as clackConfirm, select as clackSelect, text as clackText, isCancel, } from "@clack/prompts";
|
|
36
|
+
import { writeCredentials } from "./config.js";
|
|
26
37
|
import { DEFAULT_API_HOST, onboard, PlatformApiError, } from "./platform-client.js";
|
|
27
38
|
// ---------------------------------------------------------------------------
|
|
28
39
|
// Constants
|
|
@@ -73,6 +84,14 @@ class DeviceFlowError extends Error {
|
|
|
73
84
|
}
|
|
74
85
|
class DeviceFlowExpired extends Error {
|
|
75
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* User pressed Ctrl+C at any prompter step. Subclass of `DeviceFlowError`
|
|
89
|
+
* so the existing throw/catch chain still works, but distinguished so the
|
|
90
|
+
* `login` handler can skip the redundant `runtime.error` call (clack's
|
|
91
|
+
* `cancel()` already emitted the canonical "cancelled" UI).
|
|
92
|
+
*/
|
|
93
|
+
class CancelError extends DeviceFlowError {
|
|
94
|
+
}
|
|
76
95
|
/**
|
|
77
96
|
* Run the RFC 8628 device flow loop. Returns the access_token on success.
|
|
78
97
|
* On expiration, restarts the loop transparently (user gets a fresh code).
|
|
@@ -272,55 +291,107 @@ async function createAgentLoop(platformCfg, accessToken, prompter) {
|
|
|
272
291
|
}
|
|
273
292
|
}
|
|
274
293
|
// ---------------------------------------------------------------------------
|
|
275
|
-
//
|
|
294
|
+
// Clack-backed Prompter adapter
|
|
295
|
+
// ---------------------------------------------------------------------------
|
|
296
|
+
/**
|
|
297
|
+
* Build a Prompter backed by `@clack/prompts` (the same library OpenClaw CLI
|
|
298
|
+
* uses internally, so the terminal UX is consistent with other channel
|
|
299
|
+
* plugins). Cancel sentinels (user Ctrl+C) are mapped to `DeviceFlowError`
|
|
300
|
+
* so the login function can treat cancels as a clean exit condition.
|
|
301
|
+
*/
|
|
302
|
+
function createClackPrompter() {
|
|
303
|
+
const abortOnCancel = (result) => {
|
|
304
|
+
if (isCancel(result)) {
|
|
305
|
+
// Emit clack's canonical cancel UI (bracketed red "cancelled") here so
|
|
306
|
+
// the user sees a clean exit indicator, then throw `CancelError` so the
|
|
307
|
+
// outer `login` catch returns silently (avoids printing the same line
|
|
308
|
+
// twice — UI from `cancel()` + a redundant `runtime.error` afterwards).
|
|
309
|
+
cancel("Setup cancelled.");
|
|
310
|
+
throw new CancelError("Setup cancelled by user.");
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
return {
|
|
314
|
+
async text(label) {
|
|
315
|
+
// `text(label, opts?.default)` previously mapped `opts.default` to clack's
|
|
316
|
+
// `placeholder` — but clack's `placeholder` is hint-only (not auto-submitted
|
|
317
|
+
// on empty input), and no current caller passes `opts.default`. Dropped
|
|
318
|
+
// the mapping until a real default-value need surfaces; revisit by
|
|
319
|
+
// implementing `clackText({ message, defaultValue })` then.
|
|
320
|
+
const result = await clackText({ message: label });
|
|
321
|
+
abortOnCancel(result);
|
|
322
|
+
return result;
|
|
323
|
+
},
|
|
324
|
+
async confirm(label) {
|
|
325
|
+
const result = await clackConfirm({ message: label });
|
|
326
|
+
abortOnCancel(result);
|
|
327
|
+
return result;
|
|
328
|
+
},
|
|
329
|
+
async select(label, choices) {
|
|
330
|
+
// Narrow the generic — we use `string` values throughout the flow.
|
|
331
|
+
const result = await clackSelect({
|
|
332
|
+
message: label,
|
|
333
|
+
options: choices.map((choice) => ({ value: choice, label: choice })),
|
|
334
|
+
});
|
|
335
|
+
abortOnCancel(result);
|
|
336
|
+
return result;
|
|
337
|
+
},
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
// ---------------------------------------------------------------------------
|
|
341
|
+
// Public hook — `plugin.auth.login` (OpenClaw 2026.4.x contract)
|
|
276
342
|
// ---------------------------------------------------------------------------
|
|
277
343
|
/**
|
|
278
|
-
*
|
|
344
|
+
* Channel login hook — invoked by `openclaw channels login --channel agent-network`.
|
|
279
345
|
*
|
|
280
|
-
*
|
|
281
|
-
*
|
|
346
|
+
* Unlike the legacy `configureInteractive` contract (which returned a config
|
|
347
|
+
* object for the CLI to persist), the 2026.4.x `auth.login` contract returns
|
|
348
|
+
* void and expects the plugin to persist any config changes itself. We use
|
|
349
|
+
* `writeCredentials()` in config.ts, which writes `openclaw.json` atomically
|
|
350
|
+
* and bumps the state-cache generation so Layer B's dynamic context re-reads
|
|
351
|
+
* on the next turn.
|
|
282
352
|
*
|
|
283
|
-
*
|
|
353
|
+
* Errors during device flow or onboarding are surfaced via `ctx.runtime.error`
|
|
354
|
+
* (not thrown) so OpenClaw CLI doesn't display a stack trace — matches the
|
|
355
|
+
* WhatsApp/Feishu pattern.
|
|
284
356
|
*/
|
|
285
|
-
export async function
|
|
286
|
-
const { prompter } = ctx;
|
|
357
|
+
export async function login(ctx) {
|
|
287
358
|
// Channel-level config (`cfg.apiHost`, `cfg.idpBaseUrl`) — both have
|
|
288
359
|
// defaults. Existing values from openclaw.json are preserved on re-run.
|
|
289
360
|
const apiHost = typeof ctx.cfg.apiHost === "string" ? ctx.cfg.apiHost : DEFAULT_API_HOST;
|
|
290
361
|
const idpBaseUrl = typeof ctx.cfg.idpBaseUrl === "string"
|
|
291
362
|
? ctx.cfg.idpBaseUrl
|
|
292
363
|
: DEFAULT_IDP_BASE_URL;
|
|
364
|
+
const prompter = createClackPrompter();
|
|
293
365
|
let creds;
|
|
294
366
|
try {
|
|
295
367
|
const accessToken = await deviceCodeFlow(idpBaseUrl, prompter);
|
|
296
368
|
creds = await agentSetup(apiHost, accessToken, prompter);
|
|
297
369
|
}
|
|
298
370
|
catch (err) {
|
|
371
|
+
if (err instanceof CancelError) {
|
|
372
|
+
// User pressed Ctrl+C. The clack `cancel()` call inside the prompter
|
|
373
|
+
// adapter already emitted the cancellation UI; nothing else to print.
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
299
376
|
if (err instanceof DeviceFlowError) {
|
|
300
|
-
//
|
|
301
|
-
|
|
302
|
-
|
|
377
|
+
// Device-flow / onboard error with a human-friendly message.
|
|
378
|
+
// Print and return cleanly — CLI shows nothing else on a return.
|
|
379
|
+
ctx.runtime.error(err.message);
|
|
380
|
+
return;
|
|
303
381
|
}
|
|
304
382
|
if (err instanceof PlatformApiError) {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
return "skip";
|
|
383
|
+
ctx.runtime.error(`Onboard failed (HTTP ${err.status} ${err.code}): ${err.message}`);
|
|
384
|
+
return;
|
|
308
385
|
}
|
|
386
|
+
// Unknown error — let CLI surface the stack. Surfaces platform bugs
|
|
387
|
+
// that aren't covered by our structured error types.
|
|
309
388
|
throw err;
|
|
310
389
|
}
|
|
311
|
-
//
|
|
312
|
-
// (see config-schema.ts). On the wire the field is
|
|
313
|
-
// disambiguate from "session token" /
|
|
314
|
-
// persisted as `token` for backward compatibility with
|
|
315
|
-
//
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
accounts: {
|
|
319
|
-
default: { connectorUrl: creds.connectorUrl, token: creds.apiKey },
|
|
320
|
-
},
|
|
321
|
-
apiHost,
|
|
322
|
-
idpBaseUrl,
|
|
323
|
-
},
|
|
324
|
-
accountId: "default",
|
|
325
|
-
};
|
|
390
|
+
// Persist: `openclaw.json` schema for an account is `{connectorUrl, token}`
|
|
391
|
+
// (see config-schema.ts). On the wire the onboard response field is
|
|
392
|
+
// `apiKey` to disambiguate from OAuth "session token" / JWT — but locally
|
|
393
|
+
// on disk it's persisted as `token` for backward compatibility with the
|
|
394
|
+
// existing `channel.resolveAccount()` reader.
|
|
395
|
+
await writeCredentials({ connectorUrl: creds.connectorUrl, token: creds.apiKey }, apiHost, idpBaseUrl);
|
|
396
|
+
ctx.runtime.log(`✓ Connected as @${creds.handle}`);
|
|
326
397
|
}
|
package/dist/config.d.ts
CHANGED
|
@@ -160,12 +160,16 @@ export interface NetworkCredentials {
|
|
|
160
160
|
token: string;
|
|
161
161
|
}
|
|
162
162
|
/**
|
|
163
|
-
* Write credentials + apiHost to `openclaw.json`.
|
|
163
|
+
* Write credentials + apiHost (+ optional idpBaseUrl) to `openclaw.json`.
|
|
164
164
|
*
|
|
165
|
-
* Atomic:
|
|
166
|
-
*
|
|
165
|
+
* Atomic: all fields are written in a single persistConfig() call to avoid
|
|
166
|
+
* partial-write race conditions.
|
|
167
|
+
*
|
|
168
|
+
* `idpBaseUrl` is written only when provided, mirroring `apiHost`'s pattern —
|
|
169
|
+
* omitted values leave any existing field in place (useful when callers want
|
|
170
|
+
* to refresh credentials without overriding IdP URL).
|
|
167
171
|
*/
|
|
168
|
-
export declare function writeCredentials(creds: NetworkCredentials, apiHost?: string): Promise<void>;
|
|
172
|
+
export declare function writeCredentials(creds: NetworkCredentials, apiHost?: string, idpBaseUrl?: string): Promise<void>;
|
|
169
173
|
/**
|
|
170
174
|
* Write pending connection target handle.
|
|
171
175
|
*
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,sBAAsB,CAAC;AAiC9B;;;GAGG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAEhD;AAcD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC3B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAMhC;AAMD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAyCjE;AAkCD;;;;GAIG;AACH,wBAAgB,yBAAyB,IAAI,OAAO,CAEnD;AAED;;;;;;;;GAQG;AACH,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAMD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI,CAOjE;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C;AAMD;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,mBAAmB,GAAG,IAAI,CAE1E;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,IAAI,IAAI,CAE/C;AAED;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,mBAAmB,CAOhE;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,IAAI,mBAAmB,GAAG,IAAI,CAEnE;AAMD;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAExD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAO9C;AAMD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,IAAI,oBAAoB,CAE5D;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAKtC;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,IAAI,CAEhD;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,IAAI,OAAO,CAEzC;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,IAAI,eAAe,CAOxD;AAMD,+EAA+E;AAC/E,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAgDD,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;CACf;AAED
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/config.js
CHANGED
|
@@ -362,12 +362,16 @@ function ensureNetworkSection(config) {
|
|
|
362
362
|
return channels["agent-network"];
|
|
363
363
|
}
|
|
364
364
|
/**
|
|
365
|
-
* Write credentials + apiHost to `openclaw.json`.
|
|
365
|
+
* Write credentials + apiHost (+ optional idpBaseUrl) to `openclaw.json`.
|
|
366
366
|
*
|
|
367
|
-
* Atomic:
|
|
368
|
-
*
|
|
367
|
+
* Atomic: all fields are written in a single persistConfig() call to avoid
|
|
368
|
+
* partial-write race conditions.
|
|
369
|
+
*
|
|
370
|
+
* `idpBaseUrl` is written only when provided, mirroring `apiHost`'s pattern —
|
|
371
|
+
* omitted values leave any existing field in place (useful when callers want
|
|
372
|
+
* to refresh credentials without overriding IdP URL).
|
|
369
373
|
*/
|
|
370
|
-
export async function writeCredentials(creds, apiHost) {
|
|
374
|
+
export async function writeCredentials(creds, apiHost, idpBaseUrl) {
|
|
371
375
|
const config = await readConfig();
|
|
372
376
|
const section = ensureNetworkSection(config);
|
|
373
377
|
section.enabled = true;
|
|
@@ -384,6 +388,11 @@ export async function writeCredentials(creds, apiHost) {
|
|
|
384
388
|
if (apiHost) {
|
|
385
389
|
section.apiHost = apiHost;
|
|
386
390
|
}
|
|
391
|
+
// Write idpBaseUrl if provided (Better Auth IdP URL for device flow).
|
|
392
|
+
// Added in 0.5.1 alongside the plugin.auth.login hook (#1264 follow-up).
|
|
393
|
+
if (idpBaseUrl) {
|
|
394
|
+
section.idpBaseUrl = idpBaseUrl;
|
|
395
|
+
}
|
|
387
396
|
await persistConfig(config);
|
|
388
397
|
// Update module-level var — deliberate exception to read/write separation,
|
|
389
398
|
// same pattern as clearTargetHandle(). Without this, tools fail with
|
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAiJA,UAAU,iBAAiB;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACjD,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACjE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,GAAG,IAAI,CAAC;CACnE;AAED,QAAA,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;kBAaI,iBAAiB;
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAiJA,UAAU,iBAAiB;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACjD,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACjE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,GAAG,IAAI,CAAC;CACnE;AAED,QAAA,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;kBAaI,iBAAiB;CA6XhC,CAAC;AAEF,eAAe,MAAM,CAAC"}
|
package/dist/plugin.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
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
5
|
import { agentNetworkChannel, consumeIdentityLinkingNudge } from "./channel.js";
|
|
6
|
-
import {
|
|
6
|
+
import { login } from "./cli-setup.js";
|
|
7
7
|
import { detectPendingState, getConversationManager, getDmScope, getStateCacheGeneration, initPluginRuntime, } from "./config.js";
|
|
8
8
|
import { getAgentIdentity } from "./environment-context.js";
|
|
9
9
|
import { ownerNotesQueue } from "./owner-notes.js";
|
|
@@ -126,27 +126,33 @@ const plugin = {
|
|
|
126
126
|
// Register tools FIRST — they must be available even when the channel
|
|
127
127
|
// has no credentials yet.
|
|
128
128
|
registerTools(api);
|
|
129
|
-
//
|
|
130
|
-
//
|
|
131
|
-
//
|
|
132
|
-
//
|
|
133
|
-
// are persisted to openclaw.json, OpenClaw hot-reloads and re-runs
|
|
134
|
-
// register() — the channel then activates.
|
|
129
|
+
// Register the agent-network channel. The 2026.4.x contract reads
|
|
130
|
+
// `plugin.auth?.login` for `openclaw channels login --channel agent-network`
|
|
131
|
+
// (CLI dispatch in `dist/channels-cli-Cc40S0aS.js:85`). Reference plugins
|
|
132
|
+
// (WhatsApp, Feishu in the OpenClaw bundle) use the same shape.
|
|
135
133
|
//
|
|
136
|
-
//
|
|
137
|
-
//
|
|
138
|
-
//
|
|
139
|
-
//
|
|
134
|
+
// History: 0.5.0 mounted this hook at `plugin.setup.configureInteractive`
|
|
135
|
+
// — a path no OpenClaw version reads, so `channels login` never worked.
|
|
136
|
+
// 0.5.1 corrected the mount point. 0.5.2 surfaces register errors
|
|
137
|
+
// instead of silently catching them — the previous "cheap guard"
|
|
138
|
+
// (`catch {}`) hid every kind of register-time failure including the
|
|
139
|
+
// ones we care about (schema validation, missing modules, IO errors).
|
|
140
|
+
//
|
|
141
|
+
// The new contract: log the error visibly AND re-throw, so OpenClaw
|
|
142
|
+
// surfaces the failure to the user rather than running with an
|
|
143
|
+
// un-registered channel that mysteriously "doesn't support login".
|
|
144
|
+
// Per Mingke's review of the 0.5.1 T1 failure (#1264, 2026-04-19).
|
|
140
145
|
try {
|
|
141
146
|
api.registerChannel({
|
|
142
147
|
plugin: {
|
|
143
148
|
...agentNetworkChannel,
|
|
144
|
-
|
|
149
|
+
auth: { login },
|
|
145
150
|
},
|
|
146
151
|
});
|
|
147
152
|
}
|
|
148
|
-
catch {
|
|
149
|
-
|
|
153
|
+
catch (err) {
|
|
154
|
+
console.error("[@masons/agent-network] api.registerChannel failed — channel will be unavailable:", err);
|
|
155
|
+
throw err;
|
|
150
156
|
}
|
|
151
157
|
// --- Layer B: Per-turn context injection ---
|
|
152
158
|
// Injects agent network awareness into every LLM turn via before_prompt_build.
|
package/dist/version.d.ts
CHANGED
package/dist/version.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,eAAO,MAAM,cAAc,
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,eAAO,MAAM,cAAc,WAAW,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.5.
|
|
2
|
+
export const PLUGIN_VERSION = "0.5.11";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@masons/agent-network",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.11",
|
|
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)",
|
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
}
|
|
59
59
|
},
|
|
60
60
|
"dependencies": {
|
|
61
|
+
"@clack/prompts": "^1.2.0",
|
|
61
62
|
"@sinclair/typebox": "^0.34",
|
|
62
63
|
"debug": "^4.4.3",
|
|
63
64
|
"ws": "8.18.3"
|