@codeworksh/plugin 0.1.0-canary.19.1.gbef2d437 → 0.1.0-canary.21.1.gd0108197
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/{event-mKxToqmh.d.mts → event-6sTQ_4bq.d.mts} +33 -33
- package/event.d.mts +1 -1
- package/filesystem-BFCKzgND.mjs +347 -0
- package/filesystem-BFCKzgND.mjs.map +1 -0
- package/{filesystem-Cv2gjOJa.d.mts → filesystem-BYaEdL14.d.mts} +111 -3
- package/index.d.mts +1 -1
- package/{io-DhT4Y0Lw.d.mts → io-CXi2Sjg9.d.mts} +13 -4
- package/{io-5PrgzDTe.mjs → io-RvZvG-4N.mjs} +12 -6
- package/io-RvZvG-4N.mjs.map +1 -0
- package/package.json +2 -2
- package/{plugin-C8EauawX.d.mts → plugin-Bb1gRtNX.d.mts} +3 -3
- package/plugin.d.mts +1 -1
- package/sandbox/driver.d.mts +1 -1
- package/sandbox/driver.mjs +6 -2
- package/sandbox/driver.mjs.map +1 -1
- package/sandbox/errors.d.mts +1 -1
- package/sandbox/filesystem.d.mts +2 -2
- package/sandbox/filesystem.mjs +2 -148
- package/sandbox/instance.d.mts +1 -1
- package/sandbox/io.d.mts +2 -2
- package/sandbox/io.mjs +2 -2
- package/sandbox.d.mts +3 -3
- package/sandbox.mjs +3 -2
- package/sandbox.mjs.map +1 -1
- package/io-5PrgzDTe.mjs.map +0 -1
- package/sandbox/filesystem.mjs.map +0 -1
|
@@ -1,6 +1,106 @@
|
|
|
1
1
|
import { Context, Effect, Schema } from "effect";
|
|
2
|
+
declare namespace scan_d_exports {
|
|
3
|
+
export { LineScan, LineScanOptions, LineScanner, ShellRun, parse, script, scriptArgs, validate, viaShell };
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Bounded line reads: one pass over a file that returns a window of its lines
|
|
7
|
+
* without ever holding more than that window.
|
|
8
|
+
*
|
|
9
|
+
* Lines are the file split on `\n`, where a trailing newline ends the last line
|
|
10
|
+
* rather than starting an empty one: `""` has 0 lines, `"a"` and `"a\n"` have 1,
|
|
11
|
+
* `"a\n\n"` has 2. A UTF-8 byte-order mark at the start of the file is not part
|
|
12
|
+
* of the first line. Line lengths are in bytes.
|
|
13
|
+
*
|
|
14
|
+
* Two implementations share these rules, and a backend uses whichever fits:
|
|
15
|
+
* {@link LineScanner} over a byte stream, or {@link script} run inside the
|
|
16
|
+
* sandbox so only the window crosses the network.
|
|
17
|
+
*/
|
|
18
|
+
interface LineScanOptions {
|
|
19
|
+
/** First selected line, 0-based. */
|
|
20
|
+
readonly startLine: number;
|
|
21
|
+
/** End of the selection, exclusive; absent selects to the end of the file. */
|
|
22
|
+
readonly endLine?: number;
|
|
23
|
+
/** Most UTF-8 bytes of selected text to return; selection stops at the last whole line that fits. */
|
|
24
|
+
readonly maxBytes: number;
|
|
25
|
+
}
|
|
26
|
+
interface LineScan {
|
|
27
|
+
/**
|
|
28
|
+
* The selected whole lines that fit `maxBytes`, joined with `\n`. Invalid
|
|
29
|
+
* UTF-8 becomes U+FFFD; how many per bad sequence depends on the decoder of
|
|
30
|
+
* the backend's transport.
|
|
31
|
+
*/
|
|
32
|
+
readonly text: string;
|
|
33
|
+
/** Lines in {@link text}. */
|
|
34
|
+
readonly lines: number;
|
|
35
|
+
/** Lines in the whole file. */
|
|
36
|
+
readonly totalLines: number;
|
|
37
|
+
/** Bytes in the whole file, byte-order mark included. */
|
|
38
|
+
readonly totalBytes: number;
|
|
39
|
+
/**
|
|
40
|
+
* Bytes of the first selected line, 0 when nothing is selected. Larger than
|
|
41
|
+
* `maxBytes` exactly when that line alone does not fit, and `text` is empty.
|
|
42
|
+
*/
|
|
43
|
+
readonly firstLineBytes: number;
|
|
44
|
+
}
|
|
45
|
+
/** A defect, not a file error: callers derive these from already-validated input. */
|
|
46
|
+
declare const validate: (options: LineScanOptions) => void;
|
|
47
|
+
/**
|
|
48
|
+
* Computes a {@link LineScan} from a file's bytes fed in order, in memory
|
|
49
|
+
* bounded by `maxBytes`. Feed at most the file size observed when the read
|
|
50
|
+
* started, so a file that keeps growing cannot keep the scan going.
|
|
51
|
+
*/
|
|
52
|
+
declare class LineScanner {
|
|
53
|
+
private readonly start;
|
|
54
|
+
private readonly end;
|
|
55
|
+
private readonly maxBytes;
|
|
56
|
+
private readonly decoder;
|
|
57
|
+
/** The first bytes, held until it is known whether they are a byte-order mark. */
|
|
58
|
+
private head;
|
|
59
|
+
private totalBytes;
|
|
60
|
+
private line;
|
|
61
|
+
private lineLength;
|
|
62
|
+
private lineOpen;
|
|
63
|
+
/** The current line's bytes, kept only while it is selected and could still fit. */
|
|
64
|
+
private pieces;
|
|
65
|
+
private selected;
|
|
66
|
+
private selectedBytes;
|
|
67
|
+
private firstLineBytes;
|
|
68
|
+
private full;
|
|
69
|
+
constructor(options: LineScanOptions);
|
|
70
|
+
push(chunk: Uint8Array): void;
|
|
71
|
+
finish(): LineScan;
|
|
72
|
+
private releaseHead;
|
|
73
|
+
private scan;
|
|
74
|
+
private isSelected;
|
|
75
|
+
private append;
|
|
76
|
+
private endLine;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* {@link LineScanner} as a POSIX shell script, for backends that only expose a
|
|
80
|
+
* process API. Run as `sh -c <script> _ <path> <startLine> <endLine|-1> <maxBytes>`.
|
|
81
|
+
* The whole file is read inside the sandbox; only the window is printed, after a
|
|
82
|
+
* header line `<lines> <totalLines> <totalBytes> <firstLineBytes>` and before a
|
|
83
|
+
* closing `|` — see {@link parse}.
|
|
84
|
+
* Exits 2 when the path does not exist.
|
|
85
|
+
*/
|
|
86
|
+
declare const script: string;
|
|
87
|
+
/** Arguments for {@link script} after the path. */
|
|
88
|
+
declare const scriptArgs: (options: LineScanOptions) => Array<string>;
|
|
89
|
+
/** Read {@link script}'s output. */
|
|
90
|
+
declare const parse: (stdout: string) => LineScan;
|
|
91
|
+
interface ShellRun {
|
|
92
|
+
readonly exitCode: number;
|
|
93
|
+
readonly stdout: string;
|
|
94
|
+
readonly stderr?: string;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* `Provider.scanLines` for a backend that runs an argument vector and collects
|
|
98
|
+
* its output: runs {@link script} in the sandbox and reads the result. A missing
|
|
99
|
+
* path rejects with `ENOENT`, the shape `isNotFoundError` recognises.
|
|
100
|
+
*/
|
|
101
|
+
declare const viaShell: (run: (argv: ReadonlyArray<string>) => Promise<ShellRun>) => (path: string, options: LineScanOptions) => Promise<LineScan>;
|
|
2
102
|
declare namespace filesystem_d_exports {
|
|
3
|
-
export { FileStat, FileSystemError, Interface, OperationUnsupportedError, Provider, RmOptions, filesystem_d_exports as SandboxFileSystem, Service, fromProvider, isNotFoundError, realpathScripts, validateRmOptions, withCwd };
|
|
103
|
+
export { FileStat, FileSystemError, Interface, LineScan, LineScanOptions, OperationUnsupportedError, Provider, RmOptions, filesystem_d_exports as SandboxFileSystem, scan_d_exports as Scan, Service, fromProvider, isNotFoundError, realpathScripts, validateRmOptions, withCwd };
|
|
4
104
|
}
|
|
5
105
|
declare const OperationUnsupportedError_base: Schema.Class<OperationUnsupportedError, Schema.TaggedStruct<"OperationUnsupportedError", {
|
|
6
106
|
readonly operation: Schema.String;
|
|
@@ -86,6 +186,12 @@ interface Provider {
|
|
|
86
186
|
readonly rm: (path: string, options?: RmOptions) => Promise<void>;
|
|
87
187
|
/** Canonical absolute path with symlinks resolved; rejects when the path does not exist. */
|
|
88
188
|
readonly realpath: (path: string) => Promise<string>;
|
|
189
|
+
/**
|
|
190
|
+
* A window of the file's lines, by the rules in `Scan`. Bounded: never
|
|
191
|
+
* returns, or holds, more than the window. A remote backend runs the scan
|
|
192
|
+
* inside the sandbox (`Scan.script`) so only the window crosses the network.
|
|
193
|
+
*/
|
|
194
|
+
readonly scanLines: (path: string, options: LineScanOptions) => Promise<LineScan>;
|
|
89
195
|
/**
|
|
90
196
|
* Metadata for the directory entry itself rather than a symlink's target.
|
|
91
197
|
* Optional: a backend whose `stat` has mixed symlink semantics implements it
|
|
@@ -113,6 +219,8 @@ interface Interface {
|
|
|
113
219
|
readonly rm: (path: string, options?: RmOptions) => Effect.Effect<void, FileSystemError | OperationUnsupportedError>;
|
|
114
220
|
/** Canonical absolute path with symlinks resolved; fails when the path does not exist. */
|
|
115
221
|
readonly realpath: (path: string) => Effect.Effect<string, FileSystemError>;
|
|
222
|
+
/** A bounded window of the file's lines; see `Scan`. Invalid options are a defect. */
|
|
223
|
+
readonly scanLines: (path: string, options: LineScanOptions) => Effect.Effect<LineScan, FileSystemError>;
|
|
116
224
|
readonly lstat?: (path: string) => Effect.Effect<FileStat, FileSystemError>;
|
|
117
225
|
}
|
|
118
226
|
declare const Service_base: Context.ServiceClass<Service, "@codeworksh/plugin/sandbox/filesystem/Service", Interface>;
|
|
@@ -140,5 +248,5 @@ declare const fromProvider: (provider: Provider) => Interface;
|
|
|
140
248
|
*/
|
|
141
249
|
declare const withCwd: (fs: Interface, cwd: string) => Interface;
|
|
142
250
|
//#endregion
|
|
143
|
-
export { Provider as a, filesystem_d_exports as c, realpathScripts as d, validateRmOptions as f, OperationUnsupportedError as i, fromProvider as l, FileSystemError as n, RmOptions as o, withCwd as p, Interface as r, Service as s, FileStat as t, isNotFoundError as u };
|
|
144
|
-
//# sourceMappingURL=filesystem-
|
|
251
|
+
export { Provider as a, filesystem_d_exports as c, realpathScripts as d, validateRmOptions as f, scan_d_exports as g, LineScanOptions as h, OperationUnsupportedError as i, fromProvider as l, LineScan as m, FileSystemError as n, RmOptions as o, withCwd as p, Interface as r, Service as s, FileStat as t, isNotFoundError as u };
|
|
252
|
+
//# sourceMappingURL=filesystem-BYaEdL14.d.mts.map
|
package/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { t as section_d_exports } from "./plugin/section.mjs";
|
|
2
2
|
import { g as tool_d_exports } from "./tool-DuYBgiJf.mjs";
|
|
3
|
-
import { t as plugin_d_exports } from "./plugin-
|
|
3
|
+
import { t as plugin_d_exports } from "./plugin-Bb1gRtNX.mjs";
|
|
4
4
|
export { plugin_d_exports as Plugin, section_d_exports as Section, tool_d_exports as Tool };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { c as filesystem_d_exports, n as FileSystemError, r as Interface$1, s as Service$1 } from "./filesystem-
|
|
1
|
+
import { c as filesystem_d_exports, n as FileSystemError, r as Interface$1, s as Service$1 } from "./filesystem-BYaEdL14.mjs";
|
|
2
2
|
import { i as Shell$1 } from "./shell-CZ6Y4lNU.mjs";
|
|
3
3
|
import { Context, Effect, Layer, Option, Schema } from "effect";
|
|
4
4
|
declare namespace instance_d_exports {
|
|
@@ -277,6 +277,8 @@ declare const AbsolutePath: Schema.brand<Schema.String, "SandboxDriver.AbsoluteP
|
|
|
277
277
|
type AbsolutePath = typeof AbsolutePath.Type;
|
|
278
278
|
declare const RuntimeConfigBase: Schema.Struct<{
|
|
279
279
|
readonly defaultCwd: Schema.brand<Schema.String, "SandboxDriver.AbsolutePath">;
|
|
280
|
+
/** Where oversized tool output is written inside the sandbox; `SandboxIO.DEFAULT_SPILL_PATH` when absent. */
|
|
281
|
+
readonly spillPath: Schema.optional<Schema.brand<Schema.String, "SandboxDriver.AbsolutePath">>;
|
|
280
282
|
}>;
|
|
281
283
|
interface RuntimeConfigBase extends Schema.Schema.Type<typeof RuntimeConfigBase> {}
|
|
282
284
|
interface Capabilities {
|
|
@@ -396,7 +398,7 @@ declare const Service_base: Context.ServiceClass<Service, "@codeworksh/plugin/sa
|
|
|
396
398
|
declare class Service extends Service_base {}
|
|
397
399
|
declare const make: (instance: ID, cwd: string, fs: Interface$1) => Interface;
|
|
398
400
|
declare namespace io_d_exports {
|
|
399
|
-
export { Current, FileSystem, Identity, Layer$1 as Layer, Mutation, Provides, io_d_exports as SandboxIO, Shell, host, hostLayer, identityLayer, mount, remote, resolveMountCwd, virtual, withMutation };
|
|
401
|
+
export { Current, DEFAULT_SPILL_PATH, FileSystem, Identity, Layer$1 as Layer, Mutation, Provides, io_d_exports as SandboxIO, Shell, host, hostLayer, identityLayer, mount, remote, resolveMountCwd, virtual, withMutation };
|
|
400
402
|
}
|
|
401
403
|
/**
|
|
402
404
|
* `SandboxIO` is a **mount**: a filesystem, a shell, and the identity and
|
|
@@ -443,7 +445,11 @@ interface Identity {
|
|
|
443
445
|
readonly kind: Kind;
|
|
444
446
|
/** Absolute, and always a path in *this* namespace. */
|
|
445
447
|
readonly cwd: string;
|
|
448
|
+
/** Directory, in this namespace, that oversized tool output is written to. */
|
|
449
|
+
readonly spillPath: string;
|
|
446
450
|
}
|
|
451
|
+
/** Spill directory for a driver that configures none. */
|
|
452
|
+
declare const DEFAULT_SPILL_PATH = "/tmp";
|
|
447
453
|
declare const Current_base: Context.ServiceClass<Current, "@codeworksh/plugin/sandbox/io/Current", Identity>;
|
|
448
454
|
/** Identity and working directory of the current mount. */
|
|
449
455
|
declare class Current extends Current_base {}
|
|
@@ -513,6 +519,7 @@ declare const virtual: (input: {
|
|
|
513
519
|
readonly id?: ID;
|
|
514
520
|
readonly defaultCwd?: string;
|
|
515
521
|
readonly cwd?: string;
|
|
522
|
+
readonly spillPath?: string;
|
|
516
523
|
}) => Identity;
|
|
517
524
|
/**
|
|
518
525
|
* A provider-hosted namespace. The id is always supplied: a remote resource's
|
|
@@ -525,7 +532,9 @@ declare const remote: (input: {
|
|
|
525
532
|
/** Namespace-intrinsic default supplied or discovered by the driver. */
|
|
526
533
|
readonly defaultCwd: string;
|
|
527
534
|
readonly cwd?: string;
|
|
535
|
+
/** Namespace-intrinsic spill directory configured by the driver. */
|
|
536
|
+
readonly spillPath?: string;
|
|
528
537
|
}) => Identity;
|
|
529
538
|
//#endregion
|
|
530
|
-
export {
|
|
531
|
-
//# sourceMappingURL=io-
|
|
539
|
+
export { SandboxRegisterError as $, RuntimeConfigBase as A, SandboxBusyError as B, Module as C, mountable as Ct, Provisioned as D, Observed as E, driver as F, SandboxDriverNotRegisteredError as G, SandboxDestroyError as H, driver_d_exports as I, SandboxMustBeStoppedError as J, SandboxDriverRegistrationError as K, erase as L, Source as M, apiVersion as N, Registered as O, defineModule as P, SandboxRefreshError as Q, withSource as R, Driver as S, isMountable as St, Name as T, toField as Tt, SandboxDriverLoadError as U, SandboxCreateError as V, SandboxDriverLoadPhase as W, SandboxProviderError as X, SandboxNotFoundError as Y, SandboxReadError as Z, withMutation as _, Status as _t, Layer$1 as a, SandboxWakeError as at, Capabilities as b, fromField as bt, Shell as c, providerError as ct, identityLayer as d, sanitizeError as dt, SandboxRemovedError as et, io_d_exports as f, ID as ft, virtual as g, PersistedError as gt, resolveMountCwd as h, Ownership as ht, Identity as i, SandboxUnsupportedError as it, RuntimeInput as j, Registration as k, host as l, providerErrorCause as lt, remote as m, Kind as mt, DEFAULT_SPILL_PATH as n, SandboxTransitionConflictError as nt, Mutation as o, errors_d_exports as ot, mount as p, Info as pt, SandboxMountError as q, FileSystem as r, SandboxUnavailError as rt, Provides as s, makeRedactor as st, Current as t, SandboxStopError as tt, hostLayer as u, providerErrorIsNotFound as ut, AbsolutePath as v, Usage as vt, ModuleDefinition as w, toColumn as wt, Definition as x, instance_d_exports as xt, ApiVersion as y, fromColumn as yt, Redactor as z };
|
|
540
|
+
//# sourceMappingURL=io-CXi2Sjg9.d.mts.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
|
|
2
2
|
import { ID } from "./sandbox/instance.mjs";
|
|
3
3
|
import { posix } from "./posix.mjs";
|
|
4
|
-
import {
|
|
4
|
+
import { l as withCwd, o as isNotFoundError, r as Service$1 } from "./filesystem-BFCKzgND.mjs";
|
|
5
5
|
import { Shell as Shell$1, withCwd as withCwd$1 } from "./sandbox/shell.mjs";
|
|
6
6
|
import { Context, Deferred, Effect, Layer } from "effect";
|
|
7
7
|
//#region src/sandbox/mutation.ts
|
|
@@ -49,6 +49,7 @@ const make = (instance, cwd, fs) => ({ withFile: (path, effect) => Effect.flatMa
|
|
|
49
49
|
//#region src/sandbox/io.ts
|
|
50
50
|
var io_exports = /* @__PURE__ */ __exportAll({
|
|
51
51
|
Current: () => Current,
|
|
52
|
+
DEFAULT_SPILL_PATH: () => DEFAULT_SPILL_PATH,
|
|
52
53
|
FileSystem: () => FileSystem,
|
|
53
54
|
Mutation: () => Mutation,
|
|
54
55
|
SandboxIO: () => io_exports,
|
|
@@ -88,6 +89,8 @@ const FileSystem = Service$1;
|
|
|
88
89
|
const Shell = Shell$1;
|
|
89
90
|
/** Per-file mutation ordering for this mount's instance. Re-exported here so consumers import one namespace. */
|
|
90
91
|
const Mutation = Service;
|
|
92
|
+
/** Spill directory for a driver that configures none. */
|
|
93
|
+
const DEFAULT_SPILL_PATH = "/tmp";
|
|
91
94
|
/** Identity and working directory of the current mount. */
|
|
92
95
|
var Current = class extends Context.Service()("@codeworksh/plugin/sandbox/io/Current") {};
|
|
93
96
|
/**
|
|
@@ -150,7 +153,8 @@ const host = (cwd) => ({
|
|
|
150
153
|
id: ID.local,
|
|
151
154
|
driver: "local",
|
|
152
155
|
kind: "local",
|
|
153
|
-
cwd: resolveMountCwd(cwd)
|
|
156
|
+
cwd: resolveMountCwd(cwd),
|
|
157
|
+
spillPath: DEFAULT_SPILL_PATH
|
|
154
158
|
});
|
|
155
159
|
/**
|
|
156
160
|
* A VFS-backed namespace. The id is minted per call unless one is named, because
|
|
@@ -163,7 +167,8 @@ const virtual = (input) => ({
|
|
|
163
167
|
id: input.id ?? ID.create(),
|
|
164
168
|
driver: input.driver,
|
|
165
169
|
kind: "virtual",
|
|
166
|
-
cwd: resolveMountCwd(input.defaultCwd ?? "/", input.cwd)
|
|
170
|
+
cwd: resolveMountCwd(input.defaultCwd ?? "/", input.cwd),
|
|
171
|
+
spillPath: input.spillPath ?? "/tmp"
|
|
167
172
|
});
|
|
168
173
|
/**
|
|
169
174
|
* A provider-hosted namespace. The id is always supplied: a remote resource's
|
|
@@ -174,9 +179,10 @@ const remote = (input) => ({
|
|
|
174
179
|
id: input.id,
|
|
175
180
|
driver: input.driver,
|
|
176
181
|
kind: "remote",
|
|
177
|
-
cwd: resolveMountCwd(input.defaultCwd, input.cwd)
|
|
182
|
+
cwd: resolveMountCwd(input.defaultCwd, input.cwd),
|
|
183
|
+
spillPath: input.spillPath ?? "/tmp"
|
|
178
184
|
});
|
|
179
185
|
//#endregion
|
|
180
|
-
export {
|
|
186
|
+
export { Shell as a, identityLayer as c, remote as d, resolveMountCwd as f, Mutation as i, io_exports as l, withMutation as m, DEFAULT_SPILL_PATH as n, host as o, virtual as p, FileSystem as r, hostLayer as s, Current as t, mount as u };
|
|
181
187
|
|
|
182
|
-
//# sourceMappingURL=io-
|
|
188
|
+
//# sourceMappingURL=io-RvZvG-4N.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"io-RvZvG-4N.mjs","names":["SandboxFileSystem.Service","ShellTag","SandboxMutation.Service","EffectLayer","SandboxMutation.make","SandboxFileSystem.withCwd","shellWithCwd"],"sources":["../../src/sandbox/mutation.ts","../../src/sandbox/io.ts"],"sourcesContent":["import { Context, Deferred, Effect } from \"effect\";\nimport { posix } from \"../posix.ts\";\nimport { type FileSystemError, type Interface as FileSystem, isNotFoundError } from \"./filesystem.ts\";\nimport type { SandboxInstance } from \"./instance.ts\";\n\n/**\n * Serializes mutations of one file.\n *\n * Tool calls may run in parallel, and a file-mutating tool does read → modify →\n * write. Two of those on one file interleave and the first write is lost, so a\n * tool holds the file for its whole read-modify-write.\n *\n * A file is its sandbox instance plus its canonical path: two mounts of one\n * instance share files, and a symlinked spelling of a path is the same file.\n * Other files never wait. This orders the harness's own tools within this\n * process only; it is not a lock against `bash` or other processes.\n */\nexport interface Interface {\n\t/**\n\t * Run `effect` as the only mutation of `path` in flight. Calls queue in the\n\t * order their paths resolve, which for one spelling is the order they were made.\n\t */\n\treadonly withFile: <A, E, R>(\n\t\tpath: string,\n\t\teffect: Effect.Effect<A, E, R>,\n\t) => Effect.Effect<A, E | FileSystemError, R>;\n}\n\nexport class Service extends Context.Service<Service, Interface>()(\"@codeworksh/plugin/sandbox/mutation/Service\") {}\n\ninterface Lock {\n\treadonly waiters: Array<Deferred.Deferred<void>>;\n}\n\n// Process-wide on purpose: every mount of one instance must meet in the same\n// queue, whichever layer built it. A key is present exactly while its file is held.\nconst locks = new Map<string, Lock>();\n\n/** Hand the file to the next waiter, or free it. Ownership moves directly, so no newcomer can barge in. */\nconst release = (key: string, lock: Lock): void => {\n\tconst next = lock.waiters.shift();\n\tif (next === undefined) locks.delete(key);\n\telse Deferred.doneUnsafe(next, Effect.void);\n};\n\n/** Take the file, waiting interruptibly; must run uninterruptibly so taking and releasing pair up. */\nconst acquire = (key: string, restore: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>) =>\n\tEffect.suspend(() => {\n\t\tconst lock = locks.get(key);\n\t\tif (lock === undefined) {\n\t\t\tlocks.set(key, { waiters: [] });\n\t\t\treturn Effect.void;\n\t\t}\n\t\tconst turn = Deferred.makeUnsafe<void>();\n\t\tlock.waiters.push(turn);\n\t\treturn restore(Deferred.await(turn)).pipe(\n\t\t\tEffect.onInterrupt(() =>\n\t\t\t\tEffect.sync(() => {\n\t\t\t\t\tconst index = lock.waiters.indexOf(turn);\n\t\t\t\t\t// Still queued: leave. Already handed the file: pass it on.\n\t\t\t\t\tif (index !== -1) lock.waiters.splice(index, 1);\n\t\t\t\t\telse release(key, lock);\n\t\t\t\t}),\n\t\t\t),\n\t\t);\n\t});\n\n/**\n * The canonical path. A file that does not exist yet takes its canonical\n * parent joined with its name, walking up as far as needed, so a write that\n * creates a file (and its directories) shares a key with later mutations of it.\n */\nconst canonical = (fs: FileSystem, path: string): Effect.Effect<string, FileSystemError> =>\n\tfs.realpath(path).pipe(\n\t\tEffect.catchIf(\n\t\t\t(error) => isNotFoundError(error.cause),\n\t\t\t(error) => {\n\t\t\t\tconst parent = posix.dirname(path);\n\t\t\t\tif (parent === path) return Effect.fail(error);\n\t\t\t\treturn Effect.map(canonical(fs, parent), (resolved) => posix.join(resolved, posix.basename(path)));\n\t\t\t},\n\t\t),\n\t);\n\nexport const make = (instance: SandboxInstance.ID, cwd: string, fs: FileSystem): Interface => ({\n\twithFile: (path, effect) =>\n\t\tEffect.flatMap(canonical(fs, posix.resolve(cwd, path)), (resolved) => {\n\t\t\tconst key = `${instance}\\0${resolved}`;\n\t\t\t// Held from the moment `acquire` returns: nothing can interrupt between\n\t\t\t// taking the file and installing its release.\n\t\t\treturn Effect.uninterruptibleMask((restore) =>\n\t\t\t\tEffect.andThen(\n\t\t\t\t\tacquire(key, restore),\n\t\t\t\t\trestore(effect).pipe(\n\t\t\t\t\t\tEffect.ensuring(\n\t\t\t\t\t\t\tEffect.sync(() => {\n\t\t\t\t\t\t\t\tconst lock = locks.get(key);\n\t\t\t\t\t\t\t\tif (lock !== undefined) release(key, lock);\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t);\n\t\t}),\n});\n\nexport * as SandboxMutation from \"./mutation.ts\";\n","import { Context, Effect, Layer as EffectLayer } from \"effect\";\nimport { posix } from \"../posix.ts\";\nimport type { SandboxDriver } from \"./driver.ts\";\nimport { SandboxFileSystem } from \"./filesystem.ts\";\nimport { SandboxInstance } from \"./instance.ts\";\nimport { SandboxMutation } from \"./mutation.ts\";\nimport { type ISandboxExe, Shell as ShellTag, withCwd as shellWithCwd } from \"./shell.ts\";\n\n/**\n * `SandboxIO` is a **mount**: a filesystem, a shell, and the identity and\n * working directory they act on.\n *\n * It is the whole vocabulary a consumer needs. Project, Git, Copy, Location, and\n * every tool ask for `SandboxIO.FileSystem`, `SandboxIO.Shell`, and\n * `SandboxIO.Current` — never for a driver, an address, or a provider SDK — so\n * a host directory, an in-memory VFS, and a remote microVM are interchangeable\n * behind one contract.\n *\n * The mount neither creates nor destroys infrastructure. `SandboxInstance` is\n * the durable namespace it acts on — a device, which exists whether or not\n * anything has it mounted — and `Sandbox.Controller` is the only path that\n * creates, stops, or destroys one.\n */\n\n/**\n * The filesystem tag. Re-exported here so consumers import one namespace —\n * Project, Git, Copy, and the runner ask for `SandboxIO.FileSystem`, never for\n * the module that happens to define it. Code *inside* `sandbox/` keeps importing\n * the tag directly, since `io.ts` is built on top of it.\n */\nexport const FileSystem = SandboxFileSystem.Service;\nexport type FileSystem = SandboxFileSystem.Service;\n\n/** The shell tag. Re-exported here so consumers import one namespace. */\nexport const Shell = ShellTag;\nexport type Shell = ShellTag;\n\n/** Per-file mutation ordering for this mount's instance. Re-exported here so consumers import one namespace. */\nexport const Mutation = SandboxMutation.Service;\nexport type Mutation = SandboxMutation.Service;\n\n/**\n * What a mount sees: immutable identity, plus the working directory resolved for\n * *this* mount.\n *\n * Nothing mutable belongs here. `status`, `usage`, and reference counts all\n * change while a mount is open, so a mount-time snapshot of them would be wrong\n * by construction — runtime code that needs live management state asks the\n * control plane. The driver's own resource locator is likewise absent: consumers\n * never parse a Vercel name or a Daytona id.\n */\nexport interface Identity {\n\treadonly id: SandboxInstance.ID;\n\treadonly driver: SandboxDriver.Name;\n\treadonly kind: SandboxInstance.Kind;\n\t/** Absolute, and always a path in *this* namespace. */\n\treadonly cwd: string;\n\t/** Directory, in this namespace, that oversized tool output is written to. */\n\treadonly spillPath: string;\n}\n\n/** Spill directory for a driver that configures none. */\nexport const DEFAULT_SPILL_PATH = \"/tmp\";\n\n/** Identity and working directory of the current mount. */\nexport class Current extends Context.Service<Current, Identity>()(\"@codeworksh/plugin/sandbox/io/Current\") {}\n\n/** Everything a mount provides. */\nexport type Provides = Current | SandboxFileSystem.Service | ShellTag | SandboxMutation.Service;\n\n/** A built mount. */\nexport type Layer<E = never, RIn = never> = EffectLayer.Layer<Provides, E, RIn>;\n\n/**\n * Resolve a mount's cwd without consulting ambient process state.\n *\n * The default is supplied by the namespace adapter:\n * provider metadata remotely, `/` for a virtual filesystem, and `process.cwd()` for the host adapter.\n * An explicit absolute cwd replaces it; a relative cwd is resolved inside it. The\n * result is therefore always the one concrete absolute path `Current` requires.\n *\n * A non-absolute default throws rather than failing typed. It is the one\n * defect-level guard in this module, and deliberately so:\n * Adapters reading a value from a provider call this inside their own error channel,\n * where the throw becomes their typed failure (see `EnvDaytona.mountCwd`).\n */\nexport const resolveMountCwd = (defaultCwd: string, cwd?: string): string => {\n\tif (!posix.isAbsolute(defaultCwd)) {\n\t\tthrow new TypeError(`Sandbox default cwd must be absolute: ${defaultCwd}`);\n\t}\n\t// `resolve`, not `normalize`: normalize keeps a trailing slash, and `cwd` is\n\t// persisted — `space.location` and its id hash would read\n\t// `/workspace/` and `/workspace` as two directories and keep a row for each.\n\t//\n\t// A provider-reported default (`getWorkDir()`) or a config value is free to\n\t// carry one, so it is stripped here rather than at every reader.\n\tif (cwd === undefined) return posix.resolve(defaultCwd);\n\treturn posix.isAbsolute(cwd) ? posix.resolve(cwd) : posix.resolve(defaultCwd, cwd);\n};\n\n/**\n * Complete a mount with its {@link Mutation} queue, derived from the mount's own\n * identity and filesystem. Every layer that provides a mount goes through here,\n * so mounts of one instance always meet in the same queue.\n */\nexport const withMutation = <E, R>(\n\tlayer: EffectLayer.Layer<Current | SandboxFileSystem.Service | ShellTag, E, R>,\n): EffectLayer.Layer<Provides, E, R> =>\n\tEffectLayer.provideMerge(\n\t\tEffectLayer.effect(\n\t\t\tMutation,\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst current = yield* Current;\n\t\t\t\treturn SandboxMutation.make(current.id, current.cwd, yield* SandboxFileSystem.Service);\n\t\t\t}),\n\t\t),\n\t\tlayer,\n\t);\n\n/**\n * Bind a cwd-neutral transport to one mount.\n *\n * The transport underneath is shared between\n * mounts and stays rooted at the namespace root, and everything directory-shaped\n * happens here, once per mount. Two mounts of one namespace at different working\n * directories therefore coexist without seeing or moving each other's.\n *\n * It consumes the same two tags it provides — the transport is supplied by the\n * layer this is composed over, not by itself.\n */\nexport const mount = (identity: Identity): EffectLayer.Layer<Provides, never, SandboxFileSystem.Service | ShellTag> =>\n\tEffectLayer.mergeAll(\n\t\tEffectLayer.succeed(Current, identity),\n\t\tEffectLayer.effect(\n\t\t\tSandboxFileSystem.Service,\n\t\t\tEffect.map(SandboxFileSystem.Service, (fs) => SandboxFileSystem.withCwd(fs, identity.cwd)),\n\t\t),\n\t\tEffectLayer.effect(\n\t\t\tShellTag,\n\t\t\tEffect.map(ShellTag, (shell: ISandboxExe) => shellWithCwd(shell, identity.cwd)),\n\t\t),\n\t).pipe(withMutation);\n\n/**\n * Just the identity tag, with no filesystem or shell beneath it. For consumers\n * assembled from stubs — a test that runs `Project` over a fake filesystem still\n * needs to know which namespace it is in.\n */\nexport const identityLayer = (identity: Identity) => EffectLayer.succeed(Current, identity);\n\n/** The host identity alone. See {@link identityLayer}. */\nexport const hostLayer = (cwd: string) => identityLayer(host(cwd));\n\n/**\n * The host, rooted at `cwd`. Always `SandboxInstance.ID.local`: the working\n * directory selects where relative paths resolve, it does not make a second host\n * namespace — two mounts rooted at different directories still agree on absolute\n * paths.\n *\n * The host coordinate is explicit so a caller cannot accidentally substitute ambient process\n * state for the application or session directory it owns.\n */\nexport const host = (cwd: string): Identity => ({\n\tid: SandboxInstance.ID.local,\n\tdriver: \"local\" as SandboxDriver.Name,\n\tkind: \"local\",\n\tcwd: resolveMountCwd(cwd),\n\tspillPath: DEFAULT_SPILL_PATH,\n});\n\n/**\n * A VFS-backed namespace. The id is minted per call unless one is named, because\n * building one of these builds a fresh VFS: N unnamed calls are N distinct\n * namespaces, none of which outlives the process. A file-backed store is the\n * exception — its file is the state, so whoever knows the file supplies the id\n * it was registered under.\n */\nexport const virtual = (input: {\n\treadonly driver: string;\n\treadonly id?: SandboxInstance.ID;\n\treadonly defaultCwd?: string;\n\treadonly cwd?: string;\n\treadonly spillPath?: string;\n}): Identity => ({\n\tid: input.id ?? SandboxInstance.ID.create(),\n\tdriver: input.driver as SandboxDriver.Name,\n\tkind: \"virtual\",\n\tcwd: resolveMountCwd(input.defaultCwd ?? \"/\", input.cwd),\n\tspillPath: input.spillPath ?? DEFAULT_SPILL_PATH,\n});\n\n/**\n * A provider-hosted namespace. The id is always supplied: a remote resource's\n * durable identity is minted and recorded by whoever provisioned it, never\n * derived here from the provider's own locator.\n */\nexport const remote = (input: {\n\treadonly driver: string;\n\treadonly id: SandboxInstance.ID;\n\t/** Namespace-intrinsic default supplied or discovered by the driver. */\n\treadonly defaultCwd: string;\n\treadonly cwd?: string;\n\t/** Namespace-intrinsic spill directory configured by the driver. */\n\treadonly spillPath?: string;\n}): Identity => ({\n\tid: input.id,\n\tdriver: input.driver as SandboxDriver.Name,\n\tkind: \"remote\",\n\tcwd: resolveMountCwd(input.defaultCwd, input.cwd),\n\tspillPath: input.spillPath ?? DEFAULT_SPILL_PATH,\n});\n\nexport * as SandboxIO from \"./io.ts\";\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codeworksh/plugin",
|
|
3
|
-
"version": "0.1.0-canary.
|
|
3
|
+
"version": "0.1.0-canary.21.1.gd0108197",
|
|
4
4
|
"description": "SDK for building CodeWork plugins — the plugin, tool, and sandbox contracts shared with @codeworksh/harness.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent",
|
|
@@ -168,7 +168,7 @@
|
|
|
168
168
|
"uuidv7": "^1.2.1"
|
|
169
169
|
},
|
|
170
170
|
"peerDependencies": {
|
|
171
|
-
"@codeworksh/aikit": "0.10.0-canary.
|
|
171
|
+
"@codeworksh/aikit": "0.10.0-canary.21.1.gd0108197",
|
|
172
172
|
"effect": "4.0.1"
|
|
173
173
|
}
|
|
174
174
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { i as Definition, o as Payload, r as Data, s as PublishOptions } from "./event-
|
|
1
|
+
import { i as Definition, o as Payload, r as Data, s as PublishOptions } from "./event-6sTQ_4bq.mjs";
|
|
2
2
|
import { n as SessionID } from "./ids-CHjmAdTc.mjs";
|
|
3
3
|
import { o as Service, r as Info } from "./location-Q39els63.mjs";
|
|
4
|
-
import {
|
|
4
|
+
import { f as io_d_exports, i as Identity, s as Provides } from "./io-CXi2Sjg9.mjs";
|
|
5
5
|
import { i as Info$1 } from "./settings-B6-grSTA.mjs";
|
|
6
6
|
import { t as section_d_exports } from "./plugin/section.mjs";
|
|
7
7
|
import { n as prompt_d_exports, t as PromptRegistry } from "./prompt-DWaA5ZXj.mjs";
|
|
@@ -138,4 +138,4 @@ declare namespace plugin_d_exports {
|
|
|
138
138
|
}
|
|
139
139
|
//#endregion
|
|
140
140
|
export { define as a, PluginOptions as c, PluginSpec as d, Config as f, PluginRegistry as g, SharedPluginContext as h, PluginKind as i, PluginPatch as l, PromptResolver as m, Mount as n, domains as o, Events as p, Plugin as r, rank as s, plugin_d_exports as t, PluginRef as u };
|
|
141
|
-
//# sourceMappingURL=plugin-
|
|
141
|
+
//# sourceMappingURL=plugin-Bb1gRtNX.d.mts.map
|
package/plugin.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as section_d_exports } from "./plugin/section.mjs";
|
|
2
2
|
import { n as prompt_d_exports } from "./prompt-DWaA5ZXj.mjs";
|
|
3
3
|
import { p as tool_d_exports } from "./tool-BoVqkYvL.mjs";
|
|
4
|
-
import { a as define, c as PluginOptions, d as PluginSpec, f as Config, g as PluginRegistry, h as SharedPluginContext, i as PluginKind, l as PluginPatch, m as PromptResolver, n as Mount, o as domains, p as Events, r as Plugin, s as rank, u as PluginRef } from "./plugin-
|
|
4
|
+
import { a as define, c as PluginOptions, d as PluginSpec, f as Config, g as PluginRegistry, h as SharedPluginContext, i as PluginKind, l as PluginPatch, m as PromptResolver, n as Mount, o as domains, p as Events, r as Plugin, s as rank, u as PluginRef } from "./plugin-Bb1gRtNX.mjs";
|
|
5
5
|
export { type Config, type Events, type Mount, type Plugin, type PluginKind, type PluginOptions, type PluginPatch, type PluginRef, type PluginRegistry, type PluginSpec, prompt_d_exports as Prompt, type PromptResolver, section_d_exports as Section, type SharedPluginContext, tool_d_exports as Tool, define, domains, rank };
|
package/sandbox/driver.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { A as
|
|
1
|
+
import { A as RuntimeConfigBase, C as Module, D as Provisioned, E as Observed, F as driver, I as driver_d_exports, L as erase, M as Source, N as apiVersion, O as Registered, P as defineModule, R as withSource, S as Driver, T as Name, b as Capabilities, j as RuntimeInput, k as Registration, v as AbsolutePath, w as ModuleDefinition, x as Definition, y as ApiVersion } from "../io-CXi2Sjg9.mjs";
|
|
2
2
|
export { AbsolutePath, ApiVersion, Capabilities, Definition, Driver, Module, ModuleDefinition, Name, Observed, Provisioned, Registered, Registration, RuntimeConfigBase, RuntimeInput, driver_d_exports as SandboxDriver, Source, apiVersion, driver, erase, defineModule as module, withSource };
|
package/sandbox/driver.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { t as __exportAll } from "../rolldown-runtime-D7D4PA-g.mjs";
|
|
2
2
|
import "./instance.mjs";
|
|
3
|
-
import "../io-
|
|
3
|
+
import "../io-RvZvG-4N.mjs";
|
|
4
4
|
import { Schema } from "effect";
|
|
5
5
|
//#region src/sandbox/driver.ts
|
|
6
6
|
var driver_exports = /* @__PURE__ */ __exportAll({
|
|
@@ -20,7 +20,11 @@ const apiVersion = 1;
|
|
|
20
20
|
const Name = Schema.String.check(Schema.isNonEmpty()).pipe(Schema.brand("SandboxDriver.Name"));
|
|
21
21
|
/** A path whose coordinate system is the mounted namespace. */
|
|
22
22
|
const AbsolutePath = Schema.String.check(Schema.isStartingWith("/")).pipe(Schema.brand("SandboxDriver.AbsolutePath"));
|
|
23
|
-
const RuntimeConfigBase = Schema.Struct({
|
|
23
|
+
const RuntimeConfigBase = Schema.Struct({
|
|
24
|
+
defaultCwd: AbsolutePath,
|
|
25
|
+
/** Where oversized tool output is written inside the sandbox; `SandboxIO.DEFAULT_SPILL_PATH` when absent. */
|
|
26
|
+
spillPath: Schema.optional(AbsolutePath)
|
|
27
|
+
});
|
|
24
28
|
const erase = (value) => ({
|
|
25
29
|
name: value.name,
|
|
26
30
|
kind: value.kind,
|
package/sandbox/driver.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"driver.mjs","names":[],"sources":["../../../src/sandbox/driver.ts"],"sourcesContent":["import { type Effect, type Layer, Option, Schema } from \"effect\";\nimport type { SandboxProviderError } from \"./errors.ts\";\nimport { SandboxInstance } from \"./instance.ts\";\nimport { SandboxIO } from \"./io.ts\";\n\n/** Version of the loadable sandbox-driver module ABI. */\nexport const apiVersion = 1 as const;\nexport type ApiVersion = typeof apiVersion;\n\n/** Open driver identity. Adding a driver never extends a union in core. */\nexport const Name = Schema.String.check(Schema.isNonEmpty()).pipe(Schema.brand(\"SandboxDriver.Name\"));\nexport type Name = typeof Name.Type;\n\n/** A path whose coordinate system is the mounted namespace. */\nexport const AbsolutePath = Schema.String.check(Schema.isStartingWith(\"/\")).pipe(\n\tSchema.brand(\"SandboxDriver.AbsolutePath\"),\n);\nexport type AbsolutePath = typeof AbsolutePath.Type;\n\nexport const RuntimeConfigBase = Schema.Struct({
|
|
1
|
+
{"version":3,"file":"driver.mjs","names":[],"sources":["../../../src/sandbox/driver.ts"],"sourcesContent":["import { type Effect, type Layer, Option, Schema } from \"effect\";\nimport type { SandboxProviderError } from \"./errors.ts\";\nimport { SandboxInstance } from \"./instance.ts\";\nimport { SandboxIO } from \"./io.ts\";\n\n/** Version of the loadable sandbox-driver module ABI. */\nexport const apiVersion = 1 as const;\nexport type ApiVersion = typeof apiVersion;\n\n/** Open driver identity. Adding a driver never extends a union in core. */\nexport const Name = Schema.String.check(Schema.isNonEmpty()).pipe(Schema.brand(\"SandboxDriver.Name\"));\nexport type Name = typeof Name.Type;\n\n/** A path whose coordinate system is the mounted namespace. */\nexport const AbsolutePath = Schema.String.check(Schema.isStartingWith(\"/\")).pipe(\n\tSchema.brand(\"SandboxDriver.AbsolutePath\"),\n);\nexport type AbsolutePath = typeof AbsolutePath.Type;\n\nexport const RuntimeConfigBase = Schema.Struct({\n\tdefaultCwd: AbsolutePath,\n\t/** Where oversized tool output is written inside the sandbox; `SandboxIO.DEFAULT_SPILL_PATH` when absent. */\n\tspillPath: Schema.optional(AbsolutePath),\n});\nexport interface RuntimeConfigBase extends Schema.Schema.Type<typeof RuntimeConfigBase> {}\n\nexport interface Capabilities {\n\treadonly inspect: boolean;\n\treadonly reattach: boolean;\n\treadonly wake: boolean;\n\treadonly stop: boolean;\n\treadonly destroy: boolean;\n\treadonly cancels: boolean;\n}\n\nexport interface Observed {\n\treadonly status: SandboxInstance.Status;\n\treadonly providerStatus?: string | undefined;\n\treadonly metadata?: Readonly<Record<string, string>> | undefined;\n}\n\nexport interface Provisioned<RuntimeConfig extends RuntimeConfigBase> {\n\treadonly providerResourceId?: string | undefined;\n\treadonly providerStatus?: string | undefined;\n\treadonly runtimeConfig: RuntimeConfig;\n\treadonly metadata?: Readonly<Record<string, string>> | undefined;\n}\n\nexport interface RuntimeInput<RuntimeConfig extends RuntimeConfigBase> {\n\treadonly id: SandboxInstance.ID;\n\treadonly providerResourceId: Option.Option<string>;\n\treadonly runtimeConfig: RuntimeConfig;\n}\n\nexport interface Driver<CreateConfig, RuntimeConfig extends RuntimeConfigBase> {\n\treadonly name: Name;\n\treadonly kind: Exclude<SandboxInstance.Kind, \"local\">;\n\treadonly capabilities: Capabilities;\n\treadonly createConfigCodec: Schema.Codec<CreateConfig, unknown>;\n\treadonly runtimeConfigCodec: Schema.Codec<RuntimeConfig, unknown>;\n\treadonly create: (input: {\n\t\treadonly instanceId: SandboxInstance.ID;\n\t\treadonly config: CreateConfig;\n\t}) => Effect.Effect<Provisioned<RuntimeConfig>, SandboxProviderError>;\n\treadonly runtimeConfigFor?:\n\t\t| ((input: {\n\t\t\t\treadonly providerResourceId: string;\n\t\t\t\treadonly overrides?: Partial<RuntimeConfig> | undefined;\n\t\t }) => Effect.Effect<RuntimeConfig, SandboxProviderError>)\n\t\t| undefined;\n\treadonly attach: (\n\t\tinput: RuntimeInput<RuntimeConfig>,\n\t) => Layer.Layer<SandboxIO.FileSystem | SandboxIO.Shell, SandboxProviderError>;\n\treadonly inspect?: (input: RuntimeInput<RuntimeConfig>) => Effect.Effect<Observed, SandboxProviderError>;\n\treadonly wake?: (input: RuntimeInput<RuntimeConfig>) => Effect.Effect<Observed, SandboxProviderError>;\n\treadonly stop?: (input: RuntimeInput<RuntimeConfig>) => Effect.Effect<Observed, SandboxProviderError>;\n\treadonly destroy?: (input: RuntimeInput<RuntimeConfig>) => Effect.Effect<void, SandboxProviderError>;\n}\n\nexport type Definition<CreateConfig, RuntimeConfig extends RuntimeConfigBase> = Pick<\n\tDriver<CreateConfig, RuntimeConfig>,\n\t\"name\" | \"createConfigCodec\" | \"runtimeConfigCodec\"\n>;\n\n/** Registry-only erased shape. Driver authors construct it via {@link driver}. */\nexport interface Registered {\n\treadonly name: Name;\n\treadonly kind: Exclude<SandboxInstance.Kind, \"local\">;\n\treadonly capabilities: Capabilities;\n\treadonly createConfigCodec: Schema.Codec<unknown, unknown>;\n\treadonly runtimeConfigCodec: Schema.Codec<RuntimeConfigBase, unknown>;\n\treadonly create: (input: {\n\t\treadonly instanceId: SandboxInstance.ID;\n\t\treadonly config: unknown;\n\t}) => Effect.Effect<Provisioned<RuntimeConfigBase>, SandboxProviderError>;\n\treadonly runtimeConfigFor?:\n\t\t| ((input: {\n\t\t\t\treadonly providerResourceId: string;\n\t\t\t\treadonly overrides?: Readonly<Record<string, unknown>> | undefined;\n\t\t }) => Effect.Effect<RuntimeConfigBase, SandboxProviderError>)\n\t\t| undefined;\n\treadonly attach: (\n\t\tinput: RuntimeInput<RuntimeConfigBase>,\n\t) => Layer.Layer<SandboxIO.FileSystem | SandboxIO.Shell, SandboxProviderError>;\n\treadonly inspect?: (input: RuntimeInput<RuntimeConfigBase>) => Effect.Effect<Observed, SandboxProviderError>;\n\treadonly wake?: (input: RuntimeInput<RuntimeConfigBase>) => Effect.Effect<Observed, SandboxProviderError>;\n\treadonly stop?: (input: RuntimeInput<RuntimeConfigBase>) => Effect.Effect<Observed, SandboxProviderError>;\n\treadonly destroy?: (input: RuntimeInput<RuntimeConfigBase>) => Effect.Effect<void, SandboxProviderError>;\n}\n\nexport const erase = <CreateConfig, RuntimeConfig extends RuntimeConfigBase>(\n\tvalue: Driver<CreateConfig, RuntimeConfig>,\n): Registered => ({\n\tname: value.name,\n\tkind: value.kind,\n\tcapabilities: value.capabilities,\n\tcreateConfigCodec: value.createConfigCodec as Schema.Codec<unknown, unknown>,\n\truntimeConfigCodec: value.runtimeConfigCodec as Schema.Codec<RuntimeConfigBase, unknown>,\n\tcreate: (input) => value.create({ instanceId: input.instanceId, config: input.config as CreateConfig }),\n\t...(value.runtimeConfigFor === undefined\n\t\t? {}\n\t\t: {\n\t\t\t\truntimeConfigFor: (input: {\n\t\t\t\t\treadonly providerResourceId: string;\n\t\t\t\t\treadonly overrides?: Readonly<Record<string, unknown>> | undefined;\n\t\t\t\t}) =>\n\t\t\t\t\tvalue.runtimeConfigFor!({\n\t\t\t\t\t\tproviderResourceId: input.providerResourceId,\n\t\t\t\t\t\t...(input.overrides === undefined ? {} : { overrides: input.overrides as Partial<RuntimeConfig> }),\n\t\t\t\t\t}),\n\t\t\t}),\n\tattach: (input) => value.attach(input as RuntimeInput<RuntimeConfig>),\n\t...(value.inspect === undefined\n\t\t? {}\n\t\t: { inspect: (input: RuntimeInput<RuntimeConfigBase>) => value.inspect!(input as RuntimeInput<RuntimeConfig>) }),\n\t...(value.wake === undefined\n\t\t? {}\n\t\t: { wake: (input: RuntimeInput<RuntimeConfigBase>) => value.wake!(input as RuntimeInput<RuntimeConfig>) }),\n\t...(value.stop === undefined\n\t\t? {}\n\t\t: { stop: (input: RuntimeInput<RuntimeConfigBase>) => value.stop!(input as RuntimeInput<RuntimeConfig>) }),\n\t...(value.destroy === undefined\n\t\t? {}\n\t\t: { destroy: (input: RuntimeInput<RuntimeConfigBase>) => value.destroy!(input as RuntimeInput<RuntimeConfig>) }),\n});\n\nexport type Source = \"core\" | \"builtin\" | \"package\" | \"file\";\n\nexport interface Registration {\n\treadonly registered: Registered;\n\treadonly apiVersion: ApiVersion;\n\treadonly source: Source;\n}\n\nexport interface Module<Options> {\n\treadonly apiVersion: ApiVersion;\n\treadonly name: Name;\n\treadonly options: Schema.Codec<Options, unknown>;\n\treadonly make: (options: Options) => Registration;\n}\n\nexport interface ModuleDefinition<Options> {\n\treadonly apiVersion: ApiVersion;\n\treadonly name: string | Name;\n\treadonly options: Schema.Codec<Options, unknown>;\n\treadonly make: (options: Options) => Registration;\n}\n\n/** Define the default export of a loadable sandbox package. */\nconst defineModule = <Options>(value: ModuleDefinition<Options>): Module<Options> => ({\n\t...value,\n\tname: Name.make(value.name),\n});\nexport { defineModule as module };\n\n/** Construct a driver and its registry contribution. */\nexport const driver = <CreateConfig, RuntimeConfig extends RuntimeConfigBase>(\n\tvalue: Driver<CreateConfig, RuntimeConfig>,\n): Driver<CreateConfig, RuntimeConfig> & Registration =>\n\tObject.assign(value, {\n\t\tregistered: erase(value),\n\t\tapiVersion,\n\t\tsource: \"builtin\" as const,\n\t});\n\n/** Attach trusted origin metadata without changing the driver implementation. */\nexport const withSource = (registration: Registration, source: Source): Registration => ({\n\t...registration,\n\tsource,\n});\n\nexport * as SandboxDriver from \"./driver.ts\";\n"],"mappings":";;;;;;;;;;;;;;;;;AAMA,MAAa,aAAa;;AAI1B,MAAa,OAAO,OAAO,OAAO,MAAM,OAAO,WAAW,CAAC,CAAC,CAAC,KAAK,OAAO,MAAM,oBAAoB,CAAC;;AAIpG,MAAa,eAAe,OAAO,OAAO,MAAM,OAAO,eAAe,GAAG,CAAC,CAAC,CAAC,KAC3E,OAAO,MAAM,4BAA4B,CAC1C;AAGA,MAAa,oBAAoB,OAAO,OAAO;CAC9C,YAAY;;CAEZ,WAAW,OAAO,SAAS,YAAY;AACxC,CAAC;AAuFD,MAAa,SACZ,WACiB;CACjB,MAAM,MAAM;CACZ,MAAM,MAAM;CACZ,cAAc,MAAM;CACpB,mBAAmB,MAAM;CACzB,oBAAoB,MAAM;CAC1B,SAAS,UAAU,MAAM,OAAO;EAAE,YAAY,MAAM;EAAY,QAAQ,MAAM;CAAuB,CAAC;CACtG,GAAI,MAAM,qBAAqB,KAAA,IAC5B,CAAC,IACD,EACA,mBAAmB,UAIlB,MAAM,iBAAkB;EACvB,oBAAoB,MAAM;EAC1B,GAAI,MAAM,cAAc,KAAA,IAAY,CAAC,IAAI,EAAE,WAAW,MAAM,UAAoC;CACjG,CAAC,EACH;CACF,SAAS,UAAU,MAAM,OAAO,KAAoC;CACpE,GAAI,MAAM,YAAY,KAAA,IACnB,CAAC,IACD,EAAE,UAAU,UAA2C,MAAM,QAAS,KAAoC,EAAE;CAC/G,GAAI,MAAM,SAAS,KAAA,IAChB,CAAC,IACD,EAAE,OAAO,UAA2C,MAAM,KAAM,KAAoC,EAAE;CACzG,GAAI,MAAM,SAAS,KAAA,IAChB,CAAC,IACD,EAAE,OAAO,UAA2C,MAAM,KAAM,KAAoC,EAAE;CACzG,GAAI,MAAM,YAAY,KAAA,IACnB,CAAC,IACD,EAAE,UAAU,UAA2C,MAAM,QAAS,KAAoC,EAAE;AAChH;;AAyBA,MAAM,gBAAyB,WAAuD;CACrF,GAAG;CACH,MAAM,KAAK,KAAK,MAAM,IAAI;AAC3B;;AAIA,MAAa,UACZ,UAEA,OAAO,OAAO,OAAO;CACpB,YAAY,MAAM,KAAK;CACvB,YAAA;CACA,QAAQ;AACT,CAAC;;AAGF,MAAa,cAAc,cAA4B,YAAkC;CACxF,GAAG;CACH;AACD"}
|
package/sandbox/errors.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { $ as
|
|
1
|
+
import { $ as SandboxRegisterError, B as SandboxBusyError, G as SandboxDriverNotRegisteredError, H as SandboxDestroyError, J as SandboxMustBeStoppedError, K as SandboxDriverRegistrationError, Q as SandboxRefreshError, U as SandboxDriverLoadError, V as SandboxCreateError, W as SandboxDriverLoadPhase, X as SandboxProviderError, Y as SandboxNotFoundError, Z as SandboxReadError, at as SandboxWakeError, ct as providerError, dt as sanitizeError, et as SandboxRemovedError, it as SandboxUnsupportedError, lt as providerErrorCause, nt as SandboxTransitionConflictError, ot as errors_d_exports, q as SandboxMountError, rt as SandboxUnavailError, st as makeRedactor, tt as SandboxStopError, ut as providerErrorIsNotFound, z as Redactor } from "../io-CXi2Sjg9.mjs";
|
|
2
2
|
export { Redactor, SandboxBusyError, SandboxCreateError, SandboxDestroyError, SandboxDriverLoadError, SandboxDriverLoadPhase, SandboxDriverNotRegisteredError, SandboxDriverRegistrationError, errors_d_exports as SandboxError, SandboxMountError, SandboxMustBeStoppedError, SandboxNotFoundError, SandboxProviderError, SandboxReadError, SandboxRefreshError, SandboxRegisterError, SandboxRemovedError, SandboxStopError, SandboxTransitionConflictError, SandboxUnavailError, SandboxUnsupportedError, SandboxWakeError, makeRedactor, providerError, providerErrorCause, providerErrorIsNotFound, sanitizeError };
|
package/sandbox/filesystem.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as Provider, c as filesystem_d_exports, d as realpathScripts, f as validateRmOptions, i as OperationUnsupportedError, l as fromProvider, n as FileSystemError, o as RmOptions, p as withCwd, r as Interface, s as Service, t as FileStat, u as isNotFoundError } from "../filesystem-
|
|
2
|
-
export { FileStat, FileSystemError, Interface, OperationUnsupportedError, Provider, RmOptions, filesystem_d_exports as SandboxFileSystem, Service, fromProvider, isNotFoundError, realpathScripts, validateRmOptions, withCwd };
|
|
1
|
+
import { a as Provider, c as filesystem_d_exports, d as realpathScripts, f as validateRmOptions, g as scan_d_exports, h as LineScanOptions, i as OperationUnsupportedError, l as fromProvider, m as LineScan, n as FileSystemError, o as RmOptions, p as withCwd, r as Interface, s as Service, t as FileStat, u as isNotFoundError } from "../filesystem-BYaEdL14.mjs";
|
|
2
|
+
export { FileStat, FileSystemError, Interface, type LineScan, type LineScanOptions, OperationUnsupportedError, Provider, RmOptions, filesystem_d_exports as SandboxFileSystem, scan_d_exports as Scan, Service, fromProvider, isNotFoundError, realpathScripts, validateRmOptions, withCwd };
|
package/sandbox/filesystem.mjs
CHANGED
|
@@ -1,148 +1,2 @@
|
|
|
1
|
-
import { t as
|
|
2
|
-
|
|
3
|
-
import { Context, Effect, Schema } from "effect";
|
|
4
|
-
//#region src/sandbox/filesystem.ts
|
|
5
|
-
var filesystem_exports = /* @__PURE__ */ __exportAll({
|
|
6
|
-
FileSystemError: () => FileSystemError,
|
|
7
|
-
OperationUnsupportedError: () => OperationUnsupportedError,
|
|
8
|
-
SandboxFileSystem: () => filesystem_exports,
|
|
9
|
-
Service: () => Service,
|
|
10
|
-
fromProvider: () => fromProvider,
|
|
11
|
-
isNotFoundError: () => isNotFoundError,
|
|
12
|
-
realpathScripts: () => realpathScripts,
|
|
13
|
-
validateRmOptions: () => validateRmOptions,
|
|
14
|
-
withCwd: () => withCwd
|
|
15
|
-
});
|
|
16
|
-
/**
|
|
17
|
-
* The runtime filesystem contract, independent of any backend.
|
|
18
|
-
*
|
|
19
|
-
* Two surfaces, deliberately:
|
|
20
|
-
* - {@link Provider} is what a backend implements — plain promises that reject,
|
|
21
|
-
* matching every SDK we wrap.
|
|
22
|
-
* - {@link Interface} is what the harness consumes — Effect with a typed error
|
|
23
|
-
* channel and tracing spans. {@link fromProvider} bridges the two exactly
|
|
24
|
-
* once, so no consumer ever writes `Effect.tryPromise` against a filesystem.
|
|
25
|
-
*
|
|
26
|
-
* Implementations:
|
|
27
|
-
* - Local:
|
|
28
|
-
* implement it over a VFS (`./local`);
|
|
29
|
-
* local filesystem use OS primitives; hence have broader filesytem capabilities.
|
|
30
|
-
*
|
|
31
|
-
* - Remote:
|
|
32
|
-
* implement it over a provider (`./remote`).
|
|
33
|
-
* remote filesytems depends on the interface provided by the remote provider; hence can have limited filesytem capabilities.
|
|
34
|
-
*
|
|
35
|
-
* `isFile`/`isDirectory` are required booleans; size, mtime, and isSymbolicLink are omitted when the
|
|
36
|
-
* backend cannot report them — never fabricated.
|
|
37
|
-
*
|
|
38
|
-
* **Paths are POSIX, and the harness is Unix-only (for now!).** Every path uses `/`
|
|
39
|
-
* separators on both the host and inside a sandbox — Windows is not supported,
|
|
40
|
-
* so no translation layer exists. Consumers must use the shared Effect POSIX
|
|
41
|
-
* path implementation, never the platform default, or a host running the harness would
|
|
42
|
-
* impose its own flavour on a remote sandbox's paths. Relative paths resolve
|
|
43
|
-
* against the backend's configured `cwd`.
|
|
44
|
-
*/
|
|
45
|
-
var OperationUnsupportedError = class extends Schema.TaggedError()("OperationUnsupportedError", {
|
|
46
|
-
operation: Schema.String,
|
|
47
|
-
message: Schema.String
|
|
48
|
-
}) {};
|
|
49
|
-
/** A backend operation failed. `cause` carries the provider's own rejection. */
|
|
50
|
-
var FileSystemError = class extends Schema.TaggedError()("SandboxFileSystemError", {
|
|
51
|
-
method: Schema.String,
|
|
52
|
-
path: Schema.String,
|
|
53
|
-
cause: Schema.optional(Schema.Defect())
|
|
54
|
-
}) {};
|
|
55
|
-
/** Whether a provider failure means the path itself is definitively absent. */
|
|
56
|
-
const isNotFoundError = (cause) => {
|
|
57
|
-
const code = cause?.code;
|
|
58
|
-
return code === "ENOENT" || code === "ENOTDIR";
|
|
59
|
-
};
|
|
60
|
-
/**
|
|
61
|
-
* Shell forms of `realpath` for backends that only expose a process API. Run as
|
|
62
|
-
* `sh -c <script> _ <path>`, trying each in turn. `realpath -e` (coreutils)
|
|
63
|
-
* resolves every component, a symlinked file included, and fails on a missing
|
|
64
|
-
* path. Where it is absent, `pwd -P` is the portable primitive: directories
|
|
65
|
-
* resolve directly, anything else resolves its parent and keeps the final name
|
|
66
|
-
* as given — so a symlinked *file* stays unresolved there.
|
|
67
|
-
*/
|
|
68
|
-
const realpathScripts = [
|
|
69
|
-
"realpath -e -- \"$1\"",
|
|
70
|
-
"cd -- \"$1\" && pwd -P",
|
|
71
|
-
"cd -- \"$(dirname -- \"$1\")\" && printf '%s/%s' \"$(pwd -P)\" \"$(basename -- \"$1\")\""
|
|
72
|
-
];
|
|
73
|
-
/** The runtime filesystem service — the live {@link Interface} for the active sandbox. */
|
|
74
|
-
var Service = class extends Context.Service()("@codeworksh/plugin/sandbox/filesystem/Service") {};
|
|
75
|
-
/**
|
|
76
|
-
* Reject `rm` options a provider does not implement, before any mutation. Only
|
|
77
|
-
* `recursive` and `force` are part of the contract; anything else is refused
|
|
78
|
-
* loudly rather than silently ignored.
|
|
79
|
-
*/
|
|
80
|
-
const validateRmOptions = (options, operation = "rm") => Effect.suspend(() => {
|
|
81
|
-
for (const option of Object.keys(options ?? {})) {
|
|
82
|
-
if (option === "recursive" || option === "force") continue;
|
|
83
|
-
return Effect.fail(new OperationUnsupportedError({
|
|
84
|
-
operation,
|
|
85
|
-
message: `Unsupported rm option: ${option}`
|
|
86
|
-
}));
|
|
87
|
-
}
|
|
88
|
-
return Effect.void;
|
|
89
|
-
});
|
|
90
|
-
/**
|
|
91
|
-
* Lift a {@link Provider} into the runtime {@link Interface}: one place that
|
|
92
|
-
* converts rejections into {@link FileSystemError}, validates `rm` options,
|
|
93
|
-
* creates missing parents on write, and names a tracing span per operation.
|
|
94
|
-
*/
|
|
95
|
-
const fromProvider = (provider) => {
|
|
96
|
-
const attempt = (method, path, run) => Effect.tryPromise({
|
|
97
|
-
try: run,
|
|
98
|
-
catch: (cause) => new FileSystemError({
|
|
99
|
-
method,
|
|
100
|
-
path,
|
|
101
|
-
cause
|
|
102
|
-
})
|
|
103
|
-
});
|
|
104
|
-
const writeCreatingParents = (path, content) => {
|
|
105
|
-
const write = attempt("writeFile", path, () => provider.writeFile(path, content));
|
|
106
|
-
const parent = posix.dirname(path);
|
|
107
|
-
return write.pipe(Effect.catch(() => attempt("mkdir", parent, () => provider.mkdir(parent, { recursive: true })).pipe(Effect.ignore, Effect.andThen(write))));
|
|
108
|
-
};
|
|
109
|
-
return {
|
|
110
|
-
readFile: Effect.fn("SandboxFileSystem.readFile")((path) => attempt("readFile", path, () => provider.readFile(path))),
|
|
111
|
-
readFileBuffer: Effect.fn("SandboxFileSystem.readFileBuffer")((path) => attempt("readFileBuffer", path, () => provider.readFileBuffer(path))),
|
|
112
|
-
writeFile: Effect.fn("SandboxFileSystem.writeFile")(writeCreatingParents),
|
|
113
|
-
stat: Effect.fn("SandboxFileSystem.stat")((path) => attempt("stat", path, () => provider.stat(path))),
|
|
114
|
-
...provider.lstat === void 0 ? {} : { lstat: Effect.fn("SandboxFileSystem.lstat")((path) => attempt("lstat", path, () => provider.lstat(path))) },
|
|
115
|
-
readdir: Effect.fn("SandboxFileSystem.readdir")((path) => attempt("readdir", path, () => provider.readdir(path))),
|
|
116
|
-
exists: Effect.fn("SandboxFileSystem.exists")((path) => attempt("exists", path, () => provider.exists(path))),
|
|
117
|
-
mkdir: Effect.fn("SandboxFileSystem.mkdir")((path, options) => attempt("mkdir", path, () => provider.mkdir(path, options))),
|
|
118
|
-
rm: Effect.fn("SandboxFileSystem.rm")((path, options) => validateRmOptions(options).pipe(Effect.andThen(attempt("rm", path, () => provider.rm(path, options))))),
|
|
119
|
-
realpath: Effect.fn("SandboxFileSystem.realpath")((path) => attempt("realpath", path, () => provider.realpath(path)))
|
|
120
|
-
};
|
|
121
|
-
};
|
|
122
|
-
/**
|
|
123
|
-
* Bind a cwd-neutral filesystem to one mount's working directory.
|
|
124
|
-
*
|
|
125
|
-
* The counterpart of `Shell.withCwd`, and the reason relative paths mean the
|
|
126
|
-
* same thing to both: a shared transport stays rooted at the namespace root, so
|
|
127
|
-
* resolution happens here, per mount, rather than inside a VFS whose `chdir` is
|
|
128
|
-
* global state two mounts would fight over.
|
|
129
|
-
*/
|
|
130
|
-
const withCwd = (fs, cwd) => {
|
|
131
|
-
const at = (path) => posix.resolve(cwd, path);
|
|
132
|
-
return {
|
|
133
|
-
readFile: (path) => fs.readFile(at(path)),
|
|
134
|
-
readFileBuffer: (path) => fs.readFileBuffer(at(path)),
|
|
135
|
-
writeFile: (path, content) => fs.writeFile(at(path), content),
|
|
136
|
-
stat: (path) => fs.stat(at(path)),
|
|
137
|
-
readdir: (path) => fs.readdir(at(path)),
|
|
138
|
-
exists: (path) => fs.exists(at(path)),
|
|
139
|
-
mkdir: (path, options) => fs.mkdir(at(path), options),
|
|
140
|
-
rm: (path, options) => fs.rm(at(path), options),
|
|
141
|
-
realpath: (path) => fs.realpath(at(path)),
|
|
142
|
-
...fs.lstat === void 0 ? {} : { lstat: (path) => fs.lstat(at(path)) }
|
|
143
|
-
};
|
|
144
|
-
};
|
|
145
|
-
//#endregion
|
|
146
|
-
export { FileSystemError, OperationUnsupportedError, filesystem_exports as SandboxFileSystem, Service, fromProvider, isNotFoundError, realpathScripts, validateRmOptions, withCwd };
|
|
147
|
-
|
|
148
|
-
//# sourceMappingURL=filesystem.mjs.map
|
|
1
|
+
import { a as fromProvider, c as validateRmOptions, i as filesystem_exports, l as withCwd, n as OperationUnsupportedError, o as isNotFoundError, r as Service, s as realpathScripts, t as FileSystemError, u as scan_exports } from "../filesystem-BFCKzgND.mjs";
|
|
2
|
+
export { FileSystemError, OperationUnsupportedError, filesystem_exports as SandboxFileSystem, scan_exports as Scan, Service, fromProvider, isNotFoundError, realpathScripts, validateRmOptions, withCwd };
|
package/sandbox/instance.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Ct as
|
|
1
|
+
import { Ct as mountable, St as isMountable, Tt as toField, _t as Status, bt as fromField, ft as ID, gt as PersistedError, ht as Ownership, mt as Kind, pt as Info, vt as Usage, wt as toColumn, xt as instance_d_exports, yt as fromColumn } from "../io-CXi2Sjg9.mjs";
|
|
2
2
|
export { ID, Info, Kind, Ownership, PersistedError, instance_d_exports as SandboxInstance, Status, Usage, fromColumn, fromField, isMountable, mountable, toColumn, toField };
|
package/sandbox/io.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
export { Current, FileSystem, Identity, Layer, Mutation, Provides, io_d_exports as SandboxIO, Shell, host, hostLayer, identityLayer, mount, remote, resolveMountCwd, virtual, withMutation };
|
|
1
|
+
import { _ as withMutation, a as Layer, c as Shell, d as identityLayer, f as io_d_exports, g as virtual, h as resolveMountCwd, i as Identity, l as host, m as remote, n as DEFAULT_SPILL_PATH, o as Mutation, p as mount, r as FileSystem, s as Provides, t as Current, u as hostLayer } from "../io-CXi2Sjg9.mjs";
|
|
2
|
+
export { Current, DEFAULT_SPILL_PATH, FileSystem, Identity, Layer, Mutation, Provides, io_d_exports as SandboxIO, Shell, host, hostLayer, identityLayer, mount, remote, resolveMountCwd, virtual, withMutation };
|
package/sandbox/io.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import "./instance.mjs";
|
|
2
|
-
import { a as
|
|
3
|
-
export { Current, FileSystem, Mutation, io_exports as SandboxIO, Shell, host, hostLayer, identityLayer, mount, remote, resolveMountCwd, virtual, withMutation };
|
|
2
|
+
import { a as Shell, c as identityLayer, d as remote, f as resolveMountCwd, i as Mutation, l as io_exports, m as withMutation, n as DEFAULT_SPILL_PATH, o as host, p as virtual, r as FileSystem, s as hostLayer, t as Current, u as mount } from "../io-RvZvG-4N.mjs";
|
|
3
|
+
export { Current, DEFAULT_SPILL_PATH, FileSystem, Mutation, io_exports as SandboxIO, Shell, host, hostLayer, identityLayer, mount, remote, resolveMountCwd, virtual, withMutation };
|