@goplus/agentguard 1.1.18 → 1.1.26
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 -1
- package/dist/adapters/engine.d.ts.map +1 -1
- package/dist/adapters/engine.js +10 -0
- package/dist/adapters/engine.js.map +1 -1
- package/dist/adapters/openclaw-plugin.d.ts.map +1 -1
- package/dist/adapters/openclaw-plugin.js +24 -3
- package/dist/adapters/openclaw-plugin.js.map +1 -1
- package/dist/adapters/openclaw.d.ts.map +1 -1
- package/dist/adapters/openclaw.js +7 -2
- package/dist/adapters/openclaw.js.map +1 -1
- package/dist/cli.js +254 -72
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +5 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +13 -0
- package/dist/config.js.map +1 -1
- package/dist/feed/cron.d.ts +17 -0
- package/dist/feed/cron.d.ts.map +1 -1
- package/dist/feed/cron.js +197 -18
- package/dist/feed/cron.js.map +1 -1
- package/dist/feed/selfcheck.d.ts.map +1 -1
- package/dist/feed/selfcheck.js +205 -54
- package/dist/feed/selfcheck.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -1
- package/dist/index.js.map +1 -1
- package/dist/installers.d.ts.map +1 -1
- package/dist/installers.js +91 -5
- package/dist/installers.js.map +1 -1
- package/dist/runtime/approvals.d.ts +38 -0
- package/dist/runtime/approvals.d.ts.map +1 -0
- package/dist/runtime/approvals.js +227 -0
- package/dist/runtime/approvals.js.map +1 -0
- package/dist/runtime/evaluator.d.ts.map +1 -1
- package/dist/runtime/evaluator.js +54 -0
- package/dist/runtime/evaluator.js.map +1 -1
- package/dist/runtime/protect.d.ts +2 -0
- package/dist/runtime/protect.d.ts.map +1 -1
- package/dist/runtime/protect.js +81 -9
- package/dist/runtime/protect.js.map +1 -1
- package/dist/runtime/self-command.d.ts +2 -0
- package/dist/runtime/self-command.d.ts.map +1 -0
- package/dist/runtime/self-command.js +93 -0
- package/dist/runtime/self-command.js.map +1 -0
- package/dist/tests/adapter.test.js +8 -0
- package/dist/tests/adapter.test.js.map +1 -1
- package/dist/tests/cli-connect.test.js +118 -1
- package/dist/tests/cli-connect.test.js.map +1 -1
- package/dist/tests/cli-init.test.js +123 -0
- package/dist/tests/cli-init.test.js.map +1 -1
- package/dist/tests/cli-subscribe.test.js +176 -0
- package/dist/tests/cli-subscribe.test.js.map +1 -1
- package/dist/tests/feed-cron.test.js +236 -0
- package/dist/tests/feed-cron.test.js.map +1 -1
- package/dist/tests/feed-selfcheck.test.js +81 -0
- package/dist/tests/feed-selfcheck.test.js.map +1 -1
- package/dist/tests/installer.test.js +78 -2
- package/dist/tests/installer.test.js.map +1 -1
- package/dist/tests/integration.test.js +64 -0
- package/dist/tests/integration.test.js.map +1 -1
- package/dist/tests/runtime-cloud.test.js +406 -0
- package/dist/tests/runtime-cloud.test.js.map +1 -1
- package/docs/claude-code.md +3 -2
- package/docs/cloud-connect.md +16 -3
- package/docs/cloud-native-api.md +26 -118
- package/docs/codex.md +13 -1
- package/docs/openclaw.md +32 -1
- package/docs/privacy-boundary.md +0 -1
- package/package.json +1 -1
- package/skills/agentguard/SKILL.md +14 -4
package/dist/cli.js
CHANGED
|
@@ -10,6 +10,7 @@ const client_js_1 = require("./cloud/client.js");
|
|
|
10
10
|
const config_js_1 = require("./config.js");
|
|
11
11
|
const index_js_1 = require("./scanner/index.js");
|
|
12
12
|
const protect_js_1 = require("./runtime/protect.js");
|
|
13
|
+
const approvals_js_1 = require("./runtime/approvals.js");
|
|
13
14
|
const policy_js_1 = require("./runtime/policy.js");
|
|
14
15
|
const installers_js_1 = require("./installers.js");
|
|
15
16
|
const version_js_1 = require("./version.js");
|
|
@@ -101,10 +102,11 @@ async function main() {
|
|
|
101
102
|
.action(async (options) => {
|
|
102
103
|
const apiKey = options.key || options.apiKey || process.env.AGENTGUARD_API_KEY;
|
|
103
104
|
if (!apiKey) {
|
|
104
|
-
|
|
105
|
+
let config = (0, config_js_1.ensureConfig)();
|
|
105
106
|
if (!isOpenClawAgentConfigured(config)) {
|
|
106
|
-
throw new Error('
|
|
107
|
+
throw new Error('AgentGuard Cloud connect supports API-key auth or OpenClaw Agent JWT registration. No API key was provided, and OpenClaw has not been initialized. Run `agentguard init --agent openclaw`, then rerun `agentguard connect`; or pass --key, --api-key, or AGENTGUARD_API_KEY for API-key auth.');
|
|
107
108
|
}
|
|
109
|
+
config = withDetectedOpenClawAgentHost(config);
|
|
108
110
|
const cloudUrl = (0, config_js_1.normalizeCloudUrl)(options.cloud || options.url || config.cloudUrl || 'https://agentguard.gopluslabs.io');
|
|
109
111
|
if (config.agentId && config.agentJwt) {
|
|
110
112
|
const existingConfig = { ...config, cloudUrl };
|
|
@@ -117,10 +119,11 @@ async function main() {
|
|
|
117
119
|
agentRegisterUrl: config.agentRegisterUrl,
|
|
118
120
|
cloudUrl,
|
|
119
121
|
});
|
|
120
|
-
(0,
|
|
121
|
-
|
|
122
|
-
console.log(`
|
|
123
|
-
console.log(`
|
|
122
|
+
const activeConfig = (0, config_js_1.clearAgentRegisterUrl)(savedConfig);
|
|
123
|
+
(0, policy_js_1.saveCachedPolicy)(activeConfig.policyCachePath, policy);
|
|
124
|
+
console.log(`Connected to AgentGuard Cloud (${activeConfig.cloudUrl}).`);
|
|
125
|
+
console.log(`Agent JWT is active for local agent ${activeConfig.agentId}.`);
|
|
126
|
+
console.log(`Cached policy ${policy.policyVersion} at ${activeConfig.policyCachePath}.`);
|
|
124
127
|
return;
|
|
125
128
|
}
|
|
126
129
|
catch (err) {
|
|
@@ -131,14 +134,20 @@ async function main() {
|
|
|
131
134
|
}
|
|
132
135
|
}
|
|
133
136
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
137
|
+
let registration;
|
|
138
|
+
try {
|
|
139
|
+
registration = await registerAgentCredential({
|
|
140
|
+
cloudUrl,
|
|
141
|
+
reason: 'connect',
|
|
142
|
+
notifyOpenClaw: false,
|
|
143
|
+
resetExistingJwt: true,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
catch (err) {
|
|
147
|
+
throw new Error(`Could not register AgentGuard agent: ${err instanceof Error ? err.message : String(err)}`);
|
|
148
|
+
}
|
|
140
149
|
console.log(`Registered local AgentGuard agent (${registration.config.agentId}).`);
|
|
141
|
-
console.log('Open this link to bind
|
|
150
|
+
console.log('Open this link to bind this agent to your account:');
|
|
142
151
|
console.log(registration.registerUrl);
|
|
143
152
|
if (registration.openClawNotification.notified) {
|
|
144
153
|
console.log('Sent the activation link to the last OpenClaw channel.');
|
|
@@ -164,25 +173,30 @@ async function main() {
|
|
|
164
173
|
program
|
|
165
174
|
.command('disconnect')
|
|
166
175
|
.description('Disconnect local AgentGuard from AgentGuard Cloud')
|
|
167
|
-
.action(() => {
|
|
176
|
+
.action(async () => {
|
|
177
|
+
const currentConfig = (0, config_js_1.ensureConfig)();
|
|
178
|
+
const cronRemoval = await (0, cron_js_1.removeThreatFeedCron)({
|
|
179
|
+
name: currentConfig.threatFeedCronName || 'agentguard-threat-feed',
|
|
180
|
+
backend: 'auto',
|
|
181
|
+
agentHost: resolveCronAgentHost(currentConfig),
|
|
182
|
+
agentGuardHome: (0, config_js_1.getAgentGuardPaths)().home,
|
|
183
|
+
});
|
|
168
184
|
const config = (0, config_js_1.disconnectCloud)();
|
|
169
185
|
console.log('Disconnected from AgentGuard Cloud.');
|
|
170
186
|
console.log('Removed local Cloud API key, Agent JWT, connection timestamp, pending event spool, and cached Cloud policy.');
|
|
187
|
+
printCronRemovalSummary(cronRemoval);
|
|
171
188
|
console.log(`Local protection remains active using the built-in policy. Audit log: ${config.auditPath}`);
|
|
172
189
|
});
|
|
173
190
|
program
|
|
174
191
|
.command('status')
|
|
175
192
|
.description('Show local and Cloud connection status')
|
|
176
|
-
.action(() => {
|
|
177
|
-
const config = (0, config_js_1.ensureConfig)();
|
|
193
|
+
.action(async () => {
|
|
194
|
+
const config = await refreshAgentAccountBinding((0, config_js_1.ensureConfig)());
|
|
178
195
|
const paths = (0, config_js_1.getAgentGuardPaths)();
|
|
179
196
|
console.log(`Config: ${paths.configPath}`);
|
|
180
197
|
console.log(`Protection level: ${config.level}`);
|
|
181
198
|
console.log(`Cloud URL: ${config.cloudUrl || 'not configured'}`);
|
|
182
|
-
|
|
183
|
-
console.log(`Agent ID: ${config.agentId || 'not configured'}`);
|
|
184
|
-
console.log(`Agent JWT: ${config.agentJwt ? 'configured' : 'not configured'}`);
|
|
185
|
-
console.log(`Agent activation URL: ${config.agentRegisterUrl || 'not configured'}`);
|
|
199
|
+
printCloudAuthStatus(config);
|
|
186
200
|
console.log(`Agent host: ${config.agentHost || 'not configured'}`);
|
|
187
201
|
console.log(`Agent hosts: ${config.agentHosts?.join(', ') || 'not configured'}`);
|
|
188
202
|
console.log(`Policy cache: ${config.policyCachePath}`);
|
|
@@ -324,6 +338,55 @@ async function main() {
|
|
|
324
338
|
}
|
|
325
339
|
process.exitCode = result.risk_level === 'critical' ? 2 : 0;
|
|
326
340
|
});
|
|
341
|
+
program
|
|
342
|
+
.command('approve')
|
|
343
|
+
.description('Approve one pending runtime action')
|
|
344
|
+
.option('--action-id <id>', 'Pending action id returned by agentguard protect')
|
|
345
|
+
.option('--last', 'Approve the most recent unambiguous pending action')
|
|
346
|
+
.option('--once', 'Approve only the next matching retry')
|
|
347
|
+
.option('--json', 'Print JSON output')
|
|
348
|
+
.action((options) => {
|
|
349
|
+
if (!options.once) {
|
|
350
|
+
throw new Error('Approvals must be scoped with --once.');
|
|
351
|
+
}
|
|
352
|
+
const config = (0, config_js_1.ensureConfig)();
|
|
353
|
+
const approved = (0, approvals_js_1.approvePendingApproval)(config.approvalStorePath, {
|
|
354
|
+
actionId: options.actionId,
|
|
355
|
+
last: Boolean(options.last),
|
|
356
|
+
once: true,
|
|
357
|
+
sessionId: process.env.AGENTGUARD_SESSION_ID,
|
|
358
|
+
});
|
|
359
|
+
if (options.json) {
|
|
360
|
+
console.log(JSON.stringify({ success: true, approval: approved }, null, 2));
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
console.log(`Approved once: ${approved.actionId}`);
|
|
364
|
+
console.log(`Expires: ${approved.expiresAt}`);
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
const approvals = program
|
|
368
|
+
.command('approvals')
|
|
369
|
+
.description('Inspect pending runtime approvals');
|
|
370
|
+
approvals
|
|
371
|
+
.command('list')
|
|
372
|
+
.description('List unexpired pending approvals')
|
|
373
|
+
.option('--json', 'Print JSON output')
|
|
374
|
+
.action((options) => {
|
|
375
|
+
const config = (0, config_js_1.ensureConfig)();
|
|
376
|
+
const pending = (0, approvals_js_1.listPendingApprovals)(config.approvalStorePath);
|
|
377
|
+
if (options.json) {
|
|
378
|
+
console.log(JSON.stringify({ success: true, approvals: pending }, null, 2));
|
|
379
|
+
}
|
|
380
|
+
else if (pending.length === 0) {
|
|
381
|
+
console.log('No pending approvals.');
|
|
382
|
+
}
|
|
383
|
+
else {
|
|
384
|
+
for (const approval of pending) {
|
|
385
|
+
console.log(`${approval.actionId} ${approval.actionType} ${approval.toolName} expires=${approval.expiresAt}`);
|
|
386
|
+
console.log(` ${approval.inputPreview}`);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
});
|
|
327
390
|
program
|
|
328
391
|
.command('protect')
|
|
329
392
|
.description('Evaluate one runtime action from stdin or hook environment')
|
|
@@ -370,6 +433,7 @@ async function main() {
|
|
|
370
433
|
const since = options.since;
|
|
371
434
|
const quiet = Boolean(options.quiet);
|
|
372
435
|
const cronNotifyRun = Boolean(options.cronNotifyRun);
|
|
436
|
+
const cronInternalRun = Boolean(options.cronRun || options.cronNotifyRun);
|
|
373
437
|
const cronTarget = validateCronTarget(options.cronTarget);
|
|
374
438
|
const cronRunSendsToOpenClaw = Boolean(options.cronRun) && cronAgentHost === 'openclaw';
|
|
375
439
|
const cronExpression = options.cron && !options.cronRun
|
|
@@ -411,47 +475,39 @@ async function main() {
|
|
|
411
475
|
return;
|
|
412
476
|
}
|
|
413
477
|
}
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
if (
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
process.exitCode =
|
|
478
|
+
if (!cronInternalRun) {
|
|
479
|
+
try {
|
|
480
|
+
await client.subscribeFeed();
|
|
481
|
+
}
|
|
482
|
+
catch (err) {
|
|
483
|
+
if (err instanceof client_js_2.CloudRequestError && err.status === 401) {
|
|
484
|
+
if (!isOpenClawAgentConfigured(config)) {
|
|
485
|
+
console.error('! AgentGuard Cloud credential was rejected. Run `agentguard connect --key <key>` again.');
|
|
486
|
+
process.exitCode = 1;
|
|
487
|
+
return;
|
|
488
|
+
}
|
|
489
|
+
try {
|
|
490
|
+
registration = await registerAgentCredential({
|
|
491
|
+
cloudUrl: config.cloudUrl,
|
|
492
|
+
reason: 'subscribe',
|
|
493
|
+
notifyOpenClaw: resolveCronAgentHost(config) === 'openclaw',
|
|
494
|
+
resetExistingJwt: true,
|
|
495
|
+
});
|
|
496
|
+
config = registration.config;
|
|
497
|
+
client = registration.client;
|
|
498
|
+
await client.subscribeFeed();
|
|
499
|
+
}
|
|
500
|
+
catch (retryErr) {
|
|
501
|
+
printAgentActivationRequired(registration, retryErr);
|
|
502
|
+
process.exitCode = 1;
|
|
439
503
|
return;
|
|
440
504
|
}
|
|
441
|
-
printAgentActivationRequired(registration, retryErr);
|
|
442
|
-
process.exitCode = 1;
|
|
443
|
-
return;
|
|
444
505
|
}
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
console.log('NO_REPLY');
|
|
449
|
-
process.exitCode = 0;
|
|
506
|
+
else {
|
|
507
|
+
console.error(`! Could not subscribe to AgentGuard Cloud feed: ${err.message}`);
|
|
508
|
+
process.exitCode = 1;
|
|
450
509
|
return;
|
|
451
510
|
}
|
|
452
|
-
console.error(`! Could not subscribe to AgentGuard Cloud feed: ${err.message}`);
|
|
453
|
-
process.exitCode = 1;
|
|
454
|
-
return;
|
|
455
511
|
}
|
|
456
512
|
}
|
|
457
513
|
if (registration && !cronNotifyRun && !quiet && !options.json) {
|
|
@@ -463,6 +519,11 @@ async function main() {
|
|
|
463
519
|
}
|
|
464
520
|
catch (err) {
|
|
465
521
|
if (err instanceof client_js_2.CloudRequestError && err.status === 401) {
|
|
522
|
+
if (cronInternalRun) {
|
|
523
|
+
await printSubscribeConnectRequired(options, cronRunSendsToOpenClaw);
|
|
524
|
+
process.exitCode = 1;
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
466
527
|
if (!isOpenClawAgentConfigured(config)) {
|
|
467
528
|
console.error('! AgentGuard Cloud credential was rejected. Run `agentguard connect --key <key>` again.');
|
|
468
529
|
process.exitCode = 1;
|
|
@@ -545,22 +606,35 @@ async function main() {
|
|
|
545
606
|
// match, we must NOT mark the advisory seen, otherwise a
|
|
546
607
|
// transient network blip silently buries a real hit.
|
|
547
608
|
try {
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
client,
|
|
551
|
-
reason: 'reauth',
|
|
552
|
-
notifyOpenClaw: resolveCronAgentHost(config) === 'openclaw',
|
|
553
|
-
operation: (activeClient) => activeClient.reportSelfCheck(advisory.id, result.matchedArtifacts, {
|
|
609
|
+
if (cronInternalRun) {
|
|
610
|
+
await client.reportSelfCheck(advisory.id, result.matchedArtifacts, {
|
|
554
611
|
elapsedMs: result.elapsedMs,
|
|
555
612
|
warnings: result.warnings,
|
|
556
|
-
})
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
613
|
+
});
|
|
614
|
+
}
|
|
615
|
+
else {
|
|
616
|
+
const reportResult = await runCloudRequestWithAgentJwtReauth({
|
|
617
|
+
config,
|
|
618
|
+
client,
|
|
619
|
+
reason: 'reauth',
|
|
620
|
+
notifyOpenClaw: resolveCronAgentHost(config) === 'openclaw',
|
|
621
|
+
operation: (activeClient) => activeClient.reportSelfCheck(advisory.id, result.matchedArtifacts, {
|
|
622
|
+
elapsedMs: result.elapsedMs,
|
|
623
|
+
warnings: result.warnings,
|
|
624
|
+
}),
|
|
625
|
+
});
|
|
626
|
+
config = reportResult.config;
|
|
627
|
+
client = reportResult.client;
|
|
628
|
+
if (reportResult.registration)
|
|
629
|
+
registration = reportResult.registration;
|
|
630
|
+
}
|
|
562
631
|
}
|
|
563
632
|
catch (err) {
|
|
633
|
+
if (cronInternalRun && err instanceof client_js_2.CloudRequestError && err.status === 401) {
|
|
634
|
+
await printSubscribeConnectRequired(options, cronRunSendsToOpenClaw);
|
|
635
|
+
process.exitCode = 1;
|
|
636
|
+
return;
|
|
637
|
+
}
|
|
564
638
|
console.error(`! Failed to report self-check for ${advisory.id}: ${err.message}`);
|
|
565
639
|
processed = false;
|
|
566
640
|
hardFailures += 1;
|
|
@@ -611,6 +685,13 @@ async function main() {
|
|
|
611
685
|
backend: cronTarget,
|
|
612
686
|
agentHost: resolveCronAgentHost(config),
|
|
613
687
|
agentGuardHome: (0, config_js_1.getAgentGuardPaths)().home,
|
|
688
|
+
}, {
|
|
689
|
+
gateway: resolveOpenClawGatewayOptionsFromEnv(),
|
|
690
|
+
});
|
|
691
|
+
(0, config_js_1.saveConfig)({
|
|
692
|
+
...config,
|
|
693
|
+
threatFeedCronName: summary.cron.result.name,
|
|
694
|
+
threatFeedCronInstalledAt: new Date().toISOString(),
|
|
614
695
|
});
|
|
615
696
|
summary.cron.installed = true;
|
|
616
697
|
}
|
|
@@ -663,8 +744,8 @@ async function main() {
|
|
|
663
744
|
if (!quiet && fresh.length > 0) {
|
|
664
745
|
console.log(summary.notification?.body ?? formatNewAdvisoryNotification(fresh));
|
|
665
746
|
}
|
|
666
|
-
else if (quiet && fresh.length > 0) {
|
|
667
|
-
console.log(`Self-check found ${totalMatches} match(es) across
|
|
747
|
+
else if (quiet && (fresh.length > 0 || summary.cron.result)) {
|
|
748
|
+
console.log(`Self-check found ${totalMatches} match(es) across ${fresh.length} new advisory record(s).`);
|
|
668
749
|
for (const r of results) {
|
|
669
750
|
if (r.matchedArtifacts.length === 0)
|
|
670
751
|
continue;
|
|
@@ -844,6 +925,85 @@ function printInitGuidanceIfNeeded(config) {
|
|
|
844
925
|
console.log('Required next step:');
|
|
845
926
|
console.log(` ${REQUIRED_INIT_COMMAND}`);
|
|
846
927
|
}
|
|
928
|
+
function printCloudAuthStatus(config) {
|
|
929
|
+
if (config.agentJwt) {
|
|
930
|
+
console.log('Cloud auth: connected via Agent JWT');
|
|
931
|
+
console.log('API key: not used for this connection');
|
|
932
|
+
console.log(`Agent ID: ${config.agentId || 'configured'}`);
|
|
933
|
+
console.log('Agent JWT: configured');
|
|
934
|
+
if (config.agentRegisterUrl) {
|
|
935
|
+
console.log('Agent account: not bound (activation required)');
|
|
936
|
+
console.log(`Agent activation URL: ${config.agentRegisterUrl}`);
|
|
937
|
+
}
|
|
938
|
+
else {
|
|
939
|
+
console.log('Agent account: bound');
|
|
940
|
+
console.log('Agent activation URL: not required');
|
|
941
|
+
}
|
|
942
|
+
return;
|
|
943
|
+
}
|
|
944
|
+
if (config.apiKey) {
|
|
945
|
+
console.log('Cloud auth: connected via API key');
|
|
946
|
+
console.log(`API key: ${(0, config_js_1.maskApiKey)(config.apiKey)}`);
|
|
947
|
+
console.log('Agent JWT: not used for this connection');
|
|
948
|
+
return;
|
|
949
|
+
}
|
|
950
|
+
console.log('Cloud auth: not connected');
|
|
951
|
+
console.log('API key: not configured');
|
|
952
|
+
console.log('Agent JWT: not configured');
|
|
953
|
+
}
|
|
954
|
+
async function printSubscribeConnectRequired(options, notifyOpenClaw) {
|
|
955
|
+
const message = 'AgentGuard Cloud credential was rejected. Run `agentguard connect` again before the next subscribe cron run.';
|
|
956
|
+
if (notifyOpenClaw) {
|
|
957
|
+
const notification = await (0, openclaw_notify_js_1.notifyOpenClawMessage)(message, resolveOpenClawGatewayOptionsFromEnv(), {
|
|
958
|
+
idempotencyKeyPrefix: 'agentguard-subscribe-auth',
|
|
959
|
+
});
|
|
960
|
+
if (notification.notified) {
|
|
961
|
+
console.log('NO_REPLY');
|
|
962
|
+
return;
|
|
963
|
+
}
|
|
964
|
+
console.error(`! Could not send OpenClaw cron auth notification: ${notification.reason ?? 'Unknown error'}`);
|
|
965
|
+
return;
|
|
966
|
+
}
|
|
967
|
+
if (options.cronNotifyRun) {
|
|
968
|
+
console.log(message);
|
|
969
|
+
}
|
|
970
|
+
else if (options.json) {
|
|
971
|
+
console.log(JSON.stringify({ success: false, error: message }, null, 2));
|
|
972
|
+
}
|
|
973
|
+
else {
|
|
974
|
+
console.error(`! ${message}`);
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
async function refreshAgentAccountBinding(config) {
|
|
978
|
+
if (!config.agentJwt || !config.agentRegisterUrl)
|
|
979
|
+
return config;
|
|
980
|
+
const client = new client_js_1.AgentGuardCloudClient(config);
|
|
981
|
+
try {
|
|
982
|
+
const policy = await client.fetchEffectivePolicy();
|
|
983
|
+
const activeConfig = (0, config_js_1.clearAgentRegisterUrl)(config);
|
|
984
|
+
(0, policy_js_1.saveCachedPolicy)(activeConfig.policyCachePath, policy);
|
|
985
|
+
return activeConfig;
|
|
986
|
+
}
|
|
987
|
+
catch {
|
|
988
|
+
return config;
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
function printCronRemovalSummary(results) {
|
|
992
|
+
const removed = results.filter((result) => result.removed);
|
|
993
|
+
if (removed.length > 0) {
|
|
994
|
+
console.log(`Removed AgentGuard subscribe cron job "${removed[0].name}" from: ${removed.map((result) => result.backend).join(', ')}.`);
|
|
995
|
+
return;
|
|
996
|
+
}
|
|
997
|
+
const errors = results.filter((result) => result.error);
|
|
998
|
+
if (errors.length > 0) {
|
|
999
|
+
console.log('No AgentGuard subscribe cron job was removed; some cron backends were unavailable.');
|
|
1000
|
+
for (const result of errors) {
|
|
1001
|
+
console.error(`! ${result.backend}: ${result.error}`);
|
|
1002
|
+
}
|
|
1003
|
+
return;
|
|
1004
|
+
}
|
|
1005
|
+
console.log('No AgentGuard subscribe cron job was found.');
|
|
1006
|
+
}
|
|
847
1007
|
function resolveCronAgentHost(config) {
|
|
848
1008
|
return config.agentHost ?? config.agentHosts?.[0];
|
|
849
1009
|
}
|
|
@@ -1200,16 +1360,37 @@ function printAgentActivationRequired(registration, err) {
|
|
|
1200
1360
|
console.error(`! AgentGuard Cloud authorization is not active yet. ${message}`);
|
|
1201
1361
|
const registerUrl = registration?.registerUrl || (0, config_js_1.ensureConfig)().agentRegisterUrl;
|
|
1202
1362
|
if (registerUrl) {
|
|
1203
|
-
console.error('Open this link to bind this agent to your
|
|
1363
|
+
console.error('Open this link to bind this agent to your account, then rerun the command:');
|
|
1204
1364
|
console.error(registerUrl);
|
|
1205
1365
|
}
|
|
1206
1366
|
}
|
|
1207
1367
|
function isOpenClawAgentConfigured(config) {
|
|
1208
|
-
return config.agentHost === 'openclaw' || config.agentHosts?.includes('openclaw') === true;
|
|
1368
|
+
return config.agentHost === 'openclaw' || config.agentHosts?.includes('openclaw') === true || detectOpenClawRuntime();
|
|
1369
|
+
}
|
|
1370
|
+
function withDetectedOpenClawAgentHost(config) {
|
|
1371
|
+
if (hasSavedAgentHost(config) || !detectOpenClawRuntime())
|
|
1372
|
+
return config;
|
|
1373
|
+
const next = {
|
|
1374
|
+
...config,
|
|
1375
|
+
agentHost: 'openclaw',
|
|
1376
|
+
agentHosts: appendAgentHost(config.agentHosts, 'openclaw'),
|
|
1377
|
+
};
|
|
1378
|
+
(0, config_js_1.saveConfig)(next);
|
|
1379
|
+
return next;
|
|
1380
|
+
}
|
|
1381
|
+
function detectOpenClawRuntime() {
|
|
1382
|
+
const configPath = process.env.OPENCLAW_CONFIG_PATH?.trim();
|
|
1383
|
+
if (configPath && (0, node_fs_1.existsSync)(configPath))
|
|
1384
|
+
return true;
|
|
1385
|
+
const stateDir = process.env.OPENCLAW_STATE_DIR?.trim();
|
|
1386
|
+
if (stateDir && ((0, node_fs_1.existsSync)(stateDir) || (0, node_fs_1.existsSync)((0, node_path_1.join)(stateDir, 'openclaw.json'))))
|
|
1387
|
+
return true;
|
|
1388
|
+
return (0, node_fs_1.existsSync)((0, node_path_1.join)((0, node_os_1.homedir)(), '.openclaw', 'openclaw.json'));
|
|
1209
1389
|
}
|
|
1210
1390
|
function resolveOpenClawGatewayOptionsFromEnv() {
|
|
1211
1391
|
const url = process.env.AGENTGUARD_OPENCLAW_GATEWAY_URL?.trim();
|
|
1212
1392
|
const host = process.env.AGENTGUARD_OPENCLAW_GATEWAY_HOST?.trim();
|
|
1393
|
+
const token = process.env.AGENTGUARD_OPENCLAW_GATEWAY_TOKEN?.trim();
|
|
1213
1394
|
const portRaw = process.env.AGENTGUARD_OPENCLAW_GATEWAY_PORT?.trim();
|
|
1214
1395
|
const timeoutRaw = process.env.AGENTGUARD_OPENCLAW_GATEWAY_TIMEOUT_MS?.trim();
|
|
1215
1396
|
const port = portRaw ? Number(portRaw) : undefined;
|
|
@@ -1217,6 +1398,7 @@ function resolveOpenClawGatewayOptionsFromEnv() {
|
|
|
1217
1398
|
return {
|
|
1218
1399
|
...(url ? { url } : {}),
|
|
1219
1400
|
...(host ? { host } : {}),
|
|
1401
|
+
...(token ? { token } : {}),
|
|
1220
1402
|
...(Number.isFinite(port) ? { port } : {}),
|
|
1221
1403
|
...(Number.isFinite(timeoutMs) ? { timeoutMs } : {}),
|
|
1222
1404
|
};
|