@agentsh/secure-sandbox 0.1.5 → 0.1.7
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 +45 -11
- package/dist/adapters/blaxel.d.ts +1 -1
- package/dist/adapters/cloudflare.d.ts +1 -1
- package/dist/adapters/daytona.d.ts +1 -1
- package/dist/adapters/e2b.d.ts +1 -1
- package/dist/adapters/index.d.ts +2 -1
- package/dist/adapters/index.js +11 -1
- package/dist/adapters/vercel.d.ts +1 -1
- package/dist/chunk-4FJHYLAB.js +251 -0
- package/dist/chunk-4FJHYLAB.js.map +1 -0
- package/dist/chunk-5IG6ABIZ.js +268 -0
- package/dist/chunk-5IG6ABIZ.js.map +1 -0
- package/dist/{chunk-GFPHTJLU.js → chunk-LNDICGZU.js} +3 -243
- package/dist/chunk-LNDICGZU.js.map +1 -0
- package/dist/index-TyzWAIUD.d.ts +60 -0
- package/dist/index.d.ts +5 -11
- package/dist/index.js +209 -43
- package/dist/index.js.map +1 -1
- package/dist/policies/index.d.ts +1 -1
- package/dist/policies/index.js +5 -3
- package/dist/testing/index.d.ts +1 -1
- package/dist/{types-CUqsllMs.d.ts → types-DFMGk2GV.d.ts} +127 -2
- package/package.json +19 -1
- package/dist/chunk-GFPHTJLU.js.map +0 -1
- package/dist/chunk-L4KFLVNU.js +0 -33
- package/dist/chunk-L4KFLVNU.js.map +0 -1
- package/dist/index-aQ1TVPtG.d.ts +0 -16
- package/dist/{index-Nmlhw9oj.d.ts → index-CedRtlB6.d.ts} +22 -22
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import {
|
|
2
|
+
blaxel
|
|
3
|
+
} from "./chunk-UYEAO27E.js";
|
|
4
|
+
import {
|
|
5
|
+
cloudflare
|
|
6
|
+
} from "./chunk-LMN3KM53.js";
|
|
7
|
+
import {
|
|
8
|
+
daytona
|
|
9
|
+
} from "./chunk-45FKFVMC.js";
|
|
10
|
+
import {
|
|
11
|
+
e2b
|
|
12
|
+
} from "./chunk-2P37YGN7.js";
|
|
13
|
+
import {
|
|
14
|
+
envPrefix,
|
|
15
|
+
shellEscape
|
|
16
|
+
} from "./chunk-OANLKSOD.js";
|
|
17
|
+
import {
|
|
18
|
+
vercel
|
|
19
|
+
} from "./chunk-JY5ERJTX.js";
|
|
20
|
+
import {
|
|
21
|
+
agentDefault,
|
|
22
|
+
mergePrepend
|
|
23
|
+
} from "./chunk-LNDICGZU.js";
|
|
24
|
+
import {
|
|
25
|
+
__export
|
|
26
|
+
} from "./chunk-PZ5AY32C.js";
|
|
27
|
+
|
|
28
|
+
// src/adapters/index.ts
|
|
29
|
+
var adapters_exports = {};
|
|
30
|
+
__export(adapters_exports, {
|
|
31
|
+
blaxel: () => blaxel,
|
|
32
|
+
cloudflare: () => cloudflare,
|
|
33
|
+
daytona: () => daytona,
|
|
34
|
+
e2b: () => e2b,
|
|
35
|
+
modal: () => modal,
|
|
36
|
+
modalDefaults: () => modalDefaults,
|
|
37
|
+
sprites: () => sprites,
|
|
38
|
+
spritesDefaults: () => spritesDefaults,
|
|
39
|
+
vercel: () => vercel
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// src/adapters/sprites.ts
|
|
43
|
+
function sprites(sprite) {
|
|
44
|
+
function sh(cmd, opts) {
|
|
45
|
+
if (opts) return sprite.execFile("sh", ["-c", cmd], opts);
|
|
46
|
+
return sprite.execFile("sh", ["-c", cmd]);
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
async exec(cmd, args, opts) {
|
|
50
|
+
const command = `${envPrefix(opts?.env)}${shellEscape(cmd, args)}`;
|
|
51
|
+
const fullCmd = opts?.sudo ? `sudo ${command}` : command;
|
|
52
|
+
try {
|
|
53
|
+
if (opts?.detached) {
|
|
54
|
+
sh(`nohup ${fullCmd} > /dev/null 2>&1 &`).catch(() => {
|
|
55
|
+
});
|
|
56
|
+
return { stdout: "", stderr: "", exitCode: 0 };
|
|
57
|
+
}
|
|
58
|
+
const result = await sh(fullCmd, { cwd: opts?.cwd });
|
|
59
|
+
return {
|
|
60
|
+
stdout: result.stdout ?? "",
|
|
61
|
+
stderr: result.stderr ?? "",
|
|
62
|
+
exitCode: 0
|
|
63
|
+
};
|
|
64
|
+
} catch (err) {
|
|
65
|
+
return {
|
|
66
|
+
stdout: err.stdout ?? "",
|
|
67
|
+
stderr: err.stderr ?? err.message ?? "",
|
|
68
|
+
exitCode: err.exitCode ?? err.code ?? 1
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
async writeFile(path, content) {
|
|
73
|
+
const buf = Buffer.isBuffer(content) ? content : Buffer.from(content);
|
|
74
|
+
const b64 = buf.toString("base64");
|
|
75
|
+
try {
|
|
76
|
+
await sh(`printf '%s' '${b64}' | base64 -d > '${path.replace(/'/g, "'\\''")}'`);
|
|
77
|
+
} catch (err) {
|
|
78
|
+
throw new Error(`writeFile failed (exit ${err.exitCode ?? err.code ?? 1}): ${err.stderr ?? err.message ?? ""}`);
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
async readFile(path) {
|
|
82
|
+
try {
|
|
83
|
+
const result = await sh(`cat '${path.replace(/'/g, "'\\''")}'`);
|
|
84
|
+
return result.stdout ?? "";
|
|
85
|
+
} catch (err) {
|
|
86
|
+
throw new Error(`readFile failed (exit ${err.exitCode ?? err.code ?? 1}): ${err.stderr ?? err.message ?? ""}`);
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
async stop() {
|
|
90
|
+
await sprite.delete();
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
function spritesDefaults() {
|
|
95
|
+
const serverConfig = {
|
|
96
|
+
grpc: { addr: "0.0.0.0:50051" },
|
|
97
|
+
logging: { level: "info", format: "json", output: "stdout" },
|
|
98
|
+
sessions: {
|
|
99
|
+
defaultTimeout: "30m",
|
|
100
|
+
idleTimeout: "10m",
|
|
101
|
+
cleanupInterval: "5m"
|
|
102
|
+
},
|
|
103
|
+
audit: { enabled: true, sqlitePath: "/var/lib/agentsh/audit.db" },
|
|
104
|
+
sandboxLimits: { maxMemoryMb: 512, maxCpuPercent: 90, maxProcesses: 100 },
|
|
105
|
+
fuse: { deferred: true },
|
|
106
|
+
networkIntercept: { interceptMode: "tproxy", proxyListenAddr: "127.0.0.1:8888" },
|
|
107
|
+
seccompDetails: {
|
|
108
|
+
execve: true,
|
|
109
|
+
fileMonitor: { enabled: true, enforceWithoutFuse: true }
|
|
110
|
+
},
|
|
111
|
+
cgroups: { enabled: true },
|
|
112
|
+
unixSockets: { enabled: true },
|
|
113
|
+
proxy: { mode: "mitm", port: 8080 },
|
|
114
|
+
dlp: {
|
|
115
|
+
mode: "redact",
|
|
116
|
+
patterns: { credit_card: true, ssn: true, api_key: true }
|
|
117
|
+
},
|
|
118
|
+
approvals: { enabled: false },
|
|
119
|
+
metrics: { enabled: true, path: "/metrics" },
|
|
120
|
+
health: { path: "/healthz", readinessPath: "/readyz" },
|
|
121
|
+
development: { disableAuth: false, verboseErrors: false }
|
|
122
|
+
};
|
|
123
|
+
return {
|
|
124
|
+
installStrategy: "preinstalled",
|
|
125
|
+
realPaths: true,
|
|
126
|
+
serverConfig
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// src/adapters/modal.ts
|
|
131
|
+
function modal(sandbox) {
|
|
132
|
+
async function run(cmd) {
|
|
133
|
+
try {
|
|
134
|
+
const proc = await sandbox.exec("sh", "-c", cmd);
|
|
135
|
+
await proc.wait();
|
|
136
|
+
const stdout = typeof proc.stdout?.read === "function" ? await proc.stdout.read() : proc.stdout ?? "";
|
|
137
|
+
const stderr = typeof proc.stderr?.read === "function" ? await proc.stderr.read() : proc.stderr ?? "";
|
|
138
|
+
const exitCode = proc.returncode ?? proc.exitCode ?? 0;
|
|
139
|
+
return { stdout, stderr, exitCode };
|
|
140
|
+
} catch (err) {
|
|
141
|
+
return {
|
|
142
|
+
stdout: err.stdout ?? "",
|
|
143
|
+
stderr: err.stderr ?? err.message ?? "",
|
|
144
|
+
exitCode: err.returncode ?? err.exitCode ?? err.code ?? 1
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
async exec(cmd, args, opts) {
|
|
150
|
+
const command = `${envPrefix(opts?.env)}${shellEscape(cmd, args)}`;
|
|
151
|
+
if (opts?.detached) {
|
|
152
|
+
run(`nohup ${command} > /dev/null 2>&1 &`).catch(() => {
|
|
153
|
+
});
|
|
154
|
+
return { stdout: "", stderr: "", exitCode: 0 };
|
|
155
|
+
}
|
|
156
|
+
return run(command);
|
|
157
|
+
},
|
|
158
|
+
async writeFile(path, content) {
|
|
159
|
+
const buf = Buffer.isBuffer(content) ? content : Buffer.from(content);
|
|
160
|
+
const b64 = buf.toString("base64");
|
|
161
|
+
const result = await run(
|
|
162
|
+
`printf '%s' '${b64}' | base64 -d > '${path.replace(/'/g, "'\\''")}'`
|
|
163
|
+
);
|
|
164
|
+
if (result.exitCode !== 0) {
|
|
165
|
+
throw new Error(
|
|
166
|
+
`writeFile failed (exit ${result.exitCode}): ${result.stderr}`
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
async readFile(path) {
|
|
171
|
+
const result = await run(`cat '${path.replace(/'/g, "'\\''")}'`);
|
|
172
|
+
if (result.exitCode !== 0) {
|
|
173
|
+
throw new Error(
|
|
174
|
+
`readFile failed (exit ${result.exitCode}): ${result.stderr}`
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
return result.stdout;
|
|
178
|
+
},
|
|
179
|
+
async stop() {
|
|
180
|
+
await sandbox.terminate?.();
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
function modalDefaults() {
|
|
185
|
+
const serverConfig = {
|
|
186
|
+
grpc: { addr: "127.0.0.1:9090" },
|
|
187
|
+
logging: { level: "info", format: "text", output: "stderr" },
|
|
188
|
+
sessions: {
|
|
189
|
+
defaultTimeout: "1h",
|
|
190
|
+
idleTimeout: "15m",
|
|
191
|
+
cleanupInterval: "5m"
|
|
192
|
+
},
|
|
193
|
+
audit: { enabled: true, sqlitePath: "/var/lib/agentsh/events.db" },
|
|
194
|
+
sandboxLimits: { maxMemoryMb: 4096, maxCpuPercent: 100, maxProcesses: 256 },
|
|
195
|
+
allowDegraded: true,
|
|
196
|
+
fuse: {
|
|
197
|
+
deferred: true,
|
|
198
|
+
deferredMarkerFile: "/tmp/.agentsh-fuse-enabled",
|
|
199
|
+
deferredEnableCommand: ["/bin/chmod", "666", "/dev/fuse"]
|
|
200
|
+
},
|
|
201
|
+
networkIntercept: { interceptMode: "all", proxyListenAddr: "127.0.0.1:0" },
|
|
202
|
+
cgroups: { enabled: false },
|
|
203
|
+
unixSockets: { enabled: false },
|
|
204
|
+
ptrace: {
|
|
205
|
+
enabled: true,
|
|
206
|
+
attachMode: "children",
|
|
207
|
+
maskTracerPid: "off",
|
|
208
|
+
trace: {
|
|
209
|
+
execve: true,
|
|
210
|
+
file: false,
|
|
211
|
+
network: true,
|
|
212
|
+
signal: true
|
|
213
|
+
},
|
|
214
|
+
performance: {
|
|
215
|
+
seccompPrefilter: false,
|
|
216
|
+
maxTracees: 500,
|
|
217
|
+
maxHoldMs: 5e3
|
|
218
|
+
},
|
|
219
|
+
onAttachFailure: "fail_open"
|
|
220
|
+
},
|
|
221
|
+
envInject: {
|
|
222
|
+
BASH_ENV: "/usr/lib/agentsh/bash_startup.sh"
|
|
223
|
+
},
|
|
224
|
+
dlp: {
|
|
225
|
+
mode: "redact",
|
|
226
|
+
patterns: { api_keys: true, credit_card: true, ssn: true }
|
|
227
|
+
},
|
|
228
|
+
approvals: { enabled: false },
|
|
229
|
+
metrics: { enabled: true, path: "/metrics" },
|
|
230
|
+
health: { path: "/health", readinessPath: "/ready" }
|
|
231
|
+
};
|
|
232
|
+
const policy = mergePrepend(agentDefault(), {
|
|
233
|
+
file: [
|
|
234
|
+
// System shared libraries (required for any dynamically linked binary)
|
|
235
|
+
{ allow: ["/lib/**", "/lib64/**", "/usr/lib/**", "/usr/lib64/**"], ops: ["read"] },
|
|
236
|
+
// System binaries
|
|
237
|
+
{ allow: ["/bin/**", "/sbin/**", "/usr/bin/**", "/usr/sbin/**", "/usr/local/bin/**"], ops: ["read"] },
|
|
238
|
+
// Linker config
|
|
239
|
+
{ allow: ["/etc/ld.so.cache", "/etc/ld.so.conf", "/etc/ld.so.conf.d/**"], ops: ["read"] },
|
|
240
|
+
// Shared data (locales, terminfo, mime types)
|
|
241
|
+
{ allow: "/usr/share/**", ops: ["read"] },
|
|
242
|
+
// Device files
|
|
243
|
+
{ allow: ["/dev/null", "/dev/zero", "/dev/urandom", "/dev/random", "/dev/fd/**"], ops: ["read", "write"] },
|
|
244
|
+
// /proc/self for process introspection
|
|
245
|
+
{ allow: "/proc/self/**", ops: ["read"] },
|
|
246
|
+
// Temp directories
|
|
247
|
+
{ allow: ["/tmp/**", "/var/tmp/**"], ops: ["read", "write", "create"] },
|
|
248
|
+
// System config needed by tools (SSL certs, resolv.conf, hosts)
|
|
249
|
+
{ allow: ["/etc/ssl/**", "/etc/ca-certificates/**", "/etc/resolv.conf", "/etc/hosts", "/etc/hostname", "/etc/nsswitch.conf", "/etc/passwd", "/etc/group"], ops: ["read"] }
|
|
250
|
+
]
|
|
251
|
+
});
|
|
252
|
+
return {
|
|
253
|
+
policy,
|
|
254
|
+
installStrategy: "download",
|
|
255
|
+
realPaths: true,
|
|
256
|
+
skipShim: true,
|
|
257
|
+
serverConfig
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
export {
|
|
262
|
+
sprites,
|
|
263
|
+
spritesDefaults,
|
|
264
|
+
modal,
|
|
265
|
+
modalDefaults,
|
|
266
|
+
adapters_exports
|
|
267
|
+
};
|
|
268
|
+
//# sourceMappingURL=chunk-5IG6ABIZ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/adapters/index.ts","../src/adapters/sprites.ts","../src/adapters/modal.ts"],"sourcesContent":["export { vercel } from './vercel.js';\nexport { e2b } from './e2b.js';\nexport { daytona } from './daytona.js';\nexport { cloudflare } from './cloudflare.js';\nexport { blaxel } from './blaxel.js';\nexport { sprites, spritesDefaults } from './sprites.js';\nexport { modal, modalDefaults } from './modal.js';\n","import type { SandboxAdapter, SecureConfig } from '../core/types.js';\nimport type { ServerConfigOpts } from '../core/config.js';\nimport { shellEscape, envPrefix } from '../core/shell.js';\n\nexport function sprites(sprite: any): SandboxAdapter {\n // sprite.exec() does a naive split(/\\s+/) — no shell parsing.\n // Use sprite.execFile('sh', ['-c', cmd]) for shell features (env, pipes, quotes).\n function sh(cmd: string, opts?: Record<string, unknown>) {\n if (opts) return sprite.execFile('sh', ['-c', cmd], opts);\n return sprite.execFile('sh', ['-c', cmd]);\n }\n\n return {\n async exec(cmd, args, opts) {\n const command = `${envPrefix(opts?.env)}${shellEscape(cmd, args)}`;\n const fullCmd = opts?.sudo ? `sudo ${command}` : command;\n\n try {\n if (opts?.detached) {\n sh(`nohup ${fullCmd} > /dev/null 2>&1 &`).catch(() => {});\n return { stdout: '', stderr: '', exitCode: 0 };\n }\n\n const result = await sh(fullCmd, { cwd: opts?.cwd });\n return {\n stdout: result.stdout ?? '',\n stderr: result.stderr ?? '',\n exitCode: 0,\n };\n } catch (err: any) {\n return {\n stdout: err.stdout ?? '',\n stderr: err.stderr ?? err.message ?? '',\n exitCode: err.exitCode ?? err.code ?? 1,\n };\n }\n },\n async writeFile(path, content) {\n const buf = Buffer.isBuffer(content) ? content : Buffer.from(content);\n const b64 = buf.toString('base64');\n try {\n await sh(`printf '%s' '${b64}' | base64 -d > '${path.replace(/'/g, \"'\\\\''\")}'`);\n } catch (err: any) {\n throw new Error(`writeFile failed (exit ${err.exitCode ?? err.code ?? 1}): ${err.stderr ?? err.message ?? ''}`);\n }\n },\n async readFile(path) {\n try {\n const result = await sh(`cat '${path.replace(/'/g, \"'\\\\''\")}'`);\n return result.stdout ?? '';\n } catch (err: any) {\n throw new Error(`readFile failed (exit ${err.exitCode ?? err.code ?? 1}): ${err.stderr ?? err.message ?? ''}`);\n }\n },\n async stop() {\n await sprite.delete();\n },\n };\n}\n\n/**\n * Returns Sprites-optimized defaults for SecureConfig.\n * Spread into your secureSandbox() call:\n *\n * secureSandbox(sprites(s), { ...spritesDefaults(), ...yourOverrides })\n */\nexport function spritesDefaults(): Partial<SecureConfig> {\n const serverConfig: Omit<ServerConfigOpts, 'watchtower' | 'realPaths' | 'threatFeeds' | 'packageChecks'> = {\n grpc: { addr: '0.0.0.0:50051' },\n logging: { level: 'info', format: 'json', output: 'stdout' },\n sessions: {\n defaultTimeout: '30m',\n idleTimeout: '10m',\n cleanupInterval: '5m',\n },\n audit: { enabled: true, sqlitePath: '/var/lib/agentsh/audit.db' },\n sandboxLimits: { maxMemoryMb: 512, maxCpuPercent: 90, maxProcesses: 100 },\n fuse: { deferred: true },\n networkIntercept: { interceptMode: 'tproxy', proxyListenAddr: '127.0.0.1:8888' },\n seccompDetails: {\n execve: true,\n fileMonitor: { enabled: true, enforceWithoutFuse: true },\n },\n cgroups: { enabled: true },\n unixSockets: { enabled: true },\n proxy: { mode: 'mitm', port: 8080 },\n dlp: {\n mode: 'redact',\n patterns: { credit_card: true, ssn: true, api_key: true },\n },\n approvals: { enabled: false },\n metrics: { enabled: true, path: '/metrics' },\n health: { path: '/healthz', readinessPath: '/readyz' },\n development: { disableAuth: false, verboseErrors: false },\n };\n\n return {\n installStrategy: 'preinstalled',\n realPaths: true,\n serverConfig,\n };\n}\n","import type { SandboxAdapter, SecureConfig } from '../core/types.js';\nimport type { ServerConfigOpts } from '../core/config.js';\nimport { shellEscape, envPrefix } from '../core/shell.js';\nimport { agentDefault } from '../policies/presets.js';\nimport { mergePrepend } from '../policies/merge.js';\n\n/**\n * Wraps a Modal Sandbox object into a SandboxAdapter.\n *\n * Modal sandboxes run on gVisor which lacks seccomp user-notify and\n * full FUSE support. Use `modalDefaults()` to get ptrace-optimized\n * configuration that works on gVisor.\n *\n * The `sandbox` parameter is typed as `any` to avoid a hard dependency\n * on the Modal SDK — pass any object whose `.exec()` accepts variadic\n * string arguments and returns a process with `.stdout.read()`,\n * `.stderr.read()`, `.returncode`, and `.wait()`.\n */\nexport function modal(sandbox: any): SandboxAdapter {\n async function run(cmd: string): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n try {\n const proc = await sandbox.exec('sh', '-c', cmd);\n await proc.wait();\n const stdout = typeof proc.stdout?.read === 'function' ? await proc.stdout.read() : (proc.stdout ?? '');\n const stderr = typeof proc.stderr?.read === 'function' ? await proc.stderr.read() : (proc.stderr ?? '');\n const exitCode = proc.returncode ?? proc.exitCode ?? 0;\n return { stdout, stderr, exitCode };\n } catch (err: any) {\n return {\n stdout: err.stdout ?? '',\n stderr: err.stderr ?? err.message ?? '',\n exitCode: err.returncode ?? err.exitCode ?? err.code ?? 1,\n };\n }\n }\n\n return {\n async exec(cmd, args, opts) {\n // Modal containers run as root — drop sudo\n const command = `${envPrefix(opts?.env)}${shellEscape(cmd, args)}`;\n\n if (opts?.detached) {\n run(`nohup ${command} > /dev/null 2>&1 &`).catch(() => {});\n return { stdout: '', stderr: '', exitCode: 0 };\n }\n\n return run(command);\n },\n\n async writeFile(path, content) {\n const buf = Buffer.isBuffer(content) ? content : Buffer.from(content);\n const b64 = buf.toString('base64');\n const result = await run(\n `printf '%s' '${b64}' | base64 -d > '${path.replace(/'/g, \"'\\\\''\")}'`,\n );\n if (result.exitCode !== 0) {\n throw new Error(\n `writeFile failed (exit ${result.exitCode}): ${result.stderr}`,\n );\n }\n },\n\n async readFile(path) {\n const result = await run(`cat '${path.replace(/'/g, \"'\\\\''\")}'`);\n if (result.exitCode !== 0) {\n throw new Error(\n `readFile failed (exit ${result.exitCode}): ${result.stderr}`,\n );\n }\n return result.stdout;\n },\n\n async stop() {\n await sandbox.terminate?.();\n },\n };\n}\n\n/**\n * Returns Modal-optimized defaults for SecureConfig.\n *\n * Key differences from other providers:\n * - ptrace enabled (gVisor blocks seccomp user-notify)\n * - seccomp_prefilter disabled (gVisor blocks BPF injection)\n * - FUSE deferred (may not be available on gVisor)\n * - unix_sockets disabled (mutually exclusive with ptrace)\n * - cgroups disabled (Modal handles resource limits)\n * - allow_degraded enabled (graceful fallback for FUSE/seccomp)\n *\n * Spread into your secureSandbox() call:\n *\n * secureSandbox(modal(sb), { ...modalDefaults(), ...yourOverrides })\n */\nexport function modalDefaults(): Partial<SecureConfig> {\n const serverConfig: Omit<ServerConfigOpts, 'watchtower' | 'realPaths' | 'threatFeeds' | 'packageChecks'> = {\n grpc: { addr: '127.0.0.1:9090' },\n logging: { level: 'info', format: 'text', output: 'stderr' },\n sessions: {\n defaultTimeout: '1h',\n idleTimeout: '15m',\n cleanupInterval: '5m',\n },\n audit: { enabled: true, sqlitePath: '/var/lib/agentsh/events.db' },\n sandboxLimits: { maxMemoryMb: 4096, maxCpuPercent: 100, maxProcesses: 256 },\n allowDegraded: true,\n fuse: {\n deferred: true,\n deferredMarkerFile: '/tmp/.agentsh-fuse-enabled',\n deferredEnableCommand: ['/bin/chmod', '666', '/dev/fuse'],\n },\n networkIntercept: { interceptMode: 'all', proxyListenAddr: '127.0.0.1:0' },\n cgroups: { enabled: false },\n unixSockets: { enabled: false },\n ptrace: {\n enabled: true,\n attachMode: 'children',\n maskTracerPid: 'off',\n trace: {\n execve: true,\n file: false,\n network: true,\n signal: true,\n },\n performance: {\n seccompPrefilter: false,\n maxTracees: 500,\n maxHoldMs: 5000,\n },\n onAttachFailure: 'fail_open',\n },\n envInject: {\n BASH_ENV: '/usr/lib/agentsh/bash_startup.sh',\n },\n dlp: {\n mode: 'redact',\n patterns: { api_keys: true, credit_card: true, ssn: true },\n },\n approvals: { enabled: false },\n metrics: { enabled: true, path: '/metrics' },\n health: { path: '/health', readinessPath: '/ready' },\n };\n\n // Extend agentDefault with system paths needed for ptrace mode.\n // In FUSE/seccomp mode, only workspace files are intercepted so system\n // libs are inherently accessible. With ptrace, ALL file opens are\n // intercepted, so system libraries, binaries, and linker config must\n // be explicitly allowed.\n const policy = mergePrepend(agentDefault(), {\n file: [\n // System shared libraries (required for any dynamically linked binary)\n { allow: ['/lib/**', '/lib64/**', '/usr/lib/**', '/usr/lib64/**'], ops: ['read'] },\n // System binaries\n { allow: ['/bin/**', '/sbin/**', '/usr/bin/**', '/usr/sbin/**', '/usr/local/bin/**'], ops: ['read'] },\n // Linker config\n { allow: ['/etc/ld.so.cache', '/etc/ld.so.conf', '/etc/ld.so.conf.d/**'], ops: ['read'] },\n // Shared data (locales, terminfo, mime types)\n { allow: '/usr/share/**', ops: ['read'] },\n // Device files\n { allow: ['/dev/null', '/dev/zero', '/dev/urandom', '/dev/random', '/dev/fd/**'], ops: ['read', 'write'] },\n // /proc/self for process introspection\n { allow: '/proc/self/**', ops: ['read'] },\n // Temp directories\n { allow: ['/tmp/**', '/var/tmp/**'], ops: ['read', 'write', 'create'] },\n // System config needed by tools (SSL certs, resolv.conf, hosts)\n { allow: ['/etc/ssl/**', '/etc/ca-certificates/**', '/etc/resolv.conf', '/etc/hosts', '/etc/hostname', '/etc/nsswitch.conf', '/etc/passwd', '/etc/group'], ops: ['read'] },\n ],\n });\n\n return {\n policy,\n installStrategy: 'download',\n realPaths: true,\n skipShim: true,\n serverConfig,\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,25 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
__export
|
|
3
|
-
} from "./chunk-PZ5AY32C.js";
|
|
4
|
-
|
|
5
|
-
// src/policies/index.ts
|
|
6
|
-
var policies_exports = {};
|
|
7
|
-
__export(policies_exports, {
|
|
8
|
-
PolicyDefinitionSchema: () => PolicyDefinitionSchema,
|
|
9
|
-
agentDefault: () => agentDefault,
|
|
10
|
-
agentSandbox: () => agentSandbox,
|
|
11
|
-
ciStrict: () => ciStrict,
|
|
12
|
-
devSafe: () => devSafe,
|
|
13
|
-
merge: () => merge,
|
|
14
|
-
mergePrepend: () => mergePrepend,
|
|
15
|
-
serializePolicy: () => serializePolicy,
|
|
16
|
-
systemPolicyYaml: () => systemPolicyYaml,
|
|
17
|
-
validatePolicy: () => validatePolicy
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
// src/policies/schema.ts
|
|
21
|
-
import { z, ZodError } from "zod";
|
|
22
|
-
|
|
23
1
|
// src/core/errors.ts
|
|
24
2
|
var AgentSHError = class extends Error {
|
|
25
3
|
constructor(message) {
|
|
@@ -117,6 +95,7 @@ var RuntimeError = class extends AgentSHError {
|
|
|
117
95
|
};
|
|
118
96
|
|
|
119
97
|
// src/policies/schema.ts
|
|
98
|
+
import { z, ZodError } from "zod";
|
|
120
99
|
var stringOrArray = z.union([z.string(), z.array(z.string())]);
|
|
121
100
|
var FileOpSchema = z.enum(["read", "write", "create", "delete"]);
|
|
122
101
|
var FileAllowRule = z.object({ allow: stringOrArray, ops: z.array(FileOpSchema).optional() }).strict();
|
|
@@ -464,222 +443,6 @@ function agentSandbox(extensions) {
|
|
|
464
443
|
return extensions ? merge(base, extensions) : base;
|
|
465
444
|
}
|
|
466
445
|
|
|
467
|
-
// src/policies/serialize.ts
|
|
468
|
-
import yaml from "js-yaml";
|
|
469
|
-
function toArray(value) {
|
|
470
|
-
return Array.isArray(value) ? value : [value];
|
|
471
|
-
}
|
|
472
|
-
var FILE_DECISION_KEYS = [
|
|
473
|
-
"allow",
|
|
474
|
-
"deny",
|
|
475
|
-
"redirect",
|
|
476
|
-
"audit",
|
|
477
|
-
"softDelete"
|
|
478
|
-
];
|
|
479
|
-
var SIMPLE_DECISION_KEYS = ["allow", "deny", "redirect"];
|
|
480
|
-
function findDecision(rule, keys) {
|
|
481
|
-
for (const k of keys) {
|
|
482
|
-
if (k in rule) {
|
|
483
|
-
return { key: k, value: rule[k] };
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
throw new Error(`No decision key found in rule: ${JSON.stringify(rule)}`);
|
|
487
|
-
}
|
|
488
|
-
function yamlDecision(key) {
|
|
489
|
-
return key === "softDelete" ? "soft_delete" : key;
|
|
490
|
-
}
|
|
491
|
-
function serializeFileRules(rules) {
|
|
492
|
-
return rules.map((rule, i) => {
|
|
493
|
-
const r = rule;
|
|
494
|
-
const { key, value } = findDecision(r, FILE_DECISION_KEYS);
|
|
495
|
-
const paths = toArray(value);
|
|
496
|
-
const out = {
|
|
497
|
-
name: `file-rule-${i}`,
|
|
498
|
-
paths
|
|
499
|
-
};
|
|
500
|
-
if ("ops" in r && r.ops) {
|
|
501
|
-
out.operations = r.ops;
|
|
502
|
-
}
|
|
503
|
-
out.decision = yamlDecision(key);
|
|
504
|
-
if (key === "redirect" && "to" in r) {
|
|
505
|
-
out.redirect_to = r.to;
|
|
506
|
-
}
|
|
507
|
-
return out;
|
|
508
|
-
});
|
|
509
|
-
}
|
|
510
|
-
function serializeNetworkRules(rules) {
|
|
511
|
-
return rules.map((rule, i) => {
|
|
512
|
-
const r = rule;
|
|
513
|
-
const { key, value } = findDecision(r, SIMPLE_DECISION_KEYS);
|
|
514
|
-
const domains = toArray(value);
|
|
515
|
-
const out = {
|
|
516
|
-
name: `network-rule-${i}`,
|
|
517
|
-
domains,
|
|
518
|
-
decision: key
|
|
519
|
-
};
|
|
520
|
-
if ("ports" in r && r.ports) {
|
|
521
|
-
out.ports = r.ports;
|
|
522
|
-
}
|
|
523
|
-
if (key === "redirect" && "to" in r) {
|
|
524
|
-
out.redirect_to = r.to;
|
|
525
|
-
}
|
|
526
|
-
return out;
|
|
527
|
-
});
|
|
528
|
-
}
|
|
529
|
-
function serializeCommandRules(rules) {
|
|
530
|
-
return rules.map((rule, i) => {
|
|
531
|
-
const r = rule;
|
|
532
|
-
const { key, value } = findDecision(r, SIMPLE_DECISION_KEYS);
|
|
533
|
-
const commands = toArray(value);
|
|
534
|
-
const out = {
|
|
535
|
-
name: `command-rule-${i}`,
|
|
536
|
-
commands,
|
|
537
|
-
decision: key
|
|
538
|
-
};
|
|
539
|
-
if (key === "redirect" && "to" in r) {
|
|
540
|
-
const to = r.to;
|
|
541
|
-
if (typeof to === "string") {
|
|
542
|
-
out.redirect_to = to;
|
|
543
|
-
} else if (typeof to === "object" && to !== null) {
|
|
544
|
-
const target = to;
|
|
545
|
-
out.redirect_to = { command: target.cmd, args: target.args };
|
|
546
|
-
}
|
|
547
|
-
}
|
|
548
|
-
return out;
|
|
549
|
-
});
|
|
550
|
-
}
|
|
551
|
-
function serializeEnvRules(rules) {
|
|
552
|
-
return rules.map((rule, i) => {
|
|
553
|
-
const out = {
|
|
554
|
-
name: `env-rule-${i}`,
|
|
555
|
-
commands: rule.commands
|
|
556
|
-
};
|
|
557
|
-
if (rule.allow) {
|
|
558
|
-
out.allow = rule.allow;
|
|
559
|
-
}
|
|
560
|
-
if (rule.deny) {
|
|
561
|
-
out.deny = rule.deny;
|
|
562
|
-
}
|
|
563
|
-
return out;
|
|
564
|
-
});
|
|
565
|
-
}
|
|
566
|
-
function serializeDnsRedirects(redirects) {
|
|
567
|
-
return redirects.map((r) => ({
|
|
568
|
-
match: r.match,
|
|
569
|
-
resolve_to: r.resolveTo
|
|
570
|
-
}));
|
|
571
|
-
}
|
|
572
|
-
function serializeConnectRedirects(redirects) {
|
|
573
|
-
return redirects.map((r) => ({
|
|
574
|
-
match: r.match,
|
|
575
|
-
redirect_to: r.redirectTo
|
|
576
|
-
}));
|
|
577
|
-
}
|
|
578
|
-
function serializePackageRules(rules) {
|
|
579
|
-
return rules.map((rule) => {
|
|
580
|
-
const match = {};
|
|
581
|
-
if (rule.match.packages) {
|
|
582
|
-
match.packages = rule.match.packages;
|
|
583
|
-
}
|
|
584
|
-
if (rule.match.namePatterns) {
|
|
585
|
-
match.name_patterns = rule.match.namePatterns;
|
|
586
|
-
}
|
|
587
|
-
if (rule.match.findingType) {
|
|
588
|
-
match.finding_type = rule.match.findingType;
|
|
589
|
-
}
|
|
590
|
-
if (rule.match.severity !== void 0) {
|
|
591
|
-
match.severity = rule.match.severity;
|
|
592
|
-
}
|
|
593
|
-
if (rule.match.reasons) {
|
|
594
|
-
match.reasons = rule.match.reasons;
|
|
595
|
-
}
|
|
596
|
-
if (rule.match.licenseSpdx) {
|
|
597
|
-
match.license_spdx = rule.match.licenseSpdx;
|
|
598
|
-
}
|
|
599
|
-
if (rule.match.ecosystem) {
|
|
600
|
-
match.ecosystem = rule.match.ecosystem;
|
|
601
|
-
}
|
|
602
|
-
if (rule.match.options) {
|
|
603
|
-
match.options = rule.match.options;
|
|
604
|
-
}
|
|
605
|
-
const out = {
|
|
606
|
-
match,
|
|
607
|
-
action: rule.action
|
|
608
|
-
};
|
|
609
|
-
if (rule.reason) {
|
|
610
|
-
out.reason = rule.reason;
|
|
611
|
-
}
|
|
612
|
-
return out;
|
|
613
|
-
});
|
|
614
|
-
}
|
|
615
|
-
function serializePolicy(policy) {
|
|
616
|
-
const doc = {
|
|
617
|
-
version: 1,
|
|
618
|
-
name: "secure-sandbox-policy"
|
|
619
|
-
};
|
|
620
|
-
if (policy.file && policy.file.length > 0) {
|
|
621
|
-
doc.file_rules = serializeFileRules(policy.file);
|
|
622
|
-
}
|
|
623
|
-
if (policy.network && policy.network.length > 0) {
|
|
624
|
-
doc.network_rules = serializeNetworkRules(policy.network);
|
|
625
|
-
}
|
|
626
|
-
if (policy.commands && policy.commands.length > 0) {
|
|
627
|
-
doc.command_rules = serializeCommandRules(policy.commands);
|
|
628
|
-
}
|
|
629
|
-
if (policy.env && policy.env.length > 0) {
|
|
630
|
-
doc.env_rules = serializeEnvRules(policy.env);
|
|
631
|
-
}
|
|
632
|
-
if (policy.dns && policy.dns.length > 0) {
|
|
633
|
-
doc.dns_redirects = serializeDnsRedirects(policy.dns);
|
|
634
|
-
}
|
|
635
|
-
if (policy.connect && policy.connect.length > 0) {
|
|
636
|
-
doc.connect_redirects = serializeConnectRedirects(policy.connect);
|
|
637
|
-
}
|
|
638
|
-
if (policy.packageRules && policy.packageRules.length > 0) {
|
|
639
|
-
doc.package_rules = serializePackageRules(policy.packageRules);
|
|
640
|
-
}
|
|
641
|
-
return yaml.dump(doc, { lineWidth: -1 });
|
|
642
|
-
}
|
|
643
|
-
function systemPolicyYaml() {
|
|
644
|
-
const doc = {
|
|
645
|
-
version: 1,
|
|
646
|
-
name: "_system-protection",
|
|
647
|
-
file_rules: [
|
|
648
|
-
{
|
|
649
|
-
name: "_system-protect-config",
|
|
650
|
-
paths: ["/etc/agentsh/**"],
|
|
651
|
-
operations: ["write", "create", "delete"],
|
|
652
|
-
decision: "deny",
|
|
653
|
-
message: "Policy files are immutable during agent execution"
|
|
654
|
-
},
|
|
655
|
-
{
|
|
656
|
-
name: "_system-protect-binary",
|
|
657
|
-
paths: ["/usr/local/bin/agentsh*", "/usr/bin/agentsh*"],
|
|
658
|
-
operations: ["write", "create", "delete"],
|
|
659
|
-
decision: "deny",
|
|
660
|
-
message: "agentsh binary is immutable during agent execution"
|
|
661
|
-
},
|
|
662
|
-
{
|
|
663
|
-
name: "_system-protect-shim-files",
|
|
664
|
-
paths: ["/usr/bin/agentsh-shell-shim", "/bin/bash", "/bin/sh"],
|
|
665
|
-
operations: ["write", "create", "delete"],
|
|
666
|
-
decision: "deny",
|
|
667
|
-
message: "Shell and shim binaries are immutable during agent execution"
|
|
668
|
-
}
|
|
669
|
-
],
|
|
670
|
-
command_rules: [
|
|
671
|
-
{
|
|
672
|
-
name: "_system-protect-process",
|
|
673
|
-
commands: ["kill", "killall", "pkill"],
|
|
674
|
-
args_match: ["agentsh"],
|
|
675
|
-
decision: "deny",
|
|
676
|
-
message: "Cannot terminate agentsh processes"
|
|
677
|
-
}
|
|
678
|
-
]
|
|
679
|
-
};
|
|
680
|
-
return yaml.dump(doc, { lineWidth: -1 });
|
|
681
|
-
}
|
|
682
|
-
|
|
683
446
|
export {
|
|
684
447
|
AgentSHError,
|
|
685
448
|
PolicyValidationError,
|
|
@@ -688,8 +451,6 @@ export {
|
|
|
688
451
|
ProvisioningError,
|
|
689
452
|
IntegrityError,
|
|
690
453
|
RuntimeError,
|
|
691
|
-
serializePolicy,
|
|
692
|
-
systemPolicyYaml,
|
|
693
454
|
PolicyDefinitionSchema,
|
|
694
455
|
validatePolicy,
|
|
695
456
|
merge,
|
|
@@ -697,7 +458,6 @@ export {
|
|
|
697
458
|
agentDefault,
|
|
698
459
|
devSafe,
|
|
699
460
|
ciStrict,
|
|
700
|
-
agentSandbox
|
|
701
|
-
policies_exports
|
|
461
|
+
agentSandbox
|
|
702
462
|
};
|
|
703
|
-
//# sourceMappingURL=chunk-
|
|
463
|
+
//# sourceMappingURL=chunk-LNDICGZU.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/errors.ts","../src/policies/schema.ts","../src/policies/merge.ts","../src/policies/presets.ts"],"sourcesContent":["import type { ZodIssue } from 'zod';\n\nexport class AgentSHError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'AgentSHError';\n }\n}\n\nexport class PolicyValidationError extends AgentSHError {\n readonly issues: ZodIssue[];\n\n constructor({ issues }: { issues: ZodIssue[] }) {\n const summaries = issues\n .map((issue) => `${issue.path.join('.')}: ${issue.message}`)\n .join('; ');\n super(`Policy validation failed: ${summaries}`);\n this.name = 'PolicyValidationError';\n this.issues = issues;\n }\n}\n\nexport class MissingPeerDependencyError extends AgentSHError {\n readonly packageName: string;\n readonly versionRange: string;\n\n constructor({\n packageName,\n versionRange,\n }: {\n packageName: string;\n versionRange: string;\n }) {\n super(\n `${packageName} is required but not installed. Run: npm install ${packageName}@\"${versionRange}\"`,\n );\n this.name = 'MissingPeerDependencyError';\n this.packageName = packageName;\n this.versionRange = versionRange;\n }\n}\n\nexport class IncompatibleProviderVersionError extends AgentSHError {\n readonly installed: string;\n readonly required: string;\n readonly packageName: string;\n\n constructor({\n installed,\n required,\n packageName,\n }: {\n installed: string;\n required: string;\n packageName: string;\n }) {\n super(\n `${packageName} version ${installed} is not supported. @agentsh/secure-sandbox requires ${packageName} ${required}. Please upgrade: npm install ${packageName}@latest`,\n );\n this.name = 'IncompatibleProviderVersionError';\n this.installed = installed;\n this.required = required;\n this.packageName = packageName;\n }\n}\n\nexport class ProvisioningError extends AgentSHError {\n readonly phase: string;\n readonly command: string;\n readonly stderr: string;\n\n constructor({\n phase,\n command,\n stderr,\n }: {\n phase: string;\n command: string;\n stderr: string;\n }) {\n super(`Provisioning failed at phase: ${phase}`);\n this.name = 'ProvisioningError';\n this.phase = phase;\n this.command = command;\n this.stderr = stderr;\n }\n}\n\nexport class IntegrityError extends AgentSHError {\n readonly expected: string;\n readonly actual: string;\n\n constructor({\n expected,\n actual,\n message,\n }: {\n expected: string;\n actual: string;\n message?: string;\n }) {\n super(message ?? `Checksum mismatch: expected ${expected}, got ${actual}`);\n this.name = 'IntegrityError';\n this.expected = expected;\n this.actual = actual;\n }\n}\n\nexport class RuntimeError extends AgentSHError {\n readonly sessionId: string;\n readonly command: string;\n readonly stderr: string;\n\n constructor({\n sessionId,\n command,\n stderr,\n }: {\n sessionId: string;\n command: string;\n stderr: string;\n }) {\n super(`agentsh exec failed (session ${sessionId})`);\n this.name = 'RuntimeError';\n this.sessionId = sessionId;\n this.command = command;\n this.stderr = stderr;\n }\n}\n","import { z, ZodError } from 'zod';\nimport { PolicyValidationError } from '../core/errors.js';\n\n// ─── Shared helpers ─────────────────────────────────────────\n\nconst stringOrArray = z.union([z.string(), z.array(z.string())]);\n\n// ─── File rules ─────────────────────────────────────────────\n\nexport const FileOpSchema = z.enum(['read', 'write', 'create', 'delete']);\n\nconst FileAllowRule = z\n .object({ allow: stringOrArray, ops: z.array(FileOpSchema).optional() })\n .strict();\n\nconst FileDenyRule = z\n .object({ deny: stringOrArray, ops: z.array(FileOpSchema).optional() })\n .strict();\n\nconst FileRedirectRule = z\n .object({\n redirect: stringOrArray,\n to: z.string(),\n ops: z.array(FileOpSchema).optional(),\n })\n .strict();\n\nconst FileAuditRule = z\n .object({ audit: stringOrArray, ops: z.array(FileOpSchema).optional() })\n .strict();\n\nconst FileSoftDeleteRule = z.object({ softDelete: stringOrArray }).strict();\n\nexport const FileRuleSchema = z.union([\n FileAllowRule,\n FileDenyRule,\n FileRedirectRule,\n FileAuditRule,\n FileSoftDeleteRule,\n]);\n\n// ─── Network rules ──────────────────────────────────────────\n\nconst NetworkAllowRule = z\n .object({\n allow: stringOrArray,\n ports: z.array(z.number().int().min(1).max(65535)).optional(),\n })\n .strict();\n\nconst NetworkDenyRule = z.object({ deny: stringOrArray }).strict();\n\nconst NetworkRedirectRule = z\n .object({ redirect: z.string(), to: z.string() })\n .strict();\n\nexport const NetworkRuleSchema = z.union([\n NetworkAllowRule,\n NetworkDenyRule,\n NetworkRedirectRule,\n]);\n\n// ─── Command rules ──────────────────────────────────────────\n\nconst CommandRedirectTarget = z.union([\n z.string(),\n z.object({ cmd: z.string(), args: z.array(z.string()) }).strict(),\n]);\n\nconst CommandAllowRule = z.object({ allow: stringOrArray }).strict();\n\nconst CommandDenyRule = z.object({ deny: stringOrArray }).strict();\n\nconst CommandRedirectRule = z\n .object({ redirect: stringOrArray, to: CommandRedirectTarget })\n .strict();\n\nexport const CommandRuleSchema = z.union([\n CommandAllowRule,\n CommandDenyRule,\n CommandRedirectRule,\n]);\n\n// ─── Env rules ──────────────────────────────────────────────\n\nexport const EnvRuleSchema = z\n .object({\n commands: z.array(z.string()),\n allow: z.array(z.string()).optional(),\n deny: z.array(z.string()).optional(),\n })\n .strict();\n\n// ─── DNS / Connect redirects ────────────────────────────────\n\nexport const DnsRedirectSchema = z\n .object({\n match: z.string(),\n resolveTo: z.string(),\n })\n .strict();\n\nexport const ConnectRedirectSchema = z\n .object({\n match: z.string(),\n redirectTo: z.string(),\n })\n .strict();\n\n// ─── Package rules ──────────────────────────────────────────\n\nconst LicenseSpdxMatchSchema = z\n .object({\n allow: z.array(z.string()).optional(),\n deny: z.array(z.string()).optional(),\n })\n .strict();\n\nconst PackageMatchSchema = z\n .object({\n packages: z.array(z.string()).optional(),\n namePatterns: z.array(z.string()).optional(),\n findingType: z.string().optional(),\n severity: stringOrArray.optional(),\n reasons: z.array(z.string()).optional(),\n licenseSpdx: LicenseSpdxMatchSchema.optional(),\n ecosystem: z.string().optional(),\n options: z.record(z.unknown()).optional(),\n })\n .strict();\n\nexport const PackageRuleSchema = z\n .object({\n match: PackageMatchSchema,\n action: z.enum(['allow', 'warn', 'approve', 'block']),\n reason: z.string().optional(),\n })\n .strict();\n\n// ─── PolicyDefinition ───────────────────────────────────────\n\nexport const PolicyDefinitionSchema = z\n .object({\n file: z.array(FileRuleSchema).optional(),\n network: z.array(NetworkRuleSchema).optional(),\n commands: z.array(CommandRuleSchema).optional(),\n env: z.array(EnvRuleSchema).optional(),\n dns: z.array(DnsRedirectSchema).optional(),\n connect: z.array(ConnectRedirectSchema).optional(),\n packageRules: z.array(PackageRuleSchema).optional(),\n })\n .strict();\n\n// ─── Inferred types ─────────────────────────────────────────\n\nexport type PolicyDefinition = z.infer<typeof PolicyDefinitionSchema>;\nexport type FileOp = z.infer<typeof FileOpSchema>;\nexport type FileRule = z.infer<typeof FileRuleSchema>;\nexport type NetworkRule = z.infer<typeof NetworkRuleSchema>;\nexport type CommandRule = z.infer<typeof CommandRuleSchema>;\nexport type EnvRule = z.infer<typeof EnvRuleSchema>;\nexport type DnsRedirect = z.infer<typeof DnsRedirectSchema>;\nexport type ConnectRedirect = z.infer<typeof ConnectRedirectSchema>;\nexport type PackageRule = z.infer<typeof PackageRuleSchema>;\n\n// ─── Validation ─────────────────────────────────────────────\n\nexport function validatePolicy(policy: unknown): PolicyDefinition {\n try {\n return PolicyDefinitionSchema.parse(policy);\n } catch (err) {\n if (err instanceof ZodError) {\n throw new PolicyValidationError({ issues: err.issues });\n }\n throw err;\n }\n}\n","import type { PolicyDefinition } from './schema.js';\nimport { validatePolicy } from './schema.js';\n\nconst CATEGORIES = ['file', 'network', 'commands', 'env', 'dns', 'connect', 'packageRules'] as const;\n\n/**\n * Merge policy overrides AFTER base rules for each category.\n * Since agentsh evaluates first-match-wins, appended rules only apply\n * to paths not already matched by base.\n */\nexport function merge(base: PolicyDefinition, ...overrides: Partial<PolicyDefinition>[]): PolicyDefinition {\n return validatePolicy(mergeInternal(base, overrides, 'append'));\n}\n\n/**\n * Merge policy overrides BEFORE base rules for each category,\n * making overrides take priority in first-match-wins evaluation.\n */\nexport function mergePrepend(base: PolicyDefinition, ...overrides: Partial<PolicyDefinition>[]): PolicyDefinition {\n return validatePolicy(mergeInternal(base, overrides, 'prepend'));\n}\n\nfunction mergeInternal(\n base: PolicyDefinition,\n overrides: Partial<PolicyDefinition>[],\n mode: 'append' | 'prepend',\n): PolicyDefinition {\n const result: any = { ...base };\n for (const override of overrides) {\n for (const key of CATEGORIES) {\n if (override[key] != null) {\n const baseRules = result[key] ?? [];\n result[key] = mode === 'append'\n ? [...baseRules, ...override[key]!]\n : [...override[key]!, ...baseRules];\n }\n }\n }\n return result;\n}\n","import type { PolicyDefinition } from './schema.js';\nimport { merge } from './merge.js';\n\n// ─── agentDefault ──────────────────────────────────────────\n\n/**\n * Comprehensive policy for AI coding agents. This is the DEFAULT policy\n * used when no policy is specified. Based on agentsh v0.13's agent-default\n * policy.\n */\nexport function agentDefault(\n extensions?: Partial<PolicyDefinition>,\n): PolicyDefinition {\n const base: PolicyDefinition = {\n file: [\n { allow: '/workspace/**', ops: ['read', 'write', 'create'] },\n // Git/version-control credentials\n { deny: ['/workspace/.git/config', '/workspace/.netrc'] },\n // Secrets and credentials\n { deny: ['**/.env', '**/.env.*', '**/credentials*', '**/*.pem', '**/*.key'] },\n { deny: ['~/.ssh/**', '/proc/*/environ'] },\n // Cloud provider credentials\n { deny: ['~/.aws/**', '~/.gcp/**', '~/.azure/**', '~/.config/gcloud/**'] },\n // Shell config injection (persistence)\n { deny: ['~/.bashrc', '~/.zshrc', '~/.profile', '~/.bash_profile'] },\n // Credential stores\n { deny: ['~/.gitconfig', '~/.netrc', '~/.curlrc', '~/.wgetrc'] },\n // PATH hijacking\n { deny: '~/.local/bin/**' },\n // Agent config files — allow reads (project context), deny writes (prompt injection persistence)\n { deny: ['**/.cursorrules', '**/CLAUDE.md', '**/copilot-instructions.md'], ops: ['write', 'create', 'delete'] },\n ],\n network: [\n {\n allow: [\n 'registry.npmjs.org',\n 'registry.yarnpkg.com',\n 'pypi.org',\n 'files.pythonhosted.org',\n 'crates.io',\n 'static.crates.io',\n 'index.crates.io',\n 'proxy.golang.org',\n 'sum.golang.org',\n 'github.com',\n 'raw.githubusercontent.com',\n ],\n ports: [443],\n },\n { deny: '*' },\n ],\n commands: [\n // Allow safe commands (order matters — first match wins)\n {\n allow: [\n 'bash', 'sh', 'echo', 'cat', 'head', 'tail', 'grep', 'find',\n 'ls', 'wc', 'sort', 'uniq', 'diff', 'pwd', 'date', 'which',\n 'whoami', 'id', 'uname', 'printf', 'test', 'true', 'false',\n 'mkdir', 'cp', 'mv', 'rm', 'touch', 'chmod', 'tr', 'cut',\n 'sed', 'awk', 'tee', 'xargs', 'basename', 'dirname', 'realpath',\n 'base64', 'md5sum', 'sha256sum', 'tar', 'gzip', 'gunzip',\n ],\n },\n // Allow dev tools\n {\n allow: [\n 'git', 'node', 'npm', 'npx', 'yarn', 'pnpm', 'bun',\n 'python', 'python3', 'pip', 'pip3',\n 'cargo', 'rustc', 'go', 'make', 'cmake',\n ],\n },\n // Deny dangerous commands\n { deny: ['env', 'printenv', 'sudo', 'su', 'doas'] },\n { deny: ['shutdown', 'reboot', 'halt', 'poweroff'] },\n { deny: ['nc', 'ncat', 'netcat', 'socat', 'telnet'] },\n { deny: ['git push --force', 'git reset --hard'] },\n {\n redirect: ['curl', 'wget'],\n to: { cmd: 'agentsh-fetch', args: ['--audit'] },\n },\n ],\n packageRules: [\n // Critical vulnerability = block\n {\n match: { findingType: 'vulnerability', severity: 'critical' },\n action: 'block',\n reason: 'Critical vulnerability — review before installing',\n },\n // Known malware = block\n {\n match: { findingType: 'malware' },\n action: 'block',\n reason: 'Known malware detected',\n },\n // Typosquat = block\n {\n match: { findingType: 'reputation', reasons: ['typosquat'] },\n action: 'block',\n reason: 'Package flagged as potential typosquat',\n },\n // Medium vulnerability = warn\n {\n match: { findingType: 'vulnerability', severity: 'medium' },\n action: 'warn',\n reason: 'Medium vulnerability — review before using',\n },\n // Copyleft licenses = block\n {\n match: {\n findingType: 'license',\n licenseSpdx: { deny: ['AGPL-3.0-only', 'SSPL-1.0'] },\n },\n action: 'block',\n reason: 'Copyleft license incompatible with proprietary code',\n },\n // Package too new = approve (requires human confirmation)\n {\n match: {\n findingType: 'reputation',\n reasons: ['package_too_new'],\n },\n action: 'approve',\n reason: 'Package published recently — requires approval',\n },\n ],\n };\n return extensions ? merge(base, extensions) : base;\n}\n\n// ─── devSafe ───────────────────────────────────────────────\n\n/**\n * Permissive defaults for local development. Not recommended for production.\n */\nexport function devSafe(\n extensions?: Partial<PolicyDefinition>,\n): PolicyDefinition {\n const base: PolicyDefinition = {\n file: [\n { allow: '/workspace/**', ops: ['read', 'write', 'create'] },\n { deny: ['**/.env', '**/.env.*', '**/credentials*', '**/*.pem', '**/*.key'] },\n { deny: ['~/.ssh/**', '/proc/*/environ'] },\n { deny: ['~/.aws/**', '~/.gcp/**', '~/.azure/**', '~/.config/gcloud/**'] },\n { deny: ['~/.bashrc', '~/.zshrc', '~/.profile', '~/.bash_profile'] },\n { deny: ['~/.gitconfig', '~/.netrc', '~/.curlrc', '~/.wgetrc'] },\n ],\n network: [\n {\n allow: ['registry.npmjs.org', 'registry.yarnpkg.com'],\n ports: [443],\n },\n ],\n commands: [{ deny: ['env', 'printenv', 'shutdown', 'reboot'] }],\n };\n return extensions ? merge(base, extensions) : base;\n}\n\n// ─── ciStrict ──────────────────────────────────────────────\n\n/**\n * Locked down for CI/CD runners.\n */\nexport function ciStrict(\n extensions?: Partial<PolicyDefinition>,\n): PolicyDefinition {\n const base: PolicyDefinition = {\n file: [\n { allow: '/workspace/**' },\n { deny: ['**/.env', '**/.env.*', '**/credentials*', '**/*.pem', '**/*.key'] },\n { deny: ['~/.aws/**', '~/.gcp/**', '~/.azure/**', '~/.config/gcloud/**'] },\n { deny: '/**' },\n ],\n network: [\n {\n allow: [\n 'registry.npmjs.org',\n 'registry.yarnpkg.com',\n 'pypi.org',\n 'files.pythonhosted.org',\n 'crates.io',\n 'static.crates.io',\n 'index.crates.io',\n 'proxy.golang.org',\n 'sum.golang.org',\n ],\n ports: [443],\n },\n { deny: '*' },\n ],\n commands: [\n { deny: ['env', 'printenv', 'shutdown', 'reboot', 'sudo'] },\n ],\n };\n return extensions ? merge(base, extensions) : base;\n}\n\n// ─── agentSandbox ──────────────────────────────────────────\n\n/**\n * Maximum restriction for untrusted code. Read-only workspace, no network.\n */\nexport function agentSandbox(\n extensions?: Partial<PolicyDefinition>,\n): PolicyDefinition {\n const base: PolicyDefinition = {\n file: [\n { allow: '/workspace/**', ops: ['read'] },\n { deny: '/**' },\n ],\n network: [{ deny: '*' }],\n commands: [\n { deny: ['env', 'printenv', 'sudo', 'su', 'shutdown', 'reboot'] },\n ],\n };\n return extensions ? merge(base, extensions) : base;\n}\n"],"mappings":";AAEO,IAAM,eAAN,cAA2B,MAAM;AAAA,EACtC,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,wBAAN,cAAoC,aAAa;AAAA,EAC7C;AAAA,EAET,YAAY,EAAE,OAAO,GAA2B;AAC9C,UAAM,YAAY,OACf,IAAI,CAAC,UAAU,GAAG,MAAM,KAAK,KAAK,GAAG,CAAC,KAAK,MAAM,OAAO,EAAE,EAC1D,KAAK,IAAI;AACZ,UAAM,6BAA6B,SAAS,EAAE;AAC9C,SAAK,OAAO;AACZ,SAAK,SAAS;AAAA,EAChB;AACF;AAEO,IAAM,6BAAN,cAAyC,aAAa;AAAA,EAClD;AAAA,EACA;AAAA,EAET,YAAY;AAAA,IACV;AAAA,IACA;AAAA,EACF,GAGG;AACD;AAAA,MACE,GAAG,WAAW,oDAAoD,WAAW,KAAK,YAAY;AAAA,IAChG;AACA,SAAK,OAAO;AACZ,SAAK,cAAc;AACnB,SAAK,eAAe;AAAA,EACtB;AACF;AAEO,IAAM,mCAAN,cAA+C,aAAa;AAAA,EACxD;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAIG;AACD;AAAA,MACE,GAAG,WAAW,YAAY,SAAS,uDAAuD,WAAW,IAAI,QAAQ,iCAAiC,WAAW;AAAA,IAC/J;AACA,SAAK,OAAO;AACZ,SAAK,YAAY;AACjB,SAAK,WAAW;AAChB,SAAK,cAAc;AAAA,EACrB;AACF;AAEO,IAAM,oBAAN,cAAgC,aAAa;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAIG;AACD,UAAM,iCAAiC,KAAK,EAAE;AAC9C,SAAK,OAAO;AACZ,SAAK,QAAQ;AACb,SAAK,UAAU;AACf,SAAK,SAAS;AAAA,EAChB;AACF;AAEO,IAAM,iBAAN,cAA6B,aAAa;AAAA,EACtC;AAAA,EACA;AAAA,EAET,YAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAIG;AACD,UAAM,WAAW,+BAA+B,QAAQ,SAAS,MAAM,EAAE;AACzE,SAAK,OAAO;AACZ,SAAK,WAAW;AAChB,SAAK,SAAS;AAAA,EAChB;AACF;AAEO,IAAM,eAAN,cAA2B,aAAa;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAIG;AACD,UAAM,gCAAgC,SAAS,GAAG;AAClD,SAAK,OAAO;AACZ,SAAK,YAAY;AACjB,SAAK,UAAU;AACf,SAAK,SAAS;AAAA,EAChB;AACF;;;AChIA,SAAS,GAAG,gBAAgB;AAK5B,IAAM,gBAAgB,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;AAIxD,IAAM,eAAe,EAAE,KAAK,CAAC,QAAQ,SAAS,UAAU,QAAQ,CAAC;AAExE,IAAM,gBAAgB,EACnB,OAAO,EAAE,OAAO,eAAe,KAAK,EAAE,MAAM,YAAY,EAAE,SAAS,EAAE,CAAC,EACtE,OAAO;AAEV,IAAM,eAAe,EAClB,OAAO,EAAE,MAAM,eAAe,KAAK,EAAE,MAAM,YAAY,EAAE,SAAS,EAAE,CAAC,EACrE,OAAO;AAEV,IAAM,mBAAmB,EACtB,OAAO;AAAA,EACN,UAAU;AAAA,EACV,IAAI,EAAE,OAAO;AAAA,EACb,KAAK,EAAE,MAAM,YAAY,EAAE,SAAS;AACtC,CAAC,EACA,OAAO;AAEV,IAAM,gBAAgB,EACnB,OAAO,EAAE,OAAO,eAAe,KAAK,EAAE,MAAM,YAAY,EAAE,SAAS,EAAE,CAAC,EACtE,OAAO;AAEV,IAAM,qBAAqB,EAAE,OAAO,EAAE,YAAY,cAAc,CAAC,EAAE,OAAO;AAEnE,IAAM,iBAAiB,EAAE,MAAM;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAID,IAAM,mBAAmB,EACtB,OAAO;AAAA,EACN,OAAO;AAAA,EACP,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,KAAK,CAAC,EAAE,SAAS;AAC9D,CAAC,EACA,OAAO;AAEV,IAAM,kBAAkB,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC,EAAE,OAAO;AAEjE,IAAM,sBAAsB,EACzB,OAAO,EAAE,UAAU,EAAE,OAAO,GAAG,IAAI,EAAE,OAAO,EAAE,CAAC,EAC/C,OAAO;AAEH,IAAM,oBAAoB,EAAE,MAAM;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAID,IAAM,wBAAwB,EAAE,MAAM;AAAA,EACpC,EAAE,OAAO;AAAA,EACT,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,OAAO;AAClE,CAAC;AAED,IAAM,mBAAmB,EAAE,OAAO,EAAE,OAAO,cAAc,CAAC,EAAE,OAAO;AAEnE,IAAM,kBAAkB,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC,EAAE,OAAO;AAEjE,IAAM,sBAAsB,EACzB,OAAO,EAAE,UAAU,eAAe,IAAI,sBAAsB,CAAC,EAC7D,OAAO;AAEH,IAAM,oBAAoB,EAAE,MAAM;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAIM,IAAM,gBAAgB,EAC1B,OAAO;AAAA,EACN,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC;AAAA,EAC5B,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACpC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AACrC,CAAC,EACA,OAAO;AAIH,IAAM,oBAAoB,EAC9B,OAAO;AAAA,EACN,OAAO,EAAE,OAAO;AAAA,EAChB,WAAW,EAAE,OAAO;AACtB,CAAC,EACA,OAAO;AAEH,IAAM,wBAAwB,EAClC,OAAO;AAAA,EACN,OAAO,EAAE,OAAO;AAAA,EAChB,YAAY,EAAE,OAAO;AACvB,CAAC,EACA,OAAO;AAIV,IAAM,yBAAyB,EAC5B,OAAO;AAAA,EACN,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACpC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AACrC,CAAC,EACA,OAAO;AAEV,IAAM,qBAAqB,EACxB,OAAO;AAAA,EACN,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACvC,cAAc,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EAC3C,aAAa,EAAE,OAAO,EAAE,SAAS;AAAA,EACjC,UAAU,cAAc,SAAS;AAAA,EACjC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;AAAA,EACtC,aAAa,uBAAuB,SAAS;AAAA,EAC7C,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,EAC/B,SAAS,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,SAAS;AAC1C,CAAC,EACA,OAAO;AAEH,IAAM,oBAAoB,EAC9B,OAAO;AAAA,EACN,OAAO;AAAA,EACP,QAAQ,EAAE,KAAK,CAAC,SAAS,QAAQ,WAAW,OAAO,CAAC;AAAA,EACpD,QAAQ,EAAE,OAAO,EAAE,SAAS;AAC9B,CAAC,EACA,OAAO;AAIH,IAAM,yBAAyB,EACnC,OAAO;AAAA,EACN,MAAM,EAAE,MAAM,cAAc,EAAE,SAAS;AAAA,EACvC,SAAS,EAAE,MAAM,iBAAiB,EAAE,SAAS;AAAA,EAC7C,UAAU,EAAE,MAAM,iBAAiB,EAAE,SAAS;AAAA,EAC9C,KAAK,EAAE,MAAM,aAAa,EAAE,SAAS;AAAA,EACrC,KAAK,EAAE,MAAM,iBAAiB,EAAE,SAAS;AAAA,EACzC,SAAS,EAAE,MAAM,qBAAqB,EAAE,SAAS;AAAA,EACjD,cAAc,EAAE,MAAM,iBAAiB,EAAE,SAAS;AACpD,CAAC,EACA,OAAO;AAgBH,SAAS,eAAe,QAAmC;AAChE,MAAI;AACF,WAAO,uBAAuB,MAAM,MAAM;AAAA,EAC5C,SAAS,KAAK;AACZ,QAAI,eAAe,UAAU;AAC3B,YAAM,IAAI,sBAAsB,EAAE,QAAQ,IAAI,OAAO,CAAC;AAAA,IACxD;AACA,UAAM;AAAA,EACR;AACF;;;AC7KA,IAAM,aAAa,CAAC,QAAQ,WAAW,YAAY,OAAO,OAAO,WAAW,cAAc;AAOnF,SAAS,MAAM,SAA2B,WAA0D;AACzG,SAAO,eAAe,cAAc,MAAM,WAAW,QAAQ,CAAC;AAChE;AAMO,SAAS,aAAa,SAA2B,WAA0D;AAChH,SAAO,eAAe,cAAc,MAAM,WAAW,SAAS,CAAC;AACjE;AAEA,SAAS,cACP,MACA,WACA,MACkB;AAClB,QAAM,SAAc,EAAE,GAAG,KAAK;AAC9B,aAAW,YAAY,WAAW;AAChC,eAAW,OAAO,YAAY;AAC5B,UAAI,SAAS,GAAG,KAAK,MAAM;AACzB,cAAM,YAAY,OAAO,GAAG,KAAK,CAAC;AAClC,eAAO,GAAG,IAAI,SAAS,WACnB,CAAC,GAAG,WAAW,GAAG,SAAS,GAAG,CAAE,IAChC,CAAC,GAAG,SAAS,GAAG,GAAI,GAAG,SAAS;AAAA,MACtC;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;;;AC7BO,SAAS,aACd,YACkB;AAClB,QAAM,OAAyB;AAAA,IAC7B,MAAM;AAAA,MACJ,EAAE,OAAO,iBAAiB,KAAK,CAAC,QAAQ,SAAS,QAAQ,EAAE;AAAA;AAAA,MAE3D,EAAE,MAAM,CAAC,0BAA0B,mBAAmB,EAAE;AAAA;AAAA,MAExD,EAAE,MAAM,CAAC,WAAW,aAAa,mBAAmB,YAAY,UAAU,EAAE;AAAA,MAC5E,EAAE,MAAM,CAAC,aAAa,iBAAiB,EAAE;AAAA;AAAA,MAEzC,EAAE,MAAM,CAAC,aAAa,aAAa,eAAe,qBAAqB,EAAE;AAAA;AAAA,MAEzE,EAAE,MAAM,CAAC,aAAa,YAAY,cAAc,iBAAiB,EAAE;AAAA;AAAA,MAEnE,EAAE,MAAM,CAAC,gBAAgB,YAAY,aAAa,WAAW,EAAE;AAAA;AAAA,MAE/D,EAAE,MAAM,kBAAkB;AAAA;AAAA,MAE1B,EAAE,MAAM,CAAC,mBAAmB,gBAAgB,4BAA4B,GAAG,KAAK,CAAC,SAAS,UAAU,QAAQ,EAAE;AAAA,IAChH;AAAA,IACA,SAAS;AAAA,MACP;AAAA,QACE,OAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA,OAAO,CAAC,GAAG;AAAA,MACb;AAAA,MACA,EAAE,MAAM,IAAI;AAAA,IACd;AAAA,IACA,UAAU;AAAA;AAAA,MAER;AAAA,QACE,OAAO;AAAA,UACL;AAAA,UAAQ;AAAA,UAAM;AAAA,UAAQ;AAAA,UAAO;AAAA,UAAQ;AAAA,UAAQ;AAAA,UAAQ;AAAA,UACrD;AAAA,UAAM;AAAA,UAAM;AAAA,UAAQ;AAAA,UAAQ;AAAA,UAAQ;AAAA,UAAO;AAAA,UAAQ;AAAA,UACnD;AAAA,UAAU;AAAA,UAAM;AAAA,UAAS;AAAA,UAAU;AAAA,UAAQ;AAAA,UAAQ;AAAA,UACnD;AAAA,UAAS;AAAA,UAAM;AAAA,UAAM;AAAA,UAAM;AAAA,UAAS;AAAA,UAAS;AAAA,UAAM;AAAA,UACnD;AAAA,UAAO;AAAA,UAAO;AAAA,UAAO;AAAA,UAAS;AAAA,UAAY;AAAA,UAAW;AAAA,UACrD;AAAA,UAAU;AAAA,UAAU;AAAA,UAAa;AAAA,UAAO;AAAA,UAAQ;AAAA,QAClD;AAAA,MACF;AAAA;AAAA,MAEA;AAAA,QACE,OAAO;AAAA,UACL;AAAA,UAAO;AAAA,UAAQ;AAAA,UAAO;AAAA,UAAO;AAAA,UAAQ;AAAA,UAAQ;AAAA,UAC7C;AAAA,UAAU;AAAA,UAAW;AAAA,UAAO;AAAA,UAC5B;AAAA,UAAS;AAAA,UAAS;AAAA,UAAM;AAAA,UAAQ;AAAA,QAClC;AAAA,MACF;AAAA;AAAA,MAEA,EAAE,MAAM,CAAC,OAAO,YAAY,QAAQ,MAAM,MAAM,EAAE;AAAA,MAClD,EAAE,MAAM,CAAC,YAAY,UAAU,QAAQ,UAAU,EAAE;AAAA,MACnD,EAAE,MAAM,CAAC,MAAM,QAAQ,UAAU,SAAS,QAAQ,EAAE;AAAA,MACpD,EAAE,MAAM,CAAC,oBAAoB,kBAAkB,EAAE;AAAA,MACjD;AAAA,QACE,UAAU,CAAC,QAAQ,MAAM;AAAA,QACzB,IAAI,EAAE,KAAK,iBAAiB,MAAM,CAAC,SAAS,EAAE;AAAA,MAChD;AAAA,IACF;AAAA,IACA,cAAc;AAAA;AAAA,MAEZ;AAAA,QACE,OAAO,EAAE,aAAa,iBAAiB,UAAU,WAAW;AAAA,QAC5D,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAAA;AAAA,MAEA;AAAA,QACE,OAAO,EAAE,aAAa,UAAU;AAAA,QAChC,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAAA;AAAA,MAEA;AAAA,QACE,OAAO,EAAE,aAAa,cAAc,SAAS,CAAC,WAAW,EAAE;AAAA,QAC3D,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAAA;AAAA,MAEA;AAAA,QACE,OAAO,EAAE,aAAa,iBAAiB,UAAU,SAAS;AAAA,QAC1D,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAAA;AAAA,MAEA;AAAA,QACE,OAAO;AAAA,UACL,aAAa;AAAA,UACb,aAAa,EAAE,MAAM,CAAC,iBAAiB,UAAU,EAAE;AAAA,QACrD;AAAA,QACA,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAAA;AAAA,MAEA;AAAA,QACE,OAAO;AAAA,UACL,aAAa;AAAA,UACb,SAAS,CAAC,iBAAiB;AAAA,QAC7B;AAAA,QACA,QAAQ;AAAA,QACR,QAAQ;AAAA,MACV;AAAA,IACF;AAAA,EACF;AACA,SAAO,aAAa,MAAM,MAAM,UAAU,IAAI;AAChD;AAOO,SAAS,QACd,YACkB;AAClB,QAAM,OAAyB;AAAA,IAC7B,MAAM;AAAA,MACJ,EAAE,OAAO,iBAAiB,KAAK,CAAC,QAAQ,SAAS,QAAQ,EAAE;AAAA,MAC3D,EAAE,MAAM,CAAC,WAAW,aAAa,mBAAmB,YAAY,UAAU,EAAE;AAAA,MAC5E,EAAE,MAAM,CAAC,aAAa,iBAAiB,EAAE;AAAA,MACzC,EAAE,MAAM,CAAC,aAAa,aAAa,eAAe,qBAAqB,EAAE;AAAA,MACzE,EAAE,MAAM,CAAC,aAAa,YAAY,cAAc,iBAAiB,EAAE;AAAA,MACnE,EAAE,MAAM,CAAC,gBAAgB,YAAY,aAAa,WAAW,EAAE;AAAA,IACjE;AAAA,IACA,SAAS;AAAA,MACP;AAAA,QACE,OAAO,CAAC,sBAAsB,sBAAsB;AAAA,QACpD,OAAO,CAAC,GAAG;AAAA,MACb;AAAA,IACF;AAAA,IACA,UAAU,CAAC,EAAE,MAAM,CAAC,OAAO,YAAY,YAAY,QAAQ,EAAE,CAAC;AAAA,EAChE;AACA,SAAO,aAAa,MAAM,MAAM,UAAU,IAAI;AAChD;AAOO,SAAS,SACd,YACkB;AAClB,QAAM,OAAyB;AAAA,IAC7B,MAAM;AAAA,MACJ,EAAE,OAAO,gBAAgB;AAAA,MACzB,EAAE,MAAM,CAAC,WAAW,aAAa,mBAAmB,YAAY,UAAU,EAAE;AAAA,MAC5E,EAAE,MAAM,CAAC,aAAa,aAAa,eAAe,qBAAqB,EAAE;AAAA,MACzE,EAAE,MAAM,MAAM;AAAA,IAChB;AAAA,IACA,SAAS;AAAA,MACP;AAAA,QACE,OAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,QACA,OAAO,CAAC,GAAG;AAAA,MACb;AAAA,MACA,EAAE,MAAM,IAAI;AAAA,IACd;AAAA,IACA,UAAU;AAAA,MACR,EAAE,MAAM,CAAC,OAAO,YAAY,YAAY,UAAU,MAAM,EAAE;AAAA,IAC5D;AAAA,EACF;AACA,SAAO,aAAa,MAAM,MAAM,UAAU,IAAI;AAChD;AAOO,SAAS,aACd,YACkB;AAClB,QAAM,OAAyB;AAAA,IAC7B,MAAM;AAAA,MACJ,EAAE,OAAO,iBAAiB,KAAK,CAAC,MAAM,EAAE;AAAA,MACxC,EAAE,MAAM,MAAM;AAAA,IAChB;AAAA,IACA,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;AAAA,IACvB,UAAU;AAAA,MACR,EAAE,MAAM,CAAC,OAAO,YAAY,QAAQ,MAAM,YAAY,QAAQ,EAAE;AAAA,IAClE;AAAA,EACF;AACA,SAAO,aAAa,MAAM,MAAM,UAAU,IAAI;AAChD;","names":[]}
|