@goplus/agentguard 1.0.1 → 1.0.4
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 +126 -12
- package/dist/action/detectors/exec.d.ts.map +1 -1
- package/dist/action/detectors/exec.js +36 -1
- package/dist/action/detectors/exec.js.map +1 -1
- package/dist/action/detectors/network.d.ts.map +1 -1
- package/dist/action/detectors/network.js +7 -0
- package/dist/action/detectors/network.js.map +1 -1
- package/dist/action/index.d.ts.map +1 -1
- package/dist/action/index.js +51 -6
- package/dist/action/index.js.map +1 -1
- package/dist/adapters/claude-code.d.ts +16 -0
- package/dist/adapters/claude-code.d.ts.map +1 -0
- package/dist/adapters/claude-code.js +128 -0
- package/dist/adapters/claude-code.js.map +1 -0
- package/dist/adapters/common.d.ts +40 -0
- package/dist/adapters/common.d.ts.map +1 -0
- package/dist/adapters/common.js +166 -0
- package/dist/adapters/common.js.map +1 -0
- package/dist/adapters/engine.d.ts +9 -0
- package/dist/adapters/engine.d.ts.map +1 -0
- package/dist/adapters/engine.js +93 -0
- package/dist/adapters/engine.js.map +1 -0
- package/dist/adapters/index.d.ts +7 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +22 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/adapters/openclaw-plugin.d.ts +72 -0
- package/dist/adapters/openclaw-plugin.d.ts.map +1 -0
- package/dist/adapters/openclaw-plugin.js +369 -0
- package/dist/adapters/openclaw-plugin.js.map +1 -0
- package/dist/adapters/openclaw.d.ts +22 -0
- package/dist/adapters/openclaw.d.ts.map +1 -0
- package/dist/adapters/openclaw.js +118 -0
- package/dist/adapters/openclaw.js.map +1 -0
- package/dist/adapters/types.d.ts +81 -0
- package/dist/adapters/types.d.ts.map +1 -0
- package/dist/adapters/types.js +3 -0
- package/dist/adapters/types.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -7
- package/dist/index.js.map +1 -1
- package/dist/mcp-server.js +45 -1
- package/dist/mcp-server.js.map +1 -1
- package/dist/registry/storage.d.ts.map +1 -1
- package/dist/registry/storage.js +3 -2
- package/dist/registry/storage.js.map +1 -1
- package/dist/tests/action.test.js +26 -0
- package/dist/tests/action.test.js.map +1 -1
- package/dist/tests/adapter.test.d.ts +2 -0
- package/dist/tests/adapter.test.d.ts.map +1 -0
- package/dist/tests/adapter.test.js +396 -0
- package/dist/tests/adapter.test.js.map +1 -0
- package/dist/tests/helpers/test-utils.d.ts +23 -0
- package/dist/tests/helpers/test-utils.d.ts.map +1 -0
- package/dist/tests/helpers/test-utils.js +37 -0
- package/dist/tests/helpers/test-utils.js.map +1 -0
- package/dist/tests/integration.test.d.ts +2 -0
- package/dist/tests/integration.test.d.ts.map +1 -0
- package/dist/tests/integration.test.js +229 -0
- package/dist/tests/integration.test.js.map +1 -0
- package/dist/tests/smoke.test.d.ts +2 -0
- package/dist/tests/smoke.test.d.ts.map +1 -0
- package/dist/tests/smoke.test.js +94 -0
- package/dist/tests/smoke.test.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* GoPlus AgentGuard — OpenClaw Plugin
|
|
4
|
+
*
|
|
5
|
+
* Registers before_tool_call, after_tool_call, and session_start hooks
|
|
6
|
+
* with the OpenClaw plugin API to evaluate tool safety at runtime and
|
|
7
|
+
* auto-scan installed skills on session startup.
|
|
8
|
+
*
|
|
9
|
+
* Features:
|
|
10
|
+
* - Auto-scan all loaded plugins on registration
|
|
11
|
+
* - Auto-scan skill directories (~/.openclaw/skills/, ~/.claude/skills/) on session_start
|
|
12
|
+
* - Auto-register plugins to AgentGuard trust registry
|
|
13
|
+
* - Build toolName → pluginId mapping for initiating skill inference
|
|
14
|
+
*
|
|
15
|
+
* Usage in OpenClaw plugin config:
|
|
16
|
+
* import agentguard from '@goplus/agentguard/openclaw';
|
|
17
|
+
* export default agentguard;
|
|
18
|
+
*
|
|
19
|
+
* Or register manually:
|
|
20
|
+
* import { registerOpenClawPlugin } from '@goplus/agentguard';
|
|
21
|
+
* registerOpenClawPlugin(api);
|
|
22
|
+
*/
|
|
23
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
24
|
+
if (k2 === undefined) k2 = k;
|
|
25
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
26
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
27
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
28
|
+
}
|
|
29
|
+
Object.defineProperty(o, k2, desc);
|
|
30
|
+
}) : (function(o, m, k, k2) {
|
|
31
|
+
if (k2 === undefined) k2 = k;
|
|
32
|
+
o[k2] = m[k];
|
|
33
|
+
}));
|
|
34
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
35
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
36
|
+
}) : function(o, v) {
|
|
37
|
+
o["default"] = v;
|
|
38
|
+
});
|
|
39
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
40
|
+
var ownKeys = function(o) {
|
|
41
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
42
|
+
var ar = [];
|
|
43
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
44
|
+
return ar;
|
|
45
|
+
};
|
|
46
|
+
return ownKeys(o);
|
|
47
|
+
};
|
|
48
|
+
return function (mod) {
|
|
49
|
+
if (mod && mod.__esModule) return mod;
|
|
50
|
+
var result = {};
|
|
51
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
52
|
+
__setModuleDefault(result, mod);
|
|
53
|
+
return result;
|
|
54
|
+
};
|
|
55
|
+
})();
|
|
56
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
57
|
+
exports.getPluginIdFromTool = getPluginIdFromTool;
|
|
58
|
+
exports.getPluginScanResult = getPluginScanResult;
|
|
59
|
+
exports.registerOpenClawPlugin = registerOpenClawPlugin;
|
|
60
|
+
exports.default = register;
|
|
61
|
+
const node_fs_1 = require("node:fs");
|
|
62
|
+
const node_path_1 = require("node:path");
|
|
63
|
+
const node_os_1 = require("node:os");
|
|
64
|
+
const path = __importStar(require("node:path"));
|
|
65
|
+
const openclaw_js_1 = require("./openclaw.js");
|
|
66
|
+
const engine_js_1 = require("./engine.js");
|
|
67
|
+
const common_js_1 = require("./common.js");
|
|
68
|
+
const index_js_1 = require("../scanner/index.js");
|
|
69
|
+
const index_js_2 = require("../registry/index.js");
|
|
70
|
+
// ---------------------------------------------------------------------------
|
|
71
|
+
// Auto-scan helpers (skill directories)
|
|
72
|
+
// ---------------------------------------------------------------------------
|
|
73
|
+
const OPENCLAW_SKILLS_DIR = (0, node_path_1.join)((0, node_os_1.homedir)(), '.openclaw', 'skills');
|
|
74
|
+
const CLAUDE_SKILLS_DIR = (0, node_path_1.join)((0, node_os_1.homedir)(), '.claude', 'skills');
|
|
75
|
+
const AGENTGUARD_DIR = process.env.AGENTGUARD_HOME || (0, node_path_1.join)((0, node_os_1.homedir)(), '.agentguard');
|
|
76
|
+
const AUDIT_PATH = (0, node_path_1.join)(AGENTGUARD_DIR, 'audit.jsonl');
|
|
77
|
+
function ensureAgentGuardDir() {
|
|
78
|
+
if (!(0, node_fs_1.existsSync)(AGENTGUARD_DIR)) {
|
|
79
|
+
(0, node_fs_1.mkdirSync)(AGENTGUARD_DIR, { recursive: true });
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function writeScanAuditLog(entry) {
|
|
83
|
+
try {
|
|
84
|
+
ensureAgentGuardDir();
|
|
85
|
+
(0, node_fs_1.appendFileSync)(AUDIT_PATH, JSON.stringify(entry) + '\n');
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
// Non-critical
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Discover skill directories (containing SKILL.md) under the given path.
|
|
93
|
+
*/
|
|
94
|
+
function discoverSkillDirs(skillsDir) {
|
|
95
|
+
if (!(0, node_fs_1.existsSync)(skillsDir))
|
|
96
|
+
return [];
|
|
97
|
+
const skills = [];
|
|
98
|
+
try {
|
|
99
|
+
const entries = (0, node_fs_1.readdirSync)(skillsDir, { withFileTypes: true });
|
|
100
|
+
for (const entry of entries) {
|
|
101
|
+
if (!entry.isDirectory())
|
|
102
|
+
continue;
|
|
103
|
+
const skillDir = (0, node_path_1.join)(skillsDir, entry.name);
|
|
104
|
+
if ((0, node_fs_1.existsSync)((0, node_path_1.join)(skillDir, 'SKILL.md'))) {
|
|
105
|
+
skills.push({ name: entry.name, path: skillDir });
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
// Can't read skills dir
|
|
111
|
+
}
|
|
112
|
+
return skills;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Scan skill directories (~/.openclaw/skills/ and ~/.claude/skills/).
|
|
116
|
+
* Scan-only mode: reports results via logger, does NOT modify the trust registry.
|
|
117
|
+
* Users can register skills manually with /agentguard trust attest.
|
|
118
|
+
*/
|
|
119
|
+
async function autoScanSkillDirs(scanner, _registry, logger) {
|
|
120
|
+
const skills = [
|
|
121
|
+
...discoverSkillDirs(OPENCLAW_SKILLS_DIR),
|
|
122
|
+
...discoverSkillDirs(CLAUDE_SKILLS_DIR),
|
|
123
|
+
];
|
|
124
|
+
if (skills.length === 0)
|
|
125
|
+
return;
|
|
126
|
+
let scanned = 0;
|
|
127
|
+
for (const skill of skills) {
|
|
128
|
+
// Skip self
|
|
129
|
+
if (skill.name === 'agentguard')
|
|
130
|
+
continue;
|
|
131
|
+
try {
|
|
132
|
+
const result = await scanner.quickScan(skill.path);
|
|
133
|
+
scanned++;
|
|
134
|
+
// Audit log — only record skill name, risk level, and tag names (no code/evidence)
|
|
135
|
+
writeScanAuditLog({
|
|
136
|
+
timestamp: new Date().toISOString(),
|
|
137
|
+
event: 'auto_scan',
|
|
138
|
+
skill_name: skill.name,
|
|
139
|
+
risk_level: result.risk_level,
|
|
140
|
+
risk_tags: result.risk_tags,
|
|
141
|
+
});
|
|
142
|
+
logger(`[AgentGuard] Skill "${skill.name}": ${result.risk_level} risk [${result.risk_tags.join(', ')}]`);
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
// Skip skills that fail to scan
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if (scanned > 0) {
|
|
149
|
+
logger(`[AgentGuard] Scanned ${scanned} skill dir(s). Use /agentguard trust attest to register.`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// ---------------------------------------------------------------------------
|
|
153
|
+
// Global State
|
|
154
|
+
// ---------------------------------------------------------------------------
|
|
155
|
+
/** Symbol to access OpenClaw's global registry */
|
|
156
|
+
const OPENCLAW_REGISTRY_STATE = Symbol.for('openclaw.pluginRegistryState');
|
|
157
|
+
/** Tool name → Plugin ID mapping */
|
|
158
|
+
const toolToPluginMap = new Map();
|
|
159
|
+
/** Plugin ID → Scan result cache */
|
|
160
|
+
const pluginScanCache = new Map();
|
|
161
|
+
// ---------------------------------------------------------------------------
|
|
162
|
+
// Helper Functions
|
|
163
|
+
// ---------------------------------------------------------------------------
|
|
164
|
+
/**
|
|
165
|
+
* Get OpenClaw's active plugin registry via global symbol
|
|
166
|
+
*/
|
|
167
|
+
function getOpenClawRegistry() {
|
|
168
|
+
const globalState = globalThis;
|
|
169
|
+
const state = globalState[OPENCLAW_REGISTRY_STATE];
|
|
170
|
+
return state?.registry ?? null;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Get plugin directory from source path
|
|
174
|
+
*/
|
|
175
|
+
function getPluginDir(source) {
|
|
176
|
+
// source is typically the entry file (e.g., /path/to/plugin/index.ts)
|
|
177
|
+
// We want the directory
|
|
178
|
+
return path.dirname(source);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Scan a plugin and cache its risk level. Scan-only: does NOT modify trust registry.
|
|
182
|
+
* Users can register plugins manually with /agentguard trust attest.
|
|
183
|
+
*/
|
|
184
|
+
async function scanAndRegisterPlugin(plugin, scanner, _registry, logger) {
|
|
185
|
+
// Skip if already scanned
|
|
186
|
+
if (pluginScanCache.has(plugin.id)) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const pluginDir = getPluginDir(plugin.source);
|
|
190
|
+
try {
|
|
191
|
+
// Perform scan
|
|
192
|
+
const scanResult = await scanner.quickScan(pluginDir);
|
|
193
|
+
// Cache result (for runtime before_tool_call checks)
|
|
194
|
+
pluginScanCache.set(plugin.id, {
|
|
195
|
+
riskLevel: scanResult.risk_level,
|
|
196
|
+
riskTags: scanResult.risk_tags,
|
|
197
|
+
});
|
|
198
|
+
// Build tool → plugin mapping
|
|
199
|
+
for (const toolName of plugin.toolNames) {
|
|
200
|
+
toolToPluginMap.set(toolName, plugin.id);
|
|
201
|
+
}
|
|
202
|
+
logger(`[AgentGuard] Scanned plugin "${plugin.id}": ${scanResult.risk_level} risk [${scanResult.risk_tags.join(', ')}]`);
|
|
203
|
+
}
|
|
204
|
+
catch (err) {
|
|
205
|
+
// If scan fails, cache as unknown
|
|
206
|
+
pluginScanCache.set(plugin.id, {
|
|
207
|
+
riskLevel: 'unknown',
|
|
208
|
+
riskTags: ['SCAN_FAILED'],
|
|
209
|
+
});
|
|
210
|
+
// Still build tool mapping
|
|
211
|
+
for (const toolName of plugin.toolNames) {
|
|
212
|
+
toolToPluginMap.set(toolName, plugin.id);
|
|
213
|
+
}
|
|
214
|
+
logger(`[AgentGuard] Plugin "${plugin.id}" scan failed: ${String(err)}`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Scan all loaded OpenClaw plugins
|
|
219
|
+
*/
|
|
220
|
+
async function scanAllPlugins(scanner, registry, logger, selfPluginId) {
|
|
221
|
+
const openclawRegistry = getOpenClawRegistry();
|
|
222
|
+
if (!openclawRegistry) {
|
|
223
|
+
logger('[AgentGuard] OpenClaw registry not available, skipping plugin auto-scan');
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
const plugins = openclawRegistry.plugins.filter(p => p.status === 'loaded' &&
|
|
227
|
+
p.enabled &&
|
|
228
|
+
p.id !== selfPluginId // Don't scan ourselves
|
|
229
|
+
);
|
|
230
|
+
logger(`[AgentGuard] Auto-scanning ${plugins.length} loaded plugins...`);
|
|
231
|
+
// Scan plugins in parallel (with concurrency limit)
|
|
232
|
+
const CONCURRENCY = 3;
|
|
233
|
+
for (let i = 0; i < plugins.length; i += CONCURRENCY) {
|
|
234
|
+
const batch = plugins.slice(i, i + CONCURRENCY);
|
|
235
|
+
await Promise.all(batch.map(plugin => scanAndRegisterPlugin(plugin, scanner, registry, logger)));
|
|
236
|
+
}
|
|
237
|
+
logger(`[AgentGuard] Plugin auto-scan complete. ${toolToPluginMap.size} tools mapped.`);
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Get plugin ID from tool name
|
|
241
|
+
*/
|
|
242
|
+
function getPluginIdFromTool(toolName) {
|
|
243
|
+
return toolToPluginMap.get(toolName) ?? null;
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Get scan result for a plugin
|
|
247
|
+
*/
|
|
248
|
+
function getPluginScanResult(pluginId) {
|
|
249
|
+
return pluginScanCache.get(pluginId) ?? null;
|
|
250
|
+
}
|
|
251
|
+
// ---------------------------------------------------------------------------
|
|
252
|
+
// Main Registration
|
|
253
|
+
// ---------------------------------------------------------------------------
|
|
254
|
+
/**
|
|
255
|
+
* Register AgentGuard hooks with OpenClaw plugin API
|
|
256
|
+
*/
|
|
257
|
+
function registerOpenClawPlugin(api, options = {}) {
|
|
258
|
+
const adapter = new openclaw_js_1.OpenClawAdapter();
|
|
259
|
+
const config = options.level ? { level: options.level } : (0, common_js_1.loadConfig)();
|
|
260
|
+
const scanner = options.scanner ?? new index_js_1.SkillScanner({ useExternalScanner: false });
|
|
261
|
+
const trustRegistry = options.registry ?? new index_js_2.SkillRegistry();
|
|
262
|
+
// Simple logger
|
|
263
|
+
const logger = (msg) => console.log(msg);
|
|
264
|
+
// Lazy-initialize agentguard instance
|
|
265
|
+
let agentguard = null;
|
|
266
|
+
function getAgentGuard() {
|
|
267
|
+
if (!agentguard) {
|
|
268
|
+
if (options.agentguardFactory) {
|
|
269
|
+
agentguard = options.agentguardFactory();
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
try {
|
|
273
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
274
|
+
const { createAgentGuard } = require('@goplus/agentguard');
|
|
275
|
+
agentguard = createAgentGuard();
|
|
276
|
+
}
|
|
277
|
+
catch {
|
|
278
|
+
throw new Error('AgentGuard: unable to load engine. Install @goplus/agentguard.');
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
return agentguard;
|
|
283
|
+
}
|
|
284
|
+
// Auto-scan plugins on registration (async, non-blocking, opt-in)
|
|
285
|
+
if (options.skipAutoScan === false) {
|
|
286
|
+
// Use setImmediate to allow plugin registration to complete first
|
|
287
|
+
setImmediate(async () => {
|
|
288
|
+
try {
|
|
289
|
+
await scanAllPlugins(scanner, trustRegistry, logger, api.id);
|
|
290
|
+
}
|
|
291
|
+
catch (err) {
|
|
292
|
+
logger(`[AgentGuard] Plugin auto-scan error: ${String(err)}`);
|
|
293
|
+
}
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
// session_start → auto-scan skill directories (only when opt-in)
|
|
297
|
+
if (options.skipAutoScan === false) {
|
|
298
|
+
api.on('session_start', async () => {
|
|
299
|
+
try {
|
|
300
|
+
await autoScanSkillDirs(scanner, trustRegistry, logger);
|
|
301
|
+
}
|
|
302
|
+
catch {
|
|
303
|
+
// Non-critical — never block session startup
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
// before_tool_call → evaluate and optionally block
|
|
308
|
+
api.on('before_tool_call', async (event) => {
|
|
309
|
+
try {
|
|
310
|
+
// Try to infer plugin from tool name
|
|
311
|
+
const toolEvent = event;
|
|
312
|
+
const pluginId = toolEvent.toolName ? getPluginIdFromTool(toolEvent.toolName) : null;
|
|
313
|
+
// Check if plugin is untrusted
|
|
314
|
+
if (pluginId) {
|
|
315
|
+
const scanResult = getPluginScanResult(pluginId);
|
|
316
|
+
if (scanResult?.riskLevel === 'critical') {
|
|
317
|
+
return {
|
|
318
|
+
block: true,
|
|
319
|
+
blockReason: `GoPlus AgentGuard: Plugin "${pluginId}" has critical security findings and is blocked. Run /agentguard trust attest to manually approve.`,
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
const result = await (0, engine_js_1.evaluateHook)(adapter, event, {
|
|
324
|
+
config,
|
|
325
|
+
agentguard: getAgentGuard(),
|
|
326
|
+
});
|
|
327
|
+
if (result.decision === 'deny') {
|
|
328
|
+
return {
|
|
329
|
+
block: true,
|
|
330
|
+
blockReason: result.reason || 'Blocked by GoPlus AgentGuard',
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
// OpenClaw has no 'ask' mode — block with explanation in strict/balanced
|
|
334
|
+
if (result.decision === 'ask') {
|
|
335
|
+
return {
|
|
336
|
+
block: true,
|
|
337
|
+
blockReason: result.reason || 'Requires confirmation (GoPlus AgentGuard)',
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
return undefined; // allow
|
|
341
|
+
}
|
|
342
|
+
catch {
|
|
343
|
+
// Fail open
|
|
344
|
+
return undefined;
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
// after_tool_call → audit log
|
|
348
|
+
api.on('after_tool_call', async (event) => {
|
|
349
|
+
try {
|
|
350
|
+
const input = adapter.parseInput(event);
|
|
351
|
+
const toolEvent = event;
|
|
352
|
+
const pluginId = toolEvent.toolName ? getPluginIdFromTool(toolEvent.toolName) : null;
|
|
353
|
+
(0, common_js_1.writeAuditLog)(input, null, pluginId);
|
|
354
|
+
}
|
|
355
|
+
catch {
|
|
356
|
+
// Non-critical
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
logger(`[AgentGuard] Registered with OpenClaw (protection level: ${config.level || 'balanced'})`);
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Default export for OpenClaw plugin registration
|
|
363
|
+
*
|
|
364
|
+
* Usage: export default from '@goplus/agentguard/openclaw'
|
|
365
|
+
*/
|
|
366
|
+
function register(api) {
|
|
367
|
+
registerOpenClawPlugin(api);
|
|
368
|
+
}
|
|
369
|
+
//# sourceMappingURL=openclaw-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openclaw-plugin.js","sourceRoot":"","sources":["../../src/adapters/openclaw-plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ActionEnvelope } from '../types/action.js';
|
|
2
|
+
import type { HookAdapter, HookInput } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* OpenClaw hook adapter
|
|
5
|
+
*
|
|
6
|
+
* Bridges OpenClaw's before_tool_call / after_tool_call plugin hooks
|
|
7
|
+
* to the common AgentGuard decision engine.
|
|
8
|
+
*
|
|
9
|
+
* OpenClaw plugin hooks receive an event object:
|
|
10
|
+
* { toolName: string, params: Record<string, any>, toolCallId?: string }
|
|
11
|
+
*
|
|
12
|
+
* Blocking is done by returning { block: true, blockReason: "..." }
|
|
13
|
+
* from the before_tool_call handler.
|
|
14
|
+
*/
|
|
15
|
+
export declare class OpenClawAdapter implements HookAdapter {
|
|
16
|
+
readonly name = "openclaw";
|
|
17
|
+
parseInput(raw: unknown): HookInput;
|
|
18
|
+
mapToolToActionType(toolName: string): string | null;
|
|
19
|
+
buildEnvelope(input: HookInput, initiatingSkill?: string | null): ActionEnvelope | null;
|
|
20
|
+
inferInitiatingSkill(input: HookInput): Promise<string | null>;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=openclaw.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openclaw.d.ts","sourceRoot":"","sources":["../../src/adapters/openclaw.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAazD;;;;;;;;;;;GAWG;AACH,qBAAa,eAAgB,YAAW,WAAW;IACjD,QAAQ,CAAC,IAAI,cAAc;IAE3B,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,SAAS;IAUnC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAcpD,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,cAAc,GAAG,IAAI;IAgEjF,oBAAoB,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;CAUrE"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OpenClawAdapter = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Tool name → action type mapping for OpenClaw
|
|
6
|
+
*/
|
|
7
|
+
const TOOL_ACTION_MAP = {
|
|
8
|
+
exec: 'exec_command',
|
|
9
|
+
write: 'write_file',
|
|
10
|
+
read: 'read_file',
|
|
11
|
+
web_fetch: 'network_request',
|
|
12
|
+
browser: 'network_request',
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* OpenClaw hook adapter
|
|
16
|
+
*
|
|
17
|
+
* Bridges OpenClaw's before_tool_call / after_tool_call plugin hooks
|
|
18
|
+
* to the common AgentGuard decision engine.
|
|
19
|
+
*
|
|
20
|
+
* OpenClaw plugin hooks receive an event object:
|
|
21
|
+
* { toolName: string, params: Record<string, any>, toolCallId?: string }
|
|
22
|
+
*
|
|
23
|
+
* Blocking is done by returning { block: true, blockReason: "..." }
|
|
24
|
+
* from the before_tool_call handler.
|
|
25
|
+
*/
|
|
26
|
+
class OpenClawAdapter {
|
|
27
|
+
name = 'openclaw';
|
|
28
|
+
parseInput(raw) {
|
|
29
|
+
const event = raw;
|
|
30
|
+
return {
|
|
31
|
+
toolName: event.toolName || '',
|
|
32
|
+
toolInput: event.params || {},
|
|
33
|
+
eventType: 'pre', // before_tool_call = pre
|
|
34
|
+
raw: event,
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
mapToolToActionType(toolName) {
|
|
38
|
+
// Direct match
|
|
39
|
+
if (TOOL_ACTION_MAP[toolName]) {
|
|
40
|
+
return TOOL_ACTION_MAP[toolName];
|
|
41
|
+
}
|
|
42
|
+
// Prefix match for tool families (e.g. "exec_python" → "exec_command")
|
|
43
|
+
for (const [prefix, actionType] of Object.entries(TOOL_ACTION_MAP)) {
|
|
44
|
+
if (toolName.startsWith(prefix)) {
|
|
45
|
+
return actionType;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
buildEnvelope(input, initiatingSkill) {
|
|
51
|
+
const actionType = this.mapToolToActionType(input.toolName);
|
|
52
|
+
if (!actionType)
|
|
53
|
+
return null;
|
|
54
|
+
const actor = {
|
|
55
|
+
skill: {
|
|
56
|
+
id: initiatingSkill || 'openclaw-session',
|
|
57
|
+
source: initiatingSkill || 'openclaw',
|
|
58
|
+
version_ref: '0.0.0',
|
|
59
|
+
artifact_hash: '',
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
const context = {
|
|
63
|
+
session_id: `openclaw-${Date.now()}`,
|
|
64
|
+
user_present: true,
|
|
65
|
+
env: 'prod',
|
|
66
|
+
time: new Date().toISOString(),
|
|
67
|
+
initiating_skill: initiatingSkill || undefined,
|
|
68
|
+
};
|
|
69
|
+
let actionData;
|
|
70
|
+
switch (actionType) {
|
|
71
|
+
case 'exec_command':
|
|
72
|
+
actionData = {
|
|
73
|
+
command: input.toolInput.command || '',
|
|
74
|
+
args: [],
|
|
75
|
+
};
|
|
76
|
+
break;
|
|
77
|
+
case 'write_file':
|
|
78
|
+
actionData = {
|
|
79
|
+
path: input.toolInput.path ||
|
|
80
|
+
input.toolInput.file_path || '',
|
|
81
|
+
};
|
|
82
|
+
break;
|
|
83
|
+
case 'read_file':
|
|
84
|
+
actionData = {
|
|
85
|
+
path: input.toolInput.path ||
|
|
86
|
+
input.toolInput.file_path || '',
|
|
87
|
+
};
|
|
88
|
+
break;
|
|
89
|
+
case 'network_request':
|
|
90
|
+
actionData = {
|
|
91
|
+
method: input.toolInput.method || 'GET',
|
|
92
|
+
url: input.toolInput.url || '',
|
|
93
|
+
body_preview: input.toolInput.body,
|
|
94
|
+
};
|
|
95
|
+
break;
|
|
96
|
+
default:
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
actor,
|
|
101
|
+
action: { type: actionType, data: actionData },
|
|
102
|
+
context,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
async inferInitiatingSkill(input) {
|
|
106
|
+
// Try to get plugin ID from tool → plugin mapping
|
|
107
|
+
try {
|
|
108
|
+
const { getPluginIdFromTool } = await import('./openclaw-plugin.js');
|
|
109
|
+
return getPluginIdFromTool(input.toolName);
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
// Mapping not available (plugin not loaded)
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
exports.OpenClawAdapter = OpenClawAdapter;
|
|
118
|
+
//# sourceMappingURL=openclaw.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openclaw.js","sourceRoot":"","sources":["../../src/adapters/openclaw.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import type { ActionEnvelope, PolicyDecision } from '../types/action.js';
|
|
2
|
+
/**
|
|
3
|
+
* Standardized hook input — platform-agnostic representation
|
|
4
|
+
*/
|
|
5
|
+
export interface HookInput {
|
|
6
|
+
/** Tool name (platform-specific, e.g. "Bash" or "exec") */
|
|
7
|
+
toolName: string;
|
|
8
|
+
/** Tool parameters */
|
|
9
|
+
toolInput: Record<string, unknown>;
|
|
10
|
+
/** Hook event type */
|
|
11
|
+
eventType: 'pre' | 'post';
|
|
12
|
+
/** Session identifier */
|
|
13
|
+
sessionId?: string;
|
|
14
|
+
/** Working directory */
|
|
15
|
+
cwd?: string;
|
|
16
|
+
/** Raw platform-specific input */
|
|
17
|
+
raw: unknown;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Hook evaluation result
|
|
21
|
+
*/
|
|
22
|
+
export interface HookOutput {
|
|
23
|
+
/** Decision */
|
|
24
|
+
decision: 'allow' | 'deny' | 'ask';
|
|
25
|
+
/** Human-readable reason */
|
|
26
|
+
reason?: string;
|
|
27
|
+
/** Risk level */
|
|
28
|
+
riskLevel?: string;
|
|
29
|
+
/** Risk tags */
|
|
30
|
+
riskTags?: string[];
|
|
31
|
+
/** Initiating skill (if detected) */
|
|
32
|
+
initiatingSkill?: string | null;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Platform adapter interface
|
|
36
|
+
*
|
|
37
|
+
* Each platform (Claude Code, OpenClaw, etc.) implements this interface
|
|
38
|
+
* to bridge its hook protocol to the common AgentGuard decision engine.
|
|
39
|
+
*/
|
|
40
|
+
export interface HookAdapter {
|
|
41
|
+
/** Platform identifier */
|
|
42
|
+
readonly name: string;
|
|
43
|
+
/** Parse raw platform input into standardized HookInput */
|
|
44
|
+
parseInput(raw: unknown): HookInput;
|
|
45
|
+
/** Map platform tool name to ActionEnvelope action type */
|
|
46
|
+
mapToolToActionType(toolName: string): string | null;
|
|
47
|
+
/** Build an ActionEnvelope from standardized input */
|
|
48
|
+
buildEnvelope(input: HookInput, initiatingSkill?: string | null): ActionEnvelope | null;
|
|
49
|
+
/** Infer which skill initiated the current tool call */
|
|
50
|
+
inferInitiatingSkill(input: HookInput): Promise<string | null>;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Agentguard instance interface (subset used by engine)
|
|
54
|
+
*/
|
|
55
|
+
export interface AgentGuardInstance {
|
|
56
|
+
actionScanner: {
|
|
57
|
+
decide(envelope: ActionEnvelope): Promise<PolicyDecision>;
|
|
58
|
+
};
|
|
59
|
+
registry: {
|
|
60
|
+
lookup(skill: {
|
|
61
|
+
id: string;
|
|
62
|
+
source: string;
|
|
63
|
+
version_ref: string;
|
|
64
|
+
artifact_hash: string;
|
|
65
|
+
}): Promise<{
|
|
66
|
+
effective_trust_level: string;
|
|
67
|
+
effective_capabilities: Record<string, unknown>;
|
|
68
|
+
record: unknown | null;
|
|
69
|
+
}>;
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Engine options
|
|
74
|
+
*/
|
|
75
|
+
export interface EngineOptions {
|
|
76
|
+
config: {
|
|
77
|
+
level?: string;
|
|
78
|
+
};
|
|
79
|
+
agentguard: AgentGuardInstance;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/adapters/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzE;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAC;IACjB,sBAAsB;IACtB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,sBAAsB;IACtB,SAAS,EAAE,KAAK,GAAG,MAAM,CAAC;IAC1B,yBAAyB;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wBAAwB;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,GAAG,EAAE,OAAO,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,eAAe;IACf,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;IACnC,4BAA4B;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iBAAiB;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gBAAgB;IAChB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,qCAAqC;IACrC,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAED;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,0BAA0B;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,2DAA2D;IAC3D,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,SAAS,CAAC;IAEpC,2DAA2D;IAC3D,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAErD,sDAAsD;IACtD,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,cAAc,GAAG,IAAI,CAAC;IAExF,wDAAwD;IACxD,oBAAoB,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAChE;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE;QACb,MAAM,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;KAC3D,CAAC;IACF,QAAQ,EAAE;QACR,MAAM,CAAC,KAAK,EAAE;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,WAAW,EAAE,MAAM,CAAC;YAAC,aAAa,EAAE,MAAM,CAAA;SAAE,GAAG,OAAO,CAAC;YACjG,qBAAqB,EAAE,MAAM,CAAC;YAC9B,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAChD,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;SACxB,CAAC,CAAC;KACJ,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3B,UAAU,EAAE,kBAAkB,CAAC;CAChC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/adapters/types.ts"],"names":[],"mappings":""}
|
package/dist/index.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export { SkillRegistry, RegistryStorage, type RegistryOptions, type StorageOptio
|
|
|
12
12
|
export { ActionScanner, GoPlusClient, type ActionScannerOptions, } from './action/index.js';
|
|
13
13
|
export { DEFAULT_POLICIES, RESTRICTIVE_CAPABILITY, PERMISSIVE_CAPABILITY, CAPABILITY_PRESETS, type PolicyConfig, } from './policy/default.js';
|
|
14
14
|
export { containsSensitiveData, maskSensitiveData, extractDomain, isDomainAllowed, SENSITIVE_PATTERNS, } from './utils/patterns.js';
|
|
15
|
+
export { ClaudeCodeAdapter, OpenClawAdapter, evaluateHook, registerOpenClawPlugin, loadConfig, type HookAdapter, type HookInput, type HookOutput, type EngineOptions, } from './adapters/index.js';
|
|
15
16
|
import { SkillScanner } from './scanner/index.js';
|
|
16
17
|
import { SkillRegistry } from './registry/index.js';
|
|
17
18
|
import { ActionScanner } from './action/index.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,cAAc,kBAAkB,CAAC;AAGjC,OAAO,EAAE,YAAY,EAAE,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EACL,aAAa,EACb,eAAe,EACf,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,YAAY,GAClB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,aAAa,EACb,YAAY,EACZ,KAAK,oBAAoB,GAC1B,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,qBAAqB,EACrB,kBAAkB,EAClB,KAAK,YAAY,GAClB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,CAAC,EAAE;IACzC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;;;;EAgBA;AAGD,eAAe,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,cAAc,kBAAkB,CAAC;AAGjC,OAAO,EAAE,YAAY,EAAE,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EACL,aAAa,EACb,eAAe,EACf,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,YAAY,GAClB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,aAAa,EACb,YAAY,EACZ,KAAK,oBAAoB,GAC1B,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EACL,gBAAgB,EAChB,sBAAsB,EACtB,qBAAqB,EACrB,kBAAkB,EAClB,KAAK,YAAY,GAClB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,sBAAsB,EACtB,UAAU,EACV,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,aAAa,GACnB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,CAAC,EAAE;IACzC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;;;;EAgBA;AAGD,eAAe,gBAAgB,CAAC"}
|