@gitterm/sdk 0.11.0 → 0.12.0
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 +37 -3
- package/dist/client.d.ts +49 -1
- package/dist/direct/boat.d.ts +2 -0
- package/dist/direct/index.d.ts +2 -2
- package/dist/direct/index.js +763 -346
- package/dist/direct/types.d.ts +9 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.js +50 -0
- package/dist/sandbox/artifacts.d.ts +33 -0
- package/dist/sandbox/backend.d.ts +98 -0
- package/dist/sandbox/client.d.ts +174 -0
- package/dist/sandbox/config.d.ts +128 -0
- package/dist/sandbox/index.d.ts +10 -0
- package/dist/sandbox/index.js +3974 -0
- package/dist/sandbox/jobs.d.ts +41 -0
- package/dist/sandbox/proxy.d.ts +21 -0
- package/dist/sandbox/setup-snapshots.d.ts +38 -0
- package/dist/sandbox/source.d.ts +57 -0
- package/dist/sandbox/store.d.ts +78 -0
- package/dist/sandbox/store.js +100 -0
- package/dist/sandbox/tar.d.ts +12 -0
- package/dist/sandbox/types.d.ts +39 -0
- package/dist/types.d.ts +51 -2
- package/package.json +15 -3
- package/dist/direct/ascii.d.ts +0 -2
package/dist/direct/types.d.ts
CHANGED
|
@@ -89,6 +89,11 @@ export type DirectAuthMethod = {
|
|
|
89
89
|
id: string;
|
|
90
90
|
label: string;
|
|
91
91
|
form?: DirectAuthPrompt[];
|
|
92
|
+
} | {
|
|
93
|
+
type: "external";
|
|
94
|
+
id: string;
|
|
95
|
+
label: string;
|
|
96
|
+
form?: DirectAuthPrompt[];
|
|
92
97
|
} | {
|
|
93
98
|
type: "command";
|
|
94
99
|
id: string;
|
|
@@ -112,7 +117,7 @@ export type DirectAuthIntegration = {
|
|
|
112
117
|
type: "credential";
|
|
113
118
|
id: string;
|
|
114
119
|
label: string;
|
|
115
|
-
method: "key" | "oauth";
|
|
120
|
+
method: "key" | "oauth" | "external";
|
|
116
121
|
} | {
|
|
117
122
|
type: "env";
|
|
118
123
|
name: string;
|
|
@@ -301,8 +306,8 @@ export type VercelDirectProviderConfig = {
|
|
|
301
306
|
vcpus?: number;
|
|
302
307
|
timeoutMs?: number;
|
|
303
308
|
};
|
|
304
|
-
export type
|
|
305
|
-
type: "
|
|
309
|
+
export type BoatDirectProviderConfig = {
|
|
310
|
+
type: "boat";
|
|
306
311
|
apiKey: string;
|
|
307
312
|
size?: "small" | "default" | "large";
|
|
308
313
|
runtimeSetupCommands?: string[];
|
|
@@ -333,7 +338,7 @@ export type RailwayDirectProviderConfig = {
|
|
|
333
338
|
image?: string;
|
|
334
339
|
runtimePort?: number;
|
|
335
340
|
};
|
|
336
|
-
export type DirectProviderConfig = E2BDirectProviderConfig | DaytonaDirectProviderConfig | VercelDirectProviderConfig |
|
|
341
|
+
export type DirectProviderConfig = E2BDirectProviderConfig | DaytonaDirectProviderConfig | VercelDirectProviderConfig | BoatDirectProviderConfig | ExeDevDirectProviderConfig | RailwayDirectProviderConfig;
|
|
337
342
|
export type DirectRunCreateInput = {
|
|
338
343
|
workspace: DirectWorkspace;
|
|
339
344
|
prompt: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -6,4 +6,4 @@ export type { DeviceCodeInfo, LoginWithDeviceCodeOptions } from "./device-login.
|
|
|
6
6
|
export { AgentRunError, GittermError, WorkspaceLifecycleError } from "./errors.js";
|
|
7
7
|
export { createGittermWorkspaceClient, getWorkspaceEnvironment, type GittermWorkspaceClient, type WorkspaceClientOptions, type WorkspaceEnvironment, type WorkspacePort, type WorkspacePortVisibility, type WorkspaceSelf, } from "./workspace-client.js";
|
|
8
8
|
export type { CredentialErrorCode, GittermErrorCode, WorkspaceLifecycleErrorCode, } from "./errors.js";
|
|
9
|
-
export type { AgentPermissionRequest, AgentQuestion, AgentQuestionOption, AgentQuestionRequest, AgentRun, AgentRunAttachment, AgentRunCreateInput, AgentRunInputRequest, AgentRunMessage, AgentRunMessagePart, AgentRunReply, AgentRunStatus, AgentRunEvent, AgentRunResult, AgentRunReplyPermission, AgentRunReplyQuestion, RunResultOptions, RunRef, RunWaitOptions, RunWatchOptions, AgentType, AgentKey, AuthStatus, BuiltInAgentKey, CloudProvider, ProviderKey, Workspace, WorkspaceCreateInput, WorkspaceCreateResult, WorkspaceCatalog, WorkspaceEnsureRunningResult, WorkspaceHostingType, WorkspaceListOptions, WorkspaceListResult, WorkspaceRestartResult, WorkspaceRuntimeAccess, WorkspaceStatus, WorkspaceSetupStatus, ModelCredential, ModelProviderInfo, ModelCredentialSource, WorkspaceModelsInput, WorkspaceModelAccess, WorkspacePauseResult, WorkspaceTerminateResult, WorkspaceProviderSelection, Integration, IntegrationKey, IntegrationCategory, Connection, SavedBot, ConnectionKind, ConnectionStatus, ConnectionDetails, GitHubConnectionDetails, GoogleConnectionDetails, McpConnectionDetails, McpAuthentication, CreateMcpConnectionInput, UpdateMcpConnectionInput, McpConnectionTestResult, CreateConnectionInput, CreateConnectionResult, GitHubRepository, GitHubBranch, GoogleSetup, } from "./types.js";
|
|
9
|
+
export type { AgentPermissionRequest, AgentQuestion, AgentQuestionOption, AgentQuestionRequest, AgentRun, AgentRunAttachment, AgentRunCreateInput, AgentRunInputRequest, AgentRunMessage, AgentRunMessagePart, AgentRunReply, AgentRunStatus, AgentRunEvent, AgentRunResult, AgentRunReplyPermission, AgentRunReplyQuestion, RunResultOptions, RunRef, RunWaitOptions, RunWatchOptions, AgentType, AgentKey, AuthStatus, BuiltInAgentKey, CloudProvider, ProviderKey, Workspace, WorkspaceCreateInput, WorkspaceCreateResult, WorkspaceCatalog, WorkspaceEnsureRunningResult, WorkspaceHostingType, WorkspaceListOptions, WorkspaceListResult, WorkspaceRestartResult, WorkspaceRuntimeAccess, WorkspaceStatus, WorkspaceSetupStatus, ModelCredential, ModelProviderInfo, ModelCredentialSource, WorkspaceModelsInput, WorkspaceModelAccess, WorkspacePauseResult, WorkspaceTerminateResult, WorkspaceProviderSelection, Integration, IntegrationKey, IntegrationCategory, Connection, SavedBot, ConnectionKind, ConnectionStatus, ConnectionDetails, GitHubConnectionDetails, GoogleConnectionDetails, McpConnectionDetails, McpAuthentication, CreateMcpConnectionInput, UpdateMcpConnectionInput, McpConnectionTestResult, CreateConnectionInput, CreateConnectionResult, GitHubRepository, GitHubBranch, GoogleSetup, ManagedSandbox, ManagedSandboxCreateInput, ManagedSandboxSnapshot, SandboxJobFinished, } from "./types.js";
|
package/dist/index.js
CHANGED
|
@@ -652,6 +652,56 @@ ${log}` : ""}`);
|
|
|
652
652
|
setupStatus: (ref) => run(async () => trpc.workspace.getSetupStatus.query({ workspaceId: workspaceIdOf(ref) })),
|
|
653
653
|
waitForSetup: (ref, waitOptions) => run(() => waitForWorkspaceSetup(workspaceIdOf(ref), waitOptions))
|
|
654
654
|
},
|
|
655
|
+
sandboxes: {
|
|
656
|
+
create: (input) => run(() => trpc.sandbox.create.mutate(input)),
|
|
657
|
+
list: (input) => run(() => trpc.sandbox.list.query(input)),
|
|
658
|
+
get: (sandboxId) => run(() => trpc.sandbox.get.query({ sandboxId })),
|
|
659
|
+
run: (sandboxId, command, options) => run(async () => {
|
|
660
|
+
const result = await trpc.sandbox.run.mutate({ sandboxId, command, ...options });
|
|
661
|
+
if (!result)
|
|
662
|
+
throw new GittermError("SERVER_ERROR", "Sandbox command returned no result");
|
|
663
|
+
return result;
|
|
664
|
+
}),
|
|
665
|
+
writeFile: (sandboxId, path, data) => run(async () => {
|
|
666
|
+
await trpc.sandbox.writeFile.mutate({
|
|
667
|
+
sandboxId,
|
|
668
|
+
path,
|
|
669
|
+
contentBase64: Buffer.from(data).toString("base64")
|
|
670
|
+
});
|
|
671
|
+
}),
|
|
672
|
+
readFile: (sandboxId, path) => run(async () => {
|
|
673
|
+
const result = await trpc.sandbox.readFile.mutate({ sandboxId, path });
|
|
674
|
+
return new Uint8Array(Buffer.from(result?.contentBase64 ?? "", "base64"));
|
|
675
|
+
}),
|
|
676
|
+
preview: (sandboxId, port, options) => run(async () => {
|
|
677
|
+
const result = await trpc.sandbox.preview.mutate({
|
|
678
|
+
sandboxId,
|
|
679
|
+
port,
|
|
680
|
+
public: options?.public
|
|
681
|
+
});
|
|
682
|
+
if (!result)
|
|
683
|
+
throw new GittermError("SERVER_ERROR", "Sandbox preview returned no result");
|
|
684
|
+
return result;
|
|
685
|
+
}),
|
|
686
|
+
resume: (sandboxId) => run(async () => {
|
|
687
|
+
await trpc.workspace.restartWorkspace.mutate({ workspaceId: sandboxId });
|
|
688
|
+
}),
|
|
689
|
+
terminate: (sandboxId) => run(async () => {
|
|
690
|
+
await trpc.sandbox.terminate.mutate({ sandboxId });
|
|
691
|
+
}),
|
|
692
|
+
saveSnapshot: (sandboxId, label) => run(() => trpc.sandbox.saveSnapshot.mutate({ sandboxId, label: label.slice(0, 120) })),
|
|
693
|
+
listSnapshots: () => run(() => trpc.sandbox.snapshots.query()),
|
|
694
|
+
deleteSnapshot: (snapshotId) => run(async () => {
|
|
695
|
+
await trpc.sandbox.deleteSnapshot.mutate({ snapshotId });
|
|
696
|
+
}),
|
|
697
|
+
onJobFinished: (listener) => {
|
|
698
|
+
const subscription = trpc.sandbox.jobEvents.subscribe(undefined, {
|
|
699
|
+
onData: (event) => listener(event),
|
|
700
|
+
onError: () => {}
|
|
701
|
+
});
|
|
702
|
+
return () => subscription.unsubscribe();
|
|
703
|
+
}
|
|
704
|
+
},
|
|
655
705
|
runs: {
|
|
656
706
|
create: (input) => run(async () => {
|
|
657
707
|
const { signal, workspace, ...rest } = input;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { SandboxBackend } from "./backend.js";
|
|
2
|
+
import { type SourceSnapshot } from "./source.js";
|
|
3
|
+
export declare const MAX_ARTIFACT_BYTES: number;
|
|
4
|
+
export type FetchedArtifact = {
|
|
5
|
+
remotePath: string;
|
|
6
|
+
/** Outside the checkout. Local project files are untouched until `applyArtifact`. */
|
|
7
|
+
localPath: string;
|
|
8
|
+
sha256: string;
|
|
9
|
+
bytes: number;
|
|
10
|
+
/** The downloaded bytes match the sha256 computed inside the sandbox. */
|
|
11
|
+
verified: true;
|
|
12
|
+
};
|
|
13
|
+
export declare function artifactDirectory(): string;
|
|
14
|
+
/** Relative paths resolve from the sandbox project directory. */
|
|
15
|
+
export declare function remotePath(home: string, file: string): string;
|
|
16
|
+
export declare function fetchArtifact(backend: SandboxBackend, sandboxId: string, file: string, options?: {
|
|
17
|
+
maxBytes?: number;
|
|
18
|
+
}): Promise<FetchedArtifact>;
|
|
19
|
+
export declare class ArtifactConflictError extends Error {
|
|
20
|
+
constructor(message: string);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Copies a fetched artifact into the checkout. Refuses when the local target changed
|
|
24
|
+
* since the snapshot the job ran on, so remote output never overwrites newer local work.
|
|
25
|
+
*/
|
|
26
|
+
export declare function applyArtifact(input: {
|
|
27
|
+
artifact: Pick<FetchedArtifact, "localPath" | "sha256">;
|
|
28
|
+
snapshot: Pick<SourceSnapshot, "root" | "files" | "id">;
|
|
29
|
+
target: string;
|
|
30
|
+
}): Promise<{
|
|
31
|
+
path: string;
|
|
32
|
+
sha256: string;
|
|
33
|
+
}>;
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type { GittermClient } from "../client.js";
|
|
2
|
+
import { GittermError } from "../errors.js";
|
|
3
|
+
import type { SandboxCapabilities, SandboxCommandResult, SandboxPreviewAccess, SandboxProviderKey } from "./types.js";
|
|
4
|
+
/** `managed`: billed to a Gitterm account. `direct`: your own provider account and credentials. */
|
|
5
|
+
export type SandboxMode = "managed" | "direct";
|
|
6
|
+
export type SandboxProvider = SandboxProviderKey;
|
|
7
|
+
/** Who owns and pays for a sandbox. Part of every reference; never inferred. */
|
|
8
|
+
export type SandboxIdentity = {
|
|
9
|
+
mode: SandboxMode;
|
|
10
|
+
provider: SandboxProvider;
|
|
11
|
+
account: string;
|
|
12
|
+
};
|
|
13
|
+
export type SandboxRef = SandboxIdentity & {
|
|
14
|
+
id: string;
|
|
15
|
+
};
|
|
16
|
+
/** `deleting`: terminated in Gitterm, provider deletion not yet confirmed (managed only). */
|
|
17
|
+
export type SandboxState = "pending" | "running" | "paused" | "deleting" | "terminated";
|
|
18
|
+
export type SandboxInfo = SandboxRef & {
|
|
19
|
+
state: SandboxState;
|
|
20
|
+
name: string | null;
|
|
21
|
+
createdAt: string | null;
|
|
22
|
+
/** When the sandbox is deleted regardless of activity, if anything enforces that. */
|
|
23
|
+
expiresAt: string | null;
|
|
24
|
+
labels: Record<string, string>;
|
|
25
|
+
};
|
|
26
|
+
export type SandboxCreateRequest = {
|
|
27
|
+
name: string;
|
|
28
|
+
lifetimeMs: number;
|
|
29
|
+
labels: Record<string, string>;
|
|
30
|
+
publicPreviews: boolean;
|
|
31
|
+
/** Start from this snapshot instead of the account's image. */
|
|
32
|
+
snapshot?: string;
|
|
33
|
+
};
|
|
34
|
+
/** Provider snapshots of a sandbox's disk. Stored in, and billed to, the provider account. */
|
|
35
|
+
export type SandboxSnapshotSupport = {
|
|
36
|
+
/** What saving does to the sandbox: `pauses` it briefly, or `stops` it for good (Vercel). */
|
|
37
|
+
effect: "pauses" | "stops";
|
|
38
|
+
/** Returns the id new sandboxes start from. */
|
|
39
|
+
create(id: string, name: string): Promise<string>;
|
|
40
|
+
delete(snapshotId: string): Promise<void>;
|
|
41
|
+
};
|
|
42
|
+
/** The primitives a provider account offers. Jobs, sync, and artifacts are built on these. */
|
|
43
|
+
export interface SandboxBackend {
|
|
44
|
+
readonly identity: SandboxIdentity;
|
|
45
|
+
/** Home directory of the command user in the sandbox. */
|
|
46
|
+
readonly home: string;
|
|
47
|
+
readonly capabilities: SandboxCapabilities;
|
|
48
|
+
create(input: SandboxCreateRequest): Promise<SandboxInfo>;
|
|
49
|
+
/** Returns `terminated` for a sandbox that no longer exists in this account. */
|
|
50
|
+
get(id: string): Promise<SandboxInfo>;
|
|
51
|
+
list(): Promise<SandboxInfo[]>;
|
|
52
|
+
destroy(id: string): Promise<void>;
|
|
53
|
+
/** Managed sandboxes pause when idle; direct sandboxes are deleted at their deadline instead. */
|
|
54
|
+
resume?(id: string): Promise<void>;
|
|
55
|
+
run(id: string, command: string, options?: {
|
|
56
|
+
cwd?: string;
|
|
57
|
+
timeoutMs?: number;
|
|
58
|
+
env?: Record<string, string>;
|
|
59
|
+
}): Promise<SandboxCommandResult>;
|
|
60
|
+
writeFile(id: string, path: string, data: Uint8Array): Promise<void>;
|
|
61
|
+
readFile(id: string, path: string): Promise<Uint8Array>;
|
|
62
|
+
/**
|
|
63
|
+
* `gittermUrl` is set when Gitterm serves the preview: open to anyone if `public`, else
|
|
64
|
+
* only to the owner signed in to Gitterm. `url` and `headers` reach the provider directly.
|
|
65
|
+
*/
|
|
66
|
+
preview(id: string, port: number, options?: {
|
|
67
|
+
public?: boolean;
|
|
68
|
+
}): Promise<SandboxPreviewAccess & {
|
|
69
|
+
gittermUrl?: string;
|
|
70
|
+
}>;
|
|
71
|
+
/**
|
|
72
|
+
* Pushes job completions as they happen, where the backend can (Gitterm sandboxes on
|
|
73
|
+
* gitterm.dev). Without it, callers learn a job finished by reading it. Returns a stop function.
|
|
74
|
+
*/
|
|
75
|
+
onJobFinished?(listener: (event: {
|
|
76
|
+
sandboxId: string;
|
|
77
|
+
jobId: string;
|
|
78
|
+
}) => void): () => void;
|
|
79
|
+
/** Present on direct accounts whose provider can snapshot a sandbox. */
|
|
80
|
+
snapshots?: SandboxSnapshotSupport;
|
|
81
|
+
}
|
|
82
|
+
/** What a managed account offers: Gitterm serves previews of some providers itself. */
|
|
83
|
+
export declare function managedCapabilities(provider: SandboxProvider): SandboxCapabilities;
|
|
84
|
+
export declare class SandboxAccountError extends GittermError {
|
|
85
|
+
constructor(message: string);
|
|
86
|
+
}
|
|
87
|
+
export declare function validateAccountName(name: string): string;
|
|
88
|
+
/**
|
|
89
|
+
* Sandboxes billed to your Gitterm account. The provider credential stays on the Gitterm
|
|
90
|
+
* server; this process holds only your Gitterm API token.
|
|
91
|
+
*/
|
|
92
|
+
export declare function createManagedSandboxBackend(options: {
|
|
93
|
+
account: string;
|
|
94
|
+
provider: SandboxProvider;
|
|
95
|
+
client: GittermClient;
|
|
96
|
+
/** Machine profile key; the server checks it against the plan. */
|
|
97
|
+
machine?: string;
|
|
98
|
+
}): SandboxBackend;
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { type SandboxBackend, type SandboxRef } from "./backend.js";
|
|
2
|
+
import { type FetchedArtifact } from "./artifacts.js";
|
|
3
|
+
import { type JobState } from "./jobs.js";
|
|
4
|
+
import { type SetupSnapshotRecord, type SetupSnapshotStatus, type SetupSnapshotStore } from "./setup-snapshots.js";
|
|
5
|
+
import { type CapturedSource } from "./source.js";
|
|
6
|
+
import { type JobRecord, type SandboxRecord, type SandboxStore } from "./store.js";
|
|
7
|
+
export type SandboxLimits = {
|
|
8
|
+
/** Live sandboxes per account. */
|
|
9
|
+
maxSandboxes: number;
|
|
10
|
+
maxLifetimeMinutes: number;
|
|
11
|
+
defaultLifetimeMinutes: number;
|
|
12
|
+
maxJobMinutes: number;
|
|
13
|
+
};
|
|
14
|
+
export declare const DEFAULT_SANDBOX_LIMITS: SandboxLimits;
|
|
15
|
+
/** Model-visible output defaults to this many bytes from the end of the log. */
|
|
16
|
+
export declare const DEFAULT_LOG_TAIL_BYTES: number;
|
|
17
|
+
export type SandboxCreateOptions = {
|
|
18
|
+
name: string;
|
|
19
|
+
purpose?: string;
|
|
20
|
+
project?: string | null;
|
|
21
|
+
sessionId?: string | null;
|
|
22
|
+
lifetimeMinutes?: number;
|
|
23
|
+
publicPreviews?: boolean;
|
|
24
|
+
/** Start from this snapshot, e.g. the project's setup snapshot. */
|
|
25
|
+
snapshot?: string;
|
|
26
|
+
};
|
|
27
|
+
export type SandboxExecOptions = {
|
|
28
|
+
command: string;
|
|
29
|
+
/** Relative to the synced project directory, or absolute. */
|
|
30
|
+
cwd?: string;
|
|
31
|
+
timeoutMinutes?: number;
|
|
32
|
+
/** Values reach only the sandbox process; records keep the names. */
|
|
33
|
+
env?: Record<string, string>;
|
|
34
|
+
/** Wait up to this long for completion before returning a running job. */
|
|
35
|
+
waitMs?: number;
|
|
36
|
+
/** The conversation that started the job; saved so it can be told when the job finishes. */
|
|
37
|
+
sessionId?: string;
|
|
38
|
+
};
|
|
39
|
+
export type JobLog = {
|
|
40
|
+
/** Sanitized text. Sandbox output is untrusted data. */
|
|
41
|
+
text: string;
|
|
42
|
+
offset: number;
|
|
43
|
+
nextOffset: number;
|
|
44
|
+
totalBytes: number;
|
|
45
|
+
truncated: boolean;
|
|
46
|
+
};
|
|
47
|
+
export type JobView = {
|
|
48
|
+
job: JobRecord;
|
|
49
|
+
state: JobState;
|
|
50
|
+
log: JobLog;
|
|
51
|
+
};
|
|
52
|
+
export type PreviewResult = {
|
|
53
|
+
/** The URL to open. */
|
|
54
|
+
url: string;
|
|
55
|
+
port: number;
|
|
56
|
+
public: boolean;
|
|
57
|
+
/** `url` is served by Gitterm; when private, it opens for the owner signed in to Gitterm. */
|
|
58
|
+
viaGitterm: boolean;
|
|
59
|
+
/** Direct provider access, for local proxies. The headers are secret: keep them away from models, logs, and storage. */
|
|
60
|
+
access: {
|
|
61
|
+
url: string;
|
|
62
|
+
headers: Record<string, string>;
|
|
63
|
+
};
|
|
64
|
+
ready: boolean;
|
|
65
|
+
/** HTTP status of `url` without credentials (401/403 means access is enforced). */
|
|
66
|
+
unauthenticatedStatus: number | null;
|
|
67
|
+
jobId: string | null;
|
|
68
|
+
};
|
|
69
|
+
/** Strips terminal escapes and control characters so output cannot spoof the UI. */
|
|
70
|
+
export declare function sanitizeOutput(text: string, secrets?: string[]): string;
|
|
71
|
+
export type SandboxClient = ReturnType<typeof createSandboxClient>;
|
|
72
|
+
export declare function createSandboxClient(options: {
|
|
73
|
+
backend: SandboxBackend;
|
|
74
|
+
store?: SandboxStore;
|
|
75
|
+
setupSnapshots?: SetupSnapshotStore;
|
|
76
|
+
limits?: Partial<SandboxLimits>;
|
|
77
|
+
}): {
|
|
78
|
+
identity: import("./backend.js").SandboxIdentity;
|
|
79
|
+
/** Home directory of the command user; the synced project is `projectDir(home)`. */
|
|
80
|
+
home: string;
|
|
81
|
+
capabilities: import("./types.js").SandboxCapabilities;
|
|
82
|
+
limits: {
|
|
83
|
+
maxSandboxes: number;
|
|
84
|
+
maxLifetimeMinutes: number;
|
|
85
|
+
defaultLifetimeMinutes: number;
|
|
86
|
+
maxJobMinutes: number;
|
|
87
|
+
};
|
|
88
|
+
store: SandboxStore;
|
|
89
|
+
/** Present when the backend pushes job completions; see `SandboxBackend.onJobFinished`. */
|
|
90
|
+
onJobFinished: ((listener: (event: {
|
|
91
|
+
sandboxId: string;
|
|
92
|
+
jobId: string;
|
|
93
|
+
}) => void) => () => void) | undefined;
|
|
94
|
+
create(input: SandboxCreateOptions): Promise<SandboxRecord>;
|
|
95
|
+
/** Local records reconciled with the provider, plus sandboxes this account created elsewhere. */
|
|
96
|
+
list(): Promise<SandboxRecord[]>;
|
|
97
|
+
get: (ref: SandboxRef) => Promise<SandboxRecord>;
|
|
98
|
+
sync(ref: SandboxRef, captured: CapturedSource): Promise<{
|
|
99
|
+
snapshot: import("./source.js").SourceSnapshot;
|
|
100
|
+
verified: true;
|
|
101
|
+
}>;
|
|
102
|
+
exec: (ref: SandboxRef, input: SandboxExecOptions) => Promise<JobView>;
|
|
103
|
+
wait(ref: SandboxRef, jobId: string, waitMs: number, read?: {
|
|
104
|
+
tailBytes?: number;
|
|
105
|
+
}): Promise<JobView>;
|
|
106
|
+
job(ref: SandboxRef, jobId: string, read?: {
|
|
107
|
+
offset?: number;
|
|
108
|
+
limit?: number;
|
|
109
|
+
tailBytes?: number;
|
|
110
|
+
}): Promise<JobView>;
|
|
111
|
+
cancel(ref: SandboxRef, jobId: string): Promise<JobView>;
|
|
112
|
+
/** Optionally starts `command` as a job, then waits until the port answers. */
|
|
113
|
+
preview(ref: SandboxRef, input: {
|
|
114
|
+
port: number;
|
|
115
|
+
command?: string;
|
|
116
|
+
cwd?: string;
|
|
117
|
+
readyTimeoutMs?: number;
|
|
118
|
+
}): Promise<PreviewResult>;
|
|
119
|
+
/**
|
|
120
|
+
* Downloads a file a job produced. The artifact is recorded with that job, so applying it
|
|
121
|
+
* later checks the checkout against the snapshot the job ran on, not a newer sync.
|
|
122
|
+
*/
|
|
123
|
+
fetchArtifact(ref: SandboxRef, file: string, producedBy: {
|
|
124
|
+
jobId: string;
|
|
125
|
+
}): Promise<FetchedArtifact & {
|
|
126
|
+
jobId: string;
|
|
127
|
+
}>;
|
|
128
|
+
/** Writes a fetched artifact into its job's checkout, refusing stale or escaping targets. */
|
|
129
|
+
applyArtifact(ref: SandboxRef, input: {
|
|
130
|
+
localPath: string;
|
|
131
|
+
target: string;
|
|
132
|
+
/** Called with the resolved destination before anything is written, e.g. to ask approval. */
|
|
133
|
+
beforeWrite?: (plan: {
|
|
134
|
+
root: string;
|
|
135
|
+
target: string;
|
|
136
|
+
sha256: string;
|
|
137
|
+
jobId: string;
|
|
138
|
+
snapshotId: string;
|
|
139
|
+
}) => Promise<void>;
|
|
140
|
+
}): Promise<{
|
|
141
|
+
root: string;
|
|
142
|
+
snapshotId: string;
|
|
143
|
+
jobId: string;
|
|
144
|
+
path: string;
|
|
145
|
+
sha256: string;
|
|
146
|
+
}>;
|
|
147
|
+
resume(ref: SandboxRef): Promise<SandboxRecord>;
|
|
148
|
+
/** How saving a snapshot affects the sandbox, or null where this account cannot snapshot. */
|
|
149
|
+
snapshotEffect: "pauses" | "stops" | null;
|
|
150
|
+
/**
|
|
151
|
+
* This account's setup snapshots, newest first. With `project`, only those tied to that
|
|
152
|
+
* checkout or to none, each with the dependency files changed since it was saved.
|
|
153
|
+
*/
|
|
154
|
+
setupSnapshots(project?: string): Promise<SetupSnapshotStatus[]>;
|
|
155
|
+
/**
|
|
156
|
+
* Snapshots the sandbox. `project` ties it to a checkout, whose dependency files are then
|
|
157
|
+
* watched for changes; `replace` names a snapshot to delete once this one is saved. Where
|
|
158
|
+
* the provider stops the sandbox to snapshot it (Vercel), the sandbox is gone after.
|
|
159
|
+
*/
|
|
160
|
+
saveSetupSnapshot(ref: SandboxRef, input: {
|
|
161
|
+
label: string;
|
|
162
|
+
project?: string | null;
|
|
163
|
+
note?: string;
|
|
164
|
+
replace?: string;
|
|
165
|
+
}): Promise<{
|
|
166
|
+
record: SetupSnapshotRecord;
|
|
167
|
+
replaced: string | null;
|
|
168
|
+
leftover: string | null;
|
|
169
|
+
}>;
|
|
170
|
+
/** Deletes a setup snapshot from the provider and forgets it. */
|
|
171
|
+
deleteSetupSnapshot(snapshotId: string): Promise<SetupSnapshotRecord>;
|
|
172
|
+
/** Deletes the sandbox and confirms with the provider that it is gone. */
|
|
173
|
+
destroy(ref: SandboxRef): Promise<SandboxRecord>;
|
|
174
|
+
};
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { type SandboxBackend, type SandboxMode } from "./backend.js";
|
|
2
|
+
import type { SandboxLimits } from "./client.js";
|
|
3
|
+
import { type SandboxCapabilities, type SandboxProviderKey } from "./types.js";
|
|
4
|
+
type DirectCredential = {
|
|
5
|
+
/** The resolved credential (plugin options, after `{env:...}`/`{file:...}` substitution). */
|
|
6
|
+
apiKey?: string;
|
|
7
|
+
/** Name of an environment variable holding the credential (CLI settings file). */
|
|
8
|
+
apiKeyEnv?: string;
|
|
9
|
+
/**
|
|
10
|
+
* Required for providers that never delete an abandoned sandbox themselves
|
|
11
|
+
* (exe.dev, Railway): a crashed caller leaves it running until you destroy it.
|
|
12
|
+
*/
|
|
13
|
+
allowUnboundedLifetime?: boolean;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Account settings. In OpenCode they live in the plugin options, where
|
|
17
|
+
* `"apiKey": "{env:E2B_API_KEY}"` is substituted by OpenCode before the plugin sees it.
|
|
18
|
+
* The CLI reads the same shape from a file but takes credentials only from `apiKeyEnv`.
|
|
19
|
+
*/
|
|
20
|
+
export type SandboxAccountConfig = ({
|
|
21
|
+
mode: "direct";
|
|
22
|
+
provider: "e2b";
|
|
23
|
+
/**
|
|
24
|
+
* Template ID or name. E2B fixes CPU and memory when a template is built, so this is
|
|
25
|
+
* also the machine size. Defaults to `base` (2 vCPU, 512 MB, no agent).
|
|
26
|
+
*/
|
|
27
|
+
template?: string;
|
|
28
|
+
/** A snapshot every sandbox starts from; it keeps the size it was saved at. */
|
|
29
|
+
snapshot?: string;
|
|
30
|
+
} & DirectCredential) | ({
|
|
31
|
+
mode: "direct";
|
|
32
|
+
provider: "daytona";
|
|
33
|
+
target?: "us" | "eu";
|
|
34
|
+
/** Daytona snapshot name. A snapshot carries its own size, so it excludes `resources`. */
|
|
35
|
+
snapshot?: string;
|
|
36
|
+
/** vCPUs and GiB of memory and disk. Defaults to Daytona's 1 vCPU, 1 GiB, 3 GiB. */
|
|
37
|
+
resources?: {
|
|
38
|
+
cpu?: number;
|
|
39
|
+
memory?: number;
|
|
40
|
+
disk?: number;
|
|
41
|
+
};
|
|
42
|
+
} & DirectCredential) | ({
|
|
43
|
+
mode: "direct";
|
|
44
|
+
provider: "vercel";
|
|
45
|
+
teamId: string;
|
|
46
|
+
projectId: string;
|
|
47
|
+
runtime?: "node24" | "node22" | "python3.13";
|
|
48
|
+
/** 1 to 8; Vercel gives 2 GB of memory per vCPU. Defaults to 2. */
|
|
49
|
+
vcpus?: number;
|
|
50
|
+
/** A snapshot id every sandbox starts from instead of `runtime`. */
|
|
51
|
+
snapshot?: string;
|
|
52
|
+
} & DirectCredential) | ({
|
|
53
|
+
mode: "direct";
|
|
54
|
+
provider: "boat";
|
|
55
|
+
size?: "small" | "default" | "large";
|
|
56
|
+
/** A named snapshot every box starts from. */
|
|
57
|
+
snapshot?: string;
|
|
58
|
+
} & DirectCredential) | ({
|
|
59
|
+
mode: "direct";
|
|
60
|
+
provider: "exedev";
|
|
61
|
+
/** Container image; defaults to a plain Node image. */ image?: string;
|
|
62
|
+
/** VM size, as exe.dev's `new` flags take it, e.g. `4`, `"8GB"`, `"20GB"`. */
|
|
63
|
+
cpu?: number;
|
|
64
|
+
memory?: string;
|
|
65
|
+
disk?: string;
|
|
66
|
+
} & DirectCredential) | ({
|
|
67
|
+
mode: "direct";
|
|
68
|
+
provider: "railway";
|
|
69
|
+
projectId: string;
|
|
70
|
+
environmentId: string;
|
|
71
|
+
apiUrl?: string;
|
|
72
|
+
image?: string;
|
|
73
|
+
} & DirectCredential) | {
|
|
74
|
+
mode: "managed";
|
|
75
|
+
/** Defaults to e2b, or to Gitterm when `size` is set. The deployment must enable it. */
|
|
76
|
+
provider?: SandboxProviderKey;
|
|
77
|
+
/**
|
|
78
|
+
* On gitterm.dev: `small` or `medium`. Same as `provider: "gitterm"` with that machine.
|
|
79
|
+
*/
|
|
80
|
+
size?: "small" | "medium";
|
|
81
|
+
/** Machine profile key, e.g. `small` or `large`. Defaults to your plan's default size. */
|
|
82
|
+
machine?: string;
|
|
83
|
+
/** Defaults to the CLI login's server. */
|
|
84
|
+
serverUrl?: string;
|
|
85
|
+
/** Defaults to the CLI login or GITTERM_API_TOKEN. */
|
|
86
|
+
token?: string;
|
|
87
|
+
};
|
|
88
|
+
export type SandboxSettings = {
|
|
89
|
+
/** Selected account name. */
|
|
90
|
+
account?: string;
|
|
91
|
+
accounts?: Record<string, SandboxAccountConfig>;
|
|
92
|
+
limits?: Partial<SandboxLimits>;
|
|
93
|
+
/** Extra glob patterns never uploaded. Secret-like files are always excluded. */
|
|
94
|
+
exclude?: string[];
|
|
95
|
+
/**
|
|
96
|
+
* Create every sandbox with public previews: anyone with a preview URL can open it.
|
|
97
|
+
* Setting this is the approval, so nobody is asked per sandbox.
|
|
98
|
+
*/
|
|
99
|
+
publicPreviews?: boolean;
|
|
100
|
+
/**
|
|
101
|
+
* Let the agent save a setup snapshot of a sandbox once a checkout's dependencies are
|
|
102
|
+
* installed, and start that checkout's next sandboxes from it. Direct E2B, Daytona, Vercel,
|
|
103
|
+
* and Boat accounts only. Snapshots are stored in your provider account until deleted.
|
|
104
|
+
* Off by default. An account's own `snapshot` setting always wins.
|
|
105
|
+
*/
|
|
106
|
+
snapshots?: boolean;
|
|
107
|
+
};
|
|
108
|
+
export type SandboxAccountSummary = {
|
|
109
|
+
name: string;
|
|
110
|
+
mode: SandboxMode;
|
|
111
|
+
provider: SandboxProviderKey;
|
|
112
|
+
/** Where the credential comes from. Never the credential itself. */
|
|
113
|
+
credentialSource: string;
|
|
114
|
+
credentialPresent: boolean;
|
|
115
|
+
chargedTo: string;
|
|
116
|
+
/** The machine size and who sets it: the user, in the account settings, never the agent. */
|
|
117
|
+
machine: string;
|
|
118
|
+
/** A snapshot the user set for every sandbox of this account. */
|
|
119
|
+
pinnedSnapshot: string | null;
|
|
120
|
+
capabilities: SandboxCapabilities;
|
|
121
|
+
/** Plain-language limits of this provider for sandboxes. */
|
|
122
|
+
limitations: string[];
|
|
123
|
+
};
|
|
124
|
+
export declare function describeLimitations(provider: SandboxProviderKey, mode: SandboxMode): string[];
|
|
125
|
+
export declare function describeSandboxAccount(settings: SandboxSettings, accountName?: string): SandboxAccountSummary;
|
|
126
|
+
/** Builds exactly the selected account's backend. A missing or rejected credential is an error, never a fallback. */
|
|
127
|
+
export declare function createSandboxBackend(settings: SandboxSettings, accountName?: string): SandboxBackend;
|
|
128
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { createManagedSandboxBackend, SandboxAccountError, type SandboxBackend, type SandboxIdentity, type SandboxInfo, type SandboxMode, type SandboxProvider, type SandboxRef, type SandboxState, } from "./backend.js";
|
|
2
|
+
export { isSandboxProviderError, type SandboxCapabilities, type SandboxCommandResult, type SandboxFailureCode, type SandboxPreviewAccess, type SandboxProviderFailure, type SandboxProviderKey, } from "./types.js";
|
|
3
|
+
export { createSandboxClient, DEFAULT_LOG_TAIL_BYTES, DEFAULT_SANDBOX_LIMITS, sanitizeOutput, type JobLog, type JobView, type PreviewResult, type SandboxClient, type SandboxCreateOptions, type SandboxExecOptions, type SandboxLimits, } from "./client.js";
|
|
4
|
+
export { createSandboxBackend, describeSandboxAccount, type SandboxAccountConfig, type SandboxAccountSummary, type SandboxSettings, } from "./config.js";
|
|
5
|
+
export { jobRoot, type JobState, type JobStatus } from "./jobs.js";
|
|
6
|
+
export { createFileSetupSnapshotStore, type SetupSnapshotRecord, type SetupSnapshotStatus, type SetupSnapshotStore, } from "./setup-snapshots.js";
|
|
7
|
+
export { captureSource, MAX_SOURCE_BYTES, projectDir, sensitivePath, type CapturedSource, type SnapshotFile, type SourceSnapshot, } from "./source.js";
|
|
8
|
+
export { applyArtifact, ArtifactConflictError, artifactDirectory, type FetchedArtifact, } from "./artifacts.js";
|
|
9
|
+
export { createFileSandboxStore, defaultStoreDirectory, type JobRecord, type SandboxRecord, type SandboxStore, } from "./store.js";
|
|
10
|
+
export { startPreviewProxy, type PreviewProxy } from "./proxy.js";
|