@sealant/sdk 0.3.1 → 0.4.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.
@@ -1,6 +1,6 @@
1
1
  import { Effect } from "effect";
2
2
  import { SealantApiClient } from "./api-client.js";
3
- export declare const createSandboxOp: (payload: {
3
+ export declare const createWorkspaceOp: (payload: {
4
4
  readonly ownerUserId: string;
5
5
  readonly registryId: string;
6
6
  readonly repository: string;
@@ -26,15 +26,15 @@ export declare const createSandboxOp: (payload: {
26
26
  } | undefined;
27
27
  readonly spec: unknown;
28
28
  }, idempotencyKey?: string | undefined) => Effect.Effect<{
29
- readonly sandboxId: string;
29
+ readonly workspaceId: string;
30
30
  readonly name: string;
31
31
  readonly status: "cancelled" | "failed" | "queued" | "ready" | "running";
32
32
  readonly registryId: string;
33
33
  readonly repository: string;
34
34
  readonly tag: string;
35
- }, import("effect/unstable/http/HttpClientError").HttpClientError | import("@sealant/api-contracts").SandboxBadGatewayError | import("@sealant/api-contracts").SandboxBadRequestError | import("@sealant/api-contracts").SandboxConflictError | import("@sealant/api-contracts").SandboxForbiddenError | import("@sealant/api-contracts").SandboxInternalServerError | import("@sealant/api-contracts").SandboxNotFoundError | import("@sealant/api-contracts").SandboxServiceUnavailableError | import("effect/Schema").SchemaError, SealantApiClient>;
36
- export declare const getSandboxOp: (sandboxId: string) => Effect.Effect<{
37
- readonly sandboxId: string;
35
+ }, import("effect/unstable/http/HttpClientError").HttpClientError | import("effect/Schema").SchemaError | import("@sealant/api-contracts").WorkspaceBadGatewayError | import("@sealant/api-contracts").WorkspaceBadRequestError | import("@sealant/api-contracts").WorkspaceConflictError | import("@sealant/api-contracts").WorkspaceForbiddenError | import("@sealant/api-contracts").WorkspaceInternalServerError | import("@sealant/api-contracts").WorkspaceNotFoundError | import("@sealant/api-contracts").WorkspaceServiceUnavailableError, SealantApiClient>;
36
+ export declare const getWorkspaceOp: (workspaceId: string) => Effect.Effect<{
37
+ readonly workspaceId: string;
38
38
  readonly name: string;
39
39
  readonly ownerUserId: string;
40
40
  readonly status: "cancelled" | "failed" | "queued" | "ready" | "running";
@@ -63,13 +63,13 @@ export declare const getSandboxOp: (sandboxId: string) => Effect.Effect<{
63
63
  readonly finishedAt?: string | undefined;
64
64
  readonly spec?: unknown;
65
65
  }, unknown, SealantApiClient>;
66
- export declare const listSandboxesOp: (query: {
66
+ export declare const listWorkspacesOp: (query: {
67
67
  readonly ownerUserId: string;
68
68
  readonly status?: "cancelled" | "failed" | "queued" | "ready" | "running" | undefined;
69
69
  readonly limit?: string | undefined;
70
70
  }) => Effect.Effect<{
71
71
  readonly items: readonly {
72
- readonly sandboxId: string;
72
+ readonly workspaceId: string;
73
73
  readonly name: string;
74
74
  readonly ownerUserId: string;
75
75
  readonly status: "cancelled" | "failed" | "queued" | "ready" | "running";
@@ -97,9 +97,9 @@ export declare const listSandboxesOp: (query: {
97
97
  readonly startedAt?: string | undefined;
98
98
  readonly finishedAt?: string | undefined;
99
99
  }[];
100
- }, import("effect/unstable/http/HttpClientError").HttpClientError | import("@sealant/api-contracts").SandboxBadRequestError | import("@sealant/api-contracts").SandboxInternalServerError | import("effect/Schema").SchemaError, SealantApiClient>;
100
+ }, import("effect/unstable/http/HttpClientError").HttpClientError | import("effect/Schema").SchemaError | import("@sealant/api-contracts").WorkspaceBadRequestError | import("@sealant/api-contracts").WorkspaceInternalServerError, SealantApiClient>;
101
101
  export declare const createRunOp: (payload: {
102
- readonly sandboxId: string;
102
+ readonly workspaceId: string;
103
103
  readonly harnessId: string;
104
104
  readonly ownerUserId: string;
105
105
  readonly mode?: "interactive" | "one-shot" | undefined;
@@ -112,7 +112,7 @@ export declare const createRunOp: (payload: {
112
112
  } | undefined;
113
113
  }) => Effect.Effect<{
114
114
  readonly runId: string;
115
- readonly sandboxId: string;
115
+ readonly workspaceId: string;
116
116
  readonly attemptId?: string | undefined;
117
117
  readonly ownerUserId: string;
118
118
  readonly harnessId: string;
@@ -128,7 +128,7 @@ export declare const createRunOp: (payload: {
128
128
  }, unknown, SealantApiClient>;
129
129
  export declare const getRunOp: (runId: string) => Effect.Effect<{
130
130
  readonly runId: string;
131
- readonly sandboxId: string;
131
+ readonly workspaceId: string;
132
132
  readonly attemptId?: string | undefined;
133
133
  readonly ownerUserId: string;
134
134
  readonly harnessId: string;
@@ -143,14 +143,14 @@ export declare const getRunOp: (runId: string) => Effect.Effect<{
143
143
  readonly updatedAt: string;
144
144
  }, unknown, SealantApiClient>;
145
145
  export declare const listRunsOp: (query: {
146
- readonly sandboxId?: string | undefined;
146
+ readonly workspaceId?: string | undefined;
147
147
  readonly ownerUserId?: string | undefined;
148
148
  readonly status?: "cancelled" | "completed" | "failed" | "queued" | "running" | undefined;
149
149
  readonly limit?: string | undefined;
150
150
  }) => Effect.Effect<{
151
151
  readonly items: readonly {
152
152
  readonly runId: string;
153
- readonly sandboxId: string;
153
+ readonly workspaceId: string;
154
154
  readonly attemptId?: string | undefined;
155
155
  readonly ownerUserId: string;
156
156
  readonly harnessId: string;
@@ -177,7 +177,7 @@ export declare const updateRunOp: (runId: string, payload: {
177
177
  }[] | undefined;
178
178
  }) => Effect.Effect<{
179
179
  readonly runId: string;
180
- readonly sandboxId: string;
180
+ readonly workspaceId: string;
181
181
  readonly attemptId?: string | undefined;
182
182
  readonly ownerUserId: string;
183
183
  readonly harnessId: string;
@@ -1,12 +1,12 @@
1
1
  import { Effect } from "effect";
2
2
  import { SealantApiClient } from "./api-client.js";
3
- // ---- sandboxes ----
4
- export const createSandboxOp = (payload, idempotencyKey) => Effect.flatMap(SealantApiClient, (client) => client.sandboxes.createSandbox({
3
+ // ---- workspaces ----
4
+ export const createWorkspaceOp = (payload, idempotencyKey) => Effect.flatMap(SealantApiClient, (client) => client.workspaces.createWorkspace({
5
5
  payload,
6
6
  headers: idempotencyKey === undefined ? {} : { "idempotency-key": idempotencyKey },
7
7
  }));
8
- export const getSandboxOp = (sandboxId) => Effect.flatMap(SealantApiClient, (client) => client.sandboxes.getSandbox({ params: { sandboxId } }));
9
- export const listSandboxesOp = (query) => Effect.flatMap(SealantApiClient, (client) => client.sandboxes.listSandboxes({ query }));
8
+ export const getWorkspaceOp = (workspaceId) => Effect.flatMap(SealantApiClient, (client) => client.workspaces.getWorkspace({ params: { workspaceId } }));
9
+ export const listWorkspacesOp = (query) => Effect.flatMap(SealantApiClient, (client) => client.workspaces.listWorkspaces({ query }));
10
10
  // ---- runs ----
11
11
  export const createRunOp = (payload) => Effect.flatMap(SealantApiClient, (client) => client.runs.createRun({ payload }));
12
12
  export const getRunOp = (runId) => Effect.flatMap(SealantApiClient, (client) => client.runs.getRun({ params: { runId } }));
@@ -1,5 +1,5 @@
1
- import type { RunHarnessFn } from "../facade/sandbox.js";
2
- /** The BLOCKING `harness.run()` implementation, registered into the Sandbox facade by the client. */
1
+ import type { RunHarnessFn } from "../facade/workspace.js";
2
+ /** The BLOCKING `harness.run()` implementation, registered into the Workspace facade by the client. */
3
3
  export declare const runHarness: RunHarnessFn;
4
4
  /**
5
5
  * The NON-BLOCKING `harness.start()` implementation: register the run and return the live handle
@@ -17,16 +17,16 @@ const POLL_INTERVAL = "500 millis";
17
17
  const RUN_TIMEOUT_MS = 30 * 60 * 1_000;
18
18
  /**
19
19
  * Registers the run WITH the harness command — the control plane executes it server-side (the worker
20
- * docker-execs it and ingests telemetry). The cwd is the sandbox repo, which the worker defaults to.
20
+ * docker-execs it and ingests telemetry). The cwd is the workspace repo, which the worker defaults to.
21
21
  */
22
22
  const createHarnessRunEffect = (ctx, init, prompt) => Effect.gen(function* () {
23
23
  const harness = init.harness;
24
24
  if (harness === undefined) {
25
- return yield* Effect.fail(new SealantError("This sandbox handle has no harness; use the handle returned by sandboxes.create().", { code: "harness_required" }));
25
+ return yield* Effect.fail(new SealantError("This workspace handle has no harness; use the handle returned by workspaces.create().", { code: "harness_required" }));
26
26
  }
27
27
  const command = harness.buildRunCommand(prompt);
28
28
  return yield* createRunOp({
29
- sandboxId: init.id,
29
+ workspaceId: init.id,
30
30
  ownerUserId: ctx.config.hostLocal.ownerUserId,
31
31
  harnessId: harness.id,
32
32
  mode: "one-shot",
@@ -53,7 +53,7 @@ const runHarnessEffect = (ctx, init, prompt) => Effect.gen(function* () {
53
53
  const changes = toRunChangesData(yield* getRunChangesOp(runId));
54
54
  return makeRun(ctx, { wire, changes });
55
55
  });
56
- /** The BLOCKING `harness.run()` implementation, registered into the Sandbox facade by the client. */
56
+ /** The BLOCKING `harness.run()` implementation, registered into the Workspace facade by the client. */
57
57
  export const runHarness = (ctx, init, prompt) => ctx.runtime.run(runHarnessEffect(ctx, init, prompt));
58
58
  /**
59
59
  * The NON-BLOCKING `harness.start()` implementation: register the run and return the live handle
package/dist/errors.d.ts CHANGED
@@ -13,7 +13,7 @@ export declare class SealantError extends Error {
13
13
  readonly cause?: unknown;
14
14
  });
15
15
  }
16
- /** A typed control/transport failure from the sandbox runtime daemon. */
16
+ /** A typed control/transport failure from the workspace runtime daemon. */
17
17
  export declare class SealantRuntimeError extends SealantError {
18
18
  readonly name = "SealantRuntimeError";
19
19
  constructor(message: string, options?: {
package/dist/errors.js CHANGED
@@ -13,7 +13,7 @@ export class SealantError extends Error {
13
13
  this.code = options?.code ?? "sealant_error";
14
14
  }
15
15
  }
16
- /** A typed control/transport failure from the sandbox runtime daemon. */
16
+ /** A typed control/transport failure from the workspace runtime daemon. */
17
17
  export class SealantRuntimeError extends SealantError {
18
18
  name = "SealantRuntimeError";
19
19
  constructor(message, options) {
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * The `Run` facade — one harness execution as the SDK exposes it. Built from a `runs.get` lookup
3
- * (read a past run, record outlives the sandbox), from `harness.run()` (which also captures the file
3
+ * (read a past run, record outlives the workspace), from `harness.run()` (which also captures the file
4
4
  * changes inline), or from `harness.start()` (a live handle; `wait()` settles it). `result` is
5
5
  * derived from the wire status; `changes` is captured inline by `run()` and fetched by `wait()` once
6
6
  * the run is terminal (the event-sourced fileChange projection that backs reads arrives in Phase 1);
@@ -1,18 +1,18 @@
1
- import type { Harness, Sandbox, SandboxStatus } from "../types.js";
1
+ import type { Harness, Workspace, WorkspaceStatus } from "../types.js";
2
2
  import type { SdkContext } from "./context.js";
3
- export interface SandboxInit {
3
+ export interface WorkspaceInit {
4
4
  readonly id: string;
5
5
  readonly name: string;
6
- readonly status: SandboxStatus;
6
+ readonly status: WorkspaceStatus;
7
7
  /** Present when the handle came from `create()` (needed by `harness.run()`). */
8
8
  readonly harness?: Harness;
9
9
  }
10
10
  /**
11
11
  * The `harness.run()`/`harness.start()` implementations are injected by the run-execution module to
12
- * avoid a static dependency cycle (sandbox <-> run execution). Until they are registered, both
12
+ * avoid a static dependency cycle (workspace <-> run execution). Until they are registered, both
13
13
  * report that the feature is not wired in this build.
14
14
  */
15
- export type RunHarnessFn = (ctx: SdkContext, init: SandboxInit, prompt: string, options?: import("../types.js").RunOptions) => Promise<import("../types.js").Run>;
15
+ export type RunHarnessFn = (ctx: SdkContext, init: WorkspaceInit, prompt: string, options?: import("../types.js").RunOptions) => Promise<import("../types.js").Run>;
16
16
  export interface HarnessExecutors {
17
17
  /** BLOCKING `harness.run()`: resolves once the run is terminal. */
18
18
  readonly run: RunHarnessFn;
@@ -20,4 +20,4 @@ export interface HarnessExecutors {
20
20
  readonly start: RunHarnessFn;
21
21
  }
22
22
  export declare const registerHarnessExecutors: (executors: HarnessExecutors) => void;
23
- export declare const makeSandbox: (ctx: SdkContext, init: SandboxInit) => Sandbox;
23
+ export declare const makeWorkspace: (ctx: SdkContext, init: WorkspaceInit) => Workspace;
@@ -1,4 +1,4 @@
1
- import { getSandboxOp } from "../effect/operations.js";
1
+ import { getWorkspaceOp } from "../effect/operations.js";
2
2
  import { SealantError, SealantNotImplementedError } from "../errors.js";
3
3
  const FAILED_STATUSES = new Set(["failed", "cancelled"]);
4
4
  const READY_POLL_INTERVAL_MS = 2_000;
@@ -8,7 +8,7 @@ let harnessExecutors;
8
8
  export const registerHarnessExecutors = (executors) => {
9
9
  harnessExecutors = executors;
10
10
  };
11
- export const makeSandbox = (ctx, init) => {
11
+ export const makeWorkspace = (ctx, init) => {
12
12
  const harness = {
13
13
  run: (prompt, options) => {
14
14
  if (harnessExecutors === undefined) {
@@ -24,36 +24,36 @@ export const makeSandbox = (ctx, init) => {
24
24
  },
25
25
  session: () => Promise.reject(new SealantNotImplementedError("harness.session (interactive, Phase 3)")),
26
26
  };
27
- const sandbox = {
27
+ const workspace = {
28
28
  id: init.id,
29
29
  name: init.name,
30
30
  status: async () => {
31
- const details = await ctx.runtime.run(getSandboxOp(init.id));
31
+ const details = await ctx.runtime.run(getWorkspaceOp(init.id));
32
32
  return details.status;
33
33
  },
34
34
  ready: async () => {
35
35
  const deadline = Date.now() + READY_TIMEOUT_MS;
36
36
  for (;;) {
37
- const details = await ctx.runtime.run(getSandboxOp(init.id));
37
+ const details = await ctx.runtime.run(getWorkspaceOp(init.id));
38
38
  // Gate on the coarse "ready" status, which the control plane now emits ONLY after the
39
- // in-sandbox daemon's control socket is accepting (readiness probe in the launch path).
39
+ // in-workspace daemon's control socket is accepting (readiness probe in the launch path).
40
40
  // This is honest: when ready() resolves, harness.run() can connect without racing the socket.
41
41
  if (details.status === "ready") {
42
- return sandbox;
42
+ return workspace;
43
43
  }
44
44
  if (FAILED_STATUSES.has(details.status)) {
45
- throw new SealantError(`Sandbox ${init.id} reached terminal status "${details.status}" before becoming ready.`, { code: "sandbox_not_ready" });
45
+ throw new SealantError(`Workspace ${init.id} reached terminal status "${details.status}" before becoming ready.`, { code: "workspace_not_ready" });
46
46
  }
47
47
  if (Date.now() > deadline) {
48
- throw new SealantError(`Timed out waiting for sandbox ${init.id} to become ready.`, {
49
- code: "sandbox_ready_timeout",
48
+ throw new SealantError(`Timed out waiting for workspace ${init.id} to become ready.`, {
49
+ code: "workspace_ready_timeout",
50
50
  });
51
51
  }
52
52
  await delay(READY_POLL_INTERVAL_MS);
53
53
  }
54
54
  },
55
55
  harness,
56
- // Poll-backed lifecycle stream: emit a coarse event on each status transition until the sandbox
56
+ // Poll-backed lifecycle stream: emit a coarse event on each status transition until the workspace
57
57
  // reaches a terminal/ready state. Swaps to SSE over Postgres LISTEN/NOTIFY in Stage 5 (same shape).
58
58
  events: () => {
59
59
  const ctxRun = ctx.runtime;
@@ -61,13 +61,13 @@ export const makeSandbox = (ctx, init) => {
61
61
  let lastStatus;
62
62
  const deadline = Date.now() + READY_TIMEOUT_MS;
63
63
  for (;;) {
64
- const details = await ctxRun.run(getSandboxOp(init.id));
64
+ const details = await ctxRun.run(getWorkspaceOp(init.id));
65
65
  if (details.status !== lastStatus) {
66
66
  lastStatus = details.status;
67
67
  yield {
68
68
  type: `status.${details.status}`,
69
69
  occurredAt: new Date().toISOString(),
70
- message: `Sandbox status: ${details.status}`,
70
+ message: `Workspace status: ${details.status}`,
71
71
  };
72
72
  }
73
73
  if (details.status === "ready" || FAILED_STATUSES.has(details.status)) {
@@ -81,9 +81,9 @@ export const makeSandbox = (ctx, init) => {
81
81
  }
82
82
  return iterate();
83
83
  },
84
- stop: () => Promise.reject(new SealantNotImplementedError("sandbox.stop (lifecycle, Phase 3)")),
85
- restart: () => Promise.reject(new SealantNotImplementedError("sandbox.restart (lifecycle, Phase 3)")),
86
- expire: () => Promise.reject(new SealantNotImplementedError("sandbox.expire (lifecycle, Phase 3)")),
84
+ stop: () => Promise.reject(new SealantNotImplementedError("workspace.stop (lifecycle, Phase 3)")),
85
+ restart: () => Promise.reject(new SealantNotImplementedError("workspace.restart (lifecycle, Phase 3)")),
86
+ expire: () => Promise.reject(new SealantNotImplementedError("workspace.expire (lifecycle, Phase 3)")),
87
87
  };
88
- return sandbox;
88
+ return workspace;
89
89
  };
package/dist/harness.d.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * NOTE — the one-shot invocation forms below (`opencode run <prompt>`, `codex exec <prompt>`,
6
6
  * `claude -p <prompt>`) are the expected headless shapes but are PENDING live verification against
7
- * the baked sandbox image (see the SDK plan's task #2, "verify harness one-shot CLI semantics").
7
+ * the baked workspace image (see the SDK plan's task #2, "verify harness one-shot CLI semantics").
8
8
  * Until that is confirmed, only `opencode()` is exercised end-to-end; the others are provided for the
9
9
  * typed surface and adjusted once verified.
10
10
  */
package/dist/index.d.ts CHANGED
@@ -1,17 +1,17 @@
1
1
  /**
2
2
  * @sealant/sdk — the fluent public SDK for Sealant.
3
3
  *
4
- * Create a live sandbox around a real repository, run the harness you already use, stream progress
5
- * while it works, and keep the replayable execution record after the sandbox is gone:
4
+ * Create a live workspace around a real repository, run the harness you already use, stream progress
5
+ * while it works, and keep the replayable execution record after the workspace is gone:
6
6
  *
7
7
  * import { Sealant, opencode } from "@sealant/sdk"
8
8
  *
9
9
  * const sealant = new Sealant({ baseUrl: "http://localhost:8080" })
10
- * const sandbox = await sealant.sandboxes.create({
10
+ * const workspace = await sealant.workspaces.create({
11
11
  * repository: "github.com/acme/billing-service",
12
12
  * harness: opencode(),
13
13
  * })
14
- * const run = await sandbox.harness.run("Round invoice totals once, after applying the discount.")
14
+ * const run = await workspace.harness.run("Round invoice totals once, after applying the discount.")
15
15
  * await run.record.replay()
16
16
  */
17
17
  export { Sealant } from "./client.js";
package/dist/index.js CHANGED
@@ -1,17 +1,17 @@
1
1
  /**
2
2
  * @sealant/sdk — the fluent public SDK for Sealant.
3
3
  *
4
- * Create a live sandbox around a real repository, run the harness you already use, stream progress
5
- * while it works, and keep the replayable execution record after the sandbox is gone:
4
+ * Create a live workspace around a real repository, run the harness you already use, stream progress
5
+ * while it works, and keep the replayable execution record after the workspace is gone:
6
6
  *
7
7
  * import { Sealant, opencode } from "@sealant/sdk"
8
8
  *
9
9
  * const sealant = new Sealant({ baseUrl: "http://localhost:8080" })
10
- * const sandbox = await sealant.sandboxes.create({
10
+ * const workspace = await sealant.workspaces.create({
11
11
  * repository: "github.com/acme/billing-service",
12
12
  * harness: opencode(),
13
13
  * })
14
- * const run = await sandbox.harness.run("Round invoice totals once, after applying the discount.")
14
+ * const run = await workspace.harness.run("Round invoice totals once, after applying the discount.")
15
15
  * await run.record.replay()
16
16
  */
17
17
  export { Sealant } from "./client.js";
@@ -1,6 +1,6 @@
1
1
  import type { CreateOptions } from "../types.js";
2
2
  import type { SealantInternalConfig } from "./config.js";
3
- export declare const buildCreateSandboxRequest: (options: CreateOptions, config: SealantInternalConfig) => {
3
+ export declare const buildCreateWorkspaceRequest: (options: CreateOptions, config: SealantInternalConfig) => {
4
4
  readonly payload: {
5
5
  readonly ownerUserId: string;
6
6
  readonly registryId: string;
@@ -1,17 +1,17 @@
1
1
  /**
2
2
  * Lowers the fluent `create({ repository, harness })` options into the existing
3
- * `createSandboxRequestSchema` the control plane accepts — entirely client-side, so the slice needs
3
+ * `createWorkspaceRequestSchema` the control plane accepts — entirely client-side, so the slice needs
4
4
  * no contract change. The public `repository` is the SOURCE git repo (it becomes
5
- * `spec.sources.sandbox.url`); the contract's `repository`/`tag` are the OCI push coordinates, which
5
+ * `spec.sources.workspace.url`); the contract's `repository`/`tag` are the OCI push coordinates, which
6
6
  * we derive. `customization.enableSealantd` is forced on (it bakes + launches the daemon the run path
7
7
  * connects to), the runtime target is pinned to docker (the only bridgeable adapter today), and the
8
- * foreground is a keepalive so the sandbox idles with the daemon up and the harness is exec'd on
8
+ * foreground is a keepalive so the workspace idles with the daemon up and the harness is exec'd on
9
9
  * demand by `run()` rather than launched at boot. `options.credentials`, if present, is lowered via
10
- * `mapSandboxCredentials` (see `./credentials.js`) and folded into `spec.credentials`; the control
10
+ * `mapWorkspaceCredentials` (see `./credentials.js`) and folded into `spec.credentials`; the control
11
11
  * plane resolves those account references server-side (never secret material over this path).
12
12
  */
13
13
  import { randomUUID } from "node:crypto";
14
- import { mapSandboxCredentials } from "./credentials.js";
14
+ import { mapWorkspaceCredentials } from "./credentials.js";
15
15
  const sanitizeRepoSlug = (value) => {
16
16
  const slug = value
17
17
  .toLowerCase()
@@ -26,16 +26,16 @@ const toGitUrl = (repository) => {
26
26
  }
27
27
  return `https://${repository}.git`;
28
28
  };
29
- export const buildCreateSandboxRequest = (options, config) => {
29
+ export const buildCreateWorkspaceRequest = (options, config) => {
30
30
  const tail = options.repository
31
31
  .split("/")
32
32
  .filter((s) => s.length > 0)
33
33
  .pop() ?? options.repository;
34
- const credentials = mapSandboxCredentials(options.credentials);
34
+ const credentials = mapWorkspaceCredentials(options.credentials);
35
35
  const spec = {
36
36
  version: "1",
37
37
  sources: {
38
- sandbox: {
38
+ workspace: {
39
39
  kind: "git",
40
40
  provider: "generic",
41
41
  url: toGitUrl(options.repository),
@@ -9,9 +9,9 @@
9
9
  */
10
10
  import type { SealantConfig } from "../types.js";
11
11
  export interface SealantHostLocalConfig {
12
- /** Owner principal the control plane attributes sandboxes/runs to (pre-auth). */
12
+ /** Owner principal the control plane attributes workspaces/runs to (pre-auth). */
13
13
  readonly ownerUserId: string;
14
- /** Registry the sandbox image is published to and launched from. */
14
+ /** Registry the workspace image is published to and launched from. */
15
15
  readonly registryId: string;
16
16
  }
17
17
  export interface SealantInternalConfig {
@@ -1,22 +1,22 @@
1
1
  /**
2
- * Lowers the public `SandboxCredentialsOptions` onto the control-plane's sandbox-create payload
3
- * shape. Pure and side-effect free so it is unit-testable on its own; `buildCreateSandboxRequest`
2
+ * Lowers the public `WorkspaceCredentialsOptions` onto the control-plane's workspace-create payload
3
+ * shape. Pure and side-effect free so it is unit-testable on its own; `buildCreateWorkspaceRequest`
4
4
  * calls it and folds the result into the request it builds.
5
5
  *
6
6
  * SECURITY: this only ever moves account **references** (booleans/names/ids) — never token values or
7
7
  * other secret material. `true` resolves to the literal account name `"default"`; a string passes
8
8
  * through as the named account; `profile` becomes `profileId`.
9
9
  */
10
- import type { SandboxCredentialsOptions } from "../types.js";
11
- /** The control-plane's sandbox-create payload shape for connected-account credentials. */
12
- export interface SandboxCredentialsPayload {
10
+ import type { WorkspaceCredentialsOptions } from "../types.js";
11
+ /** The control-plane's workspace-create payload shape for connected-account credentials. */
12
+ export interface WorkspaceCredentialsPayload {
13
13
  readonly profileId?: string;
14
14
  readonly claude?: string;
15
15
  readonly codex?: string;
16
16
  readonly github?: string;
17
17
  }
18
18
  /**
19
- * Maps `SandboxCredentialsOptions` to the API payload shape, or `undefined` when no credentials were
19
+ * Maps `WorkspaceCredentialsOptions` to the API payload shape, or `undefined` when no credentials were
20
20
  * requested (omitted entirely, rather than serialized as an empty object).
21
21
  */
22
- export declare const mapSandboxCredentials: (options: SandboxCredentialsOptions | undefined) => SandboxCredentialsPayload | undefined;
22
+ export declare const mapWorkspaceCredentials: (options: WorkspaceCredentialsOptions | undefined) => WorkspaceCredentialsPayload | undefined;
@@ -6,10 +6,10 @@ const mapAccountRef = (value) => {
6
6
  return value === true ? DEFAULT_ACCOUNT_NAME : value;
7
7
  };
8
8
  /**
9
- * Maps `SandboxCredentialsOptions` to the API payload shape, or `undefined` when no credentials were
9
+ * Maps `WorkspaceCredentialsOptions` to the API payload shape, or `undefined` when no credentials were
10
10
  * requested (omitted entirely, rather than serialized as an empty object).
11
11
  */
12
- export const mapSandboxCredentials = (options) => {
12
+ export const mapWorkspaceCredentials = (options) => {
13
13
  if (options === undefined) {
14
14
  return undefined;
15
15
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Maps any failure crossing the Effect boundary onto a plain public `SealantError`. The Effect core
3
- * fails with `@sealant/api-contracts` tagged errors (e.g. `SandboxNotFoundError`), Effect HTTP-client
3
+ * fails with `@sealant/api-contracts` tagged errors (e.g. `WorkspaceNotFoundError`), Effect HTTP-client
4
4
  * errors, or schema decode errors; the runtime squashes the `Cause` to its failure value and hands it
5
5
  * here. This is the single funnel that keeps Effect internals out of the public, Promise-based API.
6
6
  */
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Maps any failure crossing the Effect boundary onto a plain public `SealantError`. The Effect core
3
- * fails with `@sealant/api-contracts` tagged errors (e.g. `SandboxNotFoundError`), Effect HTTP-client
3
+ * fails with `@sealant/api-contracts` tagged errors (e.g. `WorkspaceNotFoundError`), Effect HTTP-client
4
4
  * errors, or schema decode errors; the runtime squashes the `Cause` to its failure value and hands it
5
5
  * here. This is the single funnel that keeps Effect internals out of the public, Promise-based API.
6
6
  */