@goplus/agentguard 1.1.10 → 1.1.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.
- package/README.md +6 -4
- package/dist/adapters/common.d.ts.map +1 -1
- package/dist/adapters/common.js +3 -1
- package/dist/adapters/common.js.map +1 -1
- package/dist/adapters/openclaw-plugin.d.ts.map +1 -1
- package/dist/adapters/openclaw-plugin.js +17 -3
- package/dist/adapters/openclaw-plugin.js.map +1 -1
- package/dist/cli.js +109 -5
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +3 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +12 -0
- package/dist/config.js.map +1 -1
- package/dist/feed/cron.d.ts +1 -0
- package/dist/feed/cron.d.ts.map +1 -1
- package/dist/feed/cron.js +366 -50
- package/dist/feed/cron.js.map +1 -1
- package/dist/installers.js +110 -16
- package/dist/installers.js.map +1 -1
- package/dist/postinstall.js +24 -4
- package/dist/postinstall.js.map +1 -1
- package/dist/registry/storage.d.ts.map +1 -1
- package/dist/registry/storage.js +5 -1
- package/dist/registry/storage.js.map +1 -1
- package/dist/tests/cli-init.test.js +90 -0
- package/dist/tests/cli-init.test.js.map +1 -1
- package/dist/tests/cli-subscribe.test.js +33 -0
- package/dist/tests/cli-subscribe.test.js.map +1 -1
- package/dist/tests/feed-cron.test.js +205 -15
- package/dist/tests/feed-cron.test.js.map +1 -1
- package/dist/tests/installer.test.js +26 -4
- package/dist/tests/installer.test.js.map +1 -1
- package/dist/tests/integration.test.js +9 -5
- package/dist/tests/integration.test.js.map +1 -1
- package/dist/tests/postinstall.test.js +8 -4
- package/dist/tests/postinstall.test.js.map +1 -1
- package/dist/tests/setup-script.test.d.ts +2 -0
- package/dist/tests/setup-script.test.d.ts.map +1 -0
- package/dist/tests/setup-script.test.js +63 -0
- package/dist/tests/setup-script.test.js.map +1 -0
- package/dist/tests/smoke.test.js +88 -1
- package/dist/tests/smoke.test.js.map +1 -1
- package/docs/codex.md +1 -1
- package/docs/hermes.md +3 -3
- package/package.json +1 -1
- package/skills/agentguard/SKILL.md +404 -199
- package/skills/agentguard/hermes-hooks.yaml +2 -2
- package/skills/agentguard/scan-rules.md +13 -2
- package/skills/agentguard/scripts/{action-cli.ts → action-cli.js} +13 -18
- package/skills/agentguard/scripts/auto-scan.js +3 -1
- package/skills/agentguard/scripts/checkup-score.js +369 -0
- package/skills/agentguard/scripts/hermes-hook.js +103 -16
- package/skills/agentguard/scripts/scan-to-sarif.js +195 -0
- package/skills/agentguard/scripts/{trust-cli.ts → trust-cli.js} +12 -16
- package/skills/agentguard/suppress.example.yaml +67 -0
package/dist/config.js
CHANGED
|
@@ -63,6 +63,7 @@ function loadConfig() {
|
|
|
63
63
|
version: 1,
|
|
64
64
|
level: normalizeLevel(parsed.level) ?? fallback.level,
|
|
65
65
|
agentHost: normalizeAgentHost(parsed.agentHost),
|
|
66
|
+
agentHosts: normalizeAgentHosts(parsed.agentHosts),
|
|
66
67
|
cloudUrl: parsed.cloudUrl || fallback.cloudUrl,
|
|
67
68
|
policyCachePath: parsed.policyCachePath || fallback.policyCachePath,
|
|
68
69
|
auditPath: parsed.auditPath || fallback.auditPath,
|
|
@@ -139,6 +140,17 @@ function normalizeAgentHost(value) {
|
|
|
139
140
|
? value
|
|
140
141
|
: undefined;
|
|
141
142
|
}
|
|
143
|
+
function normalizeAgentHosts(value) {
|
|
144
|
+
if (!Array.isArray(value))
|
|
145
|
+
return undefined;
|
|
146
|
+
const seen = new Set();
|
|
147
|
+
for (const item of value) {
|
|
148
|
+
const host = normalizeAgentHost(item);
|
|
149
|
+
if (host)
|
|
150
|
+
seen.add(host);
|
|
151
|
+
}
|
|
152
|
+
return seen.size > 0 ? [...seen] : undefined;
|
|
153
|
+
}
|
|
142
154
|
function chmodBestEffort(path, mode) {
|
|
143
155
|
try {
|
|
144
156
|
(0, node_fs_1.chmodSync)(path, mode);
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/feed/cron.d.ts
CHANGED
package/dist/feed/cron.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cron.d.ts","sourceRoot":"","sources":["../../src/feed/cron.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cron.d.ts","sourceRoot":"","sources":["../../src/feed/cron.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAC9E,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG,kBAAkB,GAAG,eAAe,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAC1G,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG,OAAO,GAAG,UAAU,GAAG,QAAQ,GAAG,OAAO,CAAC;AAEtF,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACjE;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;AAExG,UAAU,eAAe;IACvB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAID,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAU5D;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAsB,qBAAqB,CACzC,OAAO,EAAE;IACP,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,EACD,QAAQ,GAAE;IACR,OAAO,CAAC,EAAE,sBAAsB,CAAC;IACjC,UAAU,CAAC,EAAE,aAAa,CAAC;CACvB,GACL,OAAO,CAAC,yBAAyB,CAAC,CAkDpC;AAED,wBAAsB,6BAA6B,CACjD,OAAO,EAAE;IACP,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,EACD,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,yBAAyB,CAAC,CA4DpC;AAuYD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,eAAe,EAAE,CAczE;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,OAAO,EACf,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,OAAO,CAAC,CAmBlB"}
|
package/dist/feed/cron.js
CHANGED
|
@@ -9,11 +9,15 @@ exports.installThreatFeedCron = installThreatFeedCron;
|
|
|
9
9
|
exports.installOpenClawThreatFeedCron = installOpenClawThreatFeedCron;
|
|
10
10
|
exports.extractOpenClawCronJobs = extractOpenClawCronJobs;
|
|
11
11
|
exports.openClawGatewayRequest = openClawGatewayRequest;
|
|
12
|
-
const node_http_1 = __importDefault(require("node:http"));
|
|
13
12
|
const node_child_process_1 = require("node:child_process");
|
|
13
|
+
const node_crypto_1 = require("node:crypto");
|
|
14
14
|
const promises_1 = require("node:fs/promises");
|
|
15
|
+
const node_http_1 = __importDefault(require("node:http"));
|
|
16
|
+
const node_net_1 = __importDefault(require("node:net"));
|
|
15
17
|
const node_os_1 = require("node:os");
|
|
16
18
|
const node_path_1 = require("node:path");
|
|
19
|
+
class GatewayHttpFallbackError extends Error {
|
|
20
|
+
}
|
|
17
21
|
function validateCronExpression(value) {
|
|
18
22
|
const expr = value.trim();
|
|
19
23
|
const fields = expr.split(/\s+/);
|
|
@@ -72,7 +76,7 @@ async function installThreatFeedCron(options, adapters = {}) {
|
|
|
72
76
|
async function installOpenClawThreatFeedCron(options, gateway = {}) {
|
|
73
77
|
const schedule = validateCronExpression(options.cronExpression);
|
|
74
78
|
const timezone = options.timezone ?? localTimeZone();
|
|
75
|
-
const command = threatFeedCommand(options.quiet);
|
|
79
|
+
const command = threatFeedCommand(options.quiet, { notifyRun: true });
|
|
76
80
|
const existing = await findOpenClawCronJobsByName(options.name, gateway);
|
|
77
81
|
if (existing.length > 0 && !options.force) {
|
|
78
82
|
return {
|
|
@@ -90,31 +94,30 @@ async function installOpenClawThreatFeedCron(options, gateway = {}) {
|
|
|
90
94
|
if (existing.length > 0) {
|
|
91
95
|
await removeOpenClawCronJobs(existing, gateway);
|
|
92
96
|
}
|
|
93
|
-
await openClawGatewayRequest('cron.add',
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
command,
|
|
111
|
-
},
|
|
112
|
-
},
|
|
113
|
-
delivery: {
|
|
114
|
-
mode: 'none',
|
|
97
|
+
await openClawGatewayRequest('cron.add', {
|
|
98
|
+
name: options.name,
|
|
99
|
+
description,
|
|
100
|
+
enabled: true,
|
|
101
|
+
schedule: {
|
|
102
|
+
kind: 'cron',
|
|
103
|
+
expr: schedule,
|
|
104
|
+
tz: timezone,
|
|
105
|
+
},
|
|
106
|
+
sessionTarget: 'isolated',
|
|
107
|
+
payload: {
|
|
108
|
+
kind: 'agentTurn',
|
|
109
|
+
message,
|
|
110
|
+
timeoutSeconds: 300,
|
|
111
|
+
agentguard: {
|
|
112
|
+
mode,
|
|
113
|
+
command,
|
|
115
114
|
},
|
|
116
115
|
},
|
|
117
|
-
|
|
116
|
+
delivery: {
|
|
117
|
+
mode: 'announce',
|
|
118
|
+
channel: 'last',
|
|
119
|
+
},
|
|
120
|
+
}, gateway);
|
|
118
121
|
return {
|
|
119
122
|
name: options.name,
|
|
120
123
|
schedule,
|
|
@@ -131,7 +134,7 @@ async function findOpenClawCronJobsByName(name, gateway) {
|
|
|
131
134
|
async function installOpenClawNativeThreatFeedCron(options, runCommand = execCommand) {
|
|
132
135
|
const schedule = validateCronExpression(options.cronExpression);
|
|
133
136
|
const timezone = options.timezone ?? localTimeZone();
|
|
134
|
-
const command = threatFeedCommand(options.quiet);
|
|
137
|
+
const command = threatFeedCommand(options.quiet, { notifyRun: true });
|
|
135
138
|
const message = openClawCronMessage(options.quiet);
|
|
136
139
|
let existing;
|
|
137
140
|
try {
|
|
@@ -167,6 +170,9 @@ async function installOpenClawNativeThreatFeedCron(options, runCommand = execCom
|
|
|
167
170
|
message,
|
|
168
171
|
'--timeout-seconds',
|
|
169
172
|
'300',
|
|
173
|
+
'--announce',
|
|
174
|
+
'--channel',
|
|
175
|
+
'last',
|
|
170
176
|
'--thinking',
|
|
171
177
|
'off',
|
|
172
178
|
];
|
|
@@ -301,8 +307,9 @@ async function installSystemThreatFeedCron(options, runCommand = execCommand) {
|
|
|
301
307
|
script,
|
|
302
308
|
};
|
|
303
309
|
}
|
|
304
|
-
function threatFeedCommand(quiet) {
|
|
305
|
-
|
|
310
|
+
function threatFeedCommand(quiet, options = {}) {
|
|
311
|
+
const modeFlag = options.notifyRun ? '--cron-notify-run' : '--json --cron-run';
|
|
312
|
+
return `agentguard subscribe${quiet ? ' --quiet' : ''} ${modeFlag}`;
|
|
306
313
|
}
|
|
307
314
|
function qclawGatewayOptions(gateway = {}) {
|
|
308
315
|
return {
|
|
@@ -367,17 +374,17 @@ function shellQuote(value) {
|
|
|
367
374
|
}
|
|
368
375
|
function openClawCronMessage(quiet) {
|
|
369
376
|
const mode = quiet ? 'quiet' : 'manual';
|
|
370
|
-
const command = threatFeedCommand(quiet);
|
|
377
|
+
const command = threatFeedCommand(quiet, { notifyRun: true });
|
|
371
378
|
return [
|
|
372
379
|
`Mode: ${mode}.`,
|
|
373
380
|
`Command: \`${command}\`.`,
|
|
374
381
|
`Run exactly the command above.`,
|
|
375
382
|
'',
|
|
376
383
|
'Rules:',
|
|
377
|
-
'-
|
|
378
|
-
'-
|
|
379
|
-
'-
|
|
380
|
-
'- If the command fails or
|
|
384
|
+
'- The command prints either the exact notification body or `NO_REPLY`.',
|
|
385
|
+
'- Output the command stdout exactly as your final response.',
|
|
386
|
+
'- Do not summarize, transform, add labels, or send a separate message.',
|
|
387
|
+
'- If the command fails or prints no stdout, output `NO_REPLY`.',
|
|
381
388
|
'',
|
|
382
389
|
'Follow these rules exactly.',
|
|
383
390
|
].join('\n');
|
|
@@ -464,16 +471,27 @@ function openClawGatewayRequest(method, params, options = {}) {
|
|
|
464
471
|
if (options.request) {
|
|
465
472
|
return options.request(method, params);
|
|
466
473
|
}
|
|
467
|
-
const payload = JSON.stringify({
|
|
468
|
-
jsonrpc: '2.0',
|
|
469
|
-
method,
|
|
470
|
-
params,
|
|
471
|
-
id: 1,
|
|
472
|
-
});
|
|
473
474
|
const host = options.host ?? '127.0.0.1';
|
|
474
475
|
const port = options.port ?? 18789;
|
|
475
476
|
const label = options.label ?? 'OpenClaw Gateway';
|
|
476
477
|
const timeoutMs = options.timeoutMs ?? 5000;
|
|
478
|
+
if (options.url) {
|
|
479
|
+
return openClawGatewayWebSocketRequest({ url: options.url, method, params, label, timeoutMs });
|
|
480
|
+
}
|
|
481
|
+
return openClawGatewayHttpRequest({ host, port, method, params, label, timeoutMs }).catch((err) => {
|
|
482
|
+
if (err instanceof GatewayHttpFallbackError) {
|
|
483
|
+
return openClawGatewayWebSocketRequest({ url: `ws://${host}:${port}`, method, params, label, timeoutMs });
|
|
484
|
+
}
|
|
485
|
+
throw err;
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
function openClawGatewayHttpRequest(options) {
|
|
489
|
+
const payload = JSON.stringify({
|
|
490
|
+
jsonrpc: '2.0',
|
|
491
|
+
method: options.method,
|
|
492
|
+
params: legacyGatewayParams(options.method, options.params),
|
|
493
|
+
id: 1,
|
|
494
|
+
});
|
|
477
495
|
return new Promise((resolve, reject) => {
|
|
478
496
|
let settled = false;
|
|
479
497
|
const fail = (err) => {
|
|
@@ -489,8 +507,8 @@ function openClawGatewayRequest(method, params, options = {}) {
|
|
|
489
507
|
resolve(value);
|
|
490
508
|
};
|
|
491
509
|
const req = node_http_1.default.request({
|
|
492
|
-
hostname: host,
|
|
493
|
-
port,
|
|
510
|
+
hostname: options.host,
|
|
511
|
+
port: options.port,
|
|
494
512
|
path: '/',
|
|
495
513
|
method: 'POST',
|
|
496
514
|
headers: {
|
|
@@ -501,7 +519,7 @@ function openClawGatewayRequest(method, params, options = {}) {
|
|
|
501
519
|
let data = '';
|
|
502
520
|
res.setEncoding('utf8');
|
|
503
521
|
res.on('error', (err) => {
|
|
504
|
-
fail(new Error(`${label} ${method} response failed: ${err.message}`));
|
|
522
|
+
fail(new Error(`${options.label} ${options.method} response failed: ${err.message}`));
|
|
505
523
|
});
|
|
506
524
|
res.on('data', (chunk) => {
|
|
507
525
|
data += chunk;
|
|
@@ -512,25 +530,25 @@ function openClawGatewayRequest(method, params, options = {}) {
|
|
|
512
530
|
parsed = data ? JSON.parse(data) : null;
|
|
513
531
|
}
|
|
514
532
|
catch {
|
|
515
|
-
fail(new
|
|
533
|
+
fail(new GatewayHttpFallbackError(`${options.label} returned non-JSON response: ${data}`));
|
|
516
534
|
return;
|
|
517
535
|
}
|
|
518
|
-
if (
|
|
519
|
-
fail(new
|
|
536
|
+
if (res.statusCode && res.statusCode >= 400) {
|
|
537
|
+
fail(new GatewayHttpFallbackError(`${options.label} ${options.method} failed with HTTP ${res.statusCode}`));
|
|
520
538
|
return;
|
|
521
539
|
}
|
|
522
|
-
if (
|
|
523
|
-
fail(new Error(`${label} ${method} failed
|
|
540
|
+
if (parsed?.error) {
|
|
541
|
+
fail(new Error(`${options.label} ${options.method} failed: ${parsed.error.message ?? JSON.stringify(parsed.error)}`));
|
|
524
542
|
return;
|
|
525
543
|
}
|
|
526
544
|
succeed(parsed?.result ?? parsed);
|
|
527
545
|
});
|
|
528
546
|
});
|
|
529
547
|
req.on('error', (err) => {
|
|
530
|
-
fail(new
|
|
548
|
+
fail(new GatewayHttpFallbackError(`Could not reach ${options.label} at ${options.host}:${options.port}: ${err.message}`));
|
|
531
549
|
});
|
|
532
|
-
req.setTimeout(timeoutMs, () => {
|
|
533
|
-
const err = new
|
|
550
|
+
req.setTimeout(options.timeoutMs, () => {
|
|
551
|
+
const err = new GatewayHttpFallbackError(`${options.label} ${options.method} request timed out after ${options.timeoutMs}ms`);
|
|
534
552
|
fail(err);
|
|
535
553
|
req.destroy(err);
|
|
536
554
|
});
|
|
@@ -538,4 +556,302 @@ function openClawGatewayRequest(method, params, options = {}) {
|
|
|
538
556
|
req.end();
|
|
539
557
|
});
|
|
540
558
|
}
|
|
559
|
+
function legacyGatewayParams(method, params) {
|
|
560
|
+
if (method === 'cron.add' && !Array.isArray(params))
|
|
561
|
+
return [params];
|
|
562
|
+
return params;
|
|
563
|
+
}
|
|
564
|
+
function openClawGatewayWebSocketRequest(options) {
|
|
565
|
+
const endpoint = parseGatewayWebSocketUrl(options.url, options.label);
|
|
566
|
+
return new Promise((resolve, reject) => {
|
|
567
|
+
const connectRequestId = (0, node_crypto_1.randomUUID)();
|
|
568
|
+
const methodRequestId = (0, node_crypto_1.randomUUID)();
|
|
569
|
+
const websocketKey = (0, node_crypto_1.randomBytes)(16).toString('base64');
|
|
570
|
+
let handshakeComplete = false;
|
|
571
|
+
let connected = false;
|
|
572
|
+
let settled = false;
|
|
573
|
+
let buffer = Buffer.alloc(0);
|
|
574
|
+
let fragmentedText = null;
|
|
575
|
+
const fail = (err) => {
|
|
576
|
+
if (settled)
|
|
577
|
+
return;
|
|
578
|
+
settled = true;
|
|
579
|
+
clearTimeout(timeout);
|
|
580
|
+
socket.destroy();
|
|
581
|
+
reject(err);
|
|
582
|
+
};
|
|
583
|
+
const succeed = (value) => {
|
|
584
|
+
if (settled)
|
|
585
|
+
return;
|
|
586
|
+
settled = true;
|
|
587
|
+
clearTimeout(timeout);
|
|
588
|
+
socket.end();
|
|
589
|
+
resolve(value);
|
|
590
|
+
};
|
|
591
|
+
const socket = node_net_1.default.createConnection({ host: endpoint.hostname, port: endpoint.port }, () => {
|
|
592
|
+
socket.write(buildWebSocketHandshake(endpoint, websocketKey));
|
|
593
|
+
});
|
|
594
|
+
const timeout = setTimeout(() => {
|
|
595
|
+
fail(new Error(`${options.label} ${options.method} request timed out after ${options.timeoutMs}ms`));
|
|
596
|
+
}, options.timeoutMs);
|
|
597
|
+
socket.on('error', (err) => {
|
|
598
|
+
fail(new Error(`Could not reach ${options.label} at ${endpoint.hostname}:${endpoint.port}: ${err.message}`));
|
|
599
|
+
});
|
|
600
|
+
socket.on('data', (chunk) => {
|
|
601
|
+
buffer = Buffer.concat([buffer, chunk]);
|
|
602
|
+
if (!handshakeComplete) {
|
|
603
|
+
const headerEnd = buffer.indexOf('\r\n\r\n');
|
|
604
|
+
if (headerEnd === -1)
|
|
605
|
+
return;
|
|
606
|
+
const header = buffer.subarray(0, headerEnd + 4).toString('utf8');
|
|
607
|
+
buffer = buffer.subarray(headerEnd + 4);
|
|
608
|
+
try {
|
|
609
|
+
validateWebSocketHandshake(header, websocketKey, options.label);
|
|
610
|
+
}
|
|
611
|
+
catch (err) {
|
|
612
|
+
fail(err);
|
|
613
|
+
return;
|
|
614
|
+
}
|
|
615
|
+
handshakeComplete = true;
|
|
616
|
+
}
|
|
617
|
+
while (true) {
|
|
618
|
+
let parsed;
|
|
619
|
+
try {
|
|
620
|
+
parsed = readWebSocketFrame(buffer);
|
|
621
|
+
}
|
|
622
|
+
catch (err) {
|
|
623
|
+
fail(err);
|
|
624
|
+
return;
|
|
625
|
+
}
|
|
626
|
+
if (!parsed)
|
|
627
|
+
break;
|
|
628
|
+
buffer = parsed.rest;
|
|
629
|
+
if (parsed.opcode === 0x8) {
|
|
630
|
+
fail(new Error(`${options.label} closed the WebSocket before ${options.method} completed`));
|
|
631
|
+
return;
|
|
632
|
+
}
|
|
633
|
+
if (parsed.opcode === 0x9) {
|
|
634
|
+
socket.write(encodeWebSocketFrame(parsed.payload.toString('utf8'), 0xA));
|
|
635
|
+
continue;
|
|
636
|
+
}
|
|
637
|
+
if (parsed.opcode === 0xA)
|
|
638
|
+
continue;
|
|
639
|
+
if (parsed.opcode === 0x1) {
|
|
640
|
+
if (fragmentedText) {
|
|
641
|
+
fail(new Error(`${options.label} started a new WebSocket text message before completing the previous one`));
|
|
642
|
+
return;
|
|
643
|
+
}
|
|
644
|
+
if (parsed.fin) {
|
|
645
|
+
handleGatewayFrame(parsed.payload.toString('utf8'));
|
|
646
|
+
}
|
|
647
|
+
else {
|
|
648
|
+
fragmentedText = [parsed.payload];
|
|
649
|
+
}
|
|
650
|
+
continue;
|
|
651
|
+
}
|
|
652
|
+
if (parsed.opcode === 0x0) {
|
|
653
|
+
if (!fragmentedText) {
|
|
654
|
+
fail(new Error(`${options.label} returned an unexpected WebSocket continuation frame`));
|
|
655
|
+
return;
|
|
656
|
+
}
|
|
657
|
+
fragmentedText.push(parsed.payload);
|
|
658
|
+
if (parsed.fin) {
|
|
659
|
+
const complete = Buffer.concat(fragmentedText);
|
|
660
|
+
fragmentedText = null;
|
|
661
|
+
handleGatewayFrame(complete.toString('utf8'));
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
});
|
|
666
|
+
function handleGatewayFrame(raw) {
|
|
667
|
+
let frame;
|
|
668
|
+
try {
|
|
669
|
+
frame = JSON.parse(raw);
|
|
670
|
+
}
|
|
671
|
+
catch {
|
|
672
|
+
fail(new Error(`${options.label} returned non-JSON WebSocket frame: ${raw}`));
|
|
673
|
+
return;
|
|
674
|
+
}
|
|
675
|
+
if (frame?.type === 'event' && frame.event === 'connect.challenge') {
|
|
676
|
+
socket.write(encodeWebSocketFrame(JSON.stringify({
|
|
677
|
+
type: 'req',
|
|
678
|
+
id: connectRequestId,
|
|
679
|
+
method: 'connect',
|
|
680
|
+
params: openClawConnectParams(),
|
|
681
|
+
})));
|
|
682
|
+
return;
|
|
683
|
+
}
|
|
684
|
+
if (frame?.type !== 'res')
|
|
685
|
+
return;
|
|
686
|
+
if (frame.id === connectRequestId) {
|
|
687
|
+
if (!frame.ok) {
|
|
688
|
+
fail(new Error(`${options.label} connect failed: ${gatewayFrameErrorMessage(frame)}`));
|
|
689
|
+
return;
|
|
690
|
+
}
|
|
691
|
+
connected = true;
|
|
692
|
+
socket.write(encodeWebSocketFrame(JSON.stringify({
|
|
693
|
+
type: 'req',
|
|
694
|
+
id: methodRequestId,
|
|
695
|
+
method: options.method,
|
|
696
|
+
params: options.params,
|
|
697
|
+
})));
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
700
|
+
if (connected && frame.id === methodRequestId) {
|
|
701
|
+
if (!frame.ok) {
|
|
702
|
+
fail(new Error(`${options.label} ${options.method} failed: ${gatewayFrameErrorMessage(frame)}`));
|
|
703
|
+
return;
|
|
704
|
+
}
|
|
705
|
+
succeed(frame.payload);
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
});
|
|
709
|
+
}
|
|
710
|
+
function parseGatewayWebSocketUrl(raw, label) {
|
|
711
|
+
let parsed;
|
|
712
|
+
try {
|
|
713
|
+
parsed = new URL(raw);
|
|
714
|
+
}
|
|
715
|
+
catch {
|
|
716
|
+
throw new Error(`${label} URL is invalid: ${raw}`);
|
|
717
|
+
}
|
|
718
|
+
if (parsed.protocol !== 'ws:') {
|
|
719
|
+
throw new Error(`${label} URL must use ws:// for Gateway WebSocket RPC.`);
|
|
720
|
+
}
|
|
721
|
+
const port = parsed.port ? Number(parsed.port) : 80;
|
|
722
|
+
if (!Number.isInteger(port) || port <= 0 || port > 65535) {
|
|
723
|
+
throw new Error(`${label} URL has an invalid port: ${raw}`);
|
|
724
|
+
}
|
|
725
|
+
const path = `${parsed.pathname || '/'}${parsed.search}`;
|
|
726
|
+
const hostname = parsed.hostname;
|
|
727
|
+
const hostHeader = parsed.port ? parsed.host : `${parsed.hostname}:${port}`;
|
|
728
|
+
return { hostname, port, path, hostHeader };
|
|
729
|
+
}
|
|
730
|
+
function buildWebSocketHandshake(endpoint, key) {
|
|
731
|
+
return [
|
|
732
|
+
`GET ${endpoint.path || '/'} HTTP/1.1`,
|
|
733
|
+
`Host: ${endpoint.hostHeader}`,
|
|
734
|
+
'Upgrade: websocket',
|
|
735
|
+
'Connection: Upgrade',
|
|
736
|
+
`Sec-WebSocket-Key: ${key}`,
|
|
737
|
+
'Sec-WebSocket-Version: 13',
|
|
738
|
+
'',
|
|
739
|
+
'',
|
|
740
|
+
].join('\r\n');
|
|
741
|
+
}
|
|
742
|
+
function validateWebSocketHandshake(header, key, label) {
|
|
743
|
+
const [statusLine, ...lines] = header.split(/\r\n/);
|
|
744
|
+
if (!/^HTTP\/1\.[01] 101\b/.test(statusLine ?? '')) {
|
|
745
|
+
throw new Error(`${label} WebSocket upgrade failed: ${statusLine || 'empty response'}`);
|
|
746
|
+
}
|
|
747
|
+
const headers = new Map();
|
|
748
|
+
for (const line of lines) {
|
|
749
|
+
const index = line.indexOf(':');
|
|
750
|
+
if (index === -1)
|
|
751
|
+
continue;
|
|
752
|
+
headers.set(line.slice(0, index).trim().toLowerCase(), line.slice(index + 1).trim());
|
|
753
|
+
}
|
|
754
|
+
const expected = (0, node_crypto_1.createHash)('sha1')
|
|
755
|
+
.update(`${key}258EAFA5-E914-47DA-95CA-C5AB0DC85B11`)
|
|
756
|
+
.digest('base64');
|
|
757
|
+
if (headers.get('sec-websocket-accept') !== expected) {
|
|
758
|
+
throw new Error(`${label} WebSocket upgrade returned an invalid accept key.`);
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
function readWebSocketFrame(buffer) {
|
|
762
|
+
if (buffer.length < 2)
|
|
763
|
+
return null;
|
|
764
|
+
const first = buffer[0];
|
|
765
|
+
const second = buffer[1];
|
|
766
|
+
const fin = (first & 0x80) !== 0;
|
|
767
|
+
const opcode = first & 0x0f;
|
|
768
|
+
const masked = (second & 0x80) !== 0;
|
|
769
|
+
if (masked) {
|
|
770
|
+
throw new Error('WebSocket server frames must not be masked.');
|
|
771
|
+
}
|
|
772
|
+
if (opcode >= 0x8 && !fin) {
|
|
773
|
+
throw new Error('WebSocket control frames must not be fragmented.');
|
|
774
|
+
}
|
|
775
|
+
let length = second & 0x7f;
|
|
776
|
+
let offset = 2;
|
|
777
|
+
if (length === 126) {
|
|
778
|
+
if (buffer.length < offset + 2)
|
|
779
|
+
return null;
|
|
780
|
+
length = buffer.readUInt16BE(offset);
|
|
781
|
+
offset += 2;
|
|
782
|
+
}
|
|
783
|
+
else if (length === 127) {
|
|
784
|
+
if (buffer.length < offset + 8)
|
|
785
|
+
return null;
|
|
786
|
+
const longLength = buffer.readBigUInt64BE(offset);
|
|
787
|
+
if (longLength > BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
788
|
+
throw new Error('WebSocket frame is too large.');
|
|
789
|
+
}
|
|
790
|
+
length = Number(longLength);
|
|
791
|
+
offset += 8;
|
|
792
|
+
}
|
|
793
|
+
if (opcode >= 0x8 && length > 125) {
|
|
794
|
+
throw new Error('WebSocket control frames must not exceed 125 bytes.');
|
|
795
|
+
}
|
|
796
|
+
const mask = masked ? buffer.subarray(offset, offset + 4) : null;
|
|
797
|
+
if (masked)
|
|
798
|
+
offset += 4;
|
|
799
|
+
if (buffer.length < offset + length)
|
|
800
|
+
return null;
|
|
801
|
+
const payload = Buffer.from(buffer.subarray(offset, offset + length));
|
|
802
|
+
if (mask) {
|
|
803
|
+
for (let i = 0; i < payload.length; i += 1) {
|
|
804
|
+
payload[i] = payload[i] ^ mask[i % 4];
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
return { fin, opcode, payload, rest: buffer.subarray(offset + length) };
|
|
808
|
+
}
|
|
809
|
+
function encodeWebSocketFrame(text, opcode = 0x1) {
|
|
810
|
+
const payload = Buffer.from(text, 'utf8');
|
|
811
|
+
const mask = (0, node_crypto_1.randomBytes)(4);
|
|
812
|
+
const headerLength = payload.length < 126 ? 2 : payload.length <= 0xffff ? 4 : 10;
|
|
813
|
+
const header = Buffer.alloc(headerLength);
|
|
814
|
+
header[0] = 0x80 | opcode;
|
|
815
|
+
if (payload.length < 126) {
|
|
816
|
+
header[1] = 0x80 | payload.length;
|
|
817
|
+
}
|
|
818
|
+
else if (payload.length <= 0xffff) {
|
|
819
|
+
header[1] = 0x80 | 126;
|
|
820
|
+
header.writeUInt16BE(payload.length, 2);
|
|
821
|
+
}
|
|
822
|
+
else {
|
|
823
|
+
header[1] = 0x80 | 127;
|
|
824
|
+
header.writeBigUInt64BE(BigInt(payload.length), 2);
|
|
825
|
+
}
|
|
826
|
+
const masked = Buffer.from(payload);
|
|
827
|
+
for (let i = 0; i < masked.length; i += 1) {
|
|
828
|
+
masked[i] = masked[i] ^ mask[i % 4];
|
|
829
|
+
}
|
|
830
|
+
return Buffer.concat([header, mask, masked]);
|
|
831
|
+
}
|
|
832
|
+
function openClawConnectParams() {
|
|
833
|
+
return {
|
|
834
|
+
minProtocol: 3,
|
|
835
|
+
maxProtocol: 3,
|
|
836
|
+
client: {
|
|
837
|
+
id: 'cli',
|
|
838
|
+
version: 'agentguard',
|
|
839
|
+
platform: process.platform,
|
|
840
|
+
mode: 'cli',
|
|
841
|
+
},
|
|
842
|
+
caps: [],
|
|
843
|
+
role: 'operator',
|
|
844
|
+
scopes: [
|
|
845
|
+
'operator.admin',
|
|
846
|
+
'operator.read',
|
|
847
|
+
'operator.write',
|
|
848
|
+
'operator.approvals',
|
|
849
|
+
'operator.pairing',
|
|
850
|
+
'operator.talk.secrets',
|
|
851
|
+
],
|
|
852
|
+
};
|
|
853
|
+
}
|
|
854
|
+
function gatewayFrameErrorMessage(frame) {
|
|
855
|
+
return frame?.error?.message ?? JSON.stringify(frame?.error ?? frame);
|
|
856
|
+
}
|
|
541
857
|
//# sourceMappingURL=cron.js.map
|