@ai-sdk/sandbox-just-bash 1.0.133 → 1.0.135
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/CHANGELOG.md +20 -0
- package/dist/index.d.ts +32 -32
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +349 -418
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
- package/src/just-bash-sandbox.ts +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
1
|
# @ai-sdk/sandbox-just-bash
|
|
2
2
|
|
|
3
|
+
## 1.0.135
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 8182916: chore(harness): minor code consistency cleanup without functional changes
|
|
8
|
+
- Updated dependencies [8c65988]
|
|
9
|
+
- Updated dependencies [8182916]
|
|
10
|
+
- Updated dependencies [527a163]
|
|
11
|
+
- @ai-sdk/provider-utils@5.0.53
|
|
12
|
+
- @ai-sdk/harness@1.0.135
|
|
13
|
+
|
|
14
|
+
## 1.0.134
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- ede5b89: chore: migrate package builds from tsup to tsdown
|
|
19
|
+
- Updated dependencies [ede5b89]
|
|
20
|
+
- @ai-sdk/harness@1.0.134
|
|
21
|
+
- @ai-sdk/provider-utils@5.0.52
|
|
22
|
+
|
|
3
23
|
## 1.0.133
|
|
4
24
|
|
|
5
25
|
### Patch Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
1
|
+
import { Sandbox } from "just-bash";
|
|
2
|
+
import { HarnessV1NetworkSandboxSession, HarnessV1SandboxProvider, HarnessV1SandboxSessionCreateOptions, HarnessV1SandboxSessionResumeOptions } from "@ai-sdk/harness";
|
|
3
|
+
import { Experimental_SandboxSession } from "@ai-sdk/provider-utils";
|
|
4
|
+
//#region src/just-bash-legacy-sandbox-provider.d.ts
|
|
5
5
|
type JustBashSandboxCreateParams$1 = NonNullable<Parameters<typeof Sandbox.create>[0]>;
|
|
6
6
|
type JustBashCreationSettings$1 = JustBashSandboxCreateParams$1 & {
|
|
7
|
-
|
|
7
|
+
sandbox?: never;
|
|
8
8
|
};
|
|
9
9
|
/**
|
|
10
10
|
* Settings for `createJustBashSandbox`. Two mutually-exclusive shapes:
|
|
@@ -21,10 +21,10 @@ type JustBashCreationSettings$1 = JustBashSandboxCreateParams$1 & {
|
|
|
21
21
|
* @deprecated Use `JustBashNetworkSandboxSessionCreateOptions` for new sessions.
|
|
22
22
|
*/
|
|
23
23
|
type JustBashSandboxSettings = {
|
|
24
|
-
|
|
24
|
+
sandbox: Sandbox;
|
|
25
25
|
} | JustBashCreationSettings$1;
|
|
26
26
|
/** @deprecated Use `createJustBashNetworkSandboxSession` instead. */
|
|
27
|
-
declare function createJustBashSandbox(settings?: JustBashSandboxSettings): HarnessV1SandboxProvider;
|
|
27
|
+
export declare function createJustBashSandbox(settings?: JustBashSandboxSettings): HarnessV1SandboxProvider;
|
|
28
28
|
/**
|
|
29
29
|
* `HarnessV1SandboxProvider` implementation backed by `just-bash`. Useful for
|
|
30
30
|
* non-bridge harness flows and for handing a local `Experimental_SandboxSession`
|
|
@@ -35,29 +35,28 @@ declare function createJustBashSandbox(settings?: JustBashSandboxSettings): Harn
|
|
|
35
35
|
* (claude-code, codex) will reject this provider at start.
|
|
36
36
|
*/
|
|
37
37
|
/** @deprecated Use `createJustBashNetworkSandboxSession` instead. */
|
|
38
|
-
declare class JustBashSandboxProvider implements HarnessV1SandboxProvider {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
38
|
+
export declare class JustBashSandboxProvider implements HarnessV1SandboxProvider {
|
|
39
|
+
private readonly settings;
|
|
40
|
+
readonly specificationVersion: "harness-sandbox-v1";
|
|
41
|
+
readonly providerId = "just-bash-sandbox";
|
|
42
|
+
constructor(settings: JustBashSandboxSettings);
|
|
43
|
+
createSession: (options?: {
|
|
44
|
+
sessionId?: string;
|
|
45
|
+
abortSignal?: AbortSignal;
|
|
46
|
+
identity?: string;
|
|
47
|
+
onFirstCreate?: (session: Experimental_SandboxSession, opts: {
|
|
48
|
+
abortSignal?: AbortSignal;
|
|
49
|
+
}) => Promise<void>;
|
|
50
|
+
}) => Promise<HarnessV1NetworkSandboxSession>;
|
|
51
51
|
}
|
|
52
|
-
|
|
52
|
+
//#endregion
|
|
53
|
+
//#region src/just-bash-sandbox.d.ts
|
|
53
54
|
/**
|
|
54
55
|
* Flattens an intersection of object types into a single object type so the
|
|
55
56
|
* resolved shape displays as its named properties rather than a chain of
|
|
56
57
|
* `A & B & C`.
|
|
57
58
|
*/
|
|
58
|
-
type Prettify<T> = {
|
|
59
|
-
[K in keyof T]: T[K];
|
|
60
|
-
} & {};
|
|
59
|
+
type Prettify<T> = { [K in keyof T]: T[K]; } & {};
|
|
61
60
|
type JustBashNativeSandboxSession = Sandbox;
|
|
62
61
|
/**
|
|
63
62
|
* Parameters forwarded to `just-bash`'s `Sandbox.create` when creating a
|
|
@@ -67,13 +66,14 @@ type JustBashNativeSandboxSession = Sandbox;
|
|
|
67
66
|
type JustBashSandboxCreateParams = NonNullable<Parameters<typeof Sandbox.create>[0]>;
|
|
68
67
|
type JustBashCreationSettings = Omit<JustBashSandboxCreateParams, 'sandbox'>;
|
|
69
68
|
type JustBashNetworkSandboxSessionCreateOptions = Prettify<HarnessV1SandboxSessionCreateOptions<JustBashCreationSettings> & {
|
|
70
|
-
|
|
69
|
+
sandbox?: never;
|
|
71
70
|
}>;
|
|
72
71
|
type JustBashLookupSettings = Record<never, never>;
|
|
73
|
-
type JustBashNetworkSandboxSessionResumeOptions = HarnessV1SandboxSessionResumeOptions<JustBashLookupSettings
|
|
74
|
-
declare function createJustBashNetworkSandboxSession(options?: JustBashNetworkSandboxSessionCreateOptions): Promise<HarnessV1NetworkSandboxSession>;
|
|
75
|
-
declare function resumeJustBashNetworkSandboxSession(options: JustBashNetworkSandboxSessionResumeOptions): Promise<HarnessV1NetworkSandboxSession>;
|
|
76
|
-
declare function createJustBashSandboxSessionFromNativeSandbox(nativeSandbox: JustBashNativeSandboxSession): Experimental_SandboxSession;
|
|
77
|
-
declare function createJustBashNetworkSandboxSessionFromNativeSandbox(nativeSandbox: JustBashNativeSandboxSession): HarnessV1NetworkSandboxSession;
|
|
78
|
-
|
|
79
|
-
export {
|
|
72
|
+
type JustBashNetworkSandboxSessionResumeOptions = Prettify<HarnessV1SandboxSessionResumeOptions<JustBashLookupSettings>>;
|
|
73
|
+
export declare function createJustBashNetworkSandboxSession(options?: JustBashNetworkSandboxSessionCreateOptions): Promise<HarnessV1NetworkSandboxSession>;
|
|
74
|
+
export declare function resumeJustBashNetworkSandboxSession(options: JustBashNetworkSandboxSessionResumeOptions): Promise<HarnessV1NetworkSandboxSession>;
|
|
75
|
+
export declare function createJustBashSandboxSessionFromNativeSandbox(nativeSandbox: JustBashNativeSandboxSession): Experimental_SandboxSession;
|
|
76
|
+
export declare function createJustBashNetworkSandboxSessionFromNativeSandbox(nativeSandbox: JustBashNativeSandboxSession): HarnessV1NetworkSandboxSession;
|
|
77
|
+
//#endregion
|
|
78
|
+
export type { JustBashNativeSandboxSession, JustBashNetworkSandboxSessionCreateOptions, JustBashNetworkSandboxSessionResumeOptions, JustBashSandboxSettings };
|
|
79
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":["JustBashSandboxCreateParams","JustBashCreationSettings","SandboxSession","SandboxSession"],"sources":["../src/just-bash-legacy-sandbox-provider.ts","../src/just-bash-sandbox.ts"],"mappings":";;;;KASKA,gCAA8B,YACjC,kBAAkB,QAAQ;KAGvBC,6BAA2BD;EAC9B;;;;;;;;;;;;;;;;KAiBU;EACN,SAAS;IACXC;;wBAKY,sBACd,WAAU,0BACT;;;;;;;;;;;qBAiBU,mCAAmC;mBAIjB;WAHpB;WACA;EAEoB,YAAA,UAAU;EAMvC,gBAAuB;IACrB;IACA,cAAc;IACd;IACA,iBACE,SAASC,6BACT;MAAQ,cAAc;UACnB;QACH,QAAQ;;;;;;;;;KC1DT,SAAS,QAAQ,WAAW,IAAI,EAAE;KAE3B,+BAA+B;;;;;;KAOtC,8BAA8B,YACjC,kBAAkB,QAAQ;KAGvB,2BAA2B,KAAK;KAEzB,6CAA6C,SACvD,qCAAqC;EACnC;;KAIC,yBAAyB;KAElB,6CAA6C,SACvD,qCAAqC;wBAGjB,oCACpB,UAAS,6CACR,QAAQ;wBA6BW,oCACpB,SAAS,6CACR,QAAQ;wBAQK,8CACd,eAAe,+BACdC;wBAIa,qDACd,eAAe,+BACd"}
|
package/dist/index.js
CHANGED
|
@@ -1,451 +1,382 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
import { randomUUID } from "crypto";
|
|
9
|
-
|
|
10
|
-
// src/just-bash-sandbox-session.ts
|
|
11
|
-
import { isAbsolute, posix } from "path";
|
|
12
|
-
import {
|
|
13
|
-
extractLines
|
|
14
|
-
} from "@ai-sdk/provider-utils";
|
|
15
|
-
|
|
16
|
-
// src/utils.ts
|
|
17
|
-
import { defineCommand } from "just-bash";
|
|
18
|
-
var preparations = /* @__PURE__ */ new WeakMap();
|
|
1
|
+
import { Sandbox, defineCommand } from "just-bash";
|
|
2
|
+
import { HarnessCapabilityUnsupportedError } from "@ai-sdk/harness";
|
|
3
|
+
import { randomUUID } from "node:crypto";
|
|
4
|
+
import { isAbsolute, posix } from "node:path";
|
|
5
|
+
import { extractLines } from "@ai-sdk/provider-utils";
|
|
6
|
+
//#region src/utils.ts
|
|
7
|
+
const preparations = /* @__PURE__ */ new WeakMap();
|
|
19
8
|
async function ensureRealpath(sandbox) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
throw error;
|
|
32
|
-
}
|
|
9
|
+
let preparation = preparations.get(sandbox);
|
|
10
|
+
if (preparation == null) {
|
|
11
|
+
preparation = prepareRealpath(sandbox);
|
|
12
|
+
preparations.set(sandbox, preparation);
|
|
13
|
+
}
|
|
14
|
+
try {
|
|
15
|
+
await preparation;
|
|
16
|
+
} catch (error) {
|
|
17
|
+
if (preparations.get(sandbox) === preparation) preparations.delete(sandbox);
|
|
18
|
+
throw error;
|
|
19
|
+
}
|
|
33
20
|
}
|
|
34
21
|
async function prepareRealpath(sandbox) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
return;
|
|
38
|
-
}
|
|
39
|
-
sandbox.bashEnvInstance.registerCommand(
|
|
40
|
-
defineCommand("realpath", executeRealpath)
|
|
41
|
-
);
|
|
22
|
+
if ((await sandbox.bashEnvInstance.exec("type realpath")).exitCode === 0) return;
|
|
23
|
+
sandbox.bashEnvInstance.registerCommand(defineCommand("realpath", executeRealpath));
|
|
42
24
|
}
|
|
43
25
|
async function executeRealpath(args, context) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
stderr: "",
|
|
100
|
-
exitCode: 0
|
|
101
|
-
};
|
|
26
|
+
if (args.length === 0 || args[0] === "") return {
|
|
27
|
+
stdout: "",
|
|
28
|
+
stderr: "realpath: missing operand\n",
|
|
29
|
+
exitCode: 1
|
|
30
|
+
};
|
|
31
|
+
let pending = args[0].startsWith("/") ? args[0] : `${context.cwd}/${args[0]}`;
|
|
32
|
+
let resolved = "";
|
|
33
|
+
let linkCount = 0;
|
|
34
|
+
while (pending.length > 0) {
|
|
35
|
+
pending = pending.replace(/^\//, "");
|
|
36
|
+
if (pending.length === 0) break;
|
|
37
|
+
const separatorIndex = pending.indexOf("/");
|
|
38
|
+
const component = separatorIndex === -1 ? pending : pending.slice(0, separatorIndex);
|
|
39
|
+
pending = separatorIndex === -1 ? "" : pending.slice(separatorIndex + 1);
|
|
40
|
+
if (component === "" || component === ".") continue;
|
|
41
|
+
if (component === "..") {
|
|
42
|
+
resolved = resolved.slice(0, resolved.lastIndexOf("/"));
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
const candidate = `${resolved}/${component}`;
|
|
46
|
+
let isSymbolicLink = false;
|
|
47
|
+
try {
|
|
48
|
+
isSymbolicLink = (await context.fs.lstat(candidate)).isSymbolicLink;
|
|
49
|
+
} catch (error) {
|
|
50
|
+
if (!isFileNotFoundError$1(error)) throw error;
|
|
51
|
+
}
|
|
52
|
+
if (!isSymbolicLink) {
|
|
53
|
+
resolved = candidate;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
linkCount += 1;
|
|
57
|
+
if (linkCount > 64) return {
|
|
58
|
+
stdout: "",
|
|
59
|
+
stderr: "",
|
|
60
|
+
exitCode: 1
|
|
61
|
+
};
|
|
62
|
+
let target;
|
|
63
|
+
try {
|
|
64
|
+
target = await context.fs.readlink(candidate);
|
|
65
|
+
} catch {
|
|
66
|
+
return {
|
|
67
|
+
stdout: "",
|
|
68
|
+
stderr: "",
|
|
69
|
+
exitCode: 1
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
const remainder = pending.length > 0 ? `/${pending}` : "";
|
|
73
|
+
pending = target.startsWith("/") ? `${target}${remainder}` : `${candidate.slice(0, candidate.lastIndexOf("/"))}/${target}${remainder}`;
|
|
74
|
+
resolved = "";
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
stdout: `${resolved || "/"}\n`,
|
|
78
|
+
stderr: "",
|
|
79
|
+
exitCode: 0
|
|
80
|
+
};
|
|
102
81
|
}
|
|
103
|
-
function isFileNotFoundError(error) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
return typeof message === "string" && /no such file|not found|ENOENT/i.test(message);
|
|
82
|
+
function isFileNotFoundError$1(error) {
|
|
83
|
+
if (error == null || typeof error !== "object") return false;
|
|
84
|
+
if (error.code === "ENOENT") return true;
|
|
85
|
+
const message = error.message;
|
|
86
|
+
return typeof message === "string" && /no such file|not found|ENOENT/i.test(message);
|
|
109
87
|
}
|
|
110
|
-
|
|
111
|
-
|
|
88
|
+
//#endregion
|
|
89
|
+
//#region src/just-bash-sandbox-session.ts
|
|
90
|
+
/**
|
|
91
|
+
* `Experimental_SandboxSession` implementation backed by a `just-bash`
|
|
92
|
+
* `Sandbox`. File operations and spawned processes share the same in-memory
|
|
93
|
+
* filesystem, so a bridge process spawned via `spawn` can read files the host
|
|
94
|
+
* wrote via `writeTextFile` (and vice versa).
|
|
95
|
+
*
|
|
96
|
+
* This is the tool-safe surface returned by
|
|
97
|
+
* `JustBashNetworkSandboxSession.restricted()` — not constructed directly by
|
|
98
|
+
* consumers.
|
|
99
|
+
*/
|
|
112
100
|
var JustBashSandboxSession = class {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
const bytes = await collectStream(content);
|
|
209
|
-
await this.writeBinaryFile({ path, content: bytes, abortSignal });
|
|
210
|
-
}
|
|
211
|
-
async writeBinaryFile({
|
|
212
|
-
path,
|
|
213
|
-
content,
|
|
214
|
-
abortSignal
|
|
215
|
-
}) {
|
|
216
|
-
abortSignal?.throwIfAborted();
|
|
217
|
-
const resolved = this.resolvePath(path);
|
|
218
|
-
await this.sandbox.bashEnvInstance.fs.writeFile(resolved, content);
|
|
219
|
-
}
|
|
220
|
-
async writeTextFile({
|
|
221
|
-
path,
|
|
222
|
-
content,
|
|
223
|
-
encoding = "utf-8",
|
|
224
|
-
abortSignal
|
|
225
|
-
}) {
|
|
226
|
-
const buffer = Buffer.from(content, encoding);
|
|
227
|
-
await this.writeBinaryFile({
|
|
228
|
-
path,
|
|
229
|
-
content: new Uint8Array(
|
|
230
|
-
buffer.buffer,
|
|
231
|
-
buffer.byteOffset,
|
|
232
|
-
buffer.byteLength
|
|
233
|
-
),
|
|
234
|
-
abortSignal
|
|
235
|
-
});
|
|
236
|
-
}
|
|
101
|
+
constructor(sandbox) {
|
|
102
|
+
this.sandbox = sandbox;
|
|
103
|
+
}
|
|
104
|
+
get description() {
|
|
105
|
+
return [
|
|
106
|
+
"just-bash JavaScript bash environment with a virtual filesystem.",
|
|
107
|
+
"Filesystem changes and spawned processes share the same in-memory state.",
|
|
108
|
+
`Current working directory: ${this.sandbox.bashEnvInstance.getCwd()}`
|
|
109
|
+
].join("\n");
|
|
110
|
+
}
|
|
111
|
+
resolvePath(path) {
|
|
112
|
+
return isAbsolute(path) ? path : posix.join(this.sandbox.bashEnvInstance.getCwd(), path);
|
|
113
|
+
}
|
|
114
|
+
async run({ command, workingDirectory, env, abortSignal }) {
|
|
115
|
+
abortSignal?.throwIfAborted();
|
|
116
|
+
await ensureRealpath(this.sandbox);
|
|
117
|
+
abortSignal?.throwIfAborted();
|
|
118
|
+
const finished = await this.sandbox.runCommand({
|
|
119
|
+
cmd: "bash",
|
|
120
|
+
args: createBashArgs(command, env),
|
|
121
|
+
...workingDirectory !== void 0 ? { cwd: workingDirectory } : {},
|
|
122
|
+
...abortSignal !== void 0 ? { signal: abortSignal } : {}
|
|
123
|
+
});
|
|
124
|
+
const [stdout, stderr] = await Promise.all([finished.stdout(), finished.stderr()]);
|
|
125
|
+
return {
|
|
126
|
+
exitCode: finished.exitCode,
|
|
127
|
+
stdout,
|
|
128
|
+
stderr
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
async spawn({ command, workingDirectory, env, abortSignal }) {
|
|
132
|
+
abortSignal?.throwIfAborted();
|
|
133
|
+
await ensureRealpath(this.sandbox);
|
|
134
|
+
abortSignal?.throwIfAborted();
|
|
135
|
+
return createSandboxProcess(await this.sandbox.runCommand({
|
|
136
|
+
cmd: "bash",
|
|
137
|
+
args: createBashArgs(command, env),
|
|
138
|
+
detached: true,
|
|
139
|
+
...workingDirectory !== void 0 ? { cwd: workingDirectory } : {},
|
|
140
|
+
...abortSignal !== void 0 ? { signal: abortSignal } : {}
|
|
141
|
+
}), abortSignal);
|
|
142
|
+
}
|
|
143
|
+
async readFile({ path, abortSignal }) {
|
|
144
|
+
const bytes = await this.readBinaryFile({
|
|
145
|
+
path,
|
|
146
|
+
abortSignal
|
|
147
|
+
});
|
|
148
|
+
if (bytes == null) return null;
|
|
149
|
+
return bytesToStream(bytes);
|
|
150
|
+
}
|
|
151
|
+
async readBinaryFile({ path, abortSignal }) {
|
|
152
|
+
abortSignal?.throwIfAborted();
|
|
153
|
+
const resolved = this.resolvePath(path);
|
|
154
|
+
try {
|
|
155
|
+
const bytes = await this.sandbox.bashEnvInstance.fs.readFileBuffer(resolved);
|
|
156
|
+
return bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);
|
|
157
|
+
} catch (error) {
|
|
158
|
+
if (isFileNotFoundError(error)) return null;
|
|
159
|
+
throw error;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
async readTextFile({ path, encoding = "utf-8", startLine, endLine, abortSignal }) {
|
|
163
|
+
const bytes = await this.readBinaryFile({
|
|
164
|
+
path,
|
|
165
|
+
abortSignal
|
|
166
|
+
});
|
|
167
|
+
if (bytes == null) return null;
|
|
168
|
+
const text = Buffer.from(bytes).toString(encoding);
|
|
169
|
+
return extractLines({
|
|
170
|
+
text,
|
|
171
|
+
startLine,
|
|
172
|
+
endLine
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
async writeFile({ path, content, abortSignal }) {
|
|
176
|
+
const bytes = await collectStream(content);
|
|
177
|
+
await this.writeBinaryFile({
|
|
178
|
+
path,
|
|
179
|
+
content: bytes,
|
|
180
|
+
abortSignal
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
async writeBinaryFile({ path, content, abortSignal }) {
|
|
184
|
+
abortSignal?.throwIfAborted();
|
|
185
|
+
const resolved = this.resolvePath(path);
|
|
186
|
+
await this.sandbox.bashEnvInstance.fs.writeFile(resolved, content);
|
|
187
|
+
}
|
|
188
|
+
async writeTextFile({ path, content, encoding = "utf-8", abortSignal }) {
|
|
189
|
+
const buffer = Buffer.from(content, encoding);
|
|
190
|
+
await this.writeBinaryFile({
|
|
191
|
+
path,
|
|
192
|
+
content: new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength),
|
|
193
|
+
abortSignal
|
|
194
|
+
});
|
|
195
|
+
}
|
|
237
196
|
};
|
|
238
197
|
function createBashArgs(command, env) {
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
"bash",
|
|
248
|
-
...assignments
|
|
249
|
-
];
|
|
198
|
+
const assignments = env == null ? [] : Object.entries(env).map(([name, value]) => `${name}=${value}`);
|
|
199
|
+
if (assignments.length === 0) return ["-c", command];
|
|
200
|
+
return [
|
|
201
|
+
"-c",
|
|
202
|
+
`${assignments.map(() => "export -- \"$1\"; shift").join("\n")}\n${command}`,
|
|
203
|
+
"bash",
|
|
204
|
+
...assignments
|
|
205
|
+
];
|
|
250
206
|
}
|
|
251
207
|
function createSandboxProcess(command, abortSignal) {
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
if (abortSignal?.aborted) {
|
|
284
|
-
throw abortSignal.reason ?? new DOMException("Aborted", "AbortError");
|
|
285
|
-
}
|
|
286
|
-
return { exitCode: finished.exitCode };
|
|
287
|
-
},
|
|
288
|
-
async kill() {
|
|
289
|
-
await command.kill();
|
|
290
|
-
}
|
|
291
|
-
};
|
|
208
|
+
const encoder = new TextEncoder();
|
|
209
|
+
const controllers = {};
|
|
210
|
+
const stdout = new ReadableStream({ start(controller) {
|
|
211
|
+
controllers.stdout = controller;
|
|
212
|
+
} });
|
|
213
|
+
const stderr = new ReadableStream({ start(controller) {
|
|
214
|
+
controllers.stderr = controller;
|
|
215
|
+
} });
|
|
216
|
+
const drained = (async () => {
|
|
217
|
+
try {
|
|
218
|
+
for await (const message of command.logs()) (message.type === "stdout" ? controllers.stdout : controllers.stderr)?.enqueue(encoder.encode(message.data));
|
|
219
|
+
controllers.stdout?.close();
|
|
220
|
+
controllers.stderr?.close();
|
|
221
|
+
} catch (error) {
|
|
222
|
+
controllers.stdout?.error(error);
|
|
223
|
+
controllers.stderr?.error(error);
|
|
224
|
+
}
|
|
225
|
+
})();
|
|
226
|
+
return {
|
|
227
|
+
stdout,
|
|
228
|
+
stderr,
|
|
229
|
+
async wait() {
|
|
230
|
+
const finished = await command.wait();
|
|
231
|
+
await drained;
|
|
232
|
+
if (abortSignal?.aborted) throw abortSignal.reason ?? new DOMException("Aborted", "AbortError");
|
|
233
|
+
return { exitCode: finished.exitCode };
|
|
234
|
+
},
|
|
235
|
+
async kill() {
|
|
236
|
+
await command.kill();
|
|
237
|
+
}
|
|
238
|
+
};
|
|
292
239
|
}
|
|
293
240
|
function bytesToStream(bytes) {
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
}
|
|
299
|
-
});
|
|
241
|
+
return new ReadableStream({ start(controller) {
|
|
242
|
+
controller.enqueue(bytes);
|
|
243
|
+
controller.close();
|
|
244
|
+
} });
|
|
300
245
|
}
|
|
301
246
|
async function collectStream(stream) {
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
247
|
+
const reader = stream.getReader();
|
|
248
|
+
const chunks = [];
|
|
249
|
+
let total = 0;
|
|
250
|
+
while (true) {
|
|
251
|
+
const { value, done } = await reader.read();
|
|
252
|
+
if (done) break;
|
|
253
|
+
if (value) {
|
|
254
|
+
chunks.push(value);
|
|
255
|
+
total += value.byteLength;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
const out = new Uint8Array(total);
|
|
259
|
+
let offset = 0;
|
|
260
|
+
for (const chunk of chunks) {
|
|
261
|
+
out.set(chunk, offset);
|
|
262
|
+
offset += chunk.byteLength;
|
|
263
|
+
}
|
|
264
|
+
return out;
|
|
320
265
|
}
|
|
321
|
-
function
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
return typeof message === "string" && /no such file|not found|does not exist|ENOENT/i.test(message);
|
|
266
|
+
function isFileNotFoundError(error) {
|
|
267
|
+
if (error == null || typeof error !== "object") return false;
|
|
268
|
+
if (error.code === "ENOENT") return true;
|
|
269
|
+
const message = error.message;
|
|
270
|
+
return typeof message === "string" && /no such file|not found|does not exist|ENOENT/i.test(message);
|
|
327
271
|
}
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
272
|
+
//#endregion
|
|
273
|
+
//#region src/just-bash-network-sandbox-session.ts
|
|
274
|
+
const JUST_BASH_PROVIDER_ID$1 = "just-bash-sandbox";
|
|
275
|
+
/**
|
|
276
|
+
* `HarnessV1NetworkSandboxSession` backed by a `just-bash` `Sandbox`. It extends
|
|
277
|
+
* {@link JustBashSandboxSession} with the infra surface. Exposes no ports —
|
|
278
|
+
* there is no network namespace and no way to publish an HTTP endpoint
|
|
279
|
+
* reachable from outside the host process. Bridge-backed harness adapters that
|
|
280
|
+
* need `getPortEndpoint` will fail with `HarnessCapabilityUnsupportedError` at
|
|
281
|
+
* start.
|
|
282
|
+
*
|
|
283
|
+
* Network policy is not implementable locally either — `setNetworkPolicy` is
|
|
284
|
+
* omitted.
|
|
285
|
+
*/
|
|
331
286
|
var JustBashNetworkSandboxSession = class extends JustBashSandboxSession {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
restricted() {
|
|
357
|
-
return new JustBashSandboxSession(this.sandbox);
|
|
358
|
-
}
|
|
287
|
+
constructor(input) {
|
|
288
|
+
super(input.sandbox);
|
|
289
|
+
this.ports = [];
|
|
290
|
+
this.getPortEndpoint = async (_options) => {
|
|
291
|
+
throw new HarnessCapabilityUnsupportedError({
|
|
292
|
+
harnessId: JUST_BASH_PROVIDER_ID$1,
|
|
293
|
+
message: "just-bash sandboxes run in-process and cannot expose a port URL. Use a hosted sandbox (e.g. @ai-sdk/sandbox-vercel) for bridge-backed harness adapters."
|
|
294
|
+
});
|
|
295
|
+
};
|
|
296
|
+
this.getPortUrl = async (options) => {
|
|
297
|
+
return (await this.getPortEndpoint(options)).url;
|
|
298
|
+
};
|
|
299
|
+
this.stop = async () => {
|
|
300
|
+
await this.sandbox.stop();
|
|
301
|
+
};
|
|
302
|
+
this.destroy = async () => {
|
|
303
|
+
await this.stop();
|
|
304
|
+
};
|
|
305
|
+
this.id = input.sandboxId ?? randomUUID();
|
|
306
|
+
this.defaultWorkingDirectory = input.sandbox.bashEnvInstance.getCwd();
|
|
307
|
+
}
|
|
308
|
+
restricted() {
|
|
309
|
+
return new JustBashSandboxSession(this.sandbox);
|
|
310
|
+
}
|
|
359
311
|
};
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
312
|
+
//#endregion
|
|
313
|
+
//#region src/just-bash-legacy-sandbox-provider.ts
|
|
314
|
+
const JUST_BASH_PROVIDER_ID = "just-bash-sandbox";
|
|
315
|
+
/** @deprecated Use `createJustBashNetworkSandboxSession` instead. */
|
|
363
316
|
function createJustBashSandbox(settings = {}) {
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
);
|
|
367
|
-
return new JustBashSandboxProvider(settings);
|
|
317
|
+
console.warn("createJustBashSandbox is deprecated. Use createJustBashNetworkSandboxSession and HarnessAgent.createSession({ sandboxSession }) instead.");
|
|
318
|
+
return new JustBashSandboxProvider(settings);
|
|
368
319
|
}
|
|
320
|
+
/**
|
|
321
|
+
* `HarnessV1SandboxProvider` implementation backed by `just-bash`. Useful for
|
|
322
|
+
* non-bridge harness flows and for handing a local `Experimental_SandboxSession`
|
|
323
|
+
* to AI SDK tools — use `provider.createSession()` then
|
|
324
|
+
* `sandboxSession.restricted()` to get the latter.
|
|
325
|
+
*
|
|
326
|
+
* Note: just-bash cannot expose ports, so bridge-backed harness adapters
|
|
327
|
+
* (claude-code, codex) will reject this provider at start.
|
|
328
|
+
*/
|
|
329
|
+
/** @deprecated Use `createJustBashNetworkSandboxSession` instead. */
|
|
369
330
|
var JustBashSandboxProvider = class {
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
if (options?.onFirstCreate != null) {
|
|
385
|
-
await options.onFirstCreate(sandboxSession.restricted(), {
|
|
386
|
-
abortSignal: options?.abortSignal
|
|
387
|
-
});
|
|
388
|
-
}
|
|
389
|
-
return sandboxSession;
|
|
390
|
-
};
|
|
391
|
-
console.warn(
|
|
392
|
-
"JustBashSandboxProvider is deprecated. Use createJustBashNetworkSandboxSession instead."
|
|
393
|
-
);
|
|
394
|
-
}
|
|
331
|
+
constructor(settings) {
|
|
332
|
+
this.settings = settings;
|
|
333
|
+
this.specificationVersion = "harness-sandbox-v1";
|
|
334
|
+
this.providerId = JUST_BASH_PROVIDER_ID;
|
|
335
|
+
this.createSession = async (options) => {
|
|
336
|
+
options?.abortSignal?.throwIfAborted();
|
|
337
|
+
const sandbox = !("sandbox" in this.settings && this.settings.sandbox) ? await Sandbox.create(this.settings) : this.settings.sandbox;
|
|
338
|
+
await ensureRealpath(sandbox);
|
|
339
|
+
const sandboxSession = new JustBashNetworkSandboxSession({ sandbox });
|
|
340
|
+
if (options?.onFirstCreate != null) await options.onFirstCreate(sandboxSession.restricted(), { abortSignal: options?.abortSignal });
|
|
341
|
+
return sandboxSession;
|
|
342
|
+
};
|
|
343
|
+
console.warn("JustBashSandboxProvider is deprecated. Use createJustBashNetworkSandboxSession instead.");
|
|
344
|
+
}
|
|
395
345
|
};
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
import {
|
|
399
|
-
HarnessCapabilityUnsupportedError as HarnessCapabilityUnsupportedError2
|
|
400
|
-
} from "@ai-sdk/harness";
|
|
401
|
-
import { Sandbox as Sandbox2 } from "just-bash";
|
|
346
|
+
//#endregion
|
|
347
|
+
//#region src/just-bash-sandbox.ts
|
|
402
348
|
async function createJustBashNetworkSandboxSession(options = {}) {
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
});
|
|
423
|
-
await template?.prepare({ session: session.restricted(), abortSignal });
|
|
424
|
-
return session;
|
|
425
|
-
} catch (error) {
|
|
426
|
-
await nativeSandbox.stop().catch(() => {
|
|
427
|
-
});
|
|
428
|
-
throw error;
|
|
429
|
-
}
|
|
349
|
+
if ("sandbox" in options) throw new Error("createJustBashNetworkSandboxSession: use createJustBashNetworkSandboxSessionFromNativeSandbox for an existing sandbox.");
|
|
350
|
+
const { template, abortSignal, sandboxId, sandbox: _sandbox, ...nativeOptions } = options;
|
|
351
|
+
abortSignal?.throwIfAborted();
|
|
352
|
+
const nativeSandbox = await Sandbox.create(nativeOptions);
|
|
353
|
+
try {
|
|
354
|
+
await ensureRealpath(nativeSandbox);
|
|
355
|
+
const session = new JustBashNetworkSandboxSession({
|
|
356
|
+
sandbox: nativeSandbox,
|
|
357
|
+
sandboxId
|
|
358
|
+
});
|
|
359
|
+
await template?.prepare({
|
|
360
|
+
session: session.restricted(),
|
|
361
|
+
abortSignal
|
|
362
|
+
});
|
|
363
|
+
return session;
|
|
364
|
+
} catch (error) {
|
|
365
|
+
await nativeSandbox.stop().catch(() => {});
|
|
366
|
+
throw error;
|
|
367
|
+
}
|
|
430
368
|
}
|
|
431
369
|
async function resumeJustBashNetworkSandboxSession(options) {
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
message: "just-bash sandboxes run in-process and cannot be resumed by sandboxId."
|
|
435
|
-
});
|
|
370
|
+
options.abortSignal?.throwIfAborted();
|
|
371
|
+
throw new HarnessCapabilityUnsupportedError({ message: "just-bash sandboxes run in-process and cannot be resumed by sandboxId." });
|
|
436
372
|
}
|
|
437
373
|
function createJustBashSandboxSessionFromNativeSandbox(nativeSandbox) {
|
|
438
|
-
|
|
374
|
+
return new JustBashSandboxSession(nativeSandbox);
|
|
439
375
|
}
|
|
440
376
|
function createJustBashNetworkSandboxSessionFromNativeSandbox(nativeSandbox) {
|
|
441
|
-
|
|
377
|
+
return new JustBashNetworkSandboxSession({ sandbox: nativeSandbox });
|
|
442
378
|
}
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
createJustBashNetworkSandboxSessionFromNativeSandbox,
|
|
447
|
-
createJustBashSandbox,
|
|
448
|
-
createJustBashSandboxSessionFromNativeSandbox,
|
|
449
|
-
resumeJustBashNetworkSandboxSession
|
|
450
|
-
};
|
|
379
|
+
//#endregion
|
|
380
|
+
export { JustBashSandboxProvider, createJustBashNetworkSandboxSession, createJustBashNetworkSandboxSessionFromNativeSandbox, createJustBashSandbox, createJustBashSandboxSessionFromNativeSandbox, resumeJustBashNetworkSandboxSession };
|
|
381
|
+
|
|
451
382
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/just-bash-legacy-sandbox-provider.ts","../src/just-bash-network-sandbox-session.ts","../src/just-bash-sandbox-session.ts","../src/utils.ts","../src/just-bash-sandbox.ts"],"sourcesContent":["import type {\n HarnessV1NetworkSandboxSession,\n HarnessV1SandboxProvider,\n} from '@ai-sdk/harness';\nimport type { Experimental_SandboxSession as SandboxSession } from '@ai-sdk/provider-utils';\nimport { Sandbox } from 'just-bash';\nimport { JustBashNetworkSandboxSession } from './just-bash-network-sandbox-session';\nimport { ensureRealpath } from './utils';\n\ntype JustBashSandboxCreateParams = NonNullable<\n Parameters<typeof Sandbox.create>[0]\n>;\n\ntype JustBashCreationSettings = JustBashSandboxCreateParams & {\n sandbox?: never;\n};\n\n/**\n * Settings for `createJustBashSandbox`. Two mutually-exclusive shapes:\n *\n * - `{ sandbox }` — wrap an already-created `just-bash` `Sandbox`. The caller\n * owns its lifecycle.\n * - {@link JustBashSandboxCreateParams} fields — provider calls\n * `Sandbox.create(settings)` on every `createSession()`.\n *\n * just-bash has no port exposure and no snapshot mechanism, so image\n * management is a per-call no-op: if an adapter declares a bootstrap recipe\n * the provider runs it once on the freshly-created sandbox before returning.\n *\n * @deprecated Use `JustBashNetworkSandboxSessionCreateOptions` for new sessions.\n */\nexport type JustBashSandboxSettings =\n | { sandbox: Sandbox }\n | JustBashCreationSettings;\n\nconst JUST_BASH_PROVIDER_ID = 'just-bash-sandbox';\n\n/** @deprecated Use `createJustBashNetworkSandboxSession` instead. */\nexport function createJustBashSandbox(\n settings: JustBashSandboxSettings = {} as JustBashSandboxSettings,\n): HarnessV1SandboxProvider {\n console.warn(\n 'createJustBashSandbox is deprecated. Use createJustBashNetworkSandboxSession and HarnessAgent.createSession({ sandboxSession }) instead.',\n );\n return new JustBashSandboxProvider(settings);\n}\n\n/**\n * `HarnessV1SandboxProvider` implementation backed by `just-bash`. Useful for\n * non-bridge harness flows and for handing a local `Experimental_SandboxSession`\n * to AI SDK tools — use `provider.createSession()` then\n * `sandboxSession.restricted()` to get the latter.\n *\n * Note: just-bash cannot expose ports, so bridge-backed harness adapters\n * (claude-code, codex) will reject this provider at start.\n */\n/** @deprecated Use `createJustBashNetworkSandboxSession` instead. */\nexport class JustBashSandboxProvider implements HarnessV1SandboxProvider {\n readonly specificationVersion = 'harness-sandbox-v1' as const;\n readonly providerId = JUST_BASH_PROVIDER_ID;\n\n constructor(private readonly settings: JustBashSandboxSettings) {\n console.warn(\n 'JustBashSandboxProvider is deprecated. Use createJustBashNetworkSandboxSession instead.',\n );\n }\n\n createSession = async (options?: {\n sessionId?: string;\n abortSignal?: AbortSignal;\n identity?: string;\n onFirstCreate?: (\n session: SandboxSession,\n opts: { abortSignal?: AbortSignal },\n ) => Promise<void>;\n }): Promise<HarnessV1NetworkSandboxSession> => {\n options?.abortSignal?.throwIfAborted();\n\n const ownsLifecycle = !(\n 'sandbox' in this.settings && this.settings.sandbox\n );\n const sandbox = ownsLifecycle\n ? await Sandbox.create(\n this.settings as NonNullable<Parameters<typeof Sandbox.create>[0]>,\n )\n : this.settings.sandbox;\n await ensureRealpath(sandbox);\n const sandboxSession = new JustBashNetworkSandboxSession({\n sandbox,\n });\n\n if (options?.onFirstCreate != null) {\n await options.onFirstCreate(sandboxSession.restricted(), {\n abortSignal: options?.abortSignal,\n });\n }\n\n return sandboxSession;\n };\n}\n","import {\n HarnessCapabilityUnsupportedError,\n type HarnessV1NetworkSandboxSession,\n type HarnessV1PortEndpoint,\n} from '@ai-sdk/harness';\nimport type { Experimental_SandboxSession as SandboxSession } from '@ai-sdk/provider-utils';\nimport { randomUUID } from 'node:crypto';\nimport type { Sandbox } from 'just-bash';\nimport { JustBashSandboxSession } from './just-bash-sandbox-session';\n\nconst JUST_BASH_PROVIDER_ID = 'just-bash-sandbox';\n\n/**\n * `HarnessV1NetworkSandboxSession` backed by a `just-bash` `Sandbox`. It extends\n * {@link JustBashSandboxSession} with the infra surface. Exposes no ports —\n * there is no network namespace and no way to publish an HTTP endpoint\n * reachable from outside the host process. Bridge-backed harness adapters that\n * need `getPortEndpoint` will fail with `HarnessCapabilityUnsupportedError` at\n * start.\n *\n * Network policy is not implementable locally either — `setNetworkPolicy` is\n * omitted.\n */\nexport class JustBashNetworkSandboxSession\n extends JustBashSandboxSession\n implements HarnessV1NetworkSandboxSession\n{\n /**\n * Caller-supplied label or a UUID minted at construct time. just-bash has\n * no native identifier and cannot reattach across processes.\n */\n readonly id: string;\n readonly defaultWorkingDirectory: string;\n\n constructor(input: { sandbox: Sandbox; sandboxId?: string }) {\n super(input.sandbox);\n this.id = input.sandboxId ?? randomUUID();\n this.defaultWorkingDirectory = input.sandbox.bashEnvInstance.getCwd();\n }\n\n readonly ports: ReadonlyArray<number> = [];\n\n restricted(): SandboxSession {\n return new JustBashSandboxSession(this.sandbox);\n }\n\n getPortEndpoint = async (_options: {\n port: number;\n protocol?: 'http' | 'https' | 'ws';\n }): Promise<HarnessV1PortEndpoint> => {\n throw new HarnessCapabilityUnsupportedError({\n harnessId: JUST_BASH_PROVIDER_ID,\n message:\n 'just-bash sandboxes run in-process and cannot expose a port URL. ' +\n 'Use a hosted sandbox (e.g. @ai-sdk/sandbox-vercel) for bridge-backed harness adapters.',\n });\n };\n\n /**\n * @deprecated Use `getPortEndpoint` instead.\n */\n getPortUrl = async (options: {\n port: number;\n protocol?: 'http' | 'https' | 'ws';\n }): Promise<string> => {\n return (await this.getPortEndpoint(options)).url;\n };\n\n stop = async (): Promise<void> => {\n // just-bash has no explicit shutdown; the sandbox is garbage-collected\n // along with its in-memory filesystem once references drop.\n await this.sandbox.stop();\n };\n\n destroy = async (): Promise<void> => {\n await this.stop();\n };\n}\n","import { isAbsolute, posix } from 'node:path';\nimport {\n extractLines,\n type Experimental_SandboxSession as SandboxSession,\n type Experimental_SandboxProcess as SandboxProcess,\n} from '@ai-sdk/provider-utils';\nimport type { Sandbox, SandboxCommand } from 'just-bash';\nimport { ensureRealpath } from './utils';\n\n/**\n * `Experimental_SandboxSession` implementation backed by a `just-bash`\n * `Sandbox`. File operations and spawned processes share the same in-memory\n * filesystem, so a bridge process spawned via `spawn` can read files the host\n * wrote via `writeTextFile` (and vice versa).\n *\n * This is the tool-safe surface returned by\n * `JustBashNetworkSandboxSession.restricted()` — not constructed directly by\n * consumers.\n */\nexport class JustBashSandboxSession implements SandboxSession {\n constructor(protected readonly sandbox: Sandbox) {}\n\n get description(): string {\n return [\n 'just-bash JavaScript bash environment with a virtual filesystem.',\n 'Filesystem changes and spawned processes share the same in-memory state.',\n `Current working directory: ${this.sandbox.bashEnvInstance.getCwd()}`,\n ].join('\\n');\n }\n\n private resolvePath(path: string): string {\n return isAbsolute(path)\n ? path\n : posix.join(this.sandbox.bashEnvInstance.getCwd(), path);\n }\n\n async run({\n command,\n workingDirectory,\n env,\n abortSignal,\n }: {\n command: string;\n workingDirectory?: string;\n env?: Record<string, string>;\n abortSignal?: AbortSignal;\n }): Promise<{ exitCode: number; stdout: string; stderr: string }> {\n abortSignal?.throwIfAborted();\n await ensureRealpath(this.sandbox);\n abortSignal?.throwIfAborted();\n\n const finished = await this.sandbox.runCommand({\n cmd: 'bash',\n args: createBashArgs(command, env),\n ...(workingDirectory !== undefined ? { cwd: workingDirectory } : {}),\n ...(abortSignal !== undefined ? { signal: abortSignal } : {}),\n });\n\n const [stdout, stderr] = await Promise.all([\n finished.stdout(),\n finished.stderr(),\n ]);\n\n return {\n exitCode: finished.exitCode,\n stdout,\n stderr,\n };\n }\n\n async spawn({\n command,\n workingDirectory,\n env,\n abortSignal,\n }: {\n command: string;\n workingDirectory?: string;\n env?: Record<string, string>;\n abortSignal?: AbortSignal;\n }): Promise<SandboxProcess> {\n abortSignal?.throwIfAborted();\n await ensureRealpath(this.sandbox);\n abortSignal?.throwIfAborted();\n\n const live = await this.sandbox.runCommand({\n cmd: 'bash',\n args: createBashArgs(command, env),\n detached: true,\n ...(workingDirectory !== undefined ? { cwd: workingDirectory } : {}),\n ...(abortSignal !== undefined ? { signal: abortSignal } : {}),\n });\n\n return createSandboxProcess(live, abortSignal);\n }\n\n async readFile({\n path,\n abortSignal,\n }: {\n path: string;\n abortSignal?: AbortSignal;\n }): Promise<ReadableStream<Uint8Array> | null> {\n const bytes = await this.readBinaryFile({ path, abortSignal });\n if (bytes == null) return null;\n return bytesToStream(bytes);\n }\n\n async readBinaryFile({\n path,\n abortSignal,\n }: {\n path: string;\n abortSignal?: AbortSignal;\n }): Promise<Uint8Array | null> {\n abortSignal?.throwIfAborted();\n const resolved = this.resolvePath(path);\n try {\n const bytes =\n await this.sandbox.bashEnvInstance.fs.readFileBuffer(resolved);\n return bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);\n } catch (error) {\n if (isFileNotFoundError(error)) return null;\n throw error;\n }\n }\n\n async readTextFile({\n path,\n encoding = 'utf-8',\n startLine,\n endLine,\n abortSignal,\n }: {\n path: string;\n encoding?: string;\n startLine?: number;\n endLine?: number;\n abortSignal?: AbortSignal;\n }): Promise<string | null> {\n const bytes = await this.readBinaryFile({ path, abortSignal });\n if (bytes == null) return null;\n const text = Buffer.from(bytes).toString(encoding as BufferEncoding);\n return extractLines({ text, startLine, endLine });\n }\n\n async writeFile({\n path,\n content,\n abortSignal,\n }: {\n path: string;\n content: ReadableStream<Uint8Array>;\n abortSignal?: AbortSignal;\n }): Promise<void> {\n const bytes = await collectStream(content);\n await this.writeBinaryFile({ path, content: bytes, abortSignal });\n }\n\n async writeBinaryFile({\n path,\n content,\n abortSignal,\n }: {\n path: string;\n content: Uint8Array;\n abortSignal?: AbortSignal;\n }): Promise<void> {\n abortSignal?.throwIfAborted();\n const resolved = this.resolvePath(path);\n await this.sandbox.bashEnvInstance.fs.writeFile(resolved, content);\n }\n\n async writeTextFile({\n path,\n content,\n encoding = 'utf-8',\n abortSignal,\n }: {\n path: string;\n content: string;\n encoding?: string;\n abortSignal?: AbortSignal;\n }): Promise<void> {\n const buffer = Buffer.from(content, encoding as BufferEncoding);\n await this.writeBinaryFile({\n path,\n content: new Uint8Array(\n buffer.buffer,\n buffer.byteOffset,\n buffer.byteLength,\n ),\n abortSignal,\n });\n }\n}\n\nfunction createBashArgs(\n command: string,\n env: Record<string, string> | undefined,\n): string[] {\n // just-bash applies runCommand's env to the outer execution, but its `bash`\n // command only inherits exported variables. Export assignments passed as\n // positional arguments so values are not interpolated into the script.\n const assignments =\n env == null\n ? []\n : Object.entries(env).map(([name, value]) => `${name}=${value}`);\n\n if (assignments.length === 0) {\n return ['-c', command];\n }\n\n return [\n '-c',\n `${assignments.map(() => 'export -- \"$1\"; shift').join('\\n')}\\n${command}`,\n 'bash',\n ...assignments,\n ];\n}\n\nfunction createSandboxProcess(\n command: SandboxCommand,\n abortSignal: AbortSignal | undefined,\n): SandboxProcess {\n const encoder = new TextEncoder();\n const controllers: {\n stdout?: ReadableStreamDefaultController<Uint8Array>;\n stderr?: ReadableStreamDefaultController<Uint8Array>;\n } = {};\n\n const stdout = new ReadableStream<Uint8Array>({\n start(controller) {\n controllers.stdout = controller;\n },\n });\n\n const stderr = new ReadableStream<Uint8Array>({\n start(controller) {\n controllers.stderr = controller;\n },\n });\n\n const drained = (async () => {\n try {\n for await (const message of command.logs()) {\n const target =\n message.type === 'stdout' ? controllers.stdout : controllers.stderr;\n target?.enqueue(encoder.encode(message.data));\n }\n controllers.stdout?.close();\n controllers.stderr?.close();\n } catch (error) {\n controllers.stdout?.error(error);\n controllers.stderr?.error(error);\n }\n })();\n\n return {\n stdout,\n stderr,\n async wait(): Promise<{ exitCode: number }> {\n const finished = await command.wait();\n await drained;\n if (abortSignal?.aborted) {\n throw abortSignal.reason ?? new DOMException('Aborted', 'AbortError');\n }\n return { exitCode: finished.exitCode };\n },\n async kill(): Promise<void> {\n await command.kill();\n },\n };\n}\n\nfunction bytesToStream(bytes: Uint8Array): ReadableStream<Uint8Array> {\n return new ReadableStream<Uint8Array>({\n start(controller) {\n controller.enqueue(bytes);\n controller.close();\n },\n });\n}\n\nasync function collectStream(\n stream: ReadableStream<Uint8Array>,\n): Promise<Uint8Array> {\n const reader = stream.getReader();\n const chunks: Uint8Array[] = [];\n let total = 0;\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n if (value) {\n chunks.push(value);\n total += value.byteLength;\n }\n }\n const out = new Uint8Array(total);\n let offset = 0;\n for (const chunk of chunks) {\n out.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return out;\n}\n\nfunction isFileNotFoundError(error: unknown): boolean {\n if (error == null || typeof error !== 'object') return false;\n const code = (error as { code?: unknown }).code;\n if (code === 'ENOENT') return true;\n const message = (error as { message?: unknown }).message;\n return (\n typeof message === 'string' &&\n /no such file|not found|does not exist|ENOENT/i.test(message)\n );\n}\n","import { defineCommand, type CommandContext, type Sandbox } from 'just-bash';\n\nconst preparations = new WeakMap<Sandbox, Promise<void>>();\n\nexport async function ensureRealpath(sandbox: Sandbox): Promise<void> {\n let preparation = preparations.get(sandbox);\n if (preparation == null) {\n preparation = prepareRealpath(sandbox);\n preparations.set(sandbox, preparation);\n }\n\n try {\n await preparation;\n } catch (error) {\n if (preparations.get(sandbox) === preparation) {\n preparations.delete(sandbox);\n }\n throw error;\n }\n}\n\nasync function prepareRealpath(sandbox: Sandbox): Promise<void> {\n const realpathType = await sandbox.bashEnvInstance.exec('type realpath');\n if (realpathType.exitCode === 0) {\n return;\n }\n\n sandbox.bashEnvInstance.registerCommand(\n defineCommand('realpath', executeRealpath),\n );\n}\n\nasync function executeRealpath(\n args: string[],\n context: CommandContext,\n): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n if (args.length === 0 || args[0] === '') {\n return {\n stdout: '',\n stderr: 'realpath: missing operand\\n',\n exitCode: 1,\n };\n }\n\n let pending = args[0].startsWith('/') ? args[0] : `${context.cwd}/${args[0]}`;\n let resolved = '';\n let linkCount = 0;\n\n while (pending.length > 0) {\n pending = pending.replace(/^\\//, '');\n if (pending.length === 0) {\n break;\n }\n\n const separatorIndex = pending.indexOf('/');\n const component =\n separatorIndex === -1 ? pending : pending.slice(0, separatorIndex);\n pending = separatorIndex === -1 ? '' : pending.slice(separatorIndex + 1);\n\n if (component === '' || component === '.') {\n continue;\n }\n if (component === '..') {\n resolved = resolved.slice(0, resolved.lastIndexOf('/'));\n continue;\n }\n\n const candidate = `${resolved}/${component}`;\n let isSymbolicLink = false;\n try {\n isSymbolicLink = (await context.fs.lstat(candidate)).isSymbolicLink;\n } catch (error) {\n if (!isFileNotFoundError(error)) {\n throw error;\n }\n }\n\n if (!isSymbolicLink) {\n resolved = candidate;\n continue;\n }\n\n linkCount += 1;\n if (linkCount > 64) {\n return { stdout: '', stderr: '', exitCode: 1 };\n }\n\n let target: string;\n try {\n target = await context.fs.readlink(candidate);\n } catch {\n return { stdout: '', stderr: '', exitCode: 1 };\n }\n\n const remainder = pending.length > 0 ? `/${pending}` : '';\n pending = target.startsWith('/')\n ? `${target}${remainder}`\n : `${candidate.slice(0, candidate.lastIndexOf('/'))}/${target}${remainder}`;\n resolved = '';\n }\n\n return {\n stdout: `${resolved || '/'}\\n`,\n stderr: '',\n exitCode: 0,\n };\n}\n\nfunction isFileNotFoundError(error: unknown): boolean {\n if (error == null || typeof error !== 'object') return false;\n const code = (error as { code?: unknown }).code;\n if (code === 'ENOENT') return true;\n const message = (error as { message?: unknown }).message;\n return (\n typeof message === 'string' &&\n /no such file|not found|ENOENT/i.test(message)\n );\n}\n","import {\n HarnessCapabilityUnsupportedError,\n type HarnessV1NetworkSandboxSession,\n type HarnessV1SandboxSessionCreateOptions,\n type HarnessV1SandboxSessionResumeOptions,\n} from '@ai-sdk/harness';\nimport type { Experimental_SandboxSession as SandboxSession } from '@ai-sdk/provider-utils';\nimport { Sandbox } from 'just-bash';\nimport { JustBashNetworkSandboxSession } from './just-bash-network-sandbox-session';\nimport { JustBashSandboxSession } from './just-bash-sandbox-session';\nimport { ensureRealpath } from './utils';\n\n/**\n * Flattens an intersection of object types into a single object type so the\n * resolved shape displays as its named properties rather than a chain of\n * `A & B & C`.\n */\ntype Prettify<T> = { [K in keyof T]: T[K] } & {};\n\nexport type JustBashNativeSandboxSession = Sandbox;\n\n/**\n * Parameters forwarded to `just-bash`'s `Sandbox.create` when creating a\n * sandbox from scratch. Aliased directly from the underlying SDK so the full\n * surface is available without us re-declaring it.\n */\ntype JustBashSandboxCreateParams = NonNullable<\n Parameters<typeof Sandbox.create>[0]\n>;\n\ntype JustBashCreationSettings = Omit<JustBashSandboxCreateParams, 'sandbox'>;\n\nexport type JustBashNetworkSandboxSessionCreateOptions = Prettify<\n HarnessV1SandboxSessionCreateOptions<JustBashCreationSettings> & {\n sandbox?: never;\n }\n>;\n\ntype JustBashLookupSettings = Record<never, never>;\n\nexport type JustBashNetworkSandboxSessionResumeOptions =\n HarnessV1SandboxSessionResumeOptions<JustBashLookupSettings>;\n\nexport async function createJustBashNetworkSandboxSession(\n options: JustBashNetworkSandboxSessionCreateOptions = {},\n): Promise<HarnessV1NetworkSandboxSession> {\n if ('sandbox' in options) {\n throw new Error(\n 'createJustBashNetworkSandboxSession: use createJustBashNetworkSandboxSessionFromNativeSandbox for an existing sandbox.',\n );\n }\n const {\n template,\n abortSignal,\n sandboxId,\n sandbox: _sandbox,\n ...nativeOptions\n } = options;\n abortSignal?.throwIfAborted();\n const nativeSandbox = await Sandbox.create(nativeOptions);\n try {\n await ensureRealpath(nativeSandbox);\n const session = new JustBashNetworkSandboxSession({\n sandbox: nativeSandbox,\n sandboxId,\n });\n await template?.prepare({ session: session.restricted(), abortSignal });\n return session;\n } catch (error) {\n await nativeSandbox.stop().catch(() => {});\n throw error;\n }\n}\n\nexport async function resumeJustBashNetworkSandboxSession(\n options: JustBashNetworkSandboxSessionResumeOptions,\n): Promise<HarnessV1NetworkSandboxSession> {\n options.abortSignal?.throwIfAborted();\n throw new HarnessCapabilityUnsupportedError({\n message:\n 'just-bash sandboxes run in-process and cannot be resumed by sandboxId.',\n });\n}\n\nexport function createJustBashSandboxSessionFromNativeSandbox(\n nativeSandbox: JustBashNativeSandboxSession,\n): SandboxSession {\n return new JustBashSandboxSession(nativeSandbox);\n}\n\nexport function createJustBashNetworkSandboxSessionFromNativeSandbox(\n nativeSandbox: JustBashNativeSandboxSession,\n): HarnessV1NetworkSandboxSession {\n return new JustBashNetworkSandboxSession({ sandbox: nativeSandbox });\n}\n"],"mappings":"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","names":["isFileNotFoundError","JUST_BASH_PROVIDER_ID","HarnessCapabilityUnsupportedError","Sandbox","Sandbox","HarnessCapabilityUnsupportedError"]}
|
|
1
|
+
{"version":3,"file":"index.js","names":["isFileNotFoundError","JUST_BASH_PROVIDER_ID"],"sources":["../src/utils.ts","../src/just-bash-sandbox-session.ts","../src/just-bash-network-sandbox-session.ts","../src/just-bash-legacy-sandbox-provider.ts","../src/just-bash-sandbox.ts"],"sourcesContent":["import { defineCommand, type CommandContext, type Sandbox } from 'just-bash';\n\nconst preparations = new WeakMap<Sandbox, Promise<void>>();\n\nexport async function ensureRealpath(sandbox: Sandbox): Promise<void> {\n let preparation = preparations.get(sandbox);\n if (preparation == null) {\n preparation = prepareRealpath(sandbox);\n preparations.set(sandbox, preparation);\n }\n\n try {\n await preparation;\n } catch (error) {\n if (preparations.get(sandbox) === preparation) {\n preparations.delete(sandbox);\n }\n throw error;\n }\n}\n\nasync function prepareRealpath(sandbox: Sandbox): Promise<void> {\n const realpathType = await sandbox.bashEnvInstance.exec('type realpath');\n if (realpathType.exitCode === 0) {\n return;\n }\n\n sandbox.bashEnvInstance.registerCommand(\n defineCommand('realpath', executeRealpath),\n );\n}\n\nasync function executeRealpath(\n args: string[],\n context: CommandContext,\n): Promise<{ stdout: string; stderr: string; exitCode: number }> {\n if (args.length === 0 || args[0] === '') {\n return {\n stdout: '',\n stderr: 'realpath: missing operand\\n',\n exitCode: 1,\n };\n }\n\n let pending = args[0].startsWith('/') ? args[0] : `${context.cwd}/${args[0]}`;\n let resolved = '';\n let linkCount = 0;\n\n while (pending.length > 0) {\n pending = pending.replace(/^\\//, '');\n if (pending.length === 0) {\n break;\n }\n\n const separatorIndex = pending.indexOf('/');\n const component =\n separatorIndex === -1 ? pending : pending.slice(0, separatorIndex);\n pending = separatorIndex === -1 ? '' : pending.slice(separatorIndex + 1);\n\n if (component === '' || component === '.') {\n continue;\n }\n if (component === '..') {\n resolved = resolved.slice(0, resolved.lastIndexOf('/'));\n continue;\n }\n\n const candidate = `${resolved}/${component}`;\n let isSymbolicLink = false;\n try {\n isSymbolicLink = (await context.fs.lstat(candidate)).isSymbolicLink;\n } catch (error) {\n if (!isFileNotFoundError(error)) {\n throw error;\n }\n }\n\n if (!isSymbolicLink) {\n resolved = candidate;\n continue;\n }\n\n linkCount += 1;\n if (linkCount > 64) {\n return { stdout: '', stderr: '', exitCode: 1 };\n }\n\n let target: string;\n try {\n target = await context.fs.readlink(candidate);\n } catch {\n return { stdout: '', stderr: '', exitCode: 1 };\n }\n\n const remainder = pending.length > 0 ? `/${pending}` : '';\n pending = target.startsWith('/')\n ? `${target}${remainder}`\n : `${candidate.slice(0, candidate.lastIndexOf('/'))}/${target}${remainder}`;\n resolved = '';\n }\n\n return {\n stdout: `${resolved || '/'}\\n`,\n stderr: '',\n exitCode: 0,\n };\n}\n\nfunction isFileNotFoundError(error: unknown): boolean {\n if (error == null || typeof error !== 'object') return false;\n const code = (error as { code?: unknown }).code;\n if (code === 'ENOENT') return true;\n const message = (error as { message?: unknown }).message;\n return (\n typeof message === 'string' &&\n /no such file|not found|ENOENT/i.test(message)\n );\n}\n","import { isAbsolute, posix } from 'node:path';\nimport {\n extractLines,\n type Experimental_SandboxSession as SandboxSession,\n type Experimental_SandboxProcess as SandboxProcess,\n} from '@ai-sdk/provider-utils';\nimport type { Sandbox, SandboxCommand } from 'just-bash';\nimport { ensureRealpath } from './utils';\n\n/**\n * `Experimental_SandboxSession` implementation backed by a `just-bash`\n * `Sandbox`. File operations and spawned processes share the same in-memory\n * filesystem, so a bridge process spawned via `spawn` can read files the host\n * wrote via `writeTextFile` (and vice versa).\n *\n * This is the tool-safe surface returned by\n * `JustBashNetworkSandboxSession.restricted()` — not constructed directly by\n * consumers.\n */\nexport class JustBashSandboxSession implements SandboxSession {\n constructor(protected readonly sandbox: Sandbox) {}\n\n get description(): string {\n return [\n 'just-bash JavaScript bash environment with a virtual filesystem.',\n 'Filesystem changes and spawned processes share the same in-memory state.',\n `Current working directory: ${this.sandbox.bashEnvInstance.getCwd()}`,\n ].join('\\n');\n }\n\n private resolvePath(path: string): string {\n return isAbsolute(path)\n ? path\n : posix.join(this.sandbox.bashEnvInstance.getCwd(), path);\n }\n\n async run({\n command,\n workingDirectory,\n env,\n abortSignal,\n }: {\n command: string;\n workingDirectory?: string;\n env?: Record<string, string>;\n abortSignal?: AbortSignal;\n }): Promise<{ exitCode: number; stdout: string; stderr: string }> {\n abortSignal?.throwIfAborted();\n await ensureRealpath(this.sandbox);\n abortSignal?.throwIfAborted();\n\n const finished = await this.sandbox.runCommand({\n cmd: 'bash',\n args: createBashArgs(command, env),\n ...(workingDirectory !== undefined ? { cwd: workingDirectory } : {}),\n ...(abortSignal !== undefined ? { signal: abortSignal } : {}),\n });\n\n const [stdout, stderr] = await Promise.all([\n finished.stdout(),\n finished.stderr(),\n ]);\n\n return {\n exitCode: finished.exitCode,\n stdout,\n stderr,\n };\n }\n\n async spawn({\n command,\n workingDirectory,\n env,\n abortSignal,\n }: {\n command: string;\n workingDirectory?: string;\n env?: Record<string, string>;\n abortSignal?: AbortSignal;\n }): Promise<SandboxProcess> {\n abortSignal?.throwIfAborted();\n await ensureRealpath(this.sandbox);\n abortSignal?.throwIfAborted();\n\n const live = await this.sandbox.runCommand({\n cmd: 'bash',\n args: createBashArgs(command, env),\n detached: true,\n ...(workingDirectory !== undefined ? { cwd: workingDirectory } : {}),\n ...(abortSignal !== undefined ? { signal: abortSignal } : {}),\n });\n\n return createSandboxProcess(live, abortSignal);\n }\n\n async readFile({\n path,\n abortSignal,\n }: {\n path: string;\n abortSignal?: AbortSignal;\n }): Promise<ReadableStream<Uint8Array> | null> {\n const bytes = await this.readBinaryFile({ path, abortSignal });\n if (bytes == null) return null;\n return bytesToStream(bytes);\n }\n\n async readBinaryFile({\n path,\n abortSignal,\n }: {\n path: string;\n abortSignal?: AbortSignal;\n }): Promise<Uint8Array | null> {\n abortSignal?.throwIfAborted();\n const resolved = this.resolvePath(path);\n try {\n const bytes =\n await this.sandbox.bashEnvInstance.fs.readFileBuffer(resolved);\n return bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes);\n } catch (error) {\n if (isFileNotFoundError(error)) return null;\n throw error;\n }\n }\n\n async readTextFile({\n path,\n encoding = 'utf-8',\n startLine,\n endLine,\n abortSignal,\n }: {\n path: string;\n encoding?: string;\n startLine?: number;\n endLine?: number;\n abortSignal?: AbortSignal;\n }): Promise<string | null> {\n const bytes = await this.readBinaryFile({ path, abortSignal });\n if (bytes == null) return null;\n const text = Buffer.from(bytes).toString(encoding as BufferEncoding);\n return extractLines({ text, startLine, endLine });\n }\n\n async writeFile({\n path,\n content,\n abortSignal,\n }: {\n path: string;\n content: ReadableStream<Uint8Array>;\n abortSignal?: AbortSignal;\n }): Promise<void> {\n const bytes = await collectStream(content);\n await this.writeBinaryFile({ path, content: bytes, abortSignal });\n }\n\n async writeBinaryFile({\n path,\n content,\n abortSignal,\n }: {\n path: string;\n content: Uint8Array;\n abortSignal?: AbortSignal;\n }): Promise<void> {\n abortSignal?.throwIfAborted();\n const resolved = this.resolvePath(path);\n await this.sandbox.bashEnvInstance.fs.writeFile(resolved, content);\n }\n\n async writeTextFile({\n path,\n content,\n encoding = 'utf-8',\n abortSignal,\n }: {\n path: string;\n content: string;\n encoding?: string;\n abortSignal?: AbortSignal;\n }): Promise<void> {\n const buffer = Buffer.from(content, encoding as BufferEncoding);\n await this.writeBinaryFile({\n path,\n content: new Uint8Array(\n buffer.buffer,\n buffer.byteOffset,\n buffer.byteLength,\n ),\n abortSignal,\n });\n }\n}\n\nfunction createBashArgs(\n command: string,\n env: Record<string, string> | undefined,\n): string[] {\n // just-bash applies runCommand's env to the outer execution, but its `bash`\n // command only inherits exported variables. Export assignments passed as\n // positional arguments so values are not interpolated into the script.\n const assignments =\n env == null\n ? []\n : Object.entries(env).map(([name, value]) => `${name}=${value}`);\n\n if (assignments.length === 0) {\n return ['-c', command];\n }\n\n return [\n '-c',\n `${assignments.map(() => 'export -- \"$1\"; shift').join('\\n')}\\n${command}`,\n 'bash',\n ...assignments,\n ];\n}\n\nfunction createSandboxProcess(\n command: SandboxCommand,\n abortSignal: AbortSignal | undefined,\n): SandboxProcess {\n const encoder = new TextEncoder();\n const controllers: {\n stdout?: ReadableStreamDefaultController<Uint8Array>;\n stderr?: ReadableStreamDefaultController<Uint8Array>;\n } = {};\n\n const stdout = new ReadableStream<Uint8Array>({\n start(controller) {\n controllers.stdout = controller;\n },\n });\n\n const stderr = new ReadableStream<Uint8Array>({\n start(controller) {\n controllers.stderr = controller;\n },\n });\n\n const drained = (async () => {\n try {\n for await (const message of command.logs()) {\n const target =\n message.type === 'stdout' ? controllers.stdout : controllers.stderr;\n target?.enqueue(encoder.encode(message.data));\n }\n controllers.stdout?.close();\n controllers.stderr?.close();\n } catch (error) {\n controllers.stdout?.error(error);\n controllers.stderr?.error(error);\n }\n })();\n\n return {\n stdout,\n stderr,\n async wait(): Promise<{ exitCode: number }> {\n const finished = await command.wait();\n await drained;\n if (abortSignal?.aborted) {\n throw abortSignal.reason ?? new DOMException('Aborted', 'AbortError');\n }\n return { exitCode: finished.exitCode };\n },\n async kill(): Promise<void> {\n await command.kill();\n },\n };\n}\n\nfunction bytesToStream(bytes: Uint8Array): ReadableStream<Uint8Array> {\n return new ReadableStream<Uint8Array>({\n start(controller) {\n controller.enqueue(bytes);\n controller.close();\n },\n });\n}\n\nasync function collectStream(\n stream: ReadableStream<Uint8Array>,\n): Promise<Uint8Array> {\n const reader = stream.getReader();\n const chunks: Uint8Array[] = [];\n let total = 0;\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n if (value) {\n chunks.push(value);\n total += value.byteLength;\n }\n }\n const out = new Uint8Array(total);\n let offset = 0;\n for (const chunk of chunks) {\n out.set(chunk, offset);\n offset += chunk.byteLength;\n }\n return out;\n}\n\nfunction isFileNotFoundError(error: unknown): boolean {\n if (error == null || typeof error !== 'object') return false;\n const code = (error as { code?: unknown }).code;\n if (code === 'ENOENT') return true;\n const message = (error as { message?: unknown }).message;\n return (\n typeof message === 'string' &&\n /no such file|not found|does not exist|ENOENT/i.test(message)\n );\n}\n","import {\n HarnessCapabilityUnsupportedError,\n type HarnessV1NetworkSandboxSession,\n type HarnessV1PortEndpoint,\n} from '@ai-sdk/harness';\nimport type { Experimental_SandboxSession as SandboxSession } from '@ai-sdk/provider-utils';\nimport { randomUUID } from 'node:crypto';\nimport type { Sandbox } from 'just-bash';\nimport { JustBashSandboxSession } from './just-bash-sandbox-session';\n\nconst JUST_BASH_PROVIDER_ID = 'just-bash-sandbox';\n\n/**\n * `HarnessV1NetworkSandboxSession` backed by a `just-bash` `Sandbox`. It extends\n * {@link JustBashSandboxSession} with the infra surface. Exposes no ports —\n * there is no network namespace and no way to publish an HTTP endpoint\n * reachable from outside the host process. Bridge-backed harness adapters that\n * need `getPortEndpoint` will fail with `HarnessCapabilityUnsupportedError` at\n * start.\n *\n * Network policy is not implementable locally either — `setNetworkPolicy` is\n * omitted.\n */\nexport class JustBashNetworkSandboxSession\n extends JustBashSandboxSession\n implements HarnessV1NetworkSandboxSession\n{\n /**\n * Caller-supplied label or a UUID minted at construct time. just-bash has\n * no native identifier and cannot reattach across processes.\n */\n readonly id: string;\n readonly defaultWorkingDirectory: string;\n\n constructor(input: { sandbox: Sandbox; sandboxId?: string }) {\n super(input.sandbox);\n this.id = input.sandboxId ?? randomUUID();\n this.defaultWorkingDirectory = input.sandbox.bashEnvInstance.getCwd();\n }\n\n readonly ports: ReadonlyArray<number> = [];\n\n restricted(): SandboxSession {\n return new JustBashSandboxSession(this.sandbox);\n }\n\n getPortEndpoint = async (_options: {\n port: number;\n protocol?: 'http' | 'https' | 'ws';\n }): Promise<HarnessV1PortEndpoint> => {\n throw new HarnessCapabilityUnsupportedError({\n harnessId: JUST_BASH_PROVIDER_ID,\n message:\n 'just-bash sandboxes run in-process and cannot expose a port URL. ' +\n 'Use a hosted sandbox (e.g. @ai-sdk/sandbox-vercel) for bridge-backed harness adapters.',\n });\n };\n\n /**\n * @deprecated Use `getPortEndpoint` instead.\n */\n getPortUrl = async (options: {\n port: number;\n protocol?: 'http' | 'https' | 'ws';\n }): Promise<string> => {\n return (await this.getPortEndpoint(options)).url;\n };\n\n stop = async (): Promise<void> => {\n // just-bash has no explicit shutdown; the sandbox is garbage-collected\n // along with its in-memory filesystem once references drop.\n await this.sandbox.stop();\n };\n\n destroy = async (): Promise<void> => {\n await this.stop();\n };\n}\n","import type {\n HarnessV1NetworkSandboxSession,\n HarnessV1SandboxProvider,\n} from '@ai-sdk/harness';\nimport type { Experimental_SandboxSession as SandboxSession } from '@ai-sdk/provider-utils';\nimport { Sandbox } from 'just-bash';\nimport { JustBashNetworkSandboxSession } from './just-bash-network-sandbox-session';\nimport { ensureRealpath } from './utils';\n\ntype JustBashSandboxCreateParams = NonNullable<\n Parameters<typeof Sandbox.create>[0]\n>;\n\ntype JustBashCreationSettings = JustBashSandboxCreateParams & {\n sandbox?: never;\n};\n\n/**\n * Settings for `createJustBashSandbox`. Two mutually-exclusive shapes:\n *\n * - `{ sandbox }` — wrap an already-created `just-bash` `Sandbox`. The caller\n * owns its lifecycle.\n * - {@link JustBashSandboxCreateParams} fields — provider calls\n * `Sandbox.create(settings)` on every `createSession()`.\n *\n * just-bash has no port exposure and no snapshot mechanism, so image\n * management is a per-call no-op: if an adapter declares a bootstrap recipe\n * the provider runs it once on the freshly-created sandbox before returning.\n *\n * @deprecated Use `JustBashNetworkSandboxSessionCreateOptions` for new sessions.\n */\nexport type JustBashSandboxSettings =\n | { sandbox: Sandbox }\n | JustBashCreationSettings;\n\nconst JUST_BASH_PROVIDER_ID = 'just-bash-sandbox';\n\n/** @deprecated Use `createJustBashNetworkSandboxSession` instead. */\nexport function createJustBashSandbox(\n settings: JustBashSandboxSettings = {} as JustBashSandboxSettings,\n): HarnessV1SandboxProvider {\n console.warn(\n 'createJustBashSandbox is deprecated. Use createJustBashNetworkSandboxSession and HarnessAgent.createSession({ sandboxSession }) instead.',\n );\n return new JustBashSandboxProvider(settings);\n}\n\n/**\n * `HarnessV1SandboxProvider` implementation backed by `just-bash`. Useful for\n * non-bridge harness flows and for handing a local `Experimental_SandboxSession`\n * to AI SDK tools — use `provider.createSession()` then\n * `sandboxSession.restricted()` to get the latter.\n *\n * Note: just-bash cannot expose ports, so bridge-backed harness adapters\n * (claude-code, codex) will reject this provider at start.\n */\n/** @deprecated Use `createJustBashNetworkSandboxSession` instead. */\nexport class JustBashSandboxProvider implements HarnessV1SandboxProvider {\n readonly specificationVersion = 'harness-sandbox-v1' as const;\n readonly providerId = JUST_BASH_PROVIDER_ID;\n\n constructor(private readonly settings: JustBashSandboxSettings) {\n console.warn(\n 'JustBashSandboxProvider is deprecated. Use createJustBashNetworkSandboxSession instead.',\n );\n }\n\n createSession = async (options?: {\n sessionId?: string;\n abortSignal?: AbortSignal;\n identity?: string;\n onFirstCreate?: (\n session: SandboxSession,\n opts: { abortSignal?: AbortSignal },\n ) => Promise<void>;\n }): Promise<HarnessV1NetworkSandboxSession> => {\n options?.abortSignal?.throwIfAborted();\n\n const ownsLifecycle = !(\n 'sandbox' in this.settings && this.settings.sandbox\n );\n const sandbox = ownsLifecycle\n ? await Sandbox.create(\n this.settings as NonNullable<Parameters<typeof Sandbox.create>[0]>,\n )\n : this.settings.sandbox;\n await ensureRealpath(sandbox);\n const sandboxSession = new JustBashNetworkSandboxSession({\n sandbox,\n });\n\n if (options?.onFirstCreate != null) {\n await options.onFirstCreate(sandboxSession.restricted(), {\n abortSignal: options?.abortSignal,\n });\n }\n\n return sandboxSession;\n };\n}\n","import {\n HarnessCapabilityUnsupportedError,\n type HarnessV1NetworkSandboxSession,\n type HarnessV1SandboxSessionCreateOptions,\n type HarnessV1SandboxSessionResumeOptions,\n} from '@ai-sdk/harness';\nimport type { Experimental_SandboxSession as SandboxSession } from '@ai-sdk/provider-utils';\nimport { Sandbox } from 'just-bash';\nimport { JustBashNetworkSandboxSession } from './just-bash-network-sandbox-session';\nimport { JustBashSandboxSession } from './just-bash-sandbox-session';\nimport { ensureRealpath } from './utils';\n\n/**\n * Flattens an intersection of object types into a single object type so the\n * resolved shape displays as its named properties rather than a chain of\n * `A & B & C`.\n */\ntype Prettify<T> = { [K in keyof T]: T[K] } & {};\n\nexport type JustBashNativeSandboxSession = Sandbox;\n\n/**\n * Parameters forwarded to `just-bash`'s `Sandbox.create` when creating a\n * sandbox from scratch. Aliased directly from the underlying SDK so the full\n * surface is available without us re-declaring it.\n */\ntype JustBashSandboxCreateParams = NonNullable<\n Parameters<typeof Sandbox.create>[0]\n>;\n\ntype JustBashCreationSettings = Omit<JustBashSandboxCreateParams, 'sandbox'>;\n\nexport type JustBashNetworkSandboxSessionCreateOptions = Prettify<\n HarnessV1SandboxSessionCreateOptions<JustBashCreationSettings> & {\n sandbox?: never;\n }\n>;\n\ntype JustBashLookupSettings = Record<never, never>;\n\nexport type JustBashNetworkSandboxSessionResumeOptions = Prettify<\n HarnessV1SandboxSessionResumeOptions<JustBashLookupSettings>\n>;\n\nexport async function createJustBashNetworkSandboxSession(\n options: JustBashNetworkSandboxSessionCreateOptions = {},\n): Promise<HarnessV1NetworkSandboxSession> {\n if ('sandbox' in options) {\n throw new Error(\n 'createJustBashNetworkSandboxSession: use createJustBashNetworkSandboxSessionFromNativeSandbox for an existing sandbox.',\n );\n }\n const {\n template,\n abortSignal,\n sandboxId,\n sandbox: _sandbox,\n ...nativeOptions\n } = options;\n abortSignal?.throwIfAborted();\n const nativeSandbox = await Sandbox.create(nativeOptions);\n try {\n await ensureRealpath(nativeSandbox);\n const session = new JustBashNetworkSandboxSession({\n sandbox: nativeSandbox,\n sandboxId,\n });\n await template?.prepare({ session: session.restricted(), abortSignal });\n return session;\n } catch (error) {\n await nativeSandbox.stop().catch(() => {});\n throw error;\n }\n}\n\nexport async function resumeJustBashNetworkSandboxSession(\n options: JustBashNetworkSandboxSessionResumeOptions,\n): Promise<HarnessV1NetworkSandboxSession> {\n options.abortSignal?.throwIfAborted();\n throw new HarnessCapabilityUnsupportedError({\n message:\n 'just-bash sandboxes run in-process and cannot be resumed by sandboxId.',\n });\n}\n\nexport function createJustBashSandboxSessionFromNativeSandbox(\n nativeSandbox: JustBashNativeSandboxSession,\n): SandboxSession {\n return new JustBashSandboxSession(nativeSandbox);\n}\n\nexport function createJustBashNetworkSandboxSessionFromNativeSandbox(\n nativeSandbox: JustBashNativeSandboxSession,\n): HarnessV1NetworkSandboxSession {\n return new JustBashNetworkSandboxSession({ sandbox: nativeSandbox });\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/sandbox-just-bash",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.135",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -26,14 +26,14 @@
|
|
|
26
26
|
}
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@ai-sdk/harness": "1.0.
|
|
30
|
-
"@ai-sdk/provider-utils": "5.0.
|
|
29
|
+
"@ai-sdk/harness": "1.0.135",
|
|
30
|
+
"@ai-sdk/provider-utils": "5.0.53",
|
|
31
31
|
"just-bash": "^2.14.5"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
34
|
"@types/node": "22.19.19",
|
|
35
35
|
"@vercel/ai-tsconfig": "0.0.0",
|
|
36
|
-
"
|
|
36
|
+
"tsdown": "^0.23.0",
|
|
37
37
|
"typescript": "5.8.3"
|
|
38
38
|
},
|
|
39
39
|
"engines": {
|
|
@@ -58,9 +58,9 @@
|
|
|
58
58
|
"just-bash"
|
|
59
59
|
],
|
|
60
60
|
"scripts": {
|
|
61
|
-
"build": "pnpm clean &&
|
|
62
|
-
"build:watch": "pnpm clean &&
|
|
63
|
-
"clean": "del-cli
|
|
61
|
+
"build": "pnpm clean && tsdown",
|
|
62
|
+
"build:watch": "pnpm clean && tsdown --watch",
|
|
63
|
+
"clean": "del-cli *.tsbuildinfo",
|
|
64
64
|
"type-check": "tsc --build",
|
|
65
65
|
"test": "pnpm test:node",
|
|
66
66
|
"test:watch": "vitest --config vitest.node.config.js",
|
package/src/just-bash-sandbox.ts
CHANGED
|
@@ -38,8 +38,9 @@ export type JustBashNetworkSandboxSessionCreateOptions = Prettify<
|
|
|
38
38
|
|
|
39
39
|
type JustBashLookupSettings = Record<never, never>;
|
|
40
40
|
|
|
41
|
-
export type JustBashNetworkSandboxSessionResumeOptions =
|
|
42
|
-
HarnessV1SandboxSessionResumeOptions<JustBashLookupSettings
|
|
41
|
+
export type JustBashNetworkSandboxSessionResumeOptions = Prettify<
|
|
42
|
+
HarnessV1SandboxSessionResumeOptions<JustBashLookupSettings>
|
|
43
|
+
>;
|
|
43
44
|
|
|
44
45
|
export async function createJustBashNetworkSandboxSession(
|
|
45
46
|
options: JustBashNetworkSandboxSessionCreateOptions = {},
|