daycare-cli 2026.2.26 → 2026.2.27
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/dist/engine/agents/agent.d.ts +2 -0
- package/dist/engine/agents/agent.d.ts.map +1 -1
- package/dist/engine/agents/agent.js +7 -3
- package/dist/engine/agents/agent.js.map +1 -1
- package/dist/engine/agents/agentSystem.d.ts +5 -0
- package/dist/engine/agents/agentSystem.d.ts.map +1 -1
- package/dist/engine/agents/agentSystem.js +16 -1
- package/dist/engine/agents/agentSystem.js.map +1 -1
- package/dist/engine/agents/agentSystem.spec.js +59 -0
- package/dist/engine/agents/agentSystem.spec.js.map +1 -1
- package/dist/engine/agents/ops/agentLoopRun.d.ts +0 -2
- package/dist/engine/agents/ops/agentLoopRun.d.ts.map +1 -1
- package/dist/engine/agents/ops/agentLoopRun.js +4 -7
- package/dist/engine/agents/ops/agentLoopRun.js.map +1 -1
- package/dist/engine/agents/ops/agentLoopRun.spec.js +21 -24
- package/dist/engine/agents/ops/agentLoopRun.spec.js.map +1 -1
- package/dist/engine/apps/appExecute.spec.js +2 -10
- package/dist/engine/apps/appExecute.spec.js.map +1 -1
- package/dist/engine/apps/appInstallToolBuild.js +1 -1
- package/dist/engine/apps/appInstallToolBuild.js.map +1 -1
- package/dist/engine/apps/appInstallToolBuild.spec.js +1 -5
- package/dist/engine/apps/appInstallToolBuild.spec.js.map +1 -1
- package/dist/engine/apps/appRuleToolBuild.spec.js +1 -5
- package/dist/engine/apps/appRuleToolBuild.spec.js.map +1 -1
- package/dist/engine/apps/appToolExecutorBuild.spec.js +1 -5
- package/dist/engine/apps/appToolExecutorBuild.spec.js.map +1 -1
- package/dist/engine/engine.d.ts.map +1 -1
- package/dist/engine/engine.js +10 -0
- package/dist/engine/engine.js.map +1 -1
- package/dist/engine/friends/usertagGenerate.d.ts +6 -0
- package/dist/engine/friends/usertagGenerate.d.ts.map +1 -0
- package/dist/engine/friends/usertagGenerate.js +311 -0
- package/dist/engine/friends/usertagGenerate.js.map +1 -0
- package/dist/engine/friends/usertagGenerate.spec.d.ts +2 -0
- package/dist/engine/friends/usertagGenerate.spec.d.ts.map +1 -0
- package/dist/engine/friends/usertagGenerate.spec.js +13 -0
- package/dist/engine/friends/usertagGenerate.spec.js.map +1 -0
- package/dist/engine/modules/executablePrompts/executablePromptExpand.spec.js +1 -5
- package/dist/engine/modules/executablePrompts/executablePromptExpand.spec.js.map +1 -1
- package/dist/engine/modules/monty/montyPythonTypeFromSchemaRuntime.spec.js +1 -5
- package/dist/engine/modules/monty/montyPythonTypeFromSchemaRuntime.spec.js.map +1 -1
- package/dist/engine/modules/rlm/rlmExecute.spec.js +1 -5
- package/dist/engine/modules/rlm/rlmExecute.spec.js.map +1 -1
- package/dist/engine/modules/rlm/rlmRestore.spec.js +1 -5
- package/dist/engine/modules/rlm/rlmRestore.spec.js.map +1 -1
- package/dist/engine/modules/rlm/rlmTool.spec.js +1 -5
- package/dist/engine/modules/rlm/rlmTool.spec.js.map +1 -1
- package/dist/engine/modules/say/sayFileResolve.d.ts +4 -5
- package/dist/engine/modules/say/sayFileResolve.d.ts.map +1 -1
- package/dist/engine/modules/say/sayFileResolve.js +24 -14
- package/dist/engine/modules/say/sayFileResolve.js.map +1 -1
- package/dist/engine/modules/say/sayFileResolve.spec.js +28 -29
- package/dist/engine/modules/say/sayFileResolve.spec.js.map +1 -1
- package/dist/engine/modules/toolResolver.spec.js +1 -5
- package/dist/engine/modules/toolResolver.spec.js.map +1 -1
- package/dist/engine/modules/tools/agentCompactTool.spec.js +1 -5
- package/dist/engine/modules/tools/agentCompactTool.spec.js.map +1 -1
- package/dist/engine/modules/tools/agentResetTool.spec.js +1 -5
- package/dist/engine/modules/tools/agentResetTool.spec.js.map +1 -1
- package/dist/engine/modules/tools/background.spec.js +3 -11
- package/dist/engine/modules/tools/background.spec.js.map +1 -1
- package/dist/engine/modules/tools/channelCreateTool.spec.js +1 -5
- package/dist/engine/modules/tools/channelCreateTool.spec.js.map +1 -1
- package/dist/engine/modules/tools/channelHistoryTool.spec.js +1 -5
- package/dist/engine/modules/tools/channelHistoryTool.spec.js.map +1 -1
- package/dist/engine/modules/tools/channelMemberTool.spec.js +1 -5
- package/dist/engine/modules/tools/channelMemberTool.spec.js.map +1 -1
- package/dist/engine/modules/tools/channelSendTool.spec.js +1 -5
- package/dist/engine/modules/tools/channelSendTool.spec.js.map +1 -1
- package/dist/engine/modules/tools/friendAddToolBuild.d.ts +7 -0
- package/dist/engine/modules/tools/friendAddToolBuild.d.ts.map +1 -0
- package/dist/engine/modules/tools/friendAddToolBuild.js +163 -0
- package/dist/engine/modules/tools/friendAddToolBuild.js.map +1 -0
- package/dist/engine/modules/tools/friendAddToolBuild.spec.d.ts +2 -0
- package/dist/engine/modules/tools/friendAddToolBuild.spec.d.ts.map +1 -0
- package/dist/engine/modules/tools/friendAddToolBuild.spec.js +151 -0
- package/dist/engine/modules/tools/friendAddToolBuild.spec.js.map +1 -0
- package/dist/engine/modules/tools/friendRemoveToolBuild.d.ts +7 -0
- package/dist/engine/modules/tools/friendRemoveToolBuild.d.ts.map +1 -0
- package/dist/engine/modules/tools/friendRemoveToolBuild.js +174 -0
- package/dist/engine/modules/tools/friendRemoveToolBuild.js.map +1 -0
- package/dist/engine/modules/tools/friendRemoveToolBuild.spec.d.ts +2 -0
- package/dist/engine/modules/tools/friendRemoveToolBuild.spec.d.ts.map +1 -0
- package/dist/engine/modules/tools/friendRemoveToolBuild.spec.js +172 -0
- package/dist/engine/modules/tools/friendRemoveToolBuild.spec.js.map +1 -0
- package/dist/engine/modules/tools/friendSendToolBuild.d.ts +7 -0
- package/dist/engine/modules/tools/friendSendToolBuild.d.ts.map +1 -0
- package/dist/engine/modules/tools/friendSendToolBuild.js +104 -0
- package/dist/engine/modules/tools/friendSendToolBuild.js.map +1 -0
- package/dist/engine/modules/tools/friendSendToolBuild.spec.d.ts +2 -0
- package/dist/engine/modules/tools/friendSendToolBuild.spec.d.ts.map +1 -0
- package/dist/engine/modules/tools/friendSendToolBuild.spec.js +120 -0
- package/dist/engine/modules/tools/friendSendToolBuild.spec.js.map +1 -0
- package/dist/engine/modules/tools/friendShareSubuserToolBuild.d.ts +7 -0
- package/dist/engine/modules/tools/friendShareSubuserToolBuild.d.ts.map +1 -0
- package/dist/engine/modules/tools/friendShareSubuserToolBuild.js +133 -0
- package/dist/engine/modules/tools/friendShareSubuserToolBuild.js.map +1 -0
- package/dist/engine/modules/tools/friendShareSubuserToolBuild.spec.d.ts +2 -0
- package/dist/engine/modules/tools/friendShareSubuserToolBuild.spec.d.ts.map +1 -0
- package/dist/engine/modules/tools/friendShareSubuserToolBuild.spec.js +119 -0
- package/dist/engine/modules/tools/friendShareSubuserToolBuild.spec.js.map +1 -0
- package/dist/engine/modules/tools/friendUnshareSubuserToolBuild.d.ts +7 -0
- package/dist/engine/modules/tools/friendUnshareSubuserToolBuild.d.ts.map +1 -0
- package/dist/engine/modules/tools/friendUnshareSubuserToolBuild.js +118 -0
- package/dist/engine/modules/tools/friendUnshareSubuserToolBuild.js.map +1 -0
- package/dist/engine/modules/tools/friendUnshareSubuserToolBuild.spec.d.ts +2 -0
- package/dist/engine/modules/tools/friendUnshareSubuserToolBuild.spec.d.ts.map +1 -0
- package/dist/engine/modules/tools/friendUnshareSubuserToolBuild.spec.js +100 -0
- package/dist/engine/modules/tools/friendUnshareSubuserToolBuild.spec.js.map +1 -0
- package/dist/engine/modules/tools/image-generation.d.ts.map +1 -1
- package/dist/engine/modules/tools/image-generation.js +26 -10
- package/dist/engine/modules/tools/image-generation.js.map +1 -1
- package/dist/engine/modules/tools/image-generation.spec.js +13 -10
- package/dist/engine/modules/tools/image-generation.spec.js.map +1 -1
- package/dist/engine/modules/tools/mermaid-png.d.ts.map +1 -1
- package/dist/engine/modules/tools/mermaid-png.js +16 -11
- package/dist/engine/modules/tools/mermaid-png.js.map +1 -1
- package/dist/engine/modules/tools/mermaid-png.spec.js +20 -24
- package/dist/engine/modules/tools/mermaid-png.spec.js.map +1 -1
- package/dist/engine/modules/tools/pdf-process.d.ts.map +1 -1
- package/dist/engine/modules/tools/pdf-process.js +10 -38
- package/dist/engine/modules/tools/pdf-process.js.map +1 -1
- package/dist/engine/modules/tools/pdf-process.spec.js +15 -5
- package/dist/engine/modules/tools/pdf-process.spec.js.map +1 -1
- package/dist/engine/modules/tools/permanentAgentToolBuild.spec.js +5 -13
- package/dist/engine/modules/tools/permanentAgentToolBuild.spec.js.map +1 -1
- package/dist/engine/modules/tools/send-file.d.ts.map +1 -1
- package/dist/engine/modules/tools/send-file.js +20 -11
- package/dist/engine/modules/tools/send-file.js.map +1 -1
- package/dist/engine/modules/tools/sendUserMessageTool.spec.js +1 -5
- package/dist/engine/modules/tools/sendUserMessageTool.spec.js.map +1 -1
- package/dist/engine/modules/tools/sessionHistoryToolBuild.spec.js +1 -2
- package/dist/engine/modules/tools/sessionHistoryToolBuild.spec.js.map +1 -1
- package/dist/engine/modules/tools/signal.spec.js +1 -5
- package/dist/engine/modules/tools/signal.spec.js.map +1 -1
- package/dist/engine/modules/tools/signalEventsCsvToolBuild.spec.js +1 -5
- package/dist/engine/modules/tools/signalEventsCsvToolBuild.spec.js.map +1 -1
- package/dist/engine/modules/tools/signalSubscribeToolBuild.spec.js +1 -5
- package/dist/engine/modules/tools/signalSubscribeToolBuild.spec.js.map +1 -1
- package/dist/engine/modules/tools/signalUnsubscribeToolBuild.spec.js +1 -5
- package/dist/engine/modules/tools/signalUnsubscribeToolBuild.spec.js.map +1 -1
- package/dist/engine/modules/tools/skillToolBuild.js +3 -3
- package/dist/engine/modules/tools/skillToolBuild.js.map +1 -1
- package/dist/engine/modules/tools/skillToolBuild.spec.js +12 -9
- package/dist/engine/modules/tools/skillToolBuild.spec.js.map +1 -1
- package/dist/engine/modules/tools/subuserConfigureToolBuild.spec.js +1 -2
- package/dist/engine/modules/tools/subuserConfigureToolBuild.spec.js.map +1 -1
- package/dist/engine/modules/tools/subuserCreateToolBuild.spec.js +1 -2
- package/dist/engine/modules/tools/subuserCreateToolBuild.spec.js.map +1 -1
- package/dist/engine/modules/tools/subuserListToolBuild.spec.js +1 -2
- package/dist/engine/modules/tools/subuserListToolBuild.spec.js.map +1 -1
- package/dist/engine/modules/tools/topologyToolBuild.d.ts.map +1 -1
- package/dist/engine/modules/tools/topologyToolBuild.js +111 -2
- package/dist/engine/modules/tools/topologyToolBuild.js.map +1 -1
- package/dist/engine/modules/tools/topologyToolBuild.spec.js +99 -2
- package/dist/engine/modules/tools/topologyToolBuild.spec.js.map +1 -1
- package/dist/engine/modules/tools/types.d.ts +3 -4
- package/dist/engine/modules/tools/types.d.ts.map +1 -1
- package/dist/plugins/dashboard/site/404.html +1 -1
- package/dist/plugins/dashboard/site/agent.html +1 -1
- package/dist/plugins/dashboard/site/agent.txt +1 -1
- package/dist/plugins/dashboard/site/agents.html +1 -1
- package/dist/plugins/dashboard/site/agents.txt +1 -1
- package/dist/plugins/dashboard/site/automations.html +1 -1
- package/dist/plugins/dashboard/site/automations.txt +1 -1
- package/dist/plugins/dashboard/site/connectors.html +1 -1
- package/dist/plugins/dashboard/site/connectors.txt +1 -1
- package/dist/plugins/dashboard/site/index.html +1 -1
- package/dist/plugins/dashboard/site/index.txt +1 -1
- package/dist/plugins/dashboard/site/memory.html +1 -1
- package/dist/plugins/dashboard/site/memory.txt +1 -1
- package/dist/plugins/dashboard/site/processes.html +1 -1
- package/dist/plugins/dashboard/site/processes.txt +1 -1
- package/dist/plugins/dashboard/site/providers.html +1 -1
- package/dist/plugins/dashboard/site/providers.txt +1 -1
- package/dist/plugins/dashboard/site/signals.html +1 -1
- package/dist/plugins/dashboard/site/signals.txt +1 -1
- package/dist/plugins/dashboard/site/telemetry.html +1 -1
- package/dist/plugins/dashboard/site/telemetry.txt +1 -1
- package/dist/plugins/dashboard/site/tools.html +1 -1
- package/dist/plugins/dashboard/site/tools.txt +1 -1
- package/dist/plugins/database/__tests__/plugin.spec.js +4 -2
- package/dist/plugins/database/__tests__/plugin.spec.js.map +1 -1
- package/dist/plugins/monty-python/tool.spec.js +1 -2
- package/dist/plugins/monty-python/tool.spec.js.map +1 -1
- package/dist/plugins/shell/processTools.js +1 -1
- package/dist/plugins/shell/processTools.js.map +1 -1
- package/dist/plugins/shell/processTools.spec.js +2 -3
- package/dist/plugins/shell/processTools.spec.js.map +1 -1
- package/dist/plugins/shell/tool.d.ts.map +1 -1
- package/dist/plugins/shell/tool.js +90 -486
- package/dist/plugins/shell/tool.js.map +1 -1
- package/dist/plugins/shell/tool.spec.js +11 -20
- package/dist/plugins/shell/tool.spec.js.map +1 -1
- package/dist/sandbox/sandbox.d.ts +26 -0
- package/dist/sandbox/sandbox.d.ts.map +1 -0
- package/dist/sandbox/sandbox.js +466 -0
- package/dist/sandbox/sandbox.js.map +1 -0
- package/dist/sandbox/sandbox.spec.d.ts +2 -0
- package/dist/sandbox/sandbox.spec.d.ts.map +1 -0
- package/dist/sandbox/sandbox.spec.js +167 -0
- package/dist/sandbox/sandbox.spec.js.map +1 -0
- package/dist/sandbox/sandboxCanRead.d.ts.map +1 -1
- package/dist/sandbox/sandboxCanRead.js +4 -8
- package/dist/sandbox/sandboxCanRead.js.map +1 -1
- package/dist/sandbox/sandboxCanRead.spec.js +17 -11
- package/dist/sandbox/sandboxCanRead.spec.js.map +1 -1
- package/dist/sandbox/sandboxFilesystemPolicyBuild.d.ts +1 -1
- package/dist/sandbox/sandboxFilesystemPolicyBuild.d.ts.map +1 -1
- package/dist/sandbox/sandboxFilesystemPolicyBuild.js +14 -6
- package/dist/sandbox/sandboxFilesystemPolicyBuild.js.map +1 -1
- package/dist/sandbox/sandboxFilesystemPolicyBuild.spec.js +7 -2
- package/dist/sandbox/sandboxFilesystemPolicyBuild.spec.js.map +1 -1
- package/dist/sandbox/sandboxReadDenyPathsBuild.d.ts +13 -0
- package/dist/sandbox/sandboxReadDenyPathsBuild.d.ts.map +1 -0
- package/dist/sandbox/sandboxReadDenyPathsBuild.js +28 -0
- package/dist/sandbox/sandboxReadDenyPathsBuild.js.map +1 -0
- package/dist/sandbox/sandboxReadDenyPathsBuild.spec.d.ts +2 -0
- package/dist/sandbox/sandboxReadDenyPathsBuild.spec.d.ts.map +1 -0
- package/dist/sandbox/sandboxReadDenyPathsBuild.spec.js +29 -0
- package/dist/sandbox/sandboxReadDenyPathsBuild.spec.js.map +1 -0
- package/dist/sandbox/sandboxTypes.d.ts +67 -0
- package/dist/sandbox/sandboxTypes.d.ts.map +1 -0
- package/dist/sandbox/sandboxTypes.js +2 -0
- package/dist/sandbox/sandboxTypes.js.map +1 -0
- package/dist/storage/agentsRepository.d.ts +1 -0
- package/dist/storage/agentsRepository.d.ts.map +1 -1
- package/dist/storage/agentsRepository.js +16 -0
- package/dist/storage/agentsRepository.js.map +1 -1
- package/dist/storage/agentsRepository.spec.js +45 -0
- package/dist/storage/agentsRepository.spec.js.map +1 -1
- package/dist/storage/connectionsRepository.d.ts +18 -0
- package/dist/storage/connectionsRepository.d.ts.map +1 -0
- package/dist/storage/connectionsRepository.js +163 -0
- package/dist/storage/connectionsRepository.js.map +1 -0
- package/dist/storage/connectionsRepository.spec.d.ts +2 -0
- package/dist/storage/connectionsRepository.spec.d.ts.map +1 -0
- package/dist/storage/connectionsRepository.spec.js +115 -0
- package/dist/storage/connectionsRepository.spec.js.map +1 -0
- package/dist/storage/databaseTypes.d.ts +19 -0
- package/dist/storage/databaseTypes.d.ts.map +1 -1
- package/dist/storage/migrations/20260222_add_usertag_connections.d.ts +7 -0
- package/dist/storage/migrations/20260222_add_usertag_connections.d.ts.map +1 -0
- package/dist/storage/migrations/20260222_add_usertag_connections.js +32 -0
- package/dist/storage/migrations/20260222_add_usertag_connections.js.map +1 -0
- package/dist/storage/migrations/20260222_add_usertag_connections.spec.d.ts +2 -0
- package/dist/storage/migrations/20260222_add_usertag_connections.spec.d.ts.map +1 -0
- package/dist/storage/migrations/20260222_add_usertag_connections.spec.js +55 -0
- package/dist/storage/migrations/20260222_add_usertag_connections.spec.js.map +1 -0
- package/dist/storage/migrations/_migrations.d.ts.map +1 -1
- package/dist/storage/migrations/_migrations.js +3 -1
- package/dist/storage/migrations/_migrations.js.map +1 -1
- package/dist/storage/storage.d.ts +3 -0
- package/dist/storage/storage.d.ts.map +1 -1
- package/dist/storage/storage.js +35 -3
- package/dist/storage/storage.js.map +1 -1
- package/dist/storage/storage.spec.js +1 -0
- package/dist/storage/storage.spec.js.map +1 -1
- package/dist/storage/usersRepository.d.ts +2 -0
- package/dist/storage/usersRepository.d.ts.map +1 -1
- package/dist/storage/usersRepository.js +43 -2
- package/dist/storage/usersRepository.js.map +1 -1
- package/dist/storage/usersRepository.spec.js +9 -2
- package/dist/storage/usersRepository.spec.js.map +1 -1
- package/dist/types.d.ts +2 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -1
- package/package.json +1 -1
- /package/dist/plugins/dashboard/site/_next/static/{X_oqQhoSTmj1_qmNPx-r5 → Hr0soHgJ1L7WevXil6GIk}/_buildManifest.js +0 -0
- /package/dist/plugins/dashboard/site/_next/static/{X_oqQhoSTmj1_qmNPx-r5 → Hr0soHgJ1L7WevXil6GIk}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,466 @@
|
|
|
1
|
+
import { promises as fs } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { resolveWorkspacePath } from "../engine/permissions.js";
|
|
4
|
+
import { envNormalize } from "../util/envNormalize.js";
|
|
5
|
+
import { isWithinSecure, openSecure } from "./pathResolveSecure.js";
|
|
6
|
+
import { runInSandbox } from "./runtime.js";
|
|
7
|
+
import { sandboxAllowedDomainsResolve } from "./sandboxAllowedDomainsResolve.js";
|
|
8
|
+
import { sandboxAllowedDomainsValidate } from "./sandboxAllowedDomainsValidate.js";
|
|
9
|
+
import { sandboxCanRead } from "./sandboxCanRead.js";
|
|
10
|
+
import { sandboxCanWrite } from "./sandboxCanWrite.js";
|
|
11
|
+
import { sandboxFilesystemPolicyBuild } from "./sandboxFilesystemPolicyBuild.js";
|
|
12
|
+
const READ_MAX_LINES = 2000;
|
|
13
|
+
const READ_MAX_BYTES = 50 * 1024;
|
|
14
|
+
const DEFAULT_EXEC_TIMEOUT = 30_000;
|
|
15
|
+
const MAX_EXEC_BUFFER = 1_000_000;
|
|
16
|
+
const UNICODE_SPACES = /[\u00A0\u2000-\u200A\u202F\u205F\u3000]/g;
|
|
17
|
+
const NARROW_NO_BREAK_SPACE = "\u202F";
|
|
18
|
+
export class Sandbox {
|
|
19
|
+
homeDir;
|
|
20
|
+
workingDir;
|
|
21
|
+
permissions;
|
|
22
|
+
constructor(config) {
|
|
23
|
+
this.homeDir = path.resolve(config.homeDir);
|
|
24
|
+
this.workingDir = path.resolve(config.permissions.workingDir);
|
|
25
|
+
this.permissions = config.permissions;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Read from the host filesystem with sandbox read checks.
|
|
29
|
+
* Expects: args.path is absolute or relative to workingDir.
|
|
30
|
+
*/
|
|
31
|
+
async read(args) {
|
|
32
|
+
const permissions = this.permissionsEffectiveResolve();
|
|
33
|
+
const targetPath = await this.readInputPathResolve(args.path);
|
|
34
|
+
await pathRejectIfSymlink(targetPath, "Cannot read symbolic link directly.");
|
|
35
|
+
const resolvedPath = await sandboxCanRead(permissions, targetPath);
|
|
36
|
+
const stats = await fs.lstat(resolvedPath);
|
|
37
|
+
if (stats.isSymbolicLink()) {
|
|
38
|
+
throw new Error("Cannot read symbolic link directly.");
|
|
39
|
+
}
|
|
40
|
+
if (!stats.isFile()) {
|
|
41
|
+
throw new Error("Path is not a file.");
|
|
42
|
+
}
|
|
43
|
+
const displayPath = sandboxDisplayPath(this.workingDir, resolvedPath);
|
|
44
|
+
if (args.binary === true) {
|
|
45
|
+
const binaryContent = await readBinaryFileSecure(resolvedPath);
|
|
46
|
+
return {
|
|
47
|
+
type: "binary",
|
|
48
|
+
content: binaryContent,
|
|
49
|
+
bytes: stats.size,
|
|
50
|
+
resolvedPath,
|
|
51
|
+
displayPath
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
const mimeType = await detectSupportedImageMimeTypeFromFile(resolvedPath);
|
|
55
|
+
if (mimeType) {
|
|
56
|
+
const imageContent = await readBinaryFileSecure(resolvedPath);
|
|
57
|
+
return {
|
|
58
|
+
type: "image",
|
|
59
|
+
content: imageContent,
|
|
60
|
+
bytes: stats.size,
|
|
61
|
+
mimeType,
|
|
62
|
+
resolvedPath,
|
|
63
|
+
displayPath
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
const textContent = await readTextFileSecure(resolvedPath);
|
|
67
|
+
const allLines = textContent.split("\n");
|
|
68
|
+
const totalFileLines = allLines.length;
|
|
69
|
+
const startLine = args.offset ? Math.max(0, args.offset - 1) : 0;
|
|
70
|
+
if (startLine >= allLines.length) {
|
|
71
|
+
throw new Error(`Offset ${args.offset} is beyond end of file (${allLines.length} lines total)`);
|
|
72
|
+
}
|
|
73
|
+
let selectedContent = allLines.slice(startLine).join("\n");
|
|
74
|
+
let userLimitedLines;
|
|
75
|
+
if (args.limit !== undefined) {
|
|
76
|
+
const endLine = Math.min(startLine + args.limit, allLines.length);
|
|
77
|
+
selectedContent = allLines.slice(startLine, endLine).join("\n");
|
|
78
|
+
userLimitedLines = endLine - startLine;
|
|
79
|
+
}
|
|
80
|
+
if (args.raw === true) {
|
|
81
|
+
return {
|
|
82
|
+
type: "text",
|
|
83
|
+
content: selectedContent,
|
|
84
|
+
bytes: stats.size,
|
|
85
|
+
totalLines: totalFileLines,
|
|
86
|
+
outputLines: selectedContent.split("\n").length,
|
|
87
|
+
truncated: false,
|
|
88
|
+
truncatedBy: null,
|
|
89
|
+
resolvedPath,
|
|
90
|
+
displayPath
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
const startLineDisplay = startLine + 1;
|
|
94
|
+
const truncation = truncateHead(selectedContent);
|
|
95
|
+
const outputText = sandboxReadOutputBuild({
|
|
96
|
+
truncation,
|
|
97
|
+
allLines,
|
|
98
|
+
requestedPath: args.path,
|
|
99
|
+
totalFileLines,
|
|
100
|
+
startLine,
|
|
101
|
+
startLineDisplay,
|
|
102
|
+
userLimitedLines
|
|
103
|
+
});
|
|
104
|
+
return {
|
|
105
|
+
type: "text",
|
|
106
|
+
content: outputText,
|
|
107
|
+
bytes: stats.size,
|
|
108
|
+
totalLines: totalFileLines,
|
|
109
|
+
outputLines: truncation.outputLines,
|
|
110
|
+
truncated: truncation.truncated,
|
|
111
|
+
truncatedBy: truncation.truncatedBy,
|
|
112
|
+
resolvedPath,
|
|
113
|
+
displayPath
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Write UTF-8 content to host filesystem with sandbox write checks.
|
|
118
|
+
* Expects: args.path is an absolute path.
|
|
119
|
+
*/
|
|
120
|
+
async write(args) {
|
|
121
|
+
const permissions = this.permissionsEffectiveResolve();
|
|
122
|
+
sandboxPathAbsoluteEnsure(args.path);
|
|
123
|
+
await pathRejectIfSymlink(args.path, "Cannot write to symbolic link.");
|
|
124
|
+
const resolvedPath = await sandboxCanWrite(permissions, args.path);
|
|
125
|
+
await fs.mkdir(path.dirname(resolvedPath), { recursive: true });
|
|
126
|
+
try {
|
|
127
|
+
const stats = await fs.lstat(resolvedPath);
|
|
128
|
+
if (stats.isSymbolicLink()) {
|
|
129
|
+
throw new Error("Cannot write to symbolic link.");
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
if (error.code !== "ENOENT") {
|
|
134
|
+
throw error;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
const handle = await fs.open(resolvedPath, args.append ? "a" : "w");
|
|
138
|
+
try {
|
|
139
|
+
await handle.writeFile(args.content);
|
|
140
|
+
}
|
|
141
|
+
finally {
|
|
142
|
+
await handle.close();
|
|
143
|
+
}
|
|
144
|
+
return {
|
|
145
|
+
bytes: Buffer.isBuffer(args.content) ? args.content.byteLength : Buffer.byteLength(args.content, "utf8"),
|
|
146
|
+
resolvedPath,
|
|
147
|
+
sandboxPath: sandboxHomePath(this.homeDir, resolvedPath)
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Execute a shell command inside sandbox-runtime.
|
|
152
|
+
* Expects: args.command is non-empty and network allowlist is explicit.
|
|
153
|
+
*/
|
|
154
|
+
async exec(args) {
|
|
155
|
+
const permissions = this.permissionsEffectiveResolve();
|
|
156
|
+
const cwd = sandboxExecCwdResolve(this.workingDir, args.cwd);
|
|
157
|
+
const allowedDomains = sandboxAllowedDomainsResolve(args.allowedDomains, args.packageManagers);
|
|
158
|
+
const domainIssues = sandboxAllowedDomainsValidate(allowedDomains);
|
|
159
|
+
if (domainIssues.length > 0) {
|
|
160
|
+
throw new Error(domainIssues.join(" "));
|
|
161
|
+
}
|
|
162
|
+
const envOverrides = envNormalize(args.env);
|
|
163
|
+
const env = envOverrides ? { ...process.env, ...envOverrides } : process.env;
|
|
164
|
+
const filesystem = sandboxFilesystemPolicyBuild({
|
|
165
|
+
writeDirs: permissions.writeDirs,
|
|
166
|
+
workingDir: permissions.workingDir,
|
|
167
|
+
homeDir: this.homeDir
|
|
168
|
+
});
|
|
169
|
+
try {
|
|
170
|
+
const result = await runInSandbox(args.command, {
|
|
171
|
+
filesystem,
|
|
172
|
+
network: {
|
|
173
|
+
allowedDomains,
|
|
174
|
+
deniedDomains: []
|
|
175
|
+
},
|
|
176
|
+
enableWeakerNestedSandbox: true
|
|
177
|
+
}, {
|
|
178
|
+
cwd,
|
|
179
|
+
env,
|
|
180
|
+
home: this.homeDir,
|
|
181
|
+
timeoutMs: args.timeoutMs ?? DEFAULT_EXEC_TIMEOUT,
|
|
182
|
+
maxBufferBytes: MAX_EXEC_BUFFER
|
|
183
|
+
});
|
|
184
|
+
return {
|
|
185
|
+
stdout: sandboxText(result.stdout),
|
|
186
|
+
stderr: sandboxText(result.stderr),
|
|
187
|
+
exitCode: 0,
|
|
188
|
+
signal: null,
|
|
189
|
+
failed: false,
|
|
190
|
+
cwd
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
catch (error) {
|
|
194
|
+
const execError = error;
|
|
195
|
+
return {
|
|
196
|
+
stdout: sandboxText(execError.stdout),
|
|
197
|
+
stderr: sandboxText(execError.stderr),
|
|
198
|
+
exitCode: typeof execError.code === "number" ? execError.code : null,
|
|
199
|
+
signal: typeof execError.signal === "string" ? execError.signal : null,
|
|
200
|
+
failed: true,
|
|
201
|
+
cwd
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
permissionsEffectiveResolve() {
|
|
206
|
+
const readDirs = this.permissions.readDirs
|
|
207
|
+
? this.permissions.readDirs.map((entry) => path.resolve(entry))
|
|
208
|
+
: undefined;
|
|
209
|
+
return {
|
|
210
|
+
workingDir: this.workingDir,
|
|
211
|
+
writeDirs: Array.from(new Set([...this.permissions.writeDirs.map((entry) => path.resolve(entry)), this.homeDir])),
|
|
212
|
+
...(readDirs ? { readDirs } : {})
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
async readInputPathResolve(rawPath) {
|
|
216
|
+
const normalized = sandboxReadPathNormalize(rawPath, this.homeDir);
|
|
217
|
+
const resolved = path.isAbsolute(normalized) ? normalized : path.resolve(this.workingDir, normalized);
|
|
218
|
+
if (await pathExists(resolved)) {
|
|
219
|
+
return resolved;
|
|
220
|
+
}
|
|
221
|
+
const amPmVariant = sandboxReadPathMacOSVariant(resolved);
|
|
222
|
+
if (amPmVariant !== resolved && (await pathExists(amPmVariant))) {
|
|
223
|
+
return amPmVariant;
|
|
224
|
+
}
|
|
225
|
+
const nfdVariant = resolved.normalize("NFD");
|
|
226
|
+
if (nfdVariant !== resolved && (await pathExists(nfdVariant))) {
|
|
227
|
+
return nfdVariant;
|
|
228
|
+
}
|
|
229
|
+
const curlyVariant = resolved.replace(/'/g, "\u2019");
|
|
230
|
+
if (curlyVariant !== resolved && (await pathExists(curlyVariant))) {
|
|
231
|
+
return curlyVariant;
|
|
232
|
+
}
|
|
233
|
+
const nfdCurlyVariant = nfdVariant.replace(/'/g, "\u2019");
|
|
234
|
+
if (nfdCurlyVariant !== resolved && (await pathExists(nfdCurlyVariant))) {
|
|
235
|
+
return nfdCurlyVariant;
|
|
236
|
+
}
|
|
237
|
+
return resolved;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
function sandboxReadPathNormalize(rawPath, homeDir) {
|
|
241
|
+
const withoutAtPrefix = rawPath.startsWith("@") ? rawPath.slice(1) : rawPath;
|
|
242
|
+
const normalized = withoutAtPrefix.replace(UNICODE_SPACES, " ");
|
|
243
|
+
if (normalized === "~") {
|
|
244
|
+
return homeDir;
|
|
245
|
+
}
|
|
246
|
+
if (normalized.startsWith("~/")) {
|
|
247
|
+
return homeDir + normalized.slice(1);
|
|
248
|
+
}
|
|
249
|
+
return normalized;
|
|
250
|
+
}
|
|
251
|
+
function sandboxReadPathMacOSVariant(target) {
|
|
252
|
+
return target.replace(/ (AM|PM)\./g, `${NARROW_NO_BREAK_SPACE}$1.`);
|
|
253
|
+
}
|
|
254
|
+
function sandboxReadOutputBuild(input) {
|
|
255
|
+
const { truncation, allLines, requestedPath, totalFileLines, startLine, startLineDisplay, userLimitedLines } = input;
|
|
256
|
+
if (truncation.firstLineExceedsLimit) {
|
|
257
|
+
const firstLineSize = sandboxSizeFormat(Buffer.byteLength(allLines[startLine] ?? "", "utf8"));
|
|
258
|
+
return `[Line ${startLineDisplay} is ${firstLineSize}, exceeds ${sandboxSizeFormat(READ_MAX_BYTES)} limit. Use bash: sed -n '${startLineDisplay}p' ${requestedPath} | head -c ${READ_MAX_BYTES}]`;
|
|
259
|
+
}
|
|
260
|
+
if (truncation.truncated) {
|
|
261
|
+
const endLineDisplay = startLineDisplay + truncation.outputLines - 1;
|
|
262
|
+
const nextOffset = endLineDisplay + 1;
|
|
263
|
+
if (truncation.truncatedBy === "lines") {
|
|
264
|
+
return `${truncation.content}\n\n[Showing lines ${startLineDisplay}-${endLineDisplay} of ${totalFileLines}. Use offset=${nextOffset} to continue.]`;
|
|
265
|
+
}
|
|
266
|
+
return `${truncation.content}\n\n[Showing lines ${startLineDisplay}-${endLineDisplay} of ${totalFileLines} (${sandboxSizeFormat(READ_MAX_BYTES)} limit). Use offset=${nextOffset} to continue.]`;
|
|
267
|
+
}
|
|
268
|
+
if (userLimitedLines !== undefined && startLine + userLimitedLines < allLines.length) {
|
|
269
|
+
const remaining = allLines.length - (startLine + userLimitedLines);
|
|
270
|
+
const nextOffset = startLine + userLimitedLines + 1;
|
|
271
|
+
return `${truncation.content}\n\n[${remaining} more lines in file. Use offset=${nextOffset} to continue.]`;
|
|
272
|
+
}
|
|
273
|
+
return truncation.content;
|
|
274
|
+
}
|
|
275
|
+
function sandboxPathAbsoluteEnsure(target) {
|
|
276
|
+
if (!path.isAbsolute(target)) {
|
|
277
|
+
throw new Error("Path must be absolute.");
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
async function pathRejectIfSymlink(target, message) {
|
|
281
|
+
try {
|
|
282
|
+
const stats = await fs.lstat(target);
|
|
283
|
+
if (stats.isSymbolicLink()) {
|
|
284
|
+
throw new Error(message);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
catch (error) {
|
|
288
|
+
if (error.code !== "ENOENT") {
|
|
289
|
+
throw error;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
function sandboxDisplayPath(workingDir, target) {
|
|
294
|
+
if (isWithinSecure(workingDir, target)) {
|
|
295
|
+
return path.relative(workingDir, target) || ".";
|
|
296
|
+
}
|
|
297
|
+
return target;
|
|
298
|
+
}
|
|
299
|
+
function sandboxHomePath(homeDir, target) {
|
|
300
|
+
const homeVariants = sandboxMacPathVariants(homeDir);
|
|
301
|
+
const targetVariants = sandboxMacPathVariants(target);
|
|
302
|
+
for (const homeVariant of homeVariants) {
|
|
303
|
+
for (const targetVariant of targetVariants) {
|
|
304
|
+
if (!isWithinSecure(homeVariant, targetVariant)) {
|
|
305
|
+
continue;
|
|
306
|
+
}
|
|
307
|
+
const relative = path.relative(homeVariant, targetVariant);
|
|
308
|
+
if (relative.length === 0) {
|
|
309
|
+
return "~";
|
|
310
|
+
}
|
|
311
|
+
return `~/${relative}`;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
return target;
|
|
315
|
+
}
|
|
316
|
+
function sandboxMacPathVariants(target) {
|
|
317
|
+
const resolved = path.resolve(target);
|
|
318
|
+
if (resolved.startsWith("/private/")) {
|
|
319
|
+
return [resolved, resolved.slice("/private".length)];
|
|
320
|
+
}
|
|
321
|
+
return [resolved, path.join("/private", resolved)];
|
|
322
|
+
}
|
|
323
|
+
function sandboxExecCwdResolve(workingDir, requestedCwd) {
|
|
324
|
+
if (!requestedCwd) {
|
|
325
|
+
return workingDir;
|
|
326
|
+
}
|
|
327
|
+
const candidate = path.isAbsolute(requestedCwd)
|
|
328
|
+
? path.resolve(requestedCwd)
|
|
329
|
+
: path.resolve(workingDir, requestedCwd);
|
|
330
|
+
return resolveWorkspacePath(workingDir, candidate);
|
|
331
|
+
}
|
|
332
|
+
function sandboxText(value) {
|
|
333
|
+
if (!value) {
|
|
334
|
+
return "";
|
|
335
|
+
}
|
|
336
|
+
return typeof value === "string" ? value : value.toString("utf8");
|
|
337
|
+
}
|
|
338
|
+
async function pathExists(target) {
|
|
339
|
+
try {
|
|
340
|
+
await fs.access(target);
|
|
341
|
+
return true;
|
|
342
|
+
}
|
|
343
|
+
catch {
|
|
344
|
+
return false;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
async function readTextFileSecure(resolvedPath) {
|
|
348
|
+
const handle = await openSecure(resolvedPath, "r");
|
|
349
|
+
try {
|
|
350
|
+
return await handle.readFile("utf8");
|
|
351
|
+
}
|
|
352
|
+
finally {
|
|
353
|
+
await handle.close();
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
async function readBinaryFileSecure(resolvedPath) {
|
|
357
|
+
const handle = await openSecure(resolvedPath, "r");
|
|
358
|
+
try {
|
|
359
|
+
return await handle.readFile();
|
|
360
|
+
}
|
|
361
|
+
finally {
|
|
362
|
+
await handle.close();
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
async function detectSupportedImageMimeTypeFromFile(resolvedPath) {
|
|
366
|
+
const handle = await openSecure(resolvedPath, "r");
|
|
367
|
+
try {
|
|
368
|
+
const header = Buffer.alloc(16);
|
|
369
|
+
const { bytesRead } = await handle.read(header, 0, header.length, 0);
|
|
370
|
+
if (bytesRead === 0) {
|
|
371
|
+
return null;
|
|
372
|
+
}
|
|
373
|
+
return detectSupportedImageMimeTypeFromHeader(header.subarray(0, bytesRead));
|
|
374
|
+
}
|
|
375
|
+
finally {
|
|
376
|
+
await handle.close();
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
function detectSupportedImageMimeTypeFromHeader(header) {
|
|
380
|
+
if (header.length >= 3 && header[0] === 0xff && header[1] === 0xd8 && header[2] === 0xff) {
|
|
381
|
+
return "image/jpeg";
|
|
382
|
+
}
|
|
383
|
+
if (header.length >= 8 &&
|
|
384
|
+
header[0] === 0x89 &&
|
|
385
|
+
header[1] === 0x50 &&
|
|
386
|
+
header[2] === 0x4e &&
|
|
387
|
+
header[3] === 0x47 &&
|
|
388
|
+
header[4] === 0x0d &&
|
|
389
|
+
header[5] === 0x0a &&
|
|
390
|
+
header[6] === 0x1a &&
|
|
391
|
+
header[7] === 0x0a) {
|
|
392
|
+
return "image/png";
|
|
393
|
+
}
|
|
394
|
+
if (header.length >= 6) {
|
|
395
|
+
const signature = header.subarray(0, 6).toString("ascii");
|
|
396
|
+
if (signature === "GIF87a" || signature === "GIF89a") {
|
|
397
|
+
return "image/gif";
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
if (header.length >= 12 &&
|
|
401
|
+
header.subarray(0, 4).toString("ascii") === "RIFF" &&
|
|
402
|
+
header.subarray(8, 12).toString("ascii") === "WEBP") {
|
|
403
|
+
return "image/webp";
|
|
404
|
+
}
|
|
405
|
+
return null;
|
|
406
|
+
}
|
|
407
|
+
function sandboxSizeFormat(bytes) {
|
|
408
|
+
if (bytes < 1024) {
|
|
409
|
+
return `${bytes}B`;
|
|
410
|
+
}
|
|
411
|
+
if (bytes < 1024 * 1024) {
|
|
412
|
+
return `${(bytes / 1024).toFixed(1)}KB`;
|
|
413
|
+
}
|
|
414
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
415
|
+
}
|
|
416
|
+
function truncateHead(content) {
|
|
417
|
+
const lines = content.split("\n");
|
|
418
|
+
const totalLines = lines.length;
|
|
419
|
+
const totalBytes = Buffer.byteLength(content, "utf8");
|
|
420
|
+
if (totalLines <= READ_MAX_LINES && totalBytes <= READ_MAX_BYTES) {
|
|
421
|
+
return {
|
|
422
|
+
content,
|
|
423
|
+
truncated: false,
|
|
424
|
+
truncatedBy: null,
|
|
425
|
+
totalLines,
|
|
426
|
+
outputLines: totalLines,
|
|
427
|
+
firstLineExceedsLimit: false
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
const firstLineBytes = Buffer.byteLength(lines[0] ?? "", "utf8");
|
|
431
|
+
if (firstLineBytes > READ_MAX_BYTES) {
|
|
432
|
+
return {
|
|
433
|
+
content: "",
|
|
434
|
+
truncated: true,
|
|
435
|
+
truncatedBy: "bytes",
|
|
436
|
+
totalLines,
|
|
437
|
+
outputLines: 0,
|
|
438
|
+
firstLineExceedsLimit: true
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
const outputLines = [];
|
|
442
|
+
let outputBytes = 0;
|
|
443
|
+
let truncatedBy = "lines";
|
|
444
|
+
for (let index = 0; index < lines.length && index < READ_MAX_LINES; index += 1) {
|
|
445
|
+
const line = lines[index] ?? "";
|
|
446
|
+
const lineBytes = Buffer.byteLength(line, "utf8") + (index > 0 ? 1 : 0);
|
|
447
|
+
if (outputBytes + lineBytes > READ_MAX_BYTES) {
|
|
448
|
+
truncatedBy = "bytes";
|
|
449
|
+
break;
|
|
450
|
+
}
|
|
451
|
+
outputLines.push(line);
|
|
452
|
+
outputBytes += lineBytes;
|
|
453
|
+
}
|
|
454
|
+
if (outputLines.length >= READ_MAX_LINES && outputBytes <= READ_MAX_BYTES) {
|
|
455
|
+
truncatedBy = "lines";
|
|
456
|
+
}
|
|
457
|
+
return {
|
|
458
|
+
content: outputLines.join("\n"),
|
|
459
|
+
truncated: true,
|
|
460
|
+
truncatedBy,
|
|
461
|
+
totalLines,
|
|
462
|
+
outputLines: outputLines.length,
|
|
463
|
+
firstLineExceedsLimit: false
|
|
464
|
+
};
|
|
465
|
+
}
|
|
466
|
+
//# sourceMappingURL=sandbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../sources/sandbox/sandbox.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox.spec.d.ts","sourceRoot":"","sources":["../../sources/sandbox/sandbox.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import { promises as fs } from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
5
|
+
import { Sandbox } from "./sandbox.js";
|
|
6
|
+
const itIfSandbox = process.env.CI ? it.skip : it;
|
|
7
|
+
describe("Sandbox", () => {
|
|
8
|
+
let rootDir;
|
|
9
|
+
let homeDir;
|
|
10
|
+
let workingDir;
|
|
11
|
+
let writeDir;
|
|
12
|
+
let outsideDir;
|
|
13
|
+
let permissions;
|
|
14
|
+
let sandbox;
|
|
15
|
+
beforeEach(async () => {
|
|
16
|
+
rootDir = await fs.mkdtemp(path.join(os.tmpdir(), "daycare-sandbox-"));
|
|
17
|
+
homeDir = path.join(rootDir, "home");
|
|
18
|
+
workingDir = path.join(homeDir, "desktop");
|
|
19
|
+
writeDir = path.join(homeDir, "documents");
|
|
20
|
+
outsideDir = path.join(rootDir, "outside");
|
|
21
|
+
await fs.mkdir(workingDir, { recursive: true });
|
|
22
|
+
await fs.mkdir(writeDir, { recursive: true });
|
|
23
|
+
await fs.mkdir(outsideDir, { recursive: true });
|
|
24
|
+
permissions = {
|
|
25
|
+
workingDir,
|
|
26
|
+
writeDirs: [homeDir]
|
|
27
|
+
};
|
|
28
|
+
sandbox = new Sandbox({
|
|
29
|
+
homeDir,
|
|
30
|
+
permissions
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
afterEach(async () => {
|
|
34
|
+
await fs.rm(rootDir, { recursive: true, force: true });
|
|
35
|
+
});
|
|
36
|
+
it("stores homeDir and resolves workingDir from permissions", () => {
|
|
37
|
+
expect(sandbox.homeDir).toBe(path.resolve(homeDir));
|
|
38
|
+
expect(sandbox.workingDir).toBe(path.resolve(workingDir));
|
|
39
|
+
expect(sandbox.permissions).toBe(permissions);
|
|
40
|
+
});
|
|
41
|
+
it("uses workingDir from permissions only", () => {
|
|
42
|
+
const fromPermissions = new Sandbox({
|
|
43
|
+
homeDir,
|
|
44
|
+
permissions: {
|
|
45
|
+
...permissions,
|
|
46
|
+
workingDir: writeDir
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
expect(fromPermissions.workingDir).toBe(path.resolve(writeDir));
|
|
50
|
+
});
|
|
51
|
+
it("reads text with pagination", async () => {
|
|
52
|
+
const filePath = path.join(workingDir, "notes.txt");
|
|
53
|
+
await fs.writeFile(filePath, "line-1\nline-2\nline-3", "utf8");
|
|
54
|
+
const firstRead = await sandbox.read({ path: filePath, limit: 2 });
|
|
55
|
+
expect(firstRead.type).toBe("text");
|
|
56
|
+
if (firstRead.type !== "text") {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
expect(firstRead.content).toContain("line-1\nline-2");
|
|
60
|
+
expect(firstRead.content).toContain("Use offset=3 to continue.");
|
|
61
|
+
expect(firstRead.truncated).toBe(false);
|
|
62
|
+
const secondRead = await sandbox.read({ path: filePath, offset: 3, limit: 1 });
|
|
63
|
+
if (secondRead.type !== "text") {
|
|
64
|
+
throw new Error("Expected text read result.");
|
|
65
|
+
}
|
|
66
|
+
expect(secondRead.content).toContain("line-3");
|
|
67
|
+
});
|
|
68
|
+
it("reads image files as binary image payloads", async () => {
|
|
69
|
+
const imagePath = path.join(workingDir, "image.png");
|
|
70
|
+
const oneByOnePngBase64 = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO5L5f8AAAAASUVORK5CYII=";
|
|
71
|
+
await fs.writeFile(imagePath, Buffer.from(oneByOnePngBase64, "base64"));
|
|
72
|
+
const read = await sandbox.read({ path: imagePath });
|
|
73
|
+
expect(read.type).toBe("image");
|
|
74
|
+
if (read.type !== "image") {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
expect(read.mimeType).toBe("image/png");
|
|
78
|
+
expect(read.content.length).toBeGreaterThan(0);
|
|
79
|
+
});
|
|
80
|
+
it("rejects reading symbolic links", async () => {
|
|
81
|
+
const target = path.join(workingDir, "target.txt");
|
|
82
|
+
const symlink = path.join(workingDir, "link.txt");
|
|
83
|
+
await fs.writeFile(target, "data", "utf8");
|
|
84
|
+
await fs.symlink(target, symlink);
|
|
85
|
+
await expect(sandbox.read({ path: symlink })).rejects.toThrow("Cannot read symbolic link directly.");
|
|
86
|
+
});
|
|
87
|
+
it("rejects non-app access to app directories", async () => {
|
|
88
|
+
const appPath = path.join(workingDir, "apps", "my-app", "APP.md");
|
|
89
|
+
await fs.mkdir(path.dirname(appPath), { recursive: true });
|
|
90
|
+
await fs.writeFile(appPath, "app", "utf8");
|
|
91
|
+
await expect(sandbox.read({ path: appPath })).rejects.toThrow("App directories are not accessible from non-app agents.");
|
|
92
|
+
});
|
|
93
|
+
it("writes new files and creates parent directories", async () => {
|
|
94
|
+
const outputPath = path.join(writeDir, "nested", "out.txt");
|
|
95
|
+
const writeResult = await sandbox.write({
|
|
96
|
+
path: outputPath,
|
|
97
|
+
content: "hello"
|
|
98
|
+
});
|
|
99
|
+
expect(writeResult.bytes).toBe(5);
|
|
100
|
+
expect(writeResult.resolvedPath).toBe(await fs.realpath(outputPath));
|
|
101
|
+
expect(writeResult.sandboxPath).toBe("~/documents/nested/out.txt");
|
|
102
|
+
await expect(fs.readFile(outputPath, "utf8")).resolves.toBe("hello");
|
|
103
|
+
});
|
|
104
|
+
it("appends to files when append is true", async () => {
|
|
105
|
+
const outputPath = path.join(writeDir, "append.txt");
|
|
106
|
+
await fs.writeFile(outputPath, "start", "utf8");
|
|
107
|
+
await sandbox.write({
|
|
108
|
+
path: outputPath,
|
|
109
|
+
content: "-end",
|
|
110
|
+
append: true
|
|
111
|
+
});
|
|
112
|
+
await expect(fs.readFile(outputPath, "utf8")).resolves.toBe("start-end");
|
|
113
|
+
});
|
|
114
|
+
it("rejects writing outside granted directories", async () => {
|
|
115
|
+
const outputPath = path.join(outsideDir, "out.txt");
|
|
116
|
+
await expect(sandbox.write({ path: outputPath, content: "nope" })).rejects.toThrow("Path is outside the allowed directories.");
|
|
117
|
+
});
|
|
118
|
+
it("rejects writing to symbolic links", async () => {
|
|
119
|
+
const target = path.join(writeDir, "target.txt");
|
|
120
|
+
const symlink = path.join(writeDir, "link.txt");
|
|
121
|
+
await fs.writeFile(target, "data", "utf8");
|
|
122
|
+
await fs.symlink(target, symlink);
|
|
123
|
+
await expect(sandbox.write({ path: symlink, content: "overwrite" })).rejects.toThrow("Cannot write to symbolic link.");
|
|
124
|
+
});
|
|
125
|
+
it("reads binary content when binary mode is enabled", async () => {
|
|
126
|
+
const binaryPath = path.join(workingDir, "file.bin");
|
|
127
|
+
await fs.writeFile(binaryPath, Buffer.from([0, 1, 2, 3]));
|
|
128
|
+
const read = await sandbox.read({ path: binaryPath, binary: true });
|
|
129
|
+
expect(read.type).toBe("binary");
|
|
130
|
+
if (read.type !== "binary") {
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
expect(read.content.equals(Buffer.from([0, 1, 2, 3]))).toBe(true);
|
|
134
|
+
});
|
|
135
|
+
it("validates domain allowlist before execution", async () => {
|
|
136
|
+
await expect(sandbox.exec({
|
|
137
|
+
command: "echo ok"
|
|
138
|
+
})).rejects.toThrow("allowedDomains must include at least one explicit domain");
|
|
139
|
+
});
|
|
140
|
+
it("rejects wildcard domains", async () => {
|
|
141
|
+
await expect(sandbox.exec({
|
|
142
|
+
command: "echo ok",
|
|
143
|
+
allowedDomains: ["*"]
|
|
144
|
+
})).rejects.toThrow("Wildcard");
|
|
145
|
+
});
|
|
146
|
+
itIfSandbox("executes command with explicit domains", async () => {
|
|
147
|
+
const result = await sandbox.exec({
|
|
148
|
+
command: "echo ok",
|
|
149
|
+
allowedDomains: ["example.com"]
|
|
150
|
+
});
|
|
151
|
+
expect(result.failed).toBe(false);
|
|
152
|
+
expect(result.stdout).toContain("ok");
|
|
153
|
+
expect(result.exitCode).toBe(0);
|
|
154
|
+
});
|
|
155
|
+
itIfSandbox("supports cwd override", async () => {
|
|
156
|
+
const cwd = path.join(workingDir, "cwd");
|
|
157
|
+
await fs.mkdir(cwd, { recursive: true });
|
|
158
|
+
const result = await sandbox.exec({
|
|
159
|
+
command: "pwd",
|
|
160
|
+
cwd,
|
|
161
|
+
allowedDomains: ["example.com"]
|
|
162
|
+
});
|
|
163
|
+
expect(result.failed).toBe(false);
|
|
164
|
+
expect(result.cwd).toBe(cwd);
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
//# sourceMappingURL=sandbox.spec.js.map
|