zeitlich 0.2.14 → 0.2.16
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 +62 -12
- package/dist/adapters/sandbox/daytona/index.cjs +52 -23
- package/dist/adapters/sandbox/daytona/index.cjs.map +1 -1
- package/dist/adapters/sandbox/daytona/index.d.cts +10 -2
- package/dist/adapters/sandbox/daytona/index.d.ts +10 -2
- package/dist/adapters/sandbox/daytona/index.js +52 -23
- package/dist/adapters/sandbox/daytona/index.js.map +1 -1
- package/dist/adapters/sandbox/inmemory/index.cjs +21 -16
- package/dist/adapters/sandbox/inmemory/index.cjs.map +1 -1
- package/dist/adapters/sandbox/inmemory/index.d.cts +1 -1
- package/dist/adapters/sandbox/inmemory/index.d.ts +1 -1
- package/dist/adapters/sandbox/inmemory/index.js +21 -16
- package/dist/adapters/sandbox/inmemory/index.js.map +1 -1
- package/dist/adapters/sandbox/virtual/index.cjs +38 -38
- package/dist/adapters/sandbox/virtual/index.cjs.map +1 -1
- package/dist/adapters/sandbox/virtual/index.d.cts +6 -6
- package/dist/adapters/sandbox/virtual/index.d.ts +6 -6
- package/dist/adapters/sandbox/virtual/index.js +37 -37
- package/dist/adapters/sandbox/virtual/index.js.map +1 -1
- package/dist/adapters/thread/google-genai/index.cjs +22 -0
- package/dist/adapters/thread/google-genai/index.cjs.map +1 -1
- package/dist/adapters/thread/google-genai/index.d.cts +3 -3
- package/dist/adapters/thread/google-genai/index.d.ts +3 -3
- package/dist/adapters/thread/google-genai/index.js +22 -0
- package/dist/adapters/thread/google-genai/index.js.map +1 -1
- package/dist/adapters/thread/langchain/index.cjs +22 -0
- package/dist/adapters/thread/langchain/index.cjs.map +1 -1
- package/dist/adapters/thread/langchain/index.d.cts +3 -3
- package/dist/adapters/thread/langchain/index.d.ts +3 -3
- package/dist/adapters/thread/langchain/index.js +22 -0
- package/dist/adapters/thread/langchain/index.js.map +1 -1
- package/dist/index.cjs +38 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +38 -11
- package/dist/index.js.map +1 -1
- package/dist/{types-B9ljZewB.d.cts → types-35POpVfa.d.cts} +6 -0
- package/dist/{types-B9ljZewB.d.ts → types-35POpVfa.d.ts} +6 -0
- package/dist/{types-CDubRtad.d.cts → types-BMRzfELQ.d.cts} +2 -0
- package/dist/{types-CDubRtad.d.ts → types-BMRzfELQ.d.ts} +2 -0
- package/dist/{types-CwwgQ_9H.d.ts → types-BSOte_8s.d.ts} +6 -2
- package/dist/{types-BVP87m_W.d.cts → types-DCi2qXjN.d.cts} +6 -2
- package/dist/{types-GpMU4b0w.d.cts → types-Drli9aCK.d.cts} +3 -1
- package/dist/{types-B4C9txdq.d.ts → types-XPtivmSJ.d.ts} +3 -1
- package/dist/workflow.cjs +23 -11
- package/dist/workflow.cjs.map +1 -1
- package/dist/workflow.d.cts +6 -6
- package/dist/workflow.d.ts +6 -6
- package/dist/workflow.js +23 -11
- package/dist/workflow.js.map +1 -1
- package/package.json +7 -3
- package/src/adapters/sandbox/daytona/filesystem.ts +43 -19
- package/src/adapters/sandbox/daytona/index.ts +16 -3
- package/src/adapters/sandbox/daytona/types.ts +4 -0
- package/src/adapters/sandbox/inmemory/index.ts +22 -16
- package/src/adapters/sandbox/virtual/filesystem.ts +29 -31
- package/src/adapters/sandbox/virtual/index.ts +5 -3
- package/src/adapters/sandbox/virtual/provider.ts +5 -2
- package/src/adapters/sandbox/virtual/types.ts +3 -0
- package/src/adapters/sandbox/virtual/with-virtual-sandbox.ts +4 -3
- package/src/adapters/thread/google-genai/activities.ts +11 -0
- package/src/adapters/thread/langchain/activities.ts +11 -0
- package/src/lib/sandbox/tree.integration.test.ts +153 -0
- package/src/lib/sandbox/types.ts +2 -0
- package/src/lib/session/session-edge-cases.integration.test.ts +962 -0
- package/src/lib/session/session.integration.test.ts +852 -0
- package/src/lib/session/session.ts +11 -5
- package/src/lib/session/types.ts +2 -0
- package/src/lib/skills/skills.integration.test.ts +308 -0
- package/src/lib/state/manager.integration.test.ts +342 -0
- package/src/lib/subagent/register.ts +22 -7
- package/src/lib/subagent/subagent.integration.test.ts +467 -0
- package/src/lib/thread/id.test.ts +50 -0
- package/src/lib/thread/manager.ts +20 -1
- package/src/lib/thread/types.ts +6 -0
- package/src/lib/tool-router/auto-append-sandbox.integration.test.ts +344 -0
- package/src/lib/tool-router/router-edge-cases.integration.test.ts +623 -0
- package/src/lib/tool-router/router.integration.test.ts +699 -0
- package/src/lib/types.test.ts +29 -0
|
@@ -18,42 +18,53 @@ var SandboxNotFoundError = class extends ApplicationFailure {
|
|
|
18
18
|
}
|
|
19
19
|
};
|
|
20
20
|
var DaytonaSandboxFileSystem = class {
|
|
21
|
-
constructor(sandbox) {
|
|
21
|
+
constructor(sandbox, workspaceBase = "/home/daytona") {
|
|
22
22
|
this.sandbox = sandbox;
|
|
23
|
+
this.workspaceBase = posix.resolve("/", workspaceBase);
|
|
24
|
+
}
|
|
25
|
+
workspaceBase;
|
|
26
|
+
normalisePath(path) {
|
|
27
|
+
return posix.resolve(this.workspaceBase, path);
|
|
23
28
|
}
|
|
24
29
|
async readFile(path) {
|
|
25
|
-
const
|
|
30
|
+
const norm = this.normalisePath(path);
|
|
31
|
+
const buf = await this.sandbox.fs.downloadFile(norm);
|
|
26
32
|
return buf.toString("utf-8");
|
|
27
33
|
}
|
|
28
34
|
async readFileBuffer(path) {
|
|
29
|
-
const
|
|
35
|
+
const norm = this.normalisePath(path);
|
|
36
|
+
const buf = await this.sandbox.fs.downloadFile(norm);
|
|
30
37
|
return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
|
|
31
38
|
}
|
|
32
39
|
async writeFile(path, content) {
|
|
40
|
+
const norm = this.normalisePath(path);
|
|
33
41
|
const buf = typeof content === "string" ? Buffer.from(content, "utf-8") : Buffer.from(content);
|
|
34
|
-
await this.sandbox.fs.uploadFile(buf,
|
|
42
|
+
await this.sandbox.fs.uploadFile(buf, norm);
|
|
35
43
|
}
|
|
36
44
|
async appendFile(path, content) {
|
|
45
|
+
const norm = this.normalisePath(path);
|
|
37
46
|
let existing;
|
|
38
47
|
try {
|
|
39
|
-
existing = await this.sandbox.fs.downloadFile(
|
|
48
|
+
existing = await this.sandbox.fs.downloadFile(norm);
|
|
40
49
|
} catch {
|
|
41
|
-
return this.writeFile(
|
|
50
|
+
return this.writeFile(norm, content);
|
|
42
51
|
}
|
|
43
52
|
const addition = typeof content === "string" ? Buffer.from(content, "utf-8") : content;
|
|
44
53
|
const merged = Buffer.concat([existing, Buffer.from(addition)]);
|
|
45
|
-
await this.sandbox.fs.uploadFile(merged,
|
|
54
|
+
await this.sandbox.fs.uploadFile(merged, norm);
|
|
46
55
|
}
|
|
47
56
|
async exists(path) {
|
|
57
|
+
const norm = this.normalisePath(path);
|
|
48
58
|
try {
|
|
49
|
-
await this.sandbox.fs.getFileDetails(
|
|
59
|
+
await this.sandbox.fs.getFileDetails(norm);
|
|
50
60
|
return true;
|
|
51
61
|
} catch {
|
|
52
62
|
return false;
|
|
53
63
|
}
|
|
54
64
|
}
|
|
55
65
|
async stat(path) {
|
|
56
|
-
const
|
|
66
|
+
const norm = this.normalisePath(path);
|
|
67
|
+
const info = await this.sandbox.fs.getFileDetails(norm);
|
|
57
68
|
return {
|
|
58
69
|
isFile: !info.isDir,
|
|
59
70
|
isDirectory: info.isDir,
|
|
@@ -63,14 +74,17 @@ var DaytonaSandboxFileSystem = class {
|
|
|
63
74
|
};
|
|
64
75
|
}
|
|
65
76
|
async mkdir(path, _options) {
|
|
66
|
-
|
|
77
|
+
const norm = this.normalisePath(path);
|
|
78
|
+
await this.sandbox.fs.createFolder(norm, "755");
|
|
67
79
|
}
|
|
68
80
|
async readdir(path) {
|
|
69
|
-
const
|
|
81
|
+
const norm = this.normalisePath(path);
|
|
82
|
+
const entries = await this.sandbox.fs.listFiles(norm);
|
|
70
83
|
return entries.map((e) => e.name);
|
|
71
84
|
}
|
|
72
85
|
async readdirWithFileTypes(path) {
|
|
73
|
-
const
|
|
86
|
+
const norm = this.normalisePath(path);
|
|
87
|
+
const entries = await this.sandbox.fs.listFiles(norm);
|
|
74
88
|
return entries.map((e) => ({
|
|
75
89
|
name: e.name,
|
|
76
90
|
isFile: !e.isDir,
|
|
@@ -79,41 +93,45 @@ var DaytonaSandboxFileSystem = class {
|
|
|
79
93
|
}));
|
|
80
94
|
}
|
|
81
95
|
async rm(path, options) {
|
|
96
|
+
const norm = this.normalisePath(path);
|
|
82
97
|
try {
|
|
83
|
-
await this.sandbox.fs.deleteFile(
|
|
98
|
+
await this.sandbox.fs.deleteFile(norm, options?.recursive);
|
|
84
99
|
} catch (err) {
|
|
85
100
|
if (!options?.force) throw err;
|
|
86
101
|
}
|
|
87
102
|
}
|
|
88
103
|
async cp(src, dest, options) {
|
|
89
|
-
const
|
|
104
|
+
const normSrc = this.normalisePath(src);
|
|
105
|
+
const normDest = this.normalisePath(dest);
|
|
106
|
+
const info = await this.sandbox.fs.getFileDetails(normSrc);
|
|
90
107
|
if (info.isDir) {
|
|
91
108
|
if (!options?.recursive) {
|
|
92
109
|
throw new Error(`EISDIR: is a directory (use recursive): ${src}`);
|
|
93
110
|
}
|
|
94
|
-
await this.sandbox.process.executeCommand(`cp -r "${
|
|
111
|
+
await this.sandbox.process.executeCommand(`cp -r "${normSrc}" "${normDest}"`);
|
|
95
112
|
} else {
|
|
96
|
-
await this.sandbox.process.executeCommand(`cp "${
|
|
113
|
+
await this.sandbox.process.executeCommand(`cp "${normSrc}" "${normDest}"`);
|
|
97
114
|
}
|
|
98
115
|
}
|
|
99
116
|
async mv(src, dest) {
|
|
100
|
-
|
|
117
|
+
const normSrc = this.normalisePath(src);
|
|
118
|
+
const normDest = this.normalisePath(dest);
|
|
119
|
+
await this.sandbox.fs.moveFiles(normSrc, normDest);
|
|
101
120
|
}
|
|
102
121
|
async readlink(_path) {
|
|
103
122
|
throw new SandboxNotSupportedError("readlink");
|
|
104
123
|
}
|
|
105
124
|
resolvePath(base, path) {
|
|
106
|
-
|
|
107
|
-
return posix.resolve(base, path);
|
|
125
|
+
return posix.resolve(this.normalisePath(base), path);
|
|
108
126
|
}
|
|
109
127
|
};
|
|
110
128
|
|
|
111
129
|
// src/adapters/sandbox/daytona/index.ts
|
|
112
130
|
var DaytonaSandboxImpl = class {
|
|
113
|
-
constructor(id, sdkSandbox) {
|
|
131
|
+
constructor(id, sdkSandbox, workspaceBase = "/home/daytona") {
|
|
114
132
|
this.id = id;
|
|
115
133
|
this.sdkSandbox = sdkSandbox;
|
|
116
|
-
this.fs = new DaytonaSandboxFileSystem(sdkSandbox);
|
|
134
|
+
this.fs = new DaytonaSandboxFileSystem(sdkSandbox, workspaceBase);
|
|
117
135
|
}
|
|
118
136
|
capabilities = {
|
|
119
137
|
filesystem: true,
|
|
@@ -146,8 +164,11 @@ var DaytonaSandboxProvider = class {
|
|
|
146
164
|
persistence: false
|
|
147
165
|
};
|
|
148
166
|
client;
|
|
167
|
+
defaultWorkspaceBase;
|
|
168
|
+
workspaceBaseById = /* @__PURE__ */ new Map();
|
|
149
169
|
constructor(config) {
|
|
150
170
|
this.client = new Daytona(config);
|
|
171
|
+
this.defaultWorkspaceBase = config?.workspaceBase ?? "/home/daytona";
|
|
151
172
|
}
|
|
152
173
|
async create(options) {
|
|
153
174
|
const sdkSandbox = await this.client.create(
|
|
@@ -162,7 +183,13 @@ var DaytonaSandboxProvider = class {
|
|
|
162
183
|
},
|
|
163
184
|
{ timeout: options?.timeout ?? 60 }
|
|
164
185
|
);
|
|
165
|
-
const
|
|
186
|
+
const workspaceBase = options?.workspaceBase ?? this.defaultWorkspaceBase;
|
|
187
|
+
this.workspaceBaseById.set(sdkSandbox.id, workspaceBase);
|
|
188
|
+
const sandbox = new DaytonaSandboxImpl(
|
|
189
|
+
sdkSandbox.id,
|
|
190
|
+
sdkSandbox,
|
|
191
|
+
workspaceBase
|
|
192
|
+
);
|
|
166
193
|
if (options?.initialFiles) {
|
|
167
194
|
for (const [path, content] of Object.entries(options.initialFiles)) {
|
|
168
195
|
await sandbox.fs.writeFile(path, content);
|
|
@@ -173,7 +200,8 @@ var DaytonaSandboxProvider = class {
|
|
|
173
200
|
async get(sandboxId) {
|
|
174
201
|
try {
|
|
175
202
|
const sdkSandbox = await this.client.get(sandboxId);
|
|
176
|
-
|
|
203
|
+
const workspaceBase = this.workspaceBaseById.get(sandboxId) ?? this.defaultWorkspaceBase;
|
|
204
|
+
return new DaytonaSandboxImpl(sdkSandbox.id, sdkSandbox, workspaceBase);
|
|
177
205
|
} catch {
|
|
178
206
|
throw new SandboxNotFoundError(sandboxId);
|
|
179
207
|
}
|
|
@@ -182,6 +210,7 @@ var DaytonaSandboxProvider = class {
|
|
|
182
210
|
try {
|
|
183
211
|
const sdkSandbox = await this.client.get(sandboxId);
|
|
184
212
|
await this.client.delete(sdkSandbox);
|
|
213
|
+
this.workspaceBaseById.delete(sandboxId);
|
|
185
214
|
} catch {
|
|
186
215
|
}
|
|
187
216
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/sandbox/types.ts","../../../../src/adapters/sandbox/daytona/filesystem.ts","../../../../src/adapters/sandbox/daytona/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["// ============================================================================\n// Sandbox Filesystem\n// ============================================================================\n\nexport interface DirentEntry {\n name: string;\n isFile: boolean;\n isDirectory: boolean;\n isSymbolicLink: boolean;\n}\n\nexport interface FileStat {\n isFile: boolean;\n isDirectory: boolean;\n isSymbolicLink: boolean;\n size: number;\n mtime: Date;\n}\n\n/**\n * Provider-agnostic filesystem interface.\n *\n * Implementations that don't support a method should throw\n * {@link SandboxNotSupportedError}.\n */\nexport interface SandboxFileSystem {\n readFile(path: string): Promise<string>;\n readFileBuffer(path: string): Promise<Uint8Array>;\n writeFile(path: string, content: string | Uint8Array): Promise<void>;\n appendFile(path: string, content: string | Uint8Array): Promise<void>;\n exists(path: string): Promise<boolean>;\n stat(path: string): Promise<FileStat>;\n mkdir(path: string, options?: { recursive?: boolean }): Promise<void>;\n readdir(path: string): Promise<string[]>;\n readdirWithFileTypes(path: string): Promise<DirentEntry[]>;\n rm(path: string, options?: { recursive?: boolean; force?: boolean }): Promise<void>;\n cp(src: string, dest: string, options?: { recursive?: boolean }): Promise<void>;\n mv(src: string, dest: string): Promise<void>;\n readlink(path: string): Promise<string>;\n resolvePath(base: string, path: string): string;\n}\n\n// ============================================================================\n// Execution\n// ============================================================================\n\nexport interface ExecOptions {\n timeout?: number;\n cwd?: string;\n env?: Record<string, string>;\n}\n\nexport interface ExecResult {\n exitCode: number;\n stdout: string;\n stderr: string;\n}\n\n// ============================================================================\n// Capabilities\n// ============================================================================\n\nexport interface SandboxCapabilities {\n /** Sandbox supports filesystem operations */\n filesystem: boolean;\n /** Sandbox supports shell/command execution */\n execution: boolean;\n /** Sandbox state can be persisted and restored */\n persistence: boolean;\n}\n\n// ============================================================================\n// Sandbox\n// ============================================================================\n\nexport interface Sandbox {\n readonly id: string;\n readonly capabilities: SandboxCapabilities;\n readonly fs: SandboxFileSystem;\n\n exec(command: string, options?: ExecOptions): Promise<ExecResult>;\n destroy(): Promise<void>;\n}\n\n// ============================================================================\n// Snapshots\n// ============================================================================\n\nexport interface SandboxSnapshot {\n sandboxId: string;\n providerId: string;\n /** Provider-specific serialised state */\n data: unknown;\n createdAt: string;\n}\n\n// ============================================================================\n// Provider\n// ============================================================================\n\nexport interface SandboxCreateOptions {\n /** Preferred sandbox ID (provider may ignore) */\n id?: string;\n /** Seed the filesystem with these files */\n initialFiles?: Record<string, string | Uint8Array>;\n /** Environment variables available inside the sandbox */\n env?: Record<string, string>;\n}\n\nexport interface SandboxCreateResult {\n sandbox: Sandbox;\n /** Optional state to merge into the workflow's `AgentState` via the session. */\n stateUpdate?: Record<string, unknown>;\n}\n\nexport interface SandboxProvider<\n TOptions extends SandboxCreateOptions = SandboxCreateOptions,\n TSandbox extends Sandbox = Sandbox,\n> {\n readonly id: string;\n readonly capabilities: SandboxCapabilities;\n\n create(options?: TOptions): Promise<SandboxCreateResult>;\n get(sandboxId: string): Promise<TSandbox>;\n destroy(sandboxId: string): Promise<void>;\n snapshot(sandboxId: string): Promise<SandboxSnapshot>;\n restore(snapshot: SandboxSnapshot): Promise<Sandbox>;\n}\n\n// ============================================================================\n// SandboxOps — workflow-side activity interface (like ThreadOps)\n// ============================================================================\n\nexport interface SandboxOps<\n TOptions extends SandboxCreateOptions = SandboxCreateOptions,\n> {\n createSandbox(\n options?: TOptions,\n ): Promise<{ sandboxId: string; stateUpdate?: Record<string, unknown> }>;\n destroySandbox(sandboxId: string): Promise<void>;\n snapshotSandbox(sandboxId: string): Promise<SandboxSnapshot>;\n}\n\n// ============================================================================\n// Errors\n// ============================================================================\n\nimport { ApplicationFailure } from \"@temporalio/common\";\n\nexport class SandboxNotSupportedError extends ApplicationFailure {\n constructor(operation: string) {\n super(\n `Sandbox does not support: ${operation}`,\n \"SandboxNotSupportedError\",\n true,\n );\n }\n}\n\nexport class SandboxNotFoundError extends ApplicationFailure {\n constructor(sandboxId: string) {\n super(`Sandbox not found: ${sandboxId}`, \"SandboxNotFoundError\", true);\n }\n}\n","import type { Sandbox as DaytonaSdkSandbox } from \"@daytonaio/sdk\";\nimport type {\n SandboxFileSystem,\n DirentEntry,\n FileStat,\n} from \"../../../lib/sandbox/types\";\nimport { SandboxNotSupportedError } from \"../../../lib/sandbox/types\";\nimport { posix } from \"node:path\";\n\n/**\n * {@link SandboxFileSystem} backed by a Daytona SDK sandbox.\n *\n * Maps zeitlich's filesystem interface to Daytona's `sandbox.fs` and\n * `sandbox.process` APIs. Operations that have no direct Daytona equivalent\n * (e.g. `appendFile`, `cp`) are composed from primitives.\n */\nexport class DaytonaSandboxFileSystem implements SandboxFileSystem {\n constructor(private sandbox: DaytonaSdkSandbox) {}\n\n async readFile(path: string): Promise<string> {\n const buf = await this.sandbox.fs.downloadFile(path);\n return buf.toString(\"utf-8\");\n }\n\n async readFileBuffer(path: string): Promise<Uint8Array> {\n const buf = await this.sandbox.fs.downloadFile(path);\n return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);\n }\n\n async writeFile(path: string, content: string | Uint8Array): Promise<void> {\n const buf =\n typeof content === \"string\"\n ? Buffer.from(content, \"utf-8\")\n : Buffer.from(content);\n await this.sandbox.fs.uploadFile(buf, path);\n }\n\n async appendFile(\n path: string,\n content: string | Uint8Array,\n ): Promise<void> {\n let existing: Buffer;\n try {\n existing = await this.sandbox.fs.downloadFile(path);\n } catch {\n return this.writeFile(path, content);\n }\n\n const addition =\n typeof content === \"string\" ? Buffer.from(content, \"utf-8\") : content;\n const merged = Buffer.concat([existing, Buffer.from(addition)]);\n await this.sandbox.fs.uploadFile(merged, path);\n }\n\n async exists(path: string): Promise<boolean> {\n try {\n await this.sandbox.fs.getFileDetails(path);\n return true;\n } catch {\n return false;\n }\n }\n\n async stat(path: string): Promise<FileStat> {\n const info = await this.sandbox.fs.getFileDetails(path);\n return {\n isFile: !info.isDir,\n isDirectory: info.isDir,\n isSymbolicLink: false,\n size: info.size,\n mtime: new Date(info.modTime),\n };\n }\n\n async mkdir(\n path: string,\n _options?: { recursive?: boolean },\n ): Promise<void> {\n await this.sandbox.fs.createFolder(path, \"755\");\n }\n\n async readdir(path: string): Promise<string[]> {\n const entries = await this.sandbox.fs.listFiles(path);\n return entries.map((e) => e.name);\n }\n\n async readdirWithFileTypes(path: string): Promise<DirentEntry[]> {\n const entries = await this.sandbox.fs.listFiles(path);\n return entries.map((e) => ({\n name: e.name,\n isFile: !e.isDir,\n isDirectory: e.isDir,\n isSymbolicLink: false,\n }));\n }\n\n async rm(\n path: string,\n options?: { recursive?: boolean; force?: boolean },\n ): Promise<void> {\n try {\n await this.sandbox.fs.deleteFile(path, options?.recursive);\n } catch (err) {\n if (!options?.force) throw err;\n }\n }\n\n async cp(\n src: string,\n dest: string,\n options?: { recursive?: boolean },\n ): Promise<void> {\n const info = await this.sandbox.fs.getFileDetails(src);\n if (info.isDir) {\n if (!options?.recursive) {\n throw new Error(`EISDIR: is a directory (use recursive): ${src}`);\n }\n await this.sandbox.process.executeCommand(`cp -r \"${src}\" \"${dest}\"`);\n } else {\n await this.sandbox.process.executeCommand(`cp \"${src}\" \"${dest}\"`);\n }\n }\n\n async mv(src: string, dest: string): Promise<void> {\n await this.sandbox.fs.moveFiles(src, dest);\n }\n\n async readlink(_path: string): Promise<string> {\n throw new SandboxNotSupportedError(\"readlink\");\n }\n\n resolvePath(base: string, path: string): string {\n if (posix.isAbsolute(path)) return posix.normalize(path);\n return posix.resolve(base, path);\n }\n}\n","import {\n Daytona,\n type Sandbox as DaytonaSdkSandbox,\n} from \"@daytonaio/sdk\";\nimport type {\n Sandbox,\n SandboxCapabilities,\n SandboxCreateResult,\n SandboxProvider,\n SandboxSnapshot,\n ExecOptions,\n ExecResult,\n} from \"../../../lib/sandbox/types\";\nimport {\n SandboxNotFoundError,\n SandboxNotSupportedError,\n} from \"../../../lib/sandbox/types\";\nimport { DaytonaSandboxFileSystem } from \"./filesystem\";\nimport type {\n DaytonaSandbox,\n DaytonaSandboxConfig,\n DaytonaSandboxCreateOptions,\n} from \"./types\";\n\n// ============================================================================\n// DaytonaSandbox\n// ============================================================================\n\nclass DaytonaSandboxImpl implements Sandbox {\n readonly capabilities: SandboxCapabilities = {\n filesystem: true,\n execution: true,\n persistence: false,\n };\n\n readonly fs: DaytonaSandboxFileSystem;\n\n constructor(\n readonly id: string,\n private sdkSandbox: DaytonaSdkSandbox,\n ) {\n this.fs = new DaytonaSandboxFileSystem(sdkSandbox);\n }\n\n async exec(command: string, options?: ExecOptions): Promise<ExecResult> {\n const response = await this.sdkSandbox.process.executeCommand(\n command,\n options?.cwd,\n options?.env,\n options?.timeout,\n );\n\n return {\n exitCode: response.exitCode ?? 0,\n stdout: response.result ?? \"\",\n stderr: \"\",\n };\n }\n\n async destroy(): Promise<void> {\n await this.sdkSandbox.delete(60);\n }\n}\n\n// ============================================================================\n// DaytonaSandboxProvider\n// ============================================================================\n\nexport class DaytonaSandboxProvider\n implements SandboxProvider<DaytonaSandboxCreateOptions, DaytonaSandbox>\n{\n readonly id = \"daytona\";\n readonly capabilities: SandboxCapabilities = {\n filesystem: true,\n execution: true,\n persistence: false,\n };\n\n private client: Daytona;\n\n constructor(config?: DaytonaSandboxConfig) {\n this.client = new Daytona(config);\n }\n\n async create(\n options?: DaytonaSandboxCreateOptions,\n ): Promise<SandboxCreateResult> {\n const sdkSandbox = await this.client.create(\n {\n language: options?.language,\n snapshot: options?.snapshot,\n envVars: options?.env,\n labels: options?.labels,\n autoStopInterval: options?.autoStopInterval,\n autoArchiveInterval: options?.autoArchiveInterval,\n autoDeleteInterval: options?.autoDeleteInterval,\n },\n { timeout: options?.timeout ?? 60 },\n );\n\n const sandbox = new DaytonaSandboxImpl(sdkSandbox.id, sdkSandbox);\n\n if (options?.initialFiles) {\n for (const [path, content] of Object.entries(options.initialFiles)) {\n await sandbox.fs.writeFile(path, content);\n }\n }\n\n return { sandbox };\n }\n\n async get(sandboxId: string): Promise<DaytonaSandbox> {\n try {\n const sdkSandbox = await this.client.get(sandboxId);\n return new DaytonaSandboxImpl(sdkSandbox.id, sdkSandbox);\n } catch {\n throw new SandboxNotFoundError(sandboxId);\n }\n }\n\n async destroy(sandboxId: string): Promise<void> {\n try {\n const sdkSandbox = await this.client.get(sandboxId);\n await this.client.delete(sdkSandbox);\n } catch {\n // Already gone\n }\n }\n\n async snapshot(_sandboxId: string): Promise<SandboxSnapshot> {\n throw new SandboxNotSupportedError(\n \"snapshot (use Daytona's native snapshot API directly)\",\n );\n }\n\n async restore(_snapshot: SandboxSnapshot): Promise<never> {\n throw new SandboxNotSupportedError(\n \"restore (use Daytona's native snapshot API directly)\",\n );\n }\n}\n\n// Re-exports\nexport { DaytonaSandboxFileSystem } from \"./filesystem\";\nexport type {\n DaytonaSandbox,\n DaytonaSandboxConfig,\n DaytonaSandboxCreateOptions,\n} from \"./types\";\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/sandbox/types.ts","../../../../src/adapters/sandbox/daytona/filesystem.ts","../../../../src/adapters/sandbox/daytona/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["// ============================================================================\n// Sandbox Filesystem\n// ============================================================================\n\nexport interface DirentEntry {\n name: string;\n isFile: boolean;\n isDirectory: boolean;\n isSymbolicLink: boolean;\n}\n\nexport interface FileStat {\n isFile: boolean;\n isDirectory: boolean;\n isSymbolicLink: boolean;\n size: number;\n mtime: Date;\n}\n\n/**\n * Provider-agnostic filesystem interface.\n *\n * Implementations that don't support a method should throw\n * {@link SandboxNotSupportedError}.\n */\nexport interface SandboxFileSystem {\n /** Base directory used when resolving relative paths. */\n readonly workspaceBase: string;\n readFile(path: string): Promise<string>;\n readFileBuffer(path: string): Promise<Uint8Array>;\n writeFile(path: string, content: string | Uint8Array): Promise<void>;\n appendFile(path: string, content: string | Uint8Array): Promise<void>;\n exists(path: string): Promise<boolean>;\n stat(path: string): Promise<FileStat>;\n mkdir(path: string, options?: { recursive?: boolean }): Promise<void>;\n readdir(path: string): Promise<string[]>;\n readdirWithFileTypes(path: string): Promise<DirentEntry[]>;\n rm(path: string, options?: { recursive?: boolean; force?: boolean }): Promise<void>;\n cp(src: string, dest: string, options?: { recursive?: boolean }): Promise<void>;\n mv(src: string, dest: string): Promise<void>;\n readlink(path: string): Promise<string>;\n resolvePath(base: string, path: string): string;\n}\n\n// ============================================================================\n// Execution\n// ============================================================================\n\nexport interface ExecOptions {\n timeout?: number;\n cwd?: string;\n env?: Record<string, string>;\n}\n\nexport interface ExecResult {\n exitCode: number;\n stdout: string;\n stderr: string;\n}\n\n// ============================================================================\n// Capabilities\n// ============================================================================\n\nexport interface SandboxCapabilities {\n /** Sandbox supports filesystem operations */\n filesystem: boolean;\n /** Sandbox supports shell/command execution */\n execution: boolean;\n /** Sandbox state can be persisted and restored */\n persistence: boolean;\n}\n\n// ============================================================================\n// Sandbox\n// ============================================================================\n\nexport interface Sandbox {\n readonly id: string;\n readonly capabilities: SandboxCapabilities;\n readonly fs: SandboxFileSystem;\n\n exec(command: string, options?: ExecOptions): Promise<ExecResult>;\n destroy(): Promise<void>;\n}\n\n// ============================================================================\n// Snapshots\n// ============================================================================\n\nexport interface SandboxSnapshot {\n sandboxId: string;\n providerId: string;\n /** Provider-specific serialised state */\n data: unknown;\n createdAt: string;\n}\n\n// ============================================================================\n// Provider\n// ============================================================================\n\nexport interface SandboxCreateOptions {\n /** Preferred sandbox ID (provider may ignore) */\n id?: string;\n /** Seed the filesystem with these files */\n initialFiles?: Record<string, string | Uint8Array>;\n /** Environment variables available inside the sandbox */\n env?: Record<string, string>;\n}\n\nexport interface SandboxCreateResult {\n sandbox: Sandbox;\n /** Optional state to merge into the workflow's `AgentState` via the session. */\n stateUpdate?: Record<string, unknown>;\n}\n\nexport interface SandboxProvider<\n TOptions extends SandboxCreateOptions = SandboxCreateOptions,\n TSandbox extends Sandbox = Sandbox,\n> {\n readonly id: string;\n readonly capabilities: SandboxCapabilities;\n\n create(options?: TOptions): Promise<SandboxCreateResult>;\n get(sandboxId: string): Promise<TSandbox>;\n destroy(sandboxId: string): Promise<void>;\n snapshot(sandboxId: string): Promise<SandboxSnapshot>;\n restore(snapshot: SandboxSnapshot): Promise<Sandbox>;\n}\n\n// ============================================================================\n// SandboxOps — workflow-side activity interface (like ThreadOps)\n// ============================================================================\n\nexport interface SandboxOps<\n TOptions extends SandboxCreateOptions = SandboxCreateOptions,\n> {\n createSandbox(\n options?: TOptions,\n ): Promise<{ sandboxId: string; stateUpdate?: Record<string, unknown> }>;\n destroySandbox(sandboxId: string): Promise<void>;\n snapshotSandbox(sandboxId: string): Promise<SandboxSnapshot>;\n}\n\n// ============================================================================\n// Errors\n// ============================================================================\n\nimport { ApplicationFailure } from \"@temporalio/common\";\n\nexport class SandboxNotSupportedError extends ApplicationFailure {\n constructor(operation: string) {\n super(\n `Sandbox does not support: ${operation}`,\n \"SandboxNotSupportedError\",\n true,\n );\n }\n}\n\nexport class SandboxNotFoundError extends ApplicationFailure {\n constructor(sandboxId: string) {\n super(`Sandbox not found: ${sandboxId}`, \"SandboxNotFoundError\", true);\n }\n}\n","import type { Sandbox as DaytonaSdkSandbox } from \"@daytonaio/sdk\";\nimport type {\n SandboxFileSystem,\n DirentEntry,\n FileStat,\n} from \"../../../lib/sandbox/types\";\nimport { SandboxNotSupportedError } from \"../../../lib/sandbox/types\";\nimport { posix } from \"node:path\";\n\n/**\n * {@link SandboxFileSystem} backed by a Daytona SDK sandbox.\n *\n * Maps zeitlich's filesystem interface to Daytona's `sandbox.fs` and\n * `sandbox.process` APIs. Operations that have no direct Daytona equivalent\n * (e.g. `appendFile`, `cp`) are composed from primitives.\n */\nexport class DaytonaSandboxFileSystem implements SandboxFileSystem {\n readonly workspaceBase: string;\n\n constructor(\n private sandbox: DaytonaSdkSandbox,\n workspaceBase = \"/home/daytona\",\n ) {\n this.workspaceBase = posix.resolve(\"/\", workspaceBase);\n }\n\n private normalisePath(path: string): string {\n return posix.resolve(this.workspaceBase, path);\n }\n\n async readFile(path: string): Promise<string> {\n const norm = this.normalisePath(path);\n const buf = await this.sandbox.fs.downloadFile(norm);\n return buf.toString(\"utf-8\");\n }\n\n async readFileBuffer(path: string): Promise<Uint8Array> {\n const norm = this.normalisePath(path);\n const buf = await this.sandbox.fs.downloadFile(norm);\n return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);\n }\n\n async writeFile(path: string, content: string | Uint8Array): Promise<void> {\n const norm = this.normalisePath(path);\n const buf =\n typeof content === \"string\"\n ? Buffer.from(content, \"utf-8\")\n : Buffer.from(content);\n await this.sandbox.fs.uploadFile(buf, norm);\n }\n\n async appendFile(\n path: string,\n content: string | Uint8Array,\n ): Promise<void> {\n const norm = this.normalisePath(path);\n let existing: Buffer;\n try {\n existing = await this.sandbox.fs.downloadFile(norm);\n } catch {\n return this.writeFile(norm, content);\n }\n\n const addition =\n typeof content === \"string\" ? Buffer.from(content, \"utf-8\") : content;\n const merged = Buffer.concat([existing, Buffer.from(addition)]);\n await this.sandbox.fs.uploadFile(merged, norm);\n }\n\n async exists(path: string): Promise<boolean> {\n const norm = this.normalisePath(path);\n try {\n await this.sandbox.fs.getFileDetails(norm);\n return true;\n } catch {\n return false;\n }\n }\n\n async stat(path: string): Promise<FileStat> {\n const norm = this.normalisePath(path);\n const info = await this.sandbox.fs.getFileDetails(norm);\n return {\n isFile: !info.isDir,\n isDirectory: info.isDir,\n isSymbolicLink: false,\n size: info.size,\n mtime: new Date(info.modTime),\n };\n }\n\n async mkdir(\n path: string,\n _options?: { recursive?: boolean },\n ): Promise<void> {\n const norm = this.normalisePath(path);\n await this.sandbox.fs.createFolder(norm, \"755\");\n }\n\n async readdir(path: string): Promise<string[]> {\n const norm = this.normalisePath(path);\n const entries = await this.sandbox.fs.listFiles(norm);\n return entries.map((e) => e.name);\n }\n\n async readdirWithFileTypes(path: string): Promise<DirentEntry[]> {\n const norm = this.normalisePath(path);\n const entries = await this.sandbox.fs.listFiles(norm);\n return entries.map((e) => ({\n name: e.name,\n isFile: !e.isDir,\n isDirectory: e.isDir,\n isSymbolicLink: false,\n }));\n }\n\n async rm(\n path: string,\n options?: { recursive?: boolean; force?: boolean },\n ): Promise<void> {\n const norm = this.normalisePath(path);\n try {\n await this.sandbox.fs.deleteFile(norm, options?.recursive);\n } catch (err) {\n if (!options?.force) throw err;\n }\n }\n\n async cp(\n src: string,\n dest: string,\n options?: { recursive?: boolean },\n ): Promise<void> {\n const normSrc = this.normalisePath(src);\n const normDest = this.normalisePath(dest);\n const info = await this.sandbox.fs.getFileDetails(normSrc);\n if (info.isDir) {\n if (!options?.recursive) {\n throw new Error(`EISDIR: is a directory (use recursive): ${src}`);\n }\n await this.sandbox.process.executeCommand(`cp -r \"${normSrc}\" \"${normDest}\"`);\n } else {\n await this.sandbox.process.executeCommand(`cp \"${normSrc}\" \"${normDest}\"`);\n }\n }\n\n async mv(src: string, dest: string): Promise<void> {\n const normSrc = this.normalisePath(src);\n const normDest = this.normalisePath(dest);\n await this.sandbox.fs.moveFiles(normSrc, normDest);\n }\n\n async readlink(_path: string): Promise<string> {\n throw new SandboxNotSupportedError(\"readlink\");\n }\n\n resolvePath(base: string, path: string): string {\n return posix.resolve(this.normalisePath(base), path);\n }\n}\n","import {\n Daytona,\n type Sandbox as DaytonaSdkSandbox,\n} from \"@daytonaio/sdk\";\nimport type {\n Sandbox,\n SandboxCapabilities,\n SandboxCreateResult,\n SandboxProvider,\n SandboxSnapshot,\n ExecOptions,\n ExecResult,\n} from \"../../../lib/sandbox/types\";\nimport {\n SandboxNotFoundError,\n SandboxNotSupportedError,\n} from \"../../../lib/sandbox/types\";\nimport { DaytonaSandboxFileSystem } from \"./filesystem\";\nimport type {\n DaytonaSandbox,\n DaytonaSandboxConfig,\n DaytonaSandboxCreateOptions,\n} from \"./types\";\n\n// ============================================================================\n// DaytonaSandbox\n// ============================================================================\n\nclass DaytonaSandboxImpl implements Sandbox {\n readonly capabilities: SandboxCapabilities = {\n filesystem: true,\n execution: true,\n persistence: false,\n };\n\n readonly fs: DaytonaSandboxFileSystem;\n\n constructor(\n readonly id: string,\n private sdkSandbox: DaytonaSdkSandbox,\n workspaceBase = \"/home/daytona\",\n ) {\n this.fs = new DaytonaSandboxFileSystem(sdkSandbox, workspaceBase);\n }\n\n async exec(command: string, options?: ExecOptions): Promise<ExecResult> {\n const response = await this.sdkSandbox.process.executeCommand(\n command,\n options?.cwd,\n options?.env,\n options?.timeout,\n );\n\n return {\n exitCode: response.exitCode ?? 0,\n stdout: response.result ?? \"\",\n stderr: \"\",\n };\n }\n\n async destroy(): Promise<void> {\n await this.sdkSandbox.delete(60);\n }\n}\n\n// ============================================================================\n// DaytonaSandboxProvider\n// ============================================================================\n\nexport class DaytonaSandboxProvider\n implements SandboxProvider<DaytonaSandboxCreateOptions, DaytonaSandbox>\n{\n readonly id = \"daytona\";\n readonly capabilities: SandboxCapabilities = {\n filesystem: true,\n execution: true,\n persistence: false,\n };\n\n private client: Daytona;\n private readonly defaultWorkspaceBase: string;\n private workspaceBaseById = new Map<string, string>();\n\n constructor(config?: DaytonaSandboxConfig) {\n this.client = new Daytona(config);\n this.defaultWorkspaceBase = config?.workspaceBase ?? \"/home/daytona\";\n }\n\n async create(\n options?: DaytonaSandboxCreateOptions,\n ): Promise<SandboxCreateResult> {\n const sdkSandbox = await this.client.create(\n {\n language: options?.language,\n snapshot: options?.snapshot,\n envVars: options?.env,\n labels: options?.labels,\n autoStopInterval: options?.autoStopInterval,\n autoArchiveInterval: options?.autoArchiveInterval,\n autoDeleteInterval: options?.autoDeleteInterval,\n },\n { timeout: options?.timeout ?? 60 },\n );\n\n const workspaceBase = options?.workspaceBase ?? this.defaultWorkspaceBase;\n this.workspaceBaseById.set(sdkSandbox.id, workspaceBase);\n const sandbox = new DaytonaSandboxImpl(\n sdkSandbox.id,\n sdkSandbox,\n workspaceBase,\n );\n\n if (options?.initialFiles) {\n for (const [path, content] of Object.entries(options.initialFiles)) {\n await sandbox.fs.writeFile(path, content);\n }\n }\n\n return { sandbox };\n }\n\n async get(sandboxId: string): Promise<DaytonaSandbox> {\n try {\n const sdkSandbox = await this.client.get(sandboxId);\n const workspaceBase =\n this.workspaceBaseById.get(sandboxId) ?? this.defaultWorkspaceBase;\n return new DaytonaSandboxImpl(sdkSandbox.id, sdkSandbox, workspaceBase);\n } catch {\n throw new SandboxNotFoundError(sandboxId);\n }\n }\n\n async destroy(sandboxId: string): Promise<void> {\n try {\n const sdkSandbox = await this.client.get(sandboxId);\n await this.client.delete(sdkSandbox);\n this.workspaceBaseById.delete(sandboxId);\n } catch {\n // Already gone\n }\n }\n\n async snapshot(_sandboxId: string): Promise<SandboxSnapshot> {\n throw new SandboxNotSupportedError(\n \"snapshot (use Daytona's native snapshot API directly)\",\n );\n }\n\n async restore(_snapshot: SandboxSnapshot): Promise<never> {\n throw new SandboxNotSupportedError(\n \"restore (use Daytona's native snapshot API directly)\",\n );\n }\n}\n\n// Re-exports\nexport { DaytonaSandboxFileSystem } from \"./filesystem\";\nexport type {\n DaytonaSandbox,\n DaytonaSandboxConfig,\n DaytonaSandboxCreateOptions,\n} from \"./types\";\n"]}
|
|
@@ -23,14 +23,17 @@ function getShortId(length = 12) {
|
|
|
23
23
|
|
|
24
24
|
// src/adapters/sandbox/inmemory/index.ts
|
|
25
25
|
function toSandboxFs(fs) {
|
|
26
|
+
const workspaceBase = "/";
|
|
27
|
+
const normalisePath = (path) => fs.resolvePath(workspaceBase, path);
|
|
26
28
|
return {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
workspaceBase,
|
|
30
|
+
readFile: (path) => fs.readFile(normalisePath(path)),
|
|
31
|
+
readFileBuffer: (path) => fs.readFileBuffer(normalisePath(path)),
|
|
32
|
+
writeFile: (path, content) => fs.writeFile(normalisePath(path), content),
|
|
33
|
+
appendFile: (path, content) => fs.appendFile(normalisePath(path), content),
|
|
34
|
+
exists: (path) => fs.exists(normalisePath(path)),
|
|
32
35
|
stat: async (path) => {
|
|
33
|
-
const s = await fs.stat(path);
|
|
36
|
+
const s = await fs.stat(normalisePath(path));
|
|
34
37
|
return {
|
|
35
38
|
isFile: s.isFile,
|
|
36
39
|
isDirectory: s.isDirectory,
|
|
@@ -39,14 +42,16 @@ function toSandboxFs(fs) {
|
|
|
39
42
|
mtime: s.mtime
|
|
40
43
|
};
|
|
41
44
|
},
|
|
42
|
-
mkdir: (path, opts) => fs.mkdir(path, opts),
|
|
43
|
-
readdir: (path) => fs.readdir(path),
|
|
45
|
+
mkdir: (path, opts) => fs.mkdir(normalisePath(path), opts),
|
|
46
|
+
readdir: (path) => fs.readdir(normalisePath(path)),
|
|
44
47
|
readdirWithFileTypes: async (path) => {
|
|
48
|
+
const dirPath = normalisePath(path);
|
|
45
49
|
if (!fs.readdirWithFileTypes) {
|
|
46
|
-
const names = await fs.readdir(
|
|
50
|
+
const names = await fs.readdir(dirPath);
|
|
47
51
|
return Promise.all(
|
|
48
52
|
names.map(async (name) => {
|
|
49
|
-
const
|
|
53
|
+
const childPath = fs.resolvePath(dirPath, name);
|
|
54
|
+
const s = await fs.stat(childPath);
|
|
50
55
|
return {
|
|
51
56
|
name,
|
|
52
57
|
isFile: s.isFile,
|
|
@@ -56,13 +61,13 @@ function toSandboxFs(fs) {
|
|
|
56
61
|
})
|
|
57
62
|
);
|
|
58
63
|
}
|
|
59
|
-
return fs.readdirWithFileTypes(
|
|
64
|
+
return fs.readdirWithFileTypes(dirPath);
|
|
60
65
|
},
|
|
61
|
-
rm: (path, opts) => fs.rm(path, opts),
|
|
62
|
-
cp: (src, dest, opts) => fs.cp(src, dest, opts),
|
|
63
|
-
mv: (src, dest) => fs.mv(src, dest),
|
|
64
|
-
readlink: (path) => fs.readlink(path),
|
|
65
|
-
resolvePath: (base, p) => fs.resolvePath(base, p)
|
|
66
|
+
rm: (path, opts) => fs.rm(normalisePath(path), opts),
|
|
67
|
+
cp: (src, dest, opts) => fs.cp(normalisePath(src), normalisePath(dest), opts),
|
|
68
|
+
mv: (src, dest) => fs.mv(normalisePath(src), normalisePath(dest)),
|
|
69
|
+
readlink: (path) => fs.readlink(normalisePath(path)),
|
|
70
|
+
resolvePath: (base, p) => fs.resolvePath(normalisePath(base), p)
|
|
66
71
|
};
|
|
67
72
|
}
|
|
68
73
|
var InMemorySandboxImpl = class {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/lib/sandbox/types.ts","../../../../src/lib/thread/id.ts","../../../../src/adapters/sandbox/inmemory/index.ts"],"names":["ApplicationFailure","uuid4","Bash","InMemoryFs"],"mappings":"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","file":"index.cjs","sourcesContent":["// ============================================================================\n// Sandbox Filesystem\n// ============================================================================\n\nexport interface DirentEntry {\n name: string;\n isFile: boolean;\n isDirectory: boolean;\n isSymbolicLink: boolean;\n}\n\nexport interface FileStat {\n isFile: boolean;\n isDirectory: boolean;\n isSymbolicLink: boolean;\n size: number;\n mtime: Date;\n}\n\n/**\n * Provider-agnostic filesystem interface.\n *\n * Implementations that don't support a method should throw\n * {@link SandboxNotSupportedError}.\n */\nexport interface SandboxFileSystem {\n readFile(path: string): Promise<string>;\n readFileBuffer(path: string): Promise<Uint8Array>;\n writeFile(path: string, content: string | Uint8Array): Promise<void>;\n appendFile(path: string, content: string | Uint8Array): Promise<void>;\n exists(path: string): Promise<boolean>;\n stat(path: string): Promise<FileStat>;\n mkdir(path: string, options?: { recursive?: boolean }): Promise<void>;\n readdir(path: string): Promise<string[]>;\n readdirWithFileTypes(path: string): Promise<DirentEntry[]>;\n rm(path: string, options?: { recursive?: boolean; force?: boolean }): Promise<void>;\n cp(src: string, dest: string, options?: { recursive?: boolean }): Promise<void>;\n mv(src: string, dest: string): Promise<void>;\n readlink(path: string): Promise<string>;\n resolvePath(base: string, path: string): string;\n}\n\n// ============================================================================\n// Execution\n// ============================================================================\n\nexport interface ExecOptions {\n timeout?: number;\n cwd?: string;\n env?: Record<string, string>;\n}\n\nexport interface ExecResult {\n exitCode: number;\n stdout: string;\n stderr: string;\n}\n\n// ============================================================================\n// Capabilities\n// ============================================================================\n\nexport interface SandboxCapabilities {\n /** Sandbox supports filesystem operations */\n filesystem: boolean;\n /** Sandbox supports shell/command execution */\n execution: boolean;\n /** Sandbox state can be persisted and restored */\n persistence: boolean;\n}\n\n// ============================================================================\n// Sandbox\n// ============================================================================\n\nexport interface Sandbox {\n readonly id: string;\n readonly capabilities: SandboxCapabilities;\n readonly fs: SandboxFileSystem;\n\n exec(command: string, options?: ExecOptions): Promise<ExecResult>;\n destroy(): Promise<void>;\n}\n\n// ============================================================================\n// Snapshots\n// ============================================================================\n\nexport interface SandboxSnapshot {\n sandboxId: string;\n providerId: string;\n /** Provider-specific serialised state */\n data: unknown;\n createdAt: string;\n}\n\n// ============================================================================\n// Provider\n// ============================================================================\n\nexport interface SandboxCreateOptions {\n /** Preferred sandbox ID (provider may ignore) */\n id?: string;\n /** Seed the filesystem with these files */\n initialFiles?: Record<string, string | Uint8Array>;\n /** Environment variables available inside the sandbox */\n env?: Record<string, string>;\n}\n\nexport interface SandboxCreateResult {\n sandbox: Sandbox;\n /** Optional state to merge into the workflow's `AgentState` via the session. */\n stateUpdate?: Record<string, unknown>;\n}\n\nexport interface SandboxProvider<\n TOptions extends SandboxCreateOptions = SandboxCreateOptions,\n TSandbox extends Sandbox = Sandbox,\n> {\n readonly id: string;\n readonly capabilities: SandboxCapabilities;\n\n create(options?: TOptions): Promise<SandboxCreateResult>;\n get(sandboxId: string): Promise<TSandbox>;\n destroy(sandboxId: string): Promise<void>;\n snapshot(sandboxId: string): Promise<SandboxSnapshot>;\n restore(snapshot: SandboxSnapshot): Promise<Sandbox>;\n}\n\n// ============================================================================\n// SandboxOps — workflow-side activity interface (like ThreadOps)\n// ============================================================================\n\nexport interface SandboxOps<\n TOptions extends SandboxCreateOptions = SandboxCreateOptions,\n> {\n createSandbox(\n options?: TOptions,\n ): Promise<{ sandboxId: string; stateUpdate?: Record<string, unknown> }>;\n destroySandbox(sandboxId: string): Promise<void>;\n snapshotSandbox(sandboxId: string): Promise<SandboxSnapshot>;\n}\n\n// ============================================================================\n// Errors\n// ============================================================================\n\nimport { ApplicationFailure } from \"@temporalio/common\";\n\nexport class SandboxNotSupportedError extends ApplicationFailure {\n constructor(operation: string) {\n super(\n `Sandbox does not support: ${operation}`,\n \"SandboxNotSupportedError\",\n true,\n );\n }\n}\n\nexport class SandboxNotFoundError extends ApplicationFailure {\n constructor(sandboxId: string) {\n super(`Sandbox not found: ${sandboxId}`, \"SandboxNotFoundError\", true);\n }\n}\n","import { uuid4 } from \"@temporalio/workflow\";\n\nconst BASE62 =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\n\n/**\n * Generate a compact, workflow-deterministic identifier.\n *\n * Uses Temporal's `uuid4()` internally (seeded by the workflow's RNG),\n * then re-encodes the hex bytes into a base-62 alphabet for a shorter,\n * more token-efficient identifier (~3 tokens vs ~10 for a full UUID).\n *\n * Suitable for thread IDs, child workflow IDs, or any workflow-scoped identifier.\n *\n * @param length - Number of base-62 characters (default 12, ~71 bits of entropy)\n */\nexport function getShortId(length = 12): string {\n const hex = uuid4().replace(/-/g, \"\");\n let result = \"\";\n for (let i = 0; i < length; i++) {\n const byte = parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n result += BASE62[byte % BASE62.length];\n }\n return result;\n}\n","import {\n Bash,\n InMemoryFs,\n type BashOptions,\n type IFileSystem,\n type InitialFiles,\n} from \"just-bash\";\nimport type {\n Sandbox,\n SandboxCapabilities,\n SandboxCreateOptions,\n SandboxCreateResult,\n SandboxFileSystem,\n SandboxProvider,\n SandboxSnapshot,\n ExecOptions,\n ExecResult,\n DirentEntry,\n FileStat,\n} from \"../../../lib/sandbox/types\";\nimport { SandboxNotFoundError } from \"../../../lib/sandbox/types\";\nimport { getShortId } from \"../../../lib/thread/id\";\n\n// ============================================================================\n// Adapter: IFileSystem → SandboxFileSystem\n// ============================================================================\n\nfunction toSandboxFs(fs: IFileSystem): SandboxFileSystem {\n return {\n readFile: (path) => fs.readFile(path),\n readFileBuffer: (path) => fs.readFileBuffer(path),\n writeFile: (path, content) => fs.writeFile(path, content),\n appendFile: (path, content) => fs.appendFile(path, content),\n exists: (path) => fs.exists(path),\n stat: async (path): Promise<FileStat> => {\n const s = await fs.stat(path);\n return {\n isFile: s.isFile,\n isDirectory: s.isDirectory,\n isSymbolicLink: s.isSymbolicLink,\n size: s.size,\n mtime: s.mtime,\n };\n },\n mkdir: (path, opts) => fs.mkdir(path, opts),\n readdir: (path) => fs.readdir(path),\n readdirWithFileTypes: async (path): Promise<DirentEntry[]> => {\n if (!fs.readdirWithFileTypes) {\n const names = await fs.readdir(path);\n return Promise.all(\n names.map(async (name) => {\n const s = await fs.stat(`${path}/${name}`);\n return {\n name,\n isFile: s.isFile,\n isDirectory: s.isDirectory,\n isSymbolicLink: s.isSymbolicLink,\n };\n })\n );\n }\n return fs.readdirWithFileTypes(path);\n },\n rm: (path, opts) => fs.rm(path, opts),\n cp: (src, dest, opts) => fs.cp(src, dest, opts),\n mv: (src, dest) => fs.mv(src, dest),\n readlink: (path) => fs.readlink(path),\n resolvePath: (base, p) => fs.resolvePath(base, p),\n };\n}\n\n// ============================================================================\n// InMemorySandbox\n// ============================================================================\n\nexport interface InMemorySandboxOptions {\n /** Options forwarded to `just-bash` `Bash` (minus `fs` which is managed) */\n bashOptions?: Omit<BashOptions, \"fs\">;\n}\n\n/**\n * An in-memory {@link Sandbox} backed by `just-bash`.\n */\nexport type InMemorySandbox = Sandbox & { fs: SandboxFileSystem };\n\nclass InMemorySandboxImpl implements Sandbox {\n readonly capabilities: SandboxCapabilities = {\n filesystem: true,\n execution: true,\n persistence: true,\n };\n\n readonly fs: SandboxFileSystem;\n private bashOptions: Omit<BashOptions, \"fs\">;\n\n constructor(\n readonly id: string,\n private justBashFs: IFileSystem,\n options?: InMemorySandboxOptions\n ) {\n this.fs = toSandboxFs(justBashFs);\n this.bashOptions = {\n executionLimits: { maxStringLength: 52_428_800 },\n ...options?.bashOptions,\n };\n }\n\n async exec(command: string, _options?: ExecOptions): Promise<ExecResult> {\n const bash = new Bash({ ...this.bashOptions, fs: this.justBashFs });\n const { exitCode, stderr, stdout } = await bash.exec(command);\n return { exitCode, stdout, stderr };\n }\n\n async destroy(): Promise<void> {\n // In-memory: nothing to clean up\n }\n\n /** Expose the underlying IFileSystem for snapshot serialisation */\n _getJustBashFs(): IFileSystem {\n return this.justBashFs;\n }\n}\n\n// ============================================================================\n// InMemorySandboxProvider\n// ============================================================================\n\nexport class InMemorySandboxProvider implements SandboxProvider {\n readonly id = \"inmemory\";\n readonly capabilities: SandboxCapabilities = {\n filesystem: true,\n execution: true,\n persistence: true,\n };\n\n private sandboxes = new Map<string, InMemorySandboxImpl>();\n\n constructor(private defaultOptions?: InMemorySandboxOptions) {}\n\n async get(id: string): Promise<Sandbox> {\n const sandbox = this.sandboxes.get(id);\n if (!sandbox) throw new SandboxNotFoundError(id);\n return sandbox;\n }\n\n async destroy(id: string): Promise<void> {\n const sandbox = this.sandboxes.get(id);\n if (sandbox) {\n await sandbox.destroy();\n this.sandboxes.delete(id);\n }\n }\n\n async create(options?: SandboxCreateOptions): Promise<SandboxCreateResult> {\n const id = options?.id ?? getShortId();\n const initialFiles: InitialFiles = {};\n\n if (options?.initialFiles) {\n for (const [path, content] of Object.entries(options.initialFiles)) {\n initialFiles[path] = content;\n }\n }\n\n const fs = new InMemoryFs(initialFiles);\n const sandbox = new InMemorySandboxImpl(id, fs, this.defaultOptions);\n this.sandboxes.set(id, sandbox);\n return { sandbox };\n }\n\n async snapshot(sandboxId: string): Promise<SandboxSnapshot> {\n const sandbox = this.sandboxes.get(sandboxId);\n if (!sandbox) throw new SandboxNotFoundError(sandboxId);\n\n const fs = sandbox._getJustBashFs();\n const paths = fs.getAllPaths();\n const files: Record<string, string> = {};\n\n for (const p of paths) {\n try {\n const stat = await fs.stat(p);\n if (stat.isFile) {\n files[p] = await fs.readFile(p);\n }\n } catch {\n // skip entries that can't be read (e.g. broken symlinks)\n }\n }\n\n return {\n sandboxId,\n providerId: this.id,\n data: { files },\n createdAt: new Date().toISOString(),\n };\n }\n\n async restore(snapshot: SandboxSnapshot): Promise<Sandbox> {\n const { files } = snapshot.data as { files: Record<string, string> };\n const initialFiles: InitialFiles = {};\n for (const [path, content] of Object.entries(files)) {\n initialFiles[path] = content;\n }\n\n const fs = new InMemoryFs(initialFiles);\n const sandbox = new InMemorySandboxImpl(\n snapshot.sandboxId,\n fs,\n this.defaultOptions\n );\n this.sandboxes.set(sandbox.id, sandbox);\n return sandbox;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/lib/sandbox/types.ts","../../../../src/lib/thread/id.ts","../../../../src/adapters/sandbox/inmemory/index.ts"],"names":["ApplicationFailure","uuid4","Bash","InMemoryFs"],"mappings":"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","file":"index.cjs","sourcesContent":["// ============================================================================\n// Sandbox Filesystem\n// ============================================================================\n\nexport interface DirentEntry {\n name: string;\n isFile: boolean;\n isDirectory: boolean;\n isSymbolicLink: boolean;\n}\n\nexport interface FileStat {\n isFile: boolean;\n isDirectory: boolean;\n isSymbolicLink: boolean;\n size: number;\n mtime: Date;\n}\n\n/**\n * Provider-agnostic filesystem interface.\n *\n * Implementations that don't support a method should throw\n * {@link SandboxNotSupportedError}.\n */\nexport interface SandboxFileSystem {\n /** Base directory used when resolving relative paths. */\n readonly workspaceBase: string;\n readFile(path: string): Promise<string>;\n readFileBuffer(path: string): Promise<Uint8Array>;\n writeFile(path: string, content: string | Uint8Array): Promise<void>;\n appendFile(path: string, content: string | Uint8Array): Promise<void>;\n exists(path: string): Promise<boolean>;\n stat(path: string): Promise<FileStat>;\n mkdir(path: string, options?: { recursive?: boolean }): Promise<void>;\n readdir(path: string): Promise<string[]>;\n readdirWithFileTypes(path: string): Promise<DirentEntry[]>;\n rm(path: string, options?: { recursive?: boolean; force?: boolean }): Promise<void>;\n cp(src: string, dest: string, options?: { recursive?: boolean }): Promise<void>;\n mv(src: string, dest: string): Promise<void>;\n readlink(path: string): Promise<string>;\n resolvePath(base: string, path: string): string;\n}\n\n// ============================================================================\n// Execution\n// ============================================================================\n\nexport interface ExecOptions {\n timeout?: number;\n cwd?: string;\n env?: Record<string, string>;\n}\n\nexport interface ExecResult {\n exitCode: number;\n stdout: string;\n stderr: string;\n}\n\n// ============================================================================\n// Capabilities\n// ============================================================================\n\nexport interface SandboxCapabilities {\n /** Sandbox supports filesystem operations */\n filesystem: boolean;\n /** Sandbox supports shell/command execution */\n execution: boolean;\n /** Sandbox state can be persisted and restored */\n persistence: boolean;\n}\n\n// ============================================================================\n// Sandbox\n// ============================================================================\n\nexport interface Sandbox {\n readonly id: string;\n readonly capabilities: SandboxCapabilities;\n readonly fs: SandboxFileSystem;\n\n exec(command: string, options?: ExecOptions): Promise<ExecResult>;\n destroy(): Promise<void>;\n}\n\n// ============================================================================\n// Snapshots\n// ============================================================================\n\nexport interface SandboxSnapshot {\n sandboxId: string;\n providerId: string;\n /** Provider-specific serialised state */\n data: unknown;\n createdAt: string;\n}\n\n// ============================================================================\n// Provider\n// ============================================================================\n\nexport interface SandboxCreateOptions {\n /** Preferred sandbox ID (provider may ignore) */\n id?: string;\n /** Seed the filesystem with these files */\n initialFiles?: Record<string, string | Uint8Array>;\n /** Environment variables available inside the sandbox */\n env?: Record<string, string>;\n}\n\nexport interface SandboxCreateResult {\n sandbox: Sandbox;\n /** Optional state to merge into the workflow's `AgentState` via the session. */\n stateUpdate?: Record<string, unknown>;\n}\n\nexport interface SandboxProvider<\n TOptions extends SandboxCreateOptions = SandboxCreateOptions,\n TSandbox extends Sandbox = Sandbox,\n> {\n readonly id: string;\n readonly capabilities: SandboxCapabilities;\n\n create(options?: TOptions): Promise<SandboxCreateResult>;\n get(sandboxId: string): Promise<TSandbox>;\n destroy(sandboxId: string): Promise<void>;\n snapshot(sandboxId: string): Promise<SandboxSnapshot>;\n restore(snapshot: SandboxSnapshot): Promise<Sandbox>;\n}\n\n// ============================================================================\n// SandboxOps — workflow-side activity interface (like ThreadOps)\n// ============================================================================\n\nexport interface SandboxOps<\n TOptions extends SandboxCreateOptions = SandboxCreateOptions,\n> {\n createSandbox(\n options?: TOptions,\n ): Promise<{ sandboxId: string; stateUpdate?: Record<string, unknown> }>;\n destroySandbox(sandboxId: string): Promise<void>;\n snapshotSandbox(sandboxId: string): Promise<SandboxSnapshot>;\n}\n\n// ============================================================================\n// Errors\n// ============================================================================\n\nimport { ApplicationFailure } from \"@temporalio/common\";\n\nexport class SandboxNotSupportedError extends ApplicationFailure {\n constructor(operation: string) {\n super(\n `Sandbox does not support: ${operation}`,\n \"SandboxNotSupportedError\",\n true,\n );\n }\n}\n\nexport class SandboxNotFoundError extends ApplicationFailure {\n constructor(sandboxId: string) {\n super(`Sandbox not found: ${sandboxId}`, \"SandboxNotFoundError\", true);\n }\n}\n","import { uuid4 } from \"@temporalio/workflow\";\n\nconst BASE62 =\n \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\";\n\n/**\n * Generate a compact, workflow-deterministic identifier.\n *\n * Uses Temporal's `uuid4()` internally (seeded by the workflow's RNG),\n * then re-encodes the hex bytes into a base-62 alphabet for a shorter,\n * more token-efficient identifier (~3 tokens vs ~10 for a full UUID).\n *\n * Suitable for thread IDs, child workflow IDs, or any workflow-scoped identifier.\n *\n * @param length - Number of base-62 characters (default 12, ~71 bits of entropy)\n */\nexport function getShortId(length = 12): string {\n const hex = uuid4().replace(/-/g, \"\");\n let result = \"\";\n for (let i = 0; i < length; i++) {\n const byte = parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n result += BASE62[byte % BASE62.length];\n }\n return result;\n}\n","import {\n Bash,\n InMemoryFs,\n type BashOptions,\n type IFileSystem,\n type InitialFiles,\n} from \"just-bash\";\nimport type {\n Sandbox,\n SandboxCapabilities,\n SandboxCreateOptions,\n SandboxCreateResult,\n SandboxFileSystem,\n SandboxProvider,\n SandboxSnapshot,\n ExecOptions,\n ExecResult,\n DirentEntry,\n FileStat,\n} from \"../../../lib/sandbox/types\";\nimport { SandboxNotFoundError } from \"../../../lib/sandbox/types\";\nimport { getShortId } from \"../../../lib/thread/id\";\n\n// ============================================================================\n// Adapter: IFileSystem → SandboxFileSystem\n// ============================================================================\n\nfunction toSandboxFs(fs: IFileSystem): SandboxFileSystem {\n const workspaceBase = \"/\";\n const normalisePath = (path: string): string => fs.resolvePath(workspaceBase, path);\n\n return {\n workspaceBase,\n readFile: (path) => fs.readFile(normalisePath(path)),\n readFileBuffer: (path) => fs.readFileBuffer(normalisePath(path)),\n writeFile: (path, content) => fs.writeFile(normalisePath(path), content),\n appendFile: (path, content) => fs.appendFile(normalisePath(path), content),\n exists: (path) => fs.exists(normalisePath(path)),\n stat: async (path): Promise<FileStat> => {\n const s = await fs.stat(normalisePath(path));\n return {\n isFile: s.isFile,\n isDirectory: s.isDirectory,\n isSymbolicLink: s.isSymbolicLink,\n size: s.size,\n mtime: s.mtime,\n };\n },\n mkdir: (path, opts) => fs.mkdir(normalisePath(path), opts),\n readdir: (path) => fs.readdir(normalisePath(path)),\n readdirWithFileTypes: async (path): Promise<DirentEntry[]> => {\n const dirPath = normalisePath(path);\n if (!fs.readdirWithFileTypes) {\n const names = await fs.readdir(dirPath);\n return Promise.all(\n names.map(async (name) => {\n const childPath = fs.resolvePath(dirPath, name);\n const s = await fs.stat(childPath);\n return {\n name,\n isFile: s.isFile,\n isDirectory: s.isDirectory,\n isSymbolicLink: s.isSymbolicLink,\n };\n })\n );\n }\n return fs.readdirWithFileTypes(dirPath);\n },\n rm: (path, opts) => fs.rm(normalisePath(path), opts),\n cp: (src, dest, opts) => fs.cp(normalisePath(src), normalisePath(dest), opts),\n mv: (src, dest) => fs.mv(normalisePath(src), normalisePath(dest)),\n readlink: (path) => fs.readlink(normalisePath(path)),\n resolvePath: (base, p) => fs.resolvePath(normalisePath(base), p),\n };\n}\n\n// ============================================================================\n// InMemorySandbox\n// ============================================================================\n\nexport interface InMemorySandboxOptions {\n /** Options forwarded to `just-bash` `Bash` (minus `fs` which is managed) */\n bashOptions?: Omit<BashOptions, \"fs\">;\n}\n\n/**\n * An in-memory {@link Sandbox} backed by `just-bash`.\n */\nexport type InMemorySandbox = Sandbox & { fs: SandboxFileSystem };\n\nclass InMemorySandboxImpl implements Sandbox {\n readonly capabilities: SandboxCapabilities = {\n filesystem: true,\n execution: true,\n persistence: true,\n };\n\n readonly fs: SandboxFileSystem;\n private bashOptions: Omit<BashOptions, \"fs\">;\n\n constructor(\n readonly id: string,\n private justBashFs: IFileSystem,\n options?: InMemorySandboxOptions\n ) {\n this.fs = toSandboxFs(justBashFs);\n this.bashOptions = {\n executionLimits: { maxStringLength: 52_428_800 },\n ...options?.bashOptions,\n };\n }\n\n async exec(command: string, _options?: ExecOptions): Promise<ExecResult> {\n const bash = new Bash({ ...this.bashOptions, fs: this.justBashFs });\n const { exitCode, stderr, stdout } = await bash.exec(command);\n return { exitCode, stdout, stderr };\n }\n\n async destroy(): Promise<void> {\n // In-memory: nothing to clean up\n }\n\n /** Expose the underlying IFileSystem for snapshot serialisation */\n _getJustBashFs(): IFileSystem {\n return this.justBashFs;\n }\n}\n\n// ============================================================================\n// InMemorySandboxProvider\n// ============================================================================\n\nexport class InMemorySandboxProvider implements SandboxProvider {\n readonly id = \"inmemory\";\n readonly capabilities: SandboxCapabilities = {\n filesystem: true,\n execution: true,\n persistence: true,\n };\n\n private sandboxes = new Map<string, InMemorySandboxImpl>();\n\n constructor(private defaultOptions?: InMemorySandboxOptions) {}\n\n async get(id: string): Promise<Sandbox> {\n const sandbox = this.sandboxes.get(id);\n if (!sandbox) throw new SandboxNotFoundError(id);\n return sandbox;\n }\n\n async destroy(id: string): Promise<void> {\n const sandbox = this.sandboxes.get(id);\n if (sandbox) {\n await sandbox.destroy();\n this.sandboxes.delete(id);\n }\n }\n\n async create(options?: SandboxCreateOptions): Promise<SandboxCreateResult> {\n const id = options?.id ?? getShortId();\n const initialFiles: InitialFiles = {};\n\n if (options?.initialFiles) {\n for (const [path, content] of Object.entries(options.initialFiles)) {\n initialFiles[path] = content;\n }\n }\n\n const fs = new InMemoryFs(initialFiles);\n const sandbox = new InMemorySandboxImpl(id, fs, this.defaultOptions);\n this.sandboxes.set(id, sandbox);\n return { sandbox };\n }\n\n async snapshot(sandboxId: string): Promise<SandboxSnapshot> {\n const sandbox = this.sandboxes.get(sandboxId);\n if (!sandbox) throw new SandboxNotFoundError(sandboxId);\n\n const fs = sandbox._getJustBashFs();\n const paths = fs.getAllPaths();\n const files: Record<string, string> = {};\n\n for (const p of paths) {\n try {\n const stat = await fs.stat(p);\n if (stat.isFile) {\n files[p] = await fs.readFile(p);\n }\n } catch {\n // skip entries that can't be read (e.g. broken symlinks)\n }\n }\n\n return {\n sandboxId,\n providerId: this.id,\n data: { files },\n createdAt: new Date().toISOString(),\n };\n }\n\n async restore(snapshot: SandboxSnapshot): Promise<Sandbox> {\n const { files } = snapshot.data as { files: Record<string, string> };\n const initialFiles: InitialFiles = {};\n for (const [path, content] of Object.entries(files)) {\n initialFiles[path] = content;\n }\n\n const fs = new InMemoryFs(initialFiles);\n const sandbox = new InMemorySandboxImpl(\n snapshot.sandboxId,\n fs,\n this.defaultOptions\n );\n this.sandboxes.set(sandbox.id, sandbox);\n return sandbox;\n }\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BashOptions } from 'just-bash';
|
|
2
|
-
import { S as Sandbox, a as SandboxFileSystem, b as SandboxProvider, c as SandboxCapabilities, d as SandboxCreateOptions, e as SandboxCreateResult, f as SandboxSnapshot } from '../../../types-
|
|
2
|
+
import { S as Sandbox, a as SandboxFileSystem, b as SandboxProvider, c as SandboxCapabilities, d as SandboxCreateOptions, e as SandboxCreateResult, f as SandboxSnapshot } from '../../../types-BMRzfELQ.cjs';
|
|
3
3
|
import '@temporalio/common';
|
|
4
4
|
|
|
5
5
|
interface InMemorySandboxOptions {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BashOptions } from 'just-bash';
|
|
2
|
-
import { S as Sandbox, a as SandboxFileSystem, b as SandboxProvider, c as SandboxCapabilities, d as SandboxCreateOptions, e as SandboxCreateResult, f as SandboxSnapshot } from '../../../types-
|
|
2
|
+
import { S as Sandbox, a as SandboxFileSystem, b as SandboxProvider, c as SandboxCapabilities, d as SandboxCreateOptions, e as SandboxCreateResult, f as SandboxSnapshot } from '../../../types-BMRzfELQ.js';
|
|
3
3
|
import '@temporalio/common';
|
|
4
4
|
|
|
5
5
|
interface InMemorySandboxOptions {
|
|
@@ -21,14 +21,17 @@ function getShortId(length = 12) {
|
|
|
21
21
|
|
|
22
22
|
// src/adapters/sandbox/inmemory/index.ts
|
|
23
23
|
function toSandboxFs(fs) {
|
|
24
|
+
const workspaceBase = "/";
|
|
25
|
+
const normalisePath = (path) => fs.resolvePath(workspaceBase, path);
|
|
24
26
|
return {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
workspaceBase,
|
|
28
|
+
readFile: (path) => fs.readFile(normalisePath(path)),
|
|
29
|
+
readFileBuffer: (path) => fs.readFileBuffer(normalisePath(path)),
|
|
30
|
+
writeFile: (path, content) => fs.writeFile(normalisePath(path), content),
|
|
31
|
+
appendFile: (path, content) => fs.appendFile(normalisePath(path), content),
|
|
32
|
+
exists: (path) => fs.exists(normalisePath(path)),
|
|
30
33
|
stat: async (path) => {
|
|
31
|
-
const s = await fs.stat(path);
|
|
34
|
+
const s = await fs.stat(normalisePath(path));
|
|
32
35
|
return {
|
|
33
36
|
isFile: s.isFile,
|
|
34
37
|
isDirectory: s.isDirectory,
|
|
@@ -37,14 +40,16 @@ function toSandboxFs(fs) {
|
|
|
37
40
|
mtime: s.mtime
|
|
38
41
|
};
|
|
39
42
|
},
|
|
40
|
-
mkdir: (path, opts) => fs.mkdir(path, opts),
|
|
41
|
-
readdir: (path) => fs.readdir(path),
|
|
43
|
+
mkdir: (path, opts) => fs.mkdir(normalisePath(path), opts),
|
|
44
|
+
readdir: (path) => fs.readdir(normalisePath(path)),
|
|
42
45
|
readdirWithFileTypes: async (path) => {
|
|
46
|
+
const dirPath = normalisePath(path);
|
|
43
47
|
if (!fs.readdirWithFileTypes) {
|
|
44
|
-
const names = await fs.readdir(
|
|
48
|
+
const names = await fs.readdir(dirPath);
|
|
45
49
|
return Promise.all(
|
|
46
50
|
names.map(async (name) => {
|
|
47
|
-
const
|
|
51
|
+
const childPath = fs.resolvePath(dirPath, name);
|
|
52
|
+
const s = await fs.stat(childPath);
|
|
48
53
|
return {
|
|
49
54
|
name,
|
|
50
55
|
isFile: s.isFile,
|
|
@@ -54,13 +59,13 @@ function toSandboxFs(fs) {
|
|
|
54
59
|
})
|
|
55
60
|
);
|
|
56
61
|
}
|
|
57
|
-
return fs.readdirWithFileTypes(
|
|
62
|
+
return fs.readdirWithFileTypes(dirPath);
|
|
58
63
|
},
|
|
59
|
-
rm: (path, opts) => fs.rm(path, opts),
|
|
60
|
-
cp: (src, dest, opts) => fs.cp(src, dest, opts),
|
|
61
|
-
mv: (src, dest) => fs.mv(src, dest),
|
|
62
|
-
readlink: (path) => fs.readlink(path),
|
|
63
|
-
resolvePath: (base, p) => fs.resolvePath(base, p)
|
|
64
|
+
rm: (path, opts) => fs.rm(normalisePath(path), opts),
|
|
65
|
+
cp: (src, dest, opts) => fs.cp(normalisePath(src), normalisePath(dest), opts),
|
|
66
|
+
mv: (src, dest) => fs.mv(normalisePath(src), normalisePath(dest)),
|
|
67
|
+
readlink: (path) => fs.readlink(normalisePath(path)),
|
|
68
|
+
resolvePath: (base, p) => fs.resolvePath(normalisePath(base), p)
|
|
64
69
|
};
|
|
65
70
|
}
|
|
66
71
|
var InMemorySandboxImpl = class {
|