@agentick/sandbox-local 0.2.1
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 +211 -0
- package/dist/executor/base.d.ts +15 -0
- package/dist/executor/base.d.ts.map +1 -0
- package/dist/executor/base.js +20 -0
- package/dist/executor/base.js.map +1 -0
- package/dist/executor/darwin.d.ts +16 -0
- package/dist/executor/darwin.d.ts.map +1 -0
- package/dist/executor/darwin.js +44 -0
- package/dist/executor/darwin.js.map +1 -0
- package/dist/executor/linux.d.ts +22 -0
- package/dist/executor/linux.d.ts.map +1 -0
- package/dist/executor/linux.js +50 -0
- package/dist/executor/linux.js.map +1 -0
- package/dist/executor/select.d.ts +12 -0
- package/dist/executor/select.d.ts.map +1 -0
- package/dist/executor/select.js +23 -0
- package/dist/executor/select.js.map +1 -0
- package/dist/executor/types.d.ts +29 -0
- package/dist/executor/types.d.ts.map +1 -0
- package/dist/executor/types.js +4 -0
- package/dist/executor/types.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/linux/bwrap.d.ts +11 -0
- package/dist/linux/bwrap.d.ts.map +1 -0
- package/dist/linux/bwrap.js +46 -0
- package/dist/linux/bwrap.js.map +1 -0
- package/dist/linux/cgroup.d.ts +27 -0
- package/dist/linux/cgroup.d.ts.map +1 -0
- package/dist/linux/cgroup.js +80 -0
- package/dist/linux/cgroup.js.map +1 -0
- package/dist/linux/unshare.d.ts +11 -0
- package/dist/linux/unshare.d.ts.map +1 -0
- package/dist/linux/unshare.js +22 -0
- package/dist/linux/unshare.js.map +1 -0
- package/dist/local-sandbox.d.ts +42 -0
- package/dist/local-sandbox.d.ts.map +1 -0
- package/dist/local-sandbox.js +235 -0
- package/dist/local-sandbox.js.map +1 -0
- package/dist/network/ca.d.ts +38 -0
- package/dist/network/ca.d.ts.map +1 -0
- package/dist/network/ca.js +143 -0
- package/dist/network/ca.js.map +1 -0
- package/dist/network/proxy.d.ts +46 -0
- package/dist/network/proxy.d.ts.map +1 -0
- package/dist/network/proxy.js +144 -0
- package/dist/network/proxy.js.map +1 -0
- package/dist/network/rules.d.ts +23 -0
- package/dist/network/rules.d.ts.map +1 -0
- package/dist/network/rules.js +64 -0
- package/dist/network/rules.js.map +1 -0
- package/dist/paths.d.ts +29 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +129 -0
- package/dist/paths.js.map +1 -0
- package/dist/platform/detect.d.ts +17 -0
- package/dist/platform/detect.d.ts.map +1 -0
- package/dist/platform/detect.js +114 -0
- package/dist/platform/detect.js.map +1 -0
- package/dist/platform/types.d.ts +16 -0
- package/dist/platform/types.d.ts.map +1 -0
- package/dist/platform/types.js +4 -0
- package/dist/platform/types.js.map +1 -0
- package/dist/provider.d.ts +33 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +137 -0
- package/dist/provider.js.map +1 -0
- package/dist/resources.d.ts +30 -0
- package/dist/resources.d.ts.map +1 -0
- package/dist/resources.js +94 -0
- package/dist/resources.js.map +1 -0
- package/dist/seatbelt/profile.d.ts +30 -0
- package/dist/seatbelt/profile.d.ts.map +1 -0
- package/dist/seatbelt/profile.js +106 -0
- package/dist/seatbelt/profile.js.map +1 -0
- package/dist/testing.d.ts +22 -0
- package/dist/testing.d.ts.map +1 -0
- package/dist/testing.js +39 -0
- package/dist/testing.js.map +1 -0
- package/dist/workspace.d.ts +30 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +68 -0
- package/dist/workspace.js.map +1 -0
- package/package.json +64 -0
- package/src/index.ts +17 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../../src/network/proxy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGrE,MAAM,WAAW,iBAAiB;IAChC,qCAAqC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,4DAA4D;IAC5D,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,CAAC;IAE1C,wCAAwC;IACxC,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,CAAC;IAExC,iDAAiD;IACjD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,qBAAa,kBAAkB;IAC7B,QAAQ,CAAC,KAAK,EAAE,WAAW,EAAE,CAAC;IAC9B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA8B;IACrD,OAAO,CAAC,MAAM,CAAC,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAwB;IACxC,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,KAAK,CAAC,CAAS;gBAEX,KAAK,EAAE,WAAW,EAAE,EAAE,MAAM,CAAC,EAAE,iBAAiB;IAU5D,8EAA8E;IAC9E,IAAI,QAAQ,IAAI,MAAM,CAGrB;IAED,8BAA8B;IACxB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAmB5B,6BAA6B;IACvB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAU3B,iDAAiD;IACjD,WAAW,IAAI,cAAc,EAAE;IAI/B,4CAA4C;IAC5C,OAAO,CAAC,iBAAiB;IAgDzB,+CAA+C;IAC/C,OAAO,CAAC,aAAa;IAmCrB,sDAAsD;IACtD,OAAO,CAAC,UAAU;CAiBnB"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTTP/HTTPS Proxy Server
|
|
3
|
+
*
|
|
4
|
+
* Binds an HTTP proxy server that intercepts HTTP traffic and applies
|
|
5
|
+
* network rules. HTTPS connections are handled at the CONNECT level:
|
|
6
|
+
* allowed connections get a passthrough tunnel, denied ones are rejected.
|
|
7
|
+
*
|
|
8
|
+
* No MITM/TLS termination — HTTPS content is opaque. This covers the
|
|
9
|
+
* primary use case (domain-level allow/deny) without the complexity of
|
|
10
|
+
* CA generation and TLS interception.
|
|
11
|
+
*/
|
|
12
|
+
import { createServer, request as httpRequest } from "node:http";
|
|
13
|
+
import * as net from "node:net";
|
|
14
|
+
import { matchRequest } from "./rules";
|
|
15
|
+
export class NetworkProxyServer {
|
|
16
|
+
rules;
|
|
17
|
+
config;
|
|
18
|
+
server;
|
|
19
|
+
auditLog = [];
|
|
20
|
+
_proxyUrl;
|
|
21
|
+
_port;
|
|
22
|
+
constructor(rules, config) {
|
|
23
|
+
this.rules = rules;
|
|
24
|
+
this.config = {
|
|
25
|
+
port: config?.port ?? 0,
|
|
26
|
+
onRequest: config?.onRequest ?? (() => { }),
|
|
27
|
+
onBlock: config?.onBlock ?? (() => { }),
|
|
28
|
+
maxAuditEntries: config?.maxAuditEntries ?? 10000,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/** The proxy URL (e.g. "http://127.0.0.1:12345"). Available after start(). */
|
|
32
|
+
get proxyUrl() {
|
|
33
|
+
if (!this._proxyUrl)
|
|
34
|
+
throw new Error("Proxy not started");
|
|
35
|
+
return this._proxyUrl;
|
|
36
|
+
}
|
|
37
|
+
/** Start the proxy server. */
|
|
38
|
+
async start() {
|
|
39
|
+
this.server = createServer((req, res) => this.handleHttpRequest(req, res));
|
|
40
|
+
this.server.on("connect", (req, socket, head) => this.handleConnect(req, socket, head));
|
|
41
|
+
await new Promise((resolve, reject) => {
|
|
42
|
+
this.server.listen(this.config.port, "127.0.0.1", () => {
|
|
43
|
+
const addr = this.server.address();
|
|
44
|
+
if (typeof addr === "object" && addr) {
|
|
45
|
+
this._port = addr.port;
|
|
46
|
+
this._proxyUrl = `http://127.0.0.1:${addr.port}`;
|
|
47
|
+
}
|
|
48
|
+
resolve();
|
|
49
|
+
});
|
|
50
|
+
this.server.on("error", reject);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
/** Stop the proxy server. */
|
|
54
|
+
async stop() {
|
|
55
|
+
await new Promise((resolve) => {
|
|
56
|
+
if (this.server) {
|
|
57
|
+
this.server.close(() => resolve());
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
resolve();
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/** Get the audit log of all proxied requests. */
|
|
65
|
+
getAuditLog() {
|
|
66
|
+
return [...this.auditLog];
|
|
67
|
+
}
|
|
68
|
+
/** Handle an HTTP request (non-CONNECT). */
|
|
69
|
+
handleHttpRequest(req, res) {
|
|
70
|
+
const url = req.url ?? "/";
|
|
71
|
+
const host = req.headers.host ?? "unknown";
|
|
72
|
+
const port = parseInt(host.split(":")[1] ?? "80", 10);
|
|
73
|
+
const entry = this.logRequest(url, req.method ?? "GET", host.split(":")[0], port);
|
|
74
|
+
const match = matchRequest({ host: host.split(":")[0], port, method: req.method ?? "GET", url }, this.rules);
|
|
75
|
+
entry.matchedRule = match.rule;
|
|
76
|
+
if (match.action === "deny") {
|
|
77
|
+
entry.blocked = true;
|
|
78
|
+
this.config.onBlock(entry);
|
|
79
|
+
res.writeHead(403, { "Content-Type": "text/plain" });
|
|
80
|
+
res.end("Blocked by sandbox network rules");
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
this.config.onRequest(entry);
|
|
84
|
+
// Forward the request
|
|
85
|
+
const parsedUrl = new URL(url);
|
|
86
|
+
const proxyReq = httpRequest({
|
|
87
|
+
hostname: parsedUrl.hostname,
|
|
88
|
+
port: parsedUrl.port || 80,
|
|
89
|
+
path: parsedUrl.pathname + parsedUrl.search,
|
|
90
|
+
method: req.method,
|
|
91
|
+
headers: { ...req.headers, host: parsedUrl.host },
|
|
92
|
+
}, (proxyRes) => {
|
|
93
|
+
res.writeHead(proxyRes.statusCode ?? 502, proxyRes.headers);
|
|
94
|
+
proxyRes.pipe(res);
|
|
95
|
+
});
|
|
96
|
+
proxyReq.on("error", () => {
|
|
97
|
+
res.writeHead(502, { "Content-Type": "text/plain" });
|
|
98
|
+
res.end("Proxy connection error");
|
|
99
|
+
});
|
|
100
|
+
req.pipe(proxyReq);
|
|
101
|
+
}
|
|
102
|
+
/** Handle a CONNECT request (HTTPS tunnel). */
|
|
103
|
+
handleConnect(req, socket, _head) {
|
|
104
|
+
const [host, portStr] = (req.url ?? "").split(":");
|
|
105
|
+
const port = parseInt(portStr ?? "443", 10);
|
|
106
|
+
const entry = this.logRequest(`https://${host}:${port}`, "CONNECT", host, port);
|
|
107
|
+
const match = matchRequest({ host, port, method: "CONNECT", url: `https://${host}:${port}` }, this.rules);
|
|
108
|
+
entry.matchedRule = match.rule;
|
|
109
|
+
if (match.action === "deny") {
|
|
110
|
+
entry.blocked = true;
|
|
111
|
+
this.config.onBlock(entry);
|
|
112
|
+
socket.write("HTTP/1.1 403 Forbidden\r\n\r\n");
|
|
113
|
+
socket.end();
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
this.config.onRequest(entry);
|
|
117
|
+
// Passthrough: direct tunnel to target (no TLS interception)
|
|
118
|
+
const { connect } = net;
|
|
119
|
+
const remote = connect(port, host, () => {
|
|
120
|
+
socket.write("HTTP/1.1 200 Connection Established\r\n\r\n");
|
|
121
|
+
socket.pipe(remote);
|
|
122
|
+
remote.pipe(socket);
|
|
123
|
+
});
|
|
124
|
+
remote.on("error", () => socket.destroy());
|
|
125
|
+
socket.on("error", () => remote.destroy());
|
|
126
|
+
}
|
|
127
|
+
/** Log a request and trim the audit log if needed. */
|
|
128
|
+
logRequest(url, method, host, port) {
|
|
129
|
+
const entry = {
|
|
130
|
+
url,
|
|
131
|
+
method,
|
|
132
|
+
host,
|
|
133
|
+
port,
|
|
134
|
+
timestamp: Date.now(),
|
|
135
|
+
blocked: false,
|
|
136
|
+
};
|
|
137
|
+
this.auditLog.push(entry);
|
|
138
|
+
if (this.auditLog.length > this.config.maxAuditEntries) {
|
|
139
|
+
this.auditLog = this.auditLog.slice(-this.config.maxAuditEntries);
|
|
140
|
+
}
|
|
141
|
+
return entry;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=proxy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxy.js","sourceRoot":"","sources":["../../src/network/proxy.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Network Rule Matching Engine
|
|
3
|
+
*
|
|
4
|
+
* Evaluates requests against an ordered list of NetworkRules.
|
|
5
|
+
* First match wins; default action is deny.
|
|
6
|
+
*/
|
|
7
|
+
import type { NetworkRule } from "@agentick/sandbox";
|
|
8
|
+
export interface RequestInfo {
|
|
9
|
+
host: string;
|
|
10
|
+
port: number;
|
|
11
|
+
method: string;
|
|
12
|
+
url: string;
|
|
13
|
+
}
|
|
14
|
+
export interface MatchResult {
|
|
15
|
+
action: "allow" | "deny";
|
|
16
|
+
rule?: NetworkRule;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Match a request against an ordered list of rules.
|
|
20
|
+
* First matching rule wins. Default: deny.
|
|
21
|
+
*/
|
|
22
|
+
export declare function matchRequest(request: RequestInfo, rules: NetworkRule[]): MatchResult;
|
|
23
|
+
//# sourceMappingURL=rules.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../src/network/rules.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC;IACzB,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,GAAG,WAAW,CAOpF"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Network Rule Matching Engine
|
|
3
|
+
*
|
|
4
|
+
* Evaluates requests against an ordered list of NetworkRules.
|
|
5
|
+
* First match wins; default action is deny.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Match a request against an ordered list of rules.
|
|
9
|
+
* First matching rule wins. Default: deny.
|
|
10
|
+
*/
|
|
11
|
+
export function matchRequest(request, rules) {
|
|
12
|
+
for (const rule of rules) {
|
|
13
|
+
if (ruleMatches(request, rule)) {
|
|
14
|
+
return { action: rule.action, rule };
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return { action: "deny" };
|
|
18
|
+
}
|
|
19
|
+
function ruleMatches(request, rule) {
|
|
20
|
+
// Domain check
|
|
21
|
+
if (rule.domain !== undefined) {
|
|
22
|
+
if (!matchDomain(request.host, rule.domain))
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
// Port check
|
|
26
|
+
if (rule.port !== undefined) {
|
|
27
|
+
if (request.port !== rule.port)
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
// Method check
|
|
31
|
+
if (rule.methods !== undefined && rule.methods.length > 0) {
|
|
32
|
+
const upperMethod = request.method.toUpperCase();
|
|
33
|
+
if (!rule.methods.some((m) => m.toUpperCase() === upperMethod))
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
// URL pattern check
|
|
37
|
+
if (rule.urlPattern !== undefined) {
|
|
38
|
+
try {
|
|
39
|
+
const regex = new RegExp(rule.urlPattern);
|
|
40
|
+
if (!regex.test(request.url))
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
// Invalid regex — treat as no match
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Match a hostname against a domain pattern.
|
|
52
|
+
* Supports wildcards: "*.example.com" matches "sub.example.com" but not "example.com".
|
|
53
|
+
* Exact match: "example.com" matches only "example.com".
|
|
54
|
+
*/
|
|
55
|
+
function matchDomain(hostname, pattern) {
|
|
56
|
+
const host = hostname.toLowerCase();
|
|
57
|
+
const pat = pattern.toLowerCase();
|
|
58
|
+
if (pat.startsWith("*.")) {
|
|
59
|
+
const suffix = pat.slice(1); // ".example.com"
|
|
60
|
+
return host.endsWith(suffix) && host.length > suffix.length;
|
|
61
|
+
}
|
|
62
|
+
return host === pat;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=rules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules.js","sourceRoot":"","sources":["../../src/network/rules.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAgBH;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,OAAoB,EAAE,KAAoB;IACrE,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC;YAC/B,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC;QACvC,CAAC;IACH,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAC5B,CAAC;AAED,SAAS,WAAW,CAAC,OAAoB,EAAE,IAAiB;IAC1D,eAAe;IACf,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC9B,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC;YAAE,OAAO,KAAK,CAAC;IAC5D,CAAC;IAED,aAAa;IACb,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC5B,IAAI,OAAO,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;IAC/C,CAAC;IAED,eAAe;IACf,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC1D,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;QACjD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,KAAK,WAAW,CAAC;YAAE,OAAO,KAAK,CAAC;IAC/E,CAAC;IAED,oBAAoB;IACpB,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QAClC,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC1C,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC;gBAAE,OAAO,KAAK,CAAC;QAC7C,CAAC;QAAC,MAAM,CAAC;YACP,oCAAoC;YACpC,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,SAAS,WAAW,CAAC,QAAgB,EAAE,OAAe;IACpD,MAAM,IAAI,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC;IACpC,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAElC,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACzB,MAAM,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,iBAAiB;QAC9C,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAC9D,CAAC;IAED,OAAO,IAAI,KAAK,GAAG,CAAC;AACtB,CAAC"}
|
package/dist/paths.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Path Safety
|
|
3
|
+
*
|
|
4
|
+
* Resolves paths, follows symlinks, validates bounds against workspace and mounts.
|
|
5
|
+
* Rejects path traversal, null bytes, and escape attempts.
|
|
6
|
+
*/
|
|
7
|
+
import type { ResolvedMount } from "./executor/types";
|
|
8
|
+
/** Environment variables that must never be inherited. */
|
|
9
|
+
export declare const ENV_BLOCKLIST: Set<string>;
|
|
10
|
+
/**
|
|
11
|
+
* Resolve and validate a path is within the workspace or an allowed mount.
|
|
12
|
+
*
|
|
13
|
+
* IMPORTANT: workspacePath must already be realpath-resolved (done once at
|
|
14
|
+
* creation time by createWorkspace). Mount hostPaths are also pre-resolved
|
|
15
|
+
* by resolveMounts. This avoids redundant realpath calls on every file op.
|
|
16
|
+
*
|
|
17
|
+
* @param inputPath - The path to resolve (relative to workspace or absolute)
|
|
18
|
+
* @param workspacePath - The sandbox workspace root (must be pre-resolved via realpath)
|
|
19
|
+
* @param mode - Required access mode ("read" or "write")
|
|
20
|
+
* @param mounts - Resolved mounts with host paths and modes
|
|
21
|
+
* @returns The resolved absolute path
|
|
22
|
+
* @throws On null bytes, traversal, or out-of-bounds access
|
|
23
|
+
*/
|
|
24
|
+
export declare function resolveSafePath(inputPath: string, workspacePath: string, mode: "read" | "write", mounts?: ResolvedMount[]): Promise<string>;
|
|
25
|
+
/**
|
|
26
|
+
* Filter dangerous environment variables from an env record.
|
|
27
|
+
*/
|
|
28
|
+
export declare function filterEnv(env: Record<string, string>): Record<string, string>;
|
|
29
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,0DAA0D;AAC1D,eAAO,MAAM,aAAa,aAMxB,CAAC;AAEH;;;;;;;;;;;;;GAaG;AACH,wBAAsB,eAAe,CACnC,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,MAAM,GAAG,OAAO,EACtB,MAAM,GAAE,aAAa,EAAO,GAC3B,OAAO,CAAC,MAAM,CAAC,CAwEjB;AAwBD;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQ7E"}
|
package/dist/paths.js
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Path Safety
|
|
3
|
+
*
|
|
4
|
+
* Resolves paths, follows symlinks, validates bounds against workspace and mounts.
|
|
5
|
+
* Rejects path traversal, null bytes, and escape attempts.
|
|
6
|
+
*/
|
|
7
|
+
import { realpath } from "node:fs/promises";
|
|
8
|
+
import { resolve, isAbsolute } from "node:path";
|
|
9
|
+
/** Environment variables that must never be inherited. */
|
|
10
|
+
export const ENV_BLOCKLIST = new Set([
|
|
11
|
+
"LD_PRELOAD",
|
|
12
|
+
"LD_LIBRARY_PATH",
|
|
13
|
+
"DYLD_INSERT_LIBRARIES",
|
|
14
|
+
"DYLD_LIBRARY_PATH",
|
|
15
|
+
"DYLD_FRAMEWORK_PATH",
|
|
16
|
+
]);
|
|
17
|
+
/**
|
|
18
|
+
* Resolve and validate a path is within the workspace or an allowed mount.
|
|
19
|
+
*
|
|
20
|
+
* IMPORTANT: workspacePath must already be realpath-resolved (done once at
|
|
21
|
+
* creation time by createWorkspace). Mount hostPaths are also pre-resolved
|
|
22
|
+
* by resolveMounts. This avoids redundant realpath calls on every file op.
|
|
23
|
+
*
|
|
24
|
+
* @param inputPath - The path to resolve (relative to workspace or absolute)
|
|
25
|
+
* @param workspacePath - The sandbox workspace root (must be pre-resolved via realpath)
|
|
26
|
+
* @param mode - Required access mode ("read" or "write")
|
|
27
|
+
* @param mounts - Resolved mounts with host paths and modes
|
|
28
|
+
* @returns The resolved absolute path
|
|
29
|
+
* @throws On null bytes, traversal, or out-of-bounds access
|
|
30
|
+
*/
|
|
31
|
+
export async function resolveSafePath(inputPath, workspacePath, mode, mounts = []) {
|
|
32
|
+
// Reject null bytes
|
|
33
|
+
if (inputPath.includes("\0")) {
|
|
34
|
+
throw new Error("Path contains null bytes");
|
|
35
|
+
}
|
|
36
|
+
// workspacePath is pre-resolved via realpath by createWorkspace()
|
|
37
|
+
const realWorkspace = workspacePath;
|
|
38
|
+
// Resolve to absolute (relative paths are relative to workspace)
|
|
39
|
+
const absolute = isAbsolute(inputPath) ? inputPath : resolve(realWorkspace, inputPath);
|
|
40
|
+
// Try to follow symlinks to the real path. If the file doesn't exist yet
|
|
41
|
+
// (write mode), resolve the parent directory instead.
|
|
42
|
+
let resolved;
|
|
43
|
+
try {
|
|
44
|
+
resolved = await realpath(absolute);
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
if (err.code === "ENOENT") {
|
|
48
|
+
if (mode === "write") {
|
|
49
|
+
// File (or parent dirs) don't exist yet — walk up to find the
|
|
50
|
+
// closest existing ancestor, then verify it's within bounds
|
|
51
|
+
resolved = await resolveNonExistentPath(absolute);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
// For reads, if the file doesn't exist, resolve what we can and
|
|
55
|
+
// check bounds using path manipulation (to catch traversal attempts
|
|
56
|
+
// even when target doesn't exist)
|
|
57
|
+
resolved = resolve(absolute);
|
|
58
|
+
// Normalize out .. components
|
|
59
|
+
if (!resolved.startsWith(realWorkspace + "/") && resolved !== realWorkspace) {
|
|
60
|
+
// Check mounts (hostPaths are pre-resolved by resolveMounts)
|
|
61
|
+
let inMount = false;
|
|
62
|
+
for (const mount of mounts) {
|
|
63
|
+
if (resolved === mount.hostPath || resolved.startsWith(mount.hostPath + "/")) {
|
|
64
|
+
inMount = true;
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (!inMount) {
|
|
69
|
+
throw new Error(`Path escapes sandbox: ${inputPath} resolves to ${resolved} (workspace: ${realWorkspace})`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return resolved;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
throw err;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Check workspace bounds
|
|
80
|
+
if (resolved === realWorkspace || resolved.startsWith(realWorkspace + "/")) {
|
|
81
|
+
return resolved;
|
|
82
|
+
}
|
|
83
|
+
// Check mounts (hostPaths are pre-resolved by resolveMounts)
|
|
84
|
+
for (const mount of mounts) {
|
|
85
|
+
const inMount = resolved === mount.hostPath || resolved.startsWith(mount.hostPath + "/");
|
|
86
|
+
if (inMount) {
|
|
87
|
+
if (mode === "write" && mount.mode === "ro") {
|
|
88
|
+
throw new Error(`Write access denied: ${inputPath} resolves to read-only mount ${mount.sandboxPath}`);
|
|
89
|
+
}
|
|
90
|
+
return resolved;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
throw new Error(`Path escapes sandbox: ${inputPath} resolves to ${resolved} (workspace: ${realWorkspace})`);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Walk up the path tree to find the closest existing ancestor,
|
|
97
|
+
* then append the remaining segments. Used for write mode when
|
|
98
|
+
* the target file (and potentially parent dirs) don't exist yet.
|
|
99
|
+
*/
|
|
100
|
+
async function resolveNonExistentPath(absolute) {
|
|
101
|
+
let ancestor = absolute;
|
|
102
|
+
let suffix = "";
|
|
103
|
+
while (ancestor !== "/" && ancestor !== ".") {
|
|
104
|
+
const parent = resolve(ancestor, "..");
|
|
105
|
+
suffix = ancestor.slice(parent.length) + suffix;
|
|
106
|
+
ancestor = parent;
|
|
107
|
+
try {
|
|
108
|
+
const resolvedAncestor = await realpath(ancestor);
|
|
109
|
+
return resolvedAncestor + suffix;
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
// Keep walking up
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
throw new Error(`No accessible ancestor for path: ${absolute}`);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Filter dangerous environment variables from an env record.
|
|
119
|
+
*/
|
|
120
|
+
export function filterEnv(env) {
|
|
121
|
+
const filtered = {};
|
|
122
|
+
for (const [key, value] of Object.entries(env)) {
|
|
123
|
+
if (!ENV_BLOCKLIST.has(key)) {
|
|
124
|
+
filtered[key] = value;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return filtered;
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform capability detection.
|
|
3
|
+
*
|
|
4
|
+
* Probes the OS for sandbox features: macOS sandbox-exec, Linux bubblewrap/unshare,
|
|
5
|
+
* cgroups v2, user namespaces. Result is cached after first call.
|
|
6
|
+
*/
|
|
7
|
+
import type { PlatformCapabilities, SandboxStrategy } from "./types";
|
|
8
|
+
/**
|
|
9
|
+
* Detect platform sandbox capabilities.
|
|
10
|
+
* Result is cached — safe to call multiple times.
|
|
11
|
+
*/
|
|
12
|
+
export declare function detectCapabilities(): Promise<PlatformCapabilities>;
|
|
13
|
+
/** Select the best strategy given capabilities and optional override. */
|
|
14
|
+
export declare function selectStrategy(caps: PlatformCapabilities, override?: SandboxStrategy | "auto"): SandboxStrategy;
|
|
15
|
+
/** Reset the capability cache (for testing). */
|
|
16
|
+
export declare function resetCapabilitiesCache(): void;
|
|
17
|
+
//# sourceMappingURL=detect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../src/platform/detect.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AA0BrE;;;GAGG;AACH,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,oBAAoB,CAAC,CA6CxE;AAED,yEAAyE;AACzE,wBAAgB,cAAc,CAC5B,IAAI,EAAE,oBAAoB,EAC1B,QAAQ,CAAC,EAAE,eAAe,GAAG,MAAM,GAClC,eAAe,CA0BjB;AAED,gDAAgD;AAChD,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform capability detection.
|
|
3
|
+
*
|
|
4
|
+
* Probes the OS for sandbox features: macOS sandbox-exec, Linux bubblewrap/unshare,
|
|
5
|
+
* cgroups v2, user namespaces. Result is cached after first call.
|
|
6
|
+
*/
|
|
7
|
+
import { execFile } from "node:child_process";
|
|
8
|
+
import { access, readFile } from "node:fs/promises";
|
|
9
|
+
import { constants } from "node:fs";
|
|
10
|
+
import { promisify } from "node:util";
|
|
11
|
+
const execFileAsync = promisify(execFile);
|
|
12
|
+
let cached;
|
|
13
|
+
/** Check if a binary exists on PATH. */
|
|
14
|
+
async function which(name) {
|
|
15
|
+
try {
|
|
16
|
+
await execFileAsync("which", [name]);
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/** Check if a file exists and is readable. */
|
|
24
|
+
async function readable(path) {
|
|
25
|
+
try {
|
|
26
|
+
await access(path, constants.R_OK);
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Detect platform sandbox capabilities.
|
|
35
|
+
* Result is cached — safe to call multiple times.
|
|
36
|
+
*/
|
|
37
|
+
export async function detectCapabilities() {
|
|
38
|
+
if (cached)
|
|
39
|
+
return cached;
|
|
40
|
+
const rawPlatform = process.platform;
|
|
41
|
+
const platform = rawPlatform === "darwin" || rawPlatform === "linux" || rawPlatform === "win32"
|
|
42
|
+
? rawPlatform
|
|
43
|
+
: "unknown";
|
|
44
|
+
const base = {
|
|
45
|
+
platform,
|
|
46
|
+
arch: process.arch,
|
|
47
|
+
hasSandboxExec: false,
|
|
48
|
+
hasBwrap: false,
|
|
49
|
+
hasUnshare: false,
|
|
50
|
+
hasCgroupsV2: false,
|
|
51
|
+
userNamespaces: false,
|
|
52
|
+
uid: process.getuid?.() ?? -1,
|
|
53
|
+
recommended: "none",
|
|
54
|
+
};
|
|
55
|
+
if (platform === "darwin") {
|
|
56
|
+
base.hasSandboxExec = await readable("/usr/bin/sandbox-exec");
|
|
57
|
+
base.recommended = base.hasSandboxExec ? "seatbelt" : "none";
|
|
58
|
+
}
|
|
59
|
+
else if (platform === "linux") {
|
|
60
|
+
const [hasBwrap, hasUnshare, hasCgroups, userNs] = await Promise.all([
|
|
61
|
+
which("bwrap"),
|
|
62
|
+
which("unshare"),
|
|
63
|
+
readable("/sys/fs/cgroup/cgroup.controllers"),
|
|
64
|
+
readFile("/proc/sys/kernel/unprivileged_userns_clone", "utf-8")
|
|
65
|
+
.then((v) => v.trim() === "1")
|
|
66
|
+
.catch(() => false),
|
|
67
|
+
]);
|
|
68
|
+
base.hasBwrap = hasBwrap;
|
|
69
|
+
base.hasUnshare = hasUnshare;
|
|
70
|
+
base.hasCgroupsV2 = hasCgroups;
|
|
71
|
+
base.userNamespaces = userNs;
|
|
72
|
+
if (hasBwrap)
|
|
73
|
+
base.recommended = "bwrap";
|
|
74
|
+
else if (hasUnshare && userNs)
|
|
75
|
+
base.recommended = "unshare";
|
|
76
|
+
else
|
|
77
|
+
base.recommended = "none";
|
|
78
|
+
}
|
|
79
|
+
cached = base;
|
|
80
|
+
return base;
|
|
81
|
+
}
|
|
82
|
+
/** Select the best strategy given capabilities and optional override. */
|
|
83
|
+
export function selectStrategy(caps, override) {
|
|
84
|
+
if (!override || override === "auto")
|
|
85
|
+
return caps.recommended;
|
|
86
|
+
// Validate the override is available
|
|
87
|
+
switch (override) {
|
|
88
|
+
case "seatbelt":
|
|
89
|
+
if (!caps.hasSandboxExec) {
|
|
90
|
+
throw new Error("sandbox-exec not available on this platform");
|
|
91
|
+
}
|
|
92
|
+
return "seatbelt";
|
|
93
|
+
case "bwrap":
|
|
94
|
+
if (!caps.hasBwrap) {
|
|
95
|
+
throw new Error("bubblewrap (bwrap) not found on PATH");
|
|
96
|
+
}
|
|
97
|
+
return "bwrap";
|
|
98
|
+
case "unshare":
|
|
99
|
+
if (!caps.hasUnshare) {
|
|
100
|
+
throw new Error("unshare not found on PATH");
|
|
101
|
+
}
|
|
102
|
+
if (!caps.userNamespaces) {
|
|
103
|
+
throw new Error("user namespaces not available");
|
|
104
|
+
}
|
|
105
|
+
return "unshare";
|
|
106
|
+
case "none":
|
|
107
|
+
return "none";
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/** Reset the capability cache (for testing). */
|
|
111
|
+
export function resetCapabilitiesCache() {
|
|
112
|
+
cached = undefined;
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=detect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../src/platform/detect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform detection types.
|
|
3
|
+
*/
|
|
4
|
+
export type SandboxStrategy = "seatbelt" | "bwrap" | "unshare" | "none";
|
|
5
|
+
export interface PlatformCapabilities {
|
|
6
|
+
platform: "darwin" | "linux" | "win32" | "unknown";
|
|
7
|
+
arch: string;
|
|
8
|
+
hasSandboxExec: boolean;
|
|
9
|
+
hasBwrap: boolean;
|
|
10
|
+
hasUnshare: boolean;
|
|
11
|
+
hasCgroupsV2: boolean;
|
|
12
|
+
userNamespaces: boolean;
|
|
13
|
+
uid: number;
|
|
14
|
+
recommended: SandboxStrategy;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/platform/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAExE,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,CAAC;IACnD,IAAI,EAAE,MAAM,CAAC;IAGb,cAAc,EAAE,OAAO,CAAC;IAGxB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,cAAc,EAAE,OAAO,CAAC;IAGxB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,eAAe,CAAC;CAC9B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/platform/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local Sandbox Provider
|
|
3
|
+
*
|
|
4
|
+
* Factory function that creates a SandboxProvider backed by OS-level sandboxing.
|
|
5
|
+
*/
|
|
6
|
+
import type { SandboxProvider } from "@agentick/sandbox";
|
|
7
|
+
import type { SandboxStrategy } from "./platform/types";
|
|
8
|
+
import type { ProxyServerConfig } from "./network/proxy";
|
|
9
|
+
export interface LocalProviderConfig {
|
|
10
|
+
/** Sandbox strategy. "auto" detects the best available. Default: "auto". */
|
|
11
|
+
strategy?: SandboxStrategy | "auto";
|
|
12
|
+
/** Network proxy configuration. */
|
|
13
|
+
network?: ProxyServerConfig;
|
|
14
|
+
/** Base directory for temp workspaces. Default: os.tmpdir(). */
|
|
15
|
+
tmpBase?: string;
|
|
16
|
+
/** Whether to clean up auto-created workspaces on destroy. Default: true. */
|
|
17
|
+
cleanupWorkspace?: boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Create a local sandbox provider.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```typescript
|
|
24
|
+
* import { localProvider } from "@agentick/sandbox-local";
|
|
25
|
+
*
|
|
26
|
+
* const provider = localProvider();
|
|
27
|
+
* const sandbox = await provider.create({ workspace: true });
|
|
28
|
+
* const result = await sandbox.exec("echo hello");
|
|
29
|
+
* await sandbox.destroy();
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export declare function localProvider(config?: LocalProviderConfig): SandboxProvider;
|
|
33
|
+
//# sourceMappingURL=provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EACV,eAAe,EAKhB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AASxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,MAAM,WAAW,mBAAmB;IAClC,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,eAAe,GAAG,MAAM,CAAC;IAEpC,mCAAmC;IACnC,OAAO,CAAC,EAAE,iBAAiB,CAAC;IAE5B,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,6EAA6E;IAC7E,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,MAAM,CAAC,EAAE,mBAAmB,GAAG,eAAe,CAmH3E"}
|