averecion-lite 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +161 -0
- package/dashboard/dash.css +1085 -0
- package/dashboard/dash.js +898 -0
- package/dashboard/index.html +312 -0
- package/dashboard/landing.html +360 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +409 -0
- package/dist/hooks.d.ts +25 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +68 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +64 -0
- package/dist/injectionGuard.d.ts +9 -0
- package/dist/injectionGuard.d.ts.map +1 -0
- package/dist/injectionGuard.js +16 -0
- package/dist/log-watcher.d.ts +26 -0
- package/dist/log-watcher.d.ts.map +1 -0
- package/dist/log-watcher.js +397 -0
- package/dist/metrics.d.ts +53 -0
- package/dist/metrics.d.ts.map +1 -0
- package/dist/metrics.js +58 -0
- package/dist/policy.d.ts +11 -0
- package/dist/policy.d.ts.map +1 -0
- package/dist/policy.js +60 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +226 -0
- package/dist/src/capability-manifest.d.ts +16 -0
- package/dist/src/capability-manifest.d.ts.map +1 -0
- package/dist/src/capability-manifest.js +228 -0
- package/dist/src/http-proxy.d.ts +4 -0
- package/dist/src/http-proxy.d.ts.map +1 -0
- package/dist/src/http-proxy.js +266 -0
- package/dist/src/risk-engine.d.ts +43 -0
- package/dist/src/risk-engine.d.ts.map +1 -0
- package/dist/src/risk-engine.js +258 -0
- package/dist/src/shell-wrapper.d.ts +3 -0
- package/dist/src/shell-wrapper.d.ts.map +1 -0
- package/dist/src/shell-wrapper.js +264 -0
- package/dist/storage.d.ts +28 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +144 -0
- package/examples/INTEGRATION.md +162 -0
- package/examples/claude-desktop-agent.json +32 -0
- package/examples/clawdbot-agent.json +44 -0
- package/examples/custom-agent.json +20 -0
- package/lite-policy.json +5 -0
- package/package.json +56 -0
package/dist/server.js
ADDED
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.startServer = startServer;
|
|
40
|
+
exports.stopServer = stopServer;
|
|
41
|
+
const express_1 = __importDefault(require("express"));
|
|
42
|
+
const path = __importStar(require("path"));
|
|
43
|
+
const ws_1 = require("ws");
|
|
44
|
+
const metrics_1 = require("./metrics");
|
|
45
|
+
const storage_1 = require("./storage");
|
|
46
|
+
const risk_engine_1 = require("./src/risk-engine");
|
|
47
|
+
const capability_manifest_1 = require("./src/capability-manifest");
|
|
48
|
+
const log_watcher_1 = require("./log-watcher");
|
|
49
|
+
let server = null;
|
|
50
|
+
let wss = null;
|
|
51
|
+
function validateSecret(req, res, next) {
|
|
52
|
+
const secret = process.env.LITE_ADAPTER_SECRET;
|
|
53
|
+
if (!secret) {
|
|
54
|
+
res.status(500).json({ error: "LITE_ADAPTER_SECRET not set" });
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (req.headers["x-lite-secret"] !== secret) {
|
|
58
|
+
res.status(401).json({ error: "Unauthorized" });
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
next();
|
|
62
|
+
}
|
|
63
|
+
function localOnly(req, res, next) {
|
|
64
|
+
const allowRemote = process.env.LITE_ALLOW_REMOTE === "true";
|
|
65
|
+
if (allowRemote) {
|
|
66
|
+
next();
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const addr = req.socket.remoteAddress;
|
|
70
|
+
if (addr !== "127.0.0.1" && addr !== "::1" && addr !== "::ffff:127.0.0.1") {
|
|
71
|
+
res.status(403).json({ error: "Local-only" });
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
next();
|
|
75
|
+
}
|
|
76
|
+
function broadcastToClients(message) {
|
|
77
|
+
if (!wss)
|
|
78
|
+
return;
|
|
79
|
+
const data = JSON.stringify(message);
|
|
80
|
+
wss.clients.forEach((client) => {
|
|
81
|
+
if (client.readyState === ws_1.WebSocket.OPEN) {
|
|
82
|
+
client.send(data);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
async function startServer(port = 4321, host = "0.0.0.0") {
|
|
87
|
+
const app = (0, express_1.default)();
|
|
88
|
+
app.use(express_1.default.json());
|
|
89
|
+
const dashboardDir = path.join(__dirname, "..", "dashboard");
|
|
90
|
+
app.get("/lite-metrics", localOnly, validateSecret, (_req, res) => res.json((0, metrics_1.getMetrics)(24)));
|
|
91
|
+
app.get("/lite-config", localOnly, validateSecret, (_req, res) => {
|
|
92
|
+
const config = (0, storage_1.getConfig)();
|
|
93
|
+
res.json(config || { enabled: false, showMode: false, protectionLevel: "balanced", consented: false });
|
|
94
|
+
});
|
|
95
|
+
app.get("/lite-pending", localOnly, validateSecret, (_req, res) => {
|
|
96
|
+
res.json((0, storage_1.getPendingApprovals)());
|
|
97
|
+
});
|
|
98
|
+
app.post("/lite-approval", localOnly, validateSecret, (req, res) => {
|
|
99
|
+
const { id, approved } = req.body;
|
|
100
|
+
if (!id) {
|
|
101
|
+
res.status(400).json({ error: "Missing id" });
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const success = (0, storage_1.resolveApproval)(id, approved === true);
|
|
105
|
+
res.json({ success, id, approved });
|
|
106
|
+
});
|
|
107
|
+
app.get("/", localOnly, (_req, res) => res.sendFile(path.join(dashboardDir, "landing.html")));
|
|
108
|
+
app.get("/clawguard", localOnly, (_req, res) => res.sendFile(path.join(dashboardDir, "index.html")));
|
|
109
|
+
app.get("/lite-dash", localOnly, (_req, res) => res.redirect("/clawguard"));
|
|
110
|
+
app.use("/static", localOnly, express_1.default.static(dashboardDir));
|
|
111
|
+
app.get("/health", (_req, res) => res.json({ status: "ok" }));
|
|
112
|
+
app.get("/api/agents", localOnly, validateSecret, (_req, res) => {
|
|
113
|
+
const agents = (0, risk_engine_1.listAgents)();
|
|
114
|
+
const withRisk = agents.map(agent => ({
|
|
115
|
+
...agent,
|
|
116
|
+
risk: (0, risk_engine_1.assessAgentRisk)(agent)
|
|
117
|
+
}));
|
|
118
|
+
res.json(withRisk);
|
|
119
|
+
});
|
|
120
|
+
app.get("/api/agents/:id", localOnly, validateSecret, (req, res) => {
|
|
121
|
+
const agent = (0, risk_engine_1.getAgent)(req.params.id);
|
|
122
|
+
if (!agent) {
|
|
123
|
+
res.status(404).json({ error: "Agent not found" });
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
res.json({ ...agent, risk: (0, risk_engine_1.assessAgentRisk)(agent) });
|
|
127
|
+
});
|
|
128
|
+
app.post("/api/agents", localOnly, validateSecret, (req, res) => {
|
|
129
|
+
const result = (0, capability_manifest_1.parseManifestData)(req.body);
|
|
130
|
+
if (!result.success || !result.manifest) {
|
|
131
|
+
res.status(400).json({ error: result.error });
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const registered = (0, risk_engine_1.registerAgent)(result.manifest);
|
|
135
|
+
const risk = (0, risk_engine_1.assessAgentRisk)(registered);
|
|
136
|
+
res.json({ ...registered, risk });
|
|
137
|
+
});
|
|
138
|
+
app.post("/api/assess-action", localOnly, validateSecret, (req, res) => {
|
|
139
|
+
const { type, tool, command, url, path: filePath, agentId } = req.body;
|
|
140
|
+
if (!type) {
|
|
141
|
+
res.status(400).json({ error: "Missing 'type' field" });
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const assessment = (0, risk_engine_1.assessActionRisk)({ type, tool, command, url, path: filePath }, agentId);
|
|
145
|
+
res.json(assessment);
|
|
146
|
+
});
|
|
147
|
+
app.get("/api/manifest-template", localOnly, (req, res) => {
|
|
148
|
+
const framework = typeof req.query?.framework === "string" ? req.query.framework : undefined;
|
|
149
|
+
res.type("application/json").send((0, capability_manifest_1.generateManifestTemplate)(framework));
|
|
150
|
+
});
|
|
151
|
+
return new Promise((resolve, reject) => {
|
|
152
|
+
server = app.listen(port, host, () => {
|
|
153
|
+
console.log(`[Averecion Lite] http://${host}:${port}/clawguard`);
|
|
154
|
+
wss = new ws_1.WebSocketServer({ server: server });
|
|
155
|
+
wss.on("connection", (ws, req) => {
|
|
156
|
+
const allowRemote = process.env.LITE_ALLOW_REMOTE === "true";
|
|
157
|
+
const addr = req.socket.remoteAddress;
|
|
158
|
+
const isLocal = addr === "127.0.0.1" || addr === "::1" || addr === "::ffff:127.0.0.1";
|
|
159
|
+
if (!isLocal && allowRemote) {
|
|
160
|
+
const url = new URL(req.url || "/", `http://${req.headers.host}`);
|
|
161
|
+
const secret = url.searchParams.get("secret") || req.headers["x-lite-secret"];
|
|
162
|
+
const expectedSecret = process.env.LITE_ADAPTER_SECRET;
|
|
163
|
+
if (!expectedSecret || secret !== expectedSecret) {
|
|
164
|
+
console.log("[WebSocket] Unauthorized remote connection rejected");
|
|
165
|
+
ws.close(4001, "Unauthorized");
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
console.log("[WebSocket] Client connected");
|
|
170
|
+
ws.send(JSON.stringify({ type: "connected", message: "Clawguard monitoring active" }));
|
|
171
|
+
const metrics = (0, metrics_1.getMetrics)(24);
|
|
172
|
+
ws.send(JSON.stringify({ type: "metrics", data: metrics }));
|
|
173
|
+
ws.on("close", () => {
|
|
174
|
+
console.log("[WebSocket] Client disconnected");
|
|
175
|
+
});
|
|
176
|
+
});
|
|
177
|
+
const logWatcher = (0, log_watcher_1.startLogWatcher)();
|
|
178
|
+
logWatcher.on("toolEvent", (event) => {
|
|
179
|
+
broadcastToClients({
|
|
180
|
+
type: "toolEvent",
|
|
181
|
+
data: {
|
|
182
|
+
tool: event.tool,
|
|
183
|
+
runId: event.runId,
|
|
184
|
+
toolCallId: event.toolCallId,
|
|
185
|
+
phase: event.phase,
|
|
186
|
+
timestamp: event.timestamp.toISOString(),
|
|
187
|
+
analysis: event.analysis,
|
|
188
|
+
actionEvent: event.actionEvent,
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
});
|
|
192
|
+
logWatcher.on("toolComplete", (event) => {
|
|
193
|
+
broadcastToClients({
|
|
194
|
+
type: "toolComplete",
|
|
195
|
+
data: {
|
|
196
|
+
tool: event.tool,
|
|
197
|
+
runId: event.runId,
|
|
198
|
+
toolCallId: event.toolCallId,
|
|
199
|
+
duration: event.duration,
|
|
200
|
+
timestamp: event.timestamp.toISOString(),
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
resolve();
|
|
205
|
+
});
|
|
206
|
+
server.on("error", reject);
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
async function stopServer() {
|
|
210
|
+
(0, log_watcher_1.stopLogWatcher)();
|
|
211
|
+
return new Promise(resolve => {
|
|
212
|
+
if (wss) {
|
|
213
|
+
wss.close();
|
|
214
|
+
wss = null;
|
|
215
|
+
}
|
|
216
|
+
if (server) {
|
|
217
|
+
server.close(() => {
|
|
218
|
+
server = null;
|
|
219
|
+
resolve();
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
resolve();
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { AgentManifest, assessAgentRisk } from "./risk-engine";
|
|
2
|
+
export interface ManifestParseResult {
|
|
3
|
+
success: boolean;
|
|
4
|
+
manifest?: AgentManifest;
|
|
5
|
+
error?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function parseManifestFile(filePath: string): ManifestParseResult;
|
|
8
|
+
export declare function parseManifestData(data: Record<string, unknown>): ManifestParseResult;
|
|
9
|
+
export declare function registerAgentFromManifest(filePath: string): {
|
|
10
|
+
success: boolean;
|
|
11
|
+
manifest?: AgentManifest;
|
|
12
|
+
risk?: ReturnType<typeof assessAgentRisk>;
|
|
13
|
+
error?: string;
|
|
14
|
+
};
|
|
15
|
+
export declare function generateManifestTemplate(framework?: string): string;
|
|
16
|
+
//# sourceMappingURL=capability-manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capability-manifest.d.ts","sourceRoot":"","sources":["../../src/capability-manifest.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAkC,eAAe,EAAE,MAAM,eAAe,CAAC;AAE/F,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAkCD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,mBAAmB,CA+BvE;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,mBAAmB,CAqEpF;AAcD,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,aAAa,CAAC;IAAC,IAAI,CAAC,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAWrK;AAED,wBAAgB,wBAAwB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAmCnE"}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.parseManifestFile = parseManifestFile;
|
|
37
|
+
exports.parseManifestData = parseManifestData;
|
|
38
|
+
exports.registerAgentFromManifest = registerAgentFromManifest;
|
|
39
|
+
exports.generateManifestTemplate = generateManifestTemplate;
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const risk_engine_1 = require("./risk-engine");
|
|
43
|
+
const KNOWN_FRAMEWORKS = {
|
|
44
|
+
"clawdbot": [
|
|
45
|
+
{ name: "execute", type: "shell", riskWeight: 80, description: "Execute shell commands" },
|
|
46
|
+
{ name: "read", type: "filesystem", riskWeight: 20, description: "Read files" },
|
|
47
|
+
{ name: "write", type: "filesystem", riskWeight: 50, description: "Write files" },
|
|
48
|
+
{ name: "process", type: "process", riskWeight: 60, description: "Process management" },
|
|
49
|
+
{ name: "http", type: "http", riskWeight: 30, description: "HTTP requests" },
|
|
50
|
+
],
|
|
51
|
+
"claude-desktop": [
|
|
52
|
+
{ name: "computer", type: "shell", riskWeight: 90, description: "Computer use capability" },
|
|
53
|
+
{ name: "bash", type: "shell", riskWeight: 80, description: "Bash command execution" },
|
|
54
|
+
{ name: "text_editor", type: "filesystem", riskWeight: 50, description: "Text file editing" },
|
|
55
|
+
],
|
|
56
|
+
"langchain": [
|
|
57
|
+
{ name: "shell", type: "shell", riskWeight: 80, description: "Shell tool" },
|
|
58
|
+
{ name: "python_repl", type: "code", riskWeight: 85, description: "Python REPL" },
|
|
59
|
+
{ name: "requests", type: "http", riskWeight: 40, description: "HTTP requests" },
|
|
60
|
+
],
|
|
61
|
+
"autogpt": [
|
|
62
|
+
{ name: "execute_shell", type: "shell", riskWeight: 80, description: "Shell execution" },
|
|
63
|
+
{ name: "write_file", type: "filesystem", riskWeight: 50, description: "File writing" },
|
|
64
|
+
{ name: "read_file", type: "filesystem", riskWeight: 20, description: "File reading" },
|
|
65
|
+
{ name: "browse_website", type: "network", riskWeight: 40, description: "Web browsing" },
|
|
66
|
+
{ name: "execute_python_code", type: "code", riskWeight: 85, description: "Python execution" },
|
|
67
|
+
],
|
|
68
|
+
"openai-agents": [
|
|
69
|
+
{ name: "code_interpreter", type: "code", riskWeight: 70, description: "Code interpreter" },
|
|
70
|
+
{ name: "file_search", type: "filesystem", riskWeight: 20, description: "File search" },
|
|
71
|
+
{ name: "function_calling", type: "custom", riskWeight: 50, description: "Function calls" },
|
|
72
|
+
],
|
|
73
|
+
};
|
|
74
|
+
function parseManifestFile(filePath) {
|
|
75
|
+
try {
|
|
76
|
+
if (!fs.existsSync(filePath)) {
|
|
77
|
+
return { success: false, error: `File not found: ${filePath}` };
|
|
78
|
+
}
|
|
79
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
80
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
81
|
+
let data;
|
|
82
|
+
if (ext === ".yaml" || ext === ".yml") {
|
|
83
|
+
const lines = content.split("\n");
|
|
84
|
+
data = {};
|
|
85
|
+
let currentKey = "";
|
|
86
|
+
for (const line of lines) {
|
|
87
|
+
const match = line.match(/^(\w+):\s*(.*)$/);
|
|
88
|
+
if (match) {
|
|
89
|
+
currentKey = match[1];
|
|
90
|
+
data[currentKey] = match[2] || [];
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else if (ext === ".json") {
|
|
95
|
+
data = JSON.parse(content);
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
return { success: false, error: `Unsupported file format: ${ext}` };
|
|
99
|
+
}
|
|
100
|
+
return parseManifestData(data);
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
return { success: false, error: `Parse error: ${err.message}` };
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function parseManifestData(data) {
|
|
107
|
+
if (!data.id || typeof data.id !== "string") {
|
|
108
|
+
return { success: false, error: "Manifest must have an 'id' field" };
|
|
109
|
+
}
|
|
110
|
+
if (!data.name || typeof data.name !== "string") {
|
|
111
|
+
return { success: false, error: "Manifest must have a 'name' field" };
|
|
112
|
+
}
|
|
113
|
+
let capabilities = [];
|
|
114
|
+
if (data.framework && typeof data.framework === "string") {
|
|
115
|
+
const frameworkCaps = KNOWN_FRAMEWORKS[data.framework.toLowerCase()];
|
|
116
|
+
if (frameworkCaps) {
|
|
117
|
+
capabilities = [...frameworkCaps];
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (Array.isArray(data.capabilities)) {
|
|
121
|
+
for (const cap of data.capabilities) {
|
|
122
|
+
if (typeof cap === "string") {
|
|
123
|
+
capabilities.push({
|
|
124
|
+
name: cap,
|
|
125
|
+
type: inferCapabilityType(cap),
|
|
126
|
+
riskWeight: 50
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
else if (typeof cap === "object" && cap !== null) {
|
|
130
|
+
const capObj = cap;
|
|
131
|
+
capabilities.push({
|
|
132
|
+
name: String(capObj.name ?? "unknown"),
|
|
133
|
+
type: capObj.type ?? inferCapabilityType(String(capObj.name ?? "")),
|
|
134
|
+
description: capObj.description,
|
|
135
|
+
permissions: Array.isArray(capObj.permissions) ? capObj.permissions.map(String) : undefined,
|
|
136
|
+
riskWeight: typeof capObj.riskWeight === "number" ? capObj.riskWeight : 50
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (Array.isArray(data.tools)) {
|
|
142
|
+
for (const tool of data.tools) {
|
|
143
|
+
if (typeof tool === "string") {
|
|
144
|
+
capabilities.push({
|
|
145
|
+
name: tool,
|
|
146
|
+
type: inferCapabilityType(tool),
|
|
147
|
+
riskWeight: 50
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
else if (typeof tool === "object" && tool !== null) {
|
|
151
|
+
const toolObj = tool;
|
|
152
|
+
capabilities.push({
|
|
153
|
+
name: String(toolObj.name ?? toolObj.function ?? "unknown"),
|
|
154
|
+
type: inferCapabilityType(String(toolObj.name ?? toolObj.function ?? "")),
|
|
155
|
+
description: (toolObj.description ?? toolObj.desc),
|
|
156
|
+
riskWeight: 50
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
const manifest = {
|
|
162
|
+
id: data.id,
|
|
163
|
+
name: data.name,
|
|
164
|
+
version: data.version,
|
|
165
|
+
framework: data.framework,
|
|
166
|
+
capabilities,
|
|
167
|
+
registeredAt: new Date().toISOString()
|
|
168
|
+
};
|
|
169
|
+
return { success: true, manifest };
|
|
170
|
+
}
|
|
171
|
+
function inferCapabilityType(name) {
|
|
172
|
+
const lowerName = name.toLowerCase();
|
|
173
|
+
if (/shell|bash|exec|terminal|command/.test(lowerName))
|
|
174
|
+
return "shell";
|
|
175
|
+
if (/http|api|request|fetch|curl/.test(lowerName))
|
|
176
|
+
return "http";
|
|
177
|
+
if (/file|read|write|fs|disk/.test(lowerName))
|
|
178
|
+
return "filesystem";
|
|
179
|
+
if (/process|spawn|kill|signal/.test(lowerName))
|
|
180
|
+
return "process";
|
|
181
|
+
if (/network|tcp|udp|socket|connect/.test(lowerName))
|
|
182
|
+
return "network";
|
|
183
|
+
return "custom";
|
|
184
|
+
}
|
|
185
|
+
function registerAgentFromManifest(filePath) {
|
|
186
|
+
const result = parseManifestFile(filePath);
|
|
187
|
+
if (!result.success || !result.manifest) {
|
|
188
|
+
return { success: false, error: result.error };
|
|
189
|
+
}
|
|
190
|
+
const registered = (0, risk_engine_1.registerAgent)(result.manifest);
|
|
191
|
+
const risk = (0, risk_engine_1.assessAgentRisk)(registered);
|
|
192
|
+
return { success: true, manifest: registered, risk };
|
|
193
|
+
}
|
|
194
|
+
function generateManifestTemplate(framework) {
|
|
195
|
+
const template = {
|
|
196
|
+
id: "my-agent",
|
|
197
|
+
name: "My AI Agent",
|
|
198
|
+
version: "1.0.0",
|
|
199
|
+
framework: framework ?? "custom",
|
|
200
|
+
capabilities: [
|
|
201
|
+
{
|
|
202
|
+
name: "shell",
|
|
203
|
+
type: "shell",
|
|
204
|
+
description: "Execute shell commands",
|
|
205
|
+
riskWeight: 80
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
name: "file_read",
|
|
209
|
+
type: "filesystem",
|
|
210
|
+
description: "Read files from disk",
|
|
211
|
+
riskWeight: 20
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
name: "file_write",
|
|
215
|
+
type: "filesystem",
|
|
216
|
+
description: "Write files to disk",
|
|
217
|
+
riskWeight: 50
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
name: "http_request",
|
|
221
|
+
type: "http",
|
|
222
|
+
description: "Make HTTP requests",
|
|
223
|
+
riskWeight: 30
|
|
224
|
+
}
|
|
225
|
+
]
|
|
226
|
+
};
|
|
227
|
+
return JSON.stringify(template, null, 2);
|
|
228
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-proxy.d.ts","sourceRoot":"","sources":["../../src/http-proxy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AA6M7B,wBAAgB,iBAAiB,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC,MAAM,CAgE5D;AAED,wBAAgB,eAAe,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAWrE"}
|