effect-cf 0.25.3 → 0.27.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.
@@ -0,0 +1,545 @@
1
+ import { t as DurableObjectState } from "./DurableObjectState-Dux8KfjG.mjs";
2
+ import { fromClient } from "./ComputerArtifacts.mjs";
3
+ import { t as lookup } from "./ComputerWorkspaceHostRegistry-CY5Fv4Ng.mjs";
4
+ import { Context, Effect, Layer, Schema, Stream } from "effect";
5
+ //#region src/ComputerWorkspace.ts
6
+ /**
7
+ * Workspace errors use `Schema.TaggedError`, unlike most local binding errors,
8
+ * because workspace operations commonly sit behind Durable Object RPC methods.
9
+ * The schema form preserves the operation-family tags across that boundary.
10
+ */
11
+ var WorkspaceFsError = class extends Schema.TaggedError()("WorkspaceFsError", {
12
+ operation: Schema.String,
13
+ path: Schema.String,
14
+ message: Schema.String,
15
+ code: Schema.optionalKey(Schema.String),
16
+ cause: Schema.optionalKey(Schema.Defect({ includeStack: true }))
17
+ }) {};
18
+ /** Schema-serializable error for a workspace Git operation. */
19
+ var WorkspaceGitError = class extends Schema.TaggedError()("WorkspaceGitError", {
20
+ operation: Schema.String,
21
+ message: Schema.String,
22
+ code: Schema.optionalKey(Schema.String),
23
+ cause: Schema.optionalKey(Schema.Defect({ includeStack: true }))
24
+ }) {};
25
+ /** Schema-serializable error for a workspace runtime operation. */
26
+ var WorkspaceExecError = class extends Schema.TaggedError()("WorkspaceExecError", {
27
+ operation: Schema.String,
28
+ message: Schema.String,
29
+ code: Schema.optionalKey(Schema.String),
30
+ cause: Schema.optionalKey(Schema.Defect({ includeStack: true }))
31
+ }) {};
32
+ /** Schema-serializable error for a workspace Assets operation. */
33
+ var WorkspaceAssetsError = class extends Schema.TaggedError()("WorkspaceAssetsError", {
34
+ operation: Schema.String,
35
+ path: Schema.String,
36
+ message: Schema.String,
37
+ code: Schema.optionalKey(Schema.String),
38
+ cause: Schema.optionalKey(Schema.Defect({ includeStack: true }))
39
+ }) {};
40
+ const errorMessage = (cause) => cause instanceof Error ? cause.message : String(cause);
41
+ const errorCode = (cause) => {
42
+ if (typeof cause !== "object" || cause === null) return;
43
+ const code = Reflect.get(cause, "code");
44
+ return typeof code === "string" ? code : void 0;
45
+ };
46
+ const fsError = (operation, path, cause) => WorkspaceFsError.make({
47
+ operation,
48
+ path,
49
+ message: errorMessage(cause),
50
+ cause,
51
+ ...errorCode(cause) === void 0 ? {} : { code: errorCode(cause) }
52
+ });
53
+ const gitError = (operation, cause) => WorkspaceGitError.make({
54
+ operation,
55
+ message: errorMessage(cause),
56
+ cause,
57
+ ...errorCode(cause) === void 0 ? {} : { code: errorCode(cause) }
58
+ });
59
+ const execError = (operation, cause) => WorkspaceExecError.make({
60
+ operation,
61
+ message: errorMessage(cause),
62
+ cause,
63
+ ...errorCode(cause) === void 0 ? {} : { code: errorCode(cause) }
64
+ });
65
+ const assetsError = (operation, path, cause) => WorkspaceAssetsError.make({
66
+ operation,
67
+ path,
68
+ message: errorMessage(cause),
69
+ cause,
70
+ ...errorCode(cause) === void 0 ? {} : { code: errorCode(cause) }
71
+ });
72
+ const tryFs = (operation, path, evaluate) => Effect.tryPromise({
73
+ try: evaluate,
74
+ catch: (cause) => fsError(operation, path, cause)
75
+ });
76
+ const isNotFound = (error) => error.code === "ENOENT" || /ENOENT|no such/i.test(error.message);
77
+ const makeFilesystem = (fsClient) => {
78
+ const readFile = Effect.fn("ComputerWorkspace.fs.readFile", { attributes: {
79
+ family: "fs",
80
+ operation: "readFile"
81
+ } })(function* (path, options = {}) {
82
+ yield* Effect.annotateCurrentSpan("path", path);
83
+ const { encoding = "utf8", ...readOptions } = options;
84
+ if (encoding === "stream") return yield* tryFs("readFile", path, () => fsClient.readFile(path, readOptions));
85
+ return yield* tryFs("readFile", path, () => fsClient.readFile(path, {
86
+ ...readOptions,
87
+ encoding: "utf8"
88
+ }));
89
+ });
90
+ const stat = Effect.fn("ComputerWorkspace.fs.stat", { attributes: {
91
+ family: "fs",
92
+ operation: "stat"
93
+ } })(function* (path) {
94
+ yield* Effect.annotateCurrentSpan("path", path);
95
+ return yield* tryFs("stat", path, () => fsClient.stat(path));
96
+ });
97
+ return {
98
+ readFile,
99
+ stat,
100
+ lstat: Effect.fn("ComputerWorkspace.fs.lstat", { attributes: {
101
+ family: "fs",
102
+ operation: "lstat"
103
+ } })(function* (path) {
104
+ yield* Effect.annotateCurrentSpan("path", path);
105
+ return yield* tryFs("lstat", path, () => fsClient.lstat(path));
106
+ }),
107
+ exists: Effect.fn("ComputerWorkspace.fs.exists", { attributes: {
108
+ family: "fs",
109
+ operation: "exists"
110
+ } })(function* (path) {
111
+ yield* Effect.annotateCurrentSpan("path", path);
112
+ return yield* stat(path).pipe(Effect.as(true), Effect.catch((error) => isNotFound(error) ? Effect.succeed(false) : Effect.fail(error)));
113
+ }),
114
+ readlink: Effect.fn("ComputerWorkspace.fs.readlink", { attributes: {
115
+ family: "fs",
116
+ operation: "readlink"
117
+ } })(function* (path) {
118
+ yield* Effect.annotateCurrentSpan("path", path);
119
+ return yield* tryFs("readlink", path, () => fsClient.readlink(path));
120
+ }),
121
+ readdir: Effect.fn("ComputerWorkspace.fs.readdir", { attributes: {
122
+ family: "fs",
123
+ operation: "readdir"
124
+ } })(function* (path, options) {
125
+ yield* Effect.annotateCurrentSpan("path", path);
126
+ return yield* tryFs("readdir", path, () => fsClient.readdir(path, options));
127
+ }),
128
+ find: Effect.fn("ComputerWorkspace.fs.find", { attributes: {
129
+ family: "fs",
130
+ operation: "find"
131
+ } })(function* (directory, pattern, options) {
132
+ yield* Effect.annotateCurrentSpan({
133
+ path: directory,
134
+ pattern
135
+ });
136
+ return yield* tryFs("find", directory, () => fsClient.find(directory, pattern, options));
137
+ }),
138
+ ls: Effect.fn("ComputerWorkspace.fs.ls", { attributes: {
139
+ family: "fs",
140
+ operation: "ls"
141
+ } })(function* (prefix) {
142
+ yield* Effect.annotateCurrentSpan("path", prefix);
143
+ return yield* tryFs("ls", prefix, () => fsClient.ls(prefix));
144
+ }),
145
+ grep: Effect.fn("ComputerWorkspace.fs.grep", { attributes: {
146
+ family: "fs",
147
+ operation: "grep"
148
+ } })(function* (pattern, path, options) {
149
+ yield* Effect.annotateCurrentSpan({
150
+ path,
151
+ pattern
152
+ });
153
+ return yield* tryFs("grep", path, () => fsClient.grep(pattern, path, options));
154
+ }),
155
+ writeFile: Effect.fn("ComputerWorkspace.fs.writeFile", { attributes: {
156
+ family: "fs",
157
+ operation: "writeFile"
158
+ } })(function* (path, content, options) {
159
+ yield* Effect.annotateCurrentSpan("path", path);
160
+ yield* tryFs("writeFile", path, () => fsClient.writeFile(path, content, options));
161
+ }),
162
+ mkdir: Effect.fn("ComputerWorkspace.fs.mkdir", { attributes: {
163
+ family: "fs",
164
+ operation: "mkdir"
165
+ } })(function* (path, options) {
166
+ yield* Effect.annotateCurrentSpan("path", path);
167
+ yield* tryFs("mkdir", path, () => fsClient.mkdir(path, options));
168
+ }),
169
+ rm: Effect.fn("ComputerWorkspace.fs.rm", { attributes: {
170
+ family: "fs",
171
+ operation: "rm"
172
+ } })(function* (path, options) {
173
+ yield* Effect.annotateCurrentSpan("path", path);
174
+ yield* tryFs("rm", path, () => fsClient.rm(path, options));
175
+ }),
176
+ chmod: Effect.fn("ComputerWorkspace.fs.chmod", { attributes: {
177
+ family: "fs",
178
+ operation: "chmod"
179
+ } })(function* (path, mode) {
180
+ yield* Effect.annotateCurrentSpan({
181
+ path,
182
+ mode
183
+ });
184
+ yield* tryFs("chmod", path, () => fsClient.chmod(path, mode));
185
+ }),
186
+ symlink: Effect.fn("ComputerWorkspace.fs.symlink", { attributes: {
187
+ family: "fs",
188
+ operation: "symlink"
189
+ } })(function* (target, path) {
190
+ yield* Effect.annotateCurrentSpan({
191
+ path,
192
+ target
193
+ });
194
+ yield* tryFs("symlink", path, () => fsClient.symlink(target, path));
195
+ })
196
+ };
197
+ };
198
+ const gitPerson = (person) => ({
199
+ ...person,
200
+ timestampSeconds: person.timestamp
201
+ });
202
+ const gitCommit = (commit) => ({
203
+ oid: commit.oid,
204
+ message: commit.message,
205
+ tree: commit.tree,
206
+ parent: commit.parent,
207
+ parents: commit.parent,
208
+ author: gitPerson(commit.author),
209
+ committer: gitPerson(commit.committer)
210
+ });
211
+ const makeGit = (gitClient) => {
212
+ const method = (operation, evaluate) => Effect.fn(`ComputerWorkspace.git.${operation}`, { attributes: {
213
+ family: "git",
214
+ operation
215
+ } })(function* (...args) {
216
+ return yield* Effect.tryPromise({
217
+ try: () => evaluate(...args),
218
+ catch: (cause) => gitError(operation, cause)
219
+ });
220
+ });
221
+ const log = Effect.fn("ComputerWorkspace.git.log", { attributes: {
222
+ family: "git",
223
+ operation: "log"
224
+ } })(function* (options) {
225
+ const { maxCount, ...upstreamOptions } = options ?? {};
226
+ return (yield* Effect.tryPromise({
227
+ try: () => gitClient.log({
228
+ ...upstreamOptions,
229
+ ...upstreamOptions.depth === void 0 && maxCount !== void 0 ? { depth: maxCount } : {}
230
+ }),
231
+ catch: (cause) => gitError("log", cause)
232
+ })).map(gitCommit);
233
+ });
234
+ const revParse = Effect.fn("ComputerWorkspace.git.revParse", { attributes: {
235
+ family: "git",
236
+ operation: "revParse"
237
+ } })(function* (input) {
238
+ const options = typeof input === "string" ? { ref: input } : input;
239
+ return yield* Effect.tryPromise({
240
+ try: () => gitClient.revParse(options),
241
+ catch: (cause) => gitError("revParse", cause)
242
+ });
243
+ });
244
+ return {
245
+ clone: method("clone", (options) => gitClient.clone(options)),
246
+ diff: method("diff", (options) => gitClient.diff(options)),
247
+ diffSummary: method("diffSummary", (options) => gitClient.diffSummary(options)),
248
+ init: method("init", (options) => gitClient.init(options)),
249
+ status: method("status", (options) => gitClient.status(options)),
250
+ add: method("add", (options) => gitClient.add(options)),
251
+ rm: method("rm", (options) => gitClient.rm(options)),
252
+ commit: method("commit", (options) => gitClient.commit(options)),
253
+ log,
254
+ show: method("show", (options) => gitClient.show(options)),
255
+ revParse,
256
+ repoRoot: method("repoRoot", (options) => gitClient.repoRoot(options)),
257
+ currentBranch: method("currentBranch", (options) => gitClient.currentBranch(options)),
258
+ lsFiles: method("lsFiles", (options) => gitClient.lsFiles(options)),
259
+ lsTree: method("lsTree", (options) => gitClient.lsTree(options)),
260
+ branch: method("branch", (options) => gitClient.branch(options)),
261
+ branchDelete: method("branchDelete", (options) => gitClient.branchDelete(options)),
262
+ branchList: method("branchList", (options) => gitClient.branchList(options)),
263
+ tag: method("tag", (options) => gitClient.tag(options)),
264
+ tagDelete: method("tagDelete", (options) => gitClient.tagDelete(options)),
265
+ tagList: method("tagList", (options) => gitClient.tagList(options)),
266
+ checkout: method("checkout", (options) => gitClient.checkout(options)),
267
+ fetch: method("fetch", (options) => gitClient.fetch(options)),
268
+ push: method("push", (options) => gitClient.push(options)),
269
+ pull: method("pull", (options) => gitClient.pull(options)),
270
+ merge: method("merge", (options) => gitClient.merge(options)),
271
+ remoteAdd: method("remoteAdd", (options) => gitClient.remoteAdd(options)),
272
+ remoteRemove: method("remoteRemove", (options) => gitClient.remoteRemove(options)),
273
+ remoteList: method("remoteList", (options) => gitClient.remoteList(options)),
274
+ hashObject: method("hashObject", (options) => gitClient.hashObject(options)),
275
+ catFile: method("catFile", (options) => gitClient.catFile(options)),
276
+ updateRef: method("updateRef", (options) => gitClient.updateRef(options)),
277
+ configGet: method("configGet", (options) => gitClient.configGet(options)),
278
+ configSet: method("configSet", (options) => gitClient.configSet(options)),
279
+ stashPush: method("stashPush", (options) => gitClient.stashPush(options)),
280
+ stashList: method("stashList", (options) => gitClient.stashList(options)),
281
+ stashPop: method("stashPop", (options) => gitClient.stashPop(options)),
282
+ reset: method("reset", (options) => gitClient.reset(options)),
283
+ clean: method("clean", (options) => gitClient.clean(options)),
284
+ cli: method("cli", (input) => gitClient.cli(input))
285
+ };
286
+ };
287
+ const runtimeExecOptions = (options) => {
288
+ const { encoding = "utf8", timeoutMillis, timeoutMs, ...rest } = options ?? {};
289
+ return {
290
+ ...rest,
291
+ ...encoding === "utf8" ? { encoding: "utf8" } : {},
292
+ ...timeoutMs === void 0 && timeoutMillis === void 0 ? {} : { timeoutMs: timeoutMs ?? timeoutMillis }
293
+ };
294
+ };
295
+ const runtimeGetOptions = (options) => {
296
+ const { encoding = "utf8", ...rest } = options ?? {};
297
+ return {
298
+ ...rest,
299
+ ...encoding === "utf8" ? { encoding: "utf8" } : {}
300
+ };
301
+ };
302
+ const wrapRuntimeResult = (result) => ({
303
+ status: result.status,
304
+ exitCode: result.exitCode,
305
+ stdout: result.stdout,
306
+ stderr: result.stderr,
307
+ ...result.value === void 0 ? {} : { value: result.value },
308
+ pushed: result.pushed,
309
+ pulled: result.pulled,
310
+ skipped: result.skipped,
311
+ sync: result.sync
312
+ });
313
+ const wrapRuntimeEvent = (event) => {
314
+ switch (event.name) {
315
+ case "stdout": {
316
+ const chunk = event.value;
317
+ return typeof chunk === "string" ? {
318
+ _tag: "Stdout",
319
+ id: event.id,
320
+ sequence: event.seq,
321
+ chunk,
322
+ text: chunk
323
+ } : {
324
+ _tag: "Stdout",
325
+ id: event.id,
326
+ sequence: event.seq,
327
+ chunk,
328
+ bytes: chunk
329
+ };
330
+ }
331
+ case "stderr": {
332
+ const chunk = event.value;
333
+ return typeof chunk === "string" ? {
334
+ _tag: "Stderr",
335
+ id: event.id,
336
+ sequence: event.seq,
337
+ chunk,
338
+ text: chunk
339
+ } : {
340
+ _tag: "Stderr",
341
+ id: event.id,
342
+ sequence: event.seq,
343
+ chunk,
344
+ bytes: chunk
345
+ };
346
+ }
347
+ case "exit": return {
348
+ _tag: "Exit",
349
+ id: event.id,
350
+ sequence: event.seq,
351
+ exitCode: event.code,
352
+ ...event.result === void 0 ? {} : { value: event.result }
353
+ };
354
+ }
355
+ };
356
+ const wrapRun = (handle) => {
357
+ const events = Stream.fromReadableStream({
358
+ evaluate: () => handle,
359
+ onError: (cause) => execError("events", cause)
360
+ }).pipe(Stream.map(wrapRuntimeEvent));
361
+ const result = Effect.tryPromise({
362
+ try: () => handle.result(),
363
+ catch: (cause) => execError("result", cause)
364
+ }).pipe(Effect.map(wrapRuntimeResult));
365
+ const kill = Effect.fn("ComputerWorkspace.runtime.run.kill", { attributes: {
366
+ family: "runtime",
367
+ operation: "run.kill",
368
+ runId: handle.id
369
+ } })(function* (signal) {
370
+ yield* Effect.tryPromise({
371
+ try: () => handle.kill(signal),
372
+ catch: (cause) => execError("run.kill", cause)
373
+ });
374
+ });
375
+ return {
376
+ id: handle.id,
377
+ backend: handle.backend,
378
+ events,
379
+ result,
380
+ kill
381
+ };
382
+ };
383
+ const releaseRun = (handle) => Effect.sync(() => handle[Symbol.dispose]());
384
+ const makeRuntime = (client) => {
385
+ const execImplementation = Effect.fn("ComputerWorkspace.runtime.exec", { attributes: {
386
+ family: "runtime",
387
+ operation: "exec"
388
+ } })(function* (source, optionsOrValue, ...remainingValues) {
389
+ const options = typeof source === "string" ? optionsOrValue : void 0;
390
+ yield* Effect.annotateCurrentSpan({
391
+ backend: options?.backend,
392
+ runId: options?.id
393
+ });
394
+ const handle = yield* Effect.acquireRelease(Effect.tryPromise({
395
+ try: () => {
396
+ if (typeof source === "string") return client.runtime.exec(source, runtimeExecOptions(options));
397
+ const values = optionsOrValue === void 0 ? remainingValues : [optionsOrValue, ...remainingValues];
398
+ return client.runtime.exec(source, ...values);
399
+ },
400
+ catch: (cause) => execError("exec", cause)
401
+ }), releaseRun);
402
+ return wrapRun(handle);
403
+ });
404
+ const exec = execImplementation;
405
+ const getExec = Effect.fn("ComputerWorkspace.runtime.getExec", { attributes: {
406
+ family: "runtime",
407
+ operation: "getExec"
408
+ } })(function* (id, options) {
409
+ yield* Effect.annotateCurrentSpan({
410
+ backend: options?.backend,
411
+ runId: id
412
+ });
413
+ const handle = yield* Effect.acquireRelease(Effect.tryPromise({
414
+ try: () => client.runtime.getExec(id, runtimeGetOptions(options)),
415
+ catch: (cause) => execError("getExec", cause)
416
+ }), releaseRun);
417
+ return wrapRun(handle);
418
+ });
419
+ const killExec = Effect.fn("ComputerWorkspace.runtime.killExec", { attributes: {
420
+ family: "runtime",
421
+ operation: "killExec"
422
+ } })(function* (id, options) {
423
+ yield* Effect.annotateCurrentSpan({
424
+ backend: options?.backend,
425
+ runId: id
426
+ });
427
+ yield* Effect.tryPromise({
428
+ try: () => client.runtime.killExec(id, options),
429
+ catch: (cause) => execError("killExec", cause)
430
+ });
431
+ });
432
+ const disposeExec = Effect.fn("ComputerWorkspace.runtime.disposeExec", { attributes: {
433
+ family: "runtime",
434
+ operation: "disposeExec"
435
+ } })(function* (id, options) {
436
+ yield* Effect.annotateCurrentSpan({
437
+ backend: options?.backend,
438
+ runId: id
439
+ });
440
+ yield* Effect.tryPromise({
441
+ try: () => client.runtime.disposeExec(id, options),
442
+ catch: (cause) => execError("disposeExec", cause)
443
+ });
444
+ });
445
+ return {
446
+ exec,
447
+ execCollect: Effect.fn("ComputerWorkspace.runtime.execCollect", { attributes: {
448
+ family: "runtime",
449
+ operation: "execCollect"
450
+ } })(function* (source, optionsOrValue, ...remainingValues) {
451
+ return yield* Effect.scoped(Effect.gen(function* () {
452
+ return yield* (yield* execImplementation(source, optionsOrValue, ...remainingValues)).result;
453
+ }));
454
+ }),
455
+ getExec,
456
+ killExec,
457
+ disposeExec
458
+ };
459
+ };
460
+ const makeAssets = (client) => client === void 0 ? void 0 : { share: Effect.fn("ComputerWorkspace.assets.share", { attributes: {
461
+ family: "assets",
462
+ operation: "share"
463
+ } })(function* (path, options) {
464
+ yield* Effect.annotateCurrentSpan("path", path);
465
+ return yield* Effect.tryPromise({
466
+ try: () => client.share(path, options),
467
+ catch: (cause) => assetsError("share", path, cause)
468
+ });
469
+ }) };
470
+ const makeThink = (client) => {
471
+ if (client.readFile === void 0 || client.readFileBytes === void 0 || client.writeFile === void 0 || client.readDir === void 0 || client.rm === void 0 || client.glob === void 0 || client.mkdir === void 0 || client.stat === void 0) return;
472
+ const method = (operation, pathOf, evaluate) => Effect.fn(`ComputerWorkspace.think.${operation}`, { attributes: {
473
+ family: "think",
474
+ operation
475
+ } })(function* (...args) {
476
+ const path = pathOf(...args);
477
+ yield* Effect.annotateCurrentSpan("path", path);
478
+ return yield* tryFs(`think.${operation}`, path, () => evaluate(...args));
479
+ });
480
+ return {
481
+ readFile: method("readFile", (path) => path, (path) => client.readFile(path)),
482
+ readFileBytes: method("readFileBytes", (path) => path, (path) => client.readFileBytes(path)),
483
+ writeFile: method("writeFile", (path, _content) => path, (path, content) => client.writeFile(path, content)),
484
+ readDir: method("readDir", (path, _options) => path, (path, options) => client.readDir(path, options)),
485
+ rm: method("rm", (path, _options) => path, (path, options) => client.rm(path, options)),
486
+ glob: method("glob", (pattern) => pattern, (pattern) => client.glob(pattern)),
487
+ mkdir: method("mkdir", (path, _options) => path, (path, options) => client.mkdir(path, options)),
488
+ stat: method("stat", (path) => path, (path) => client.stat(path))
489
+ };
490
+ };
491
+ /**
492
+ * Wraps a client whose lifetime is owned by the caller. Prefer
493
+ * {@link ComputerWorkspace.layer} in Durable Objects so the parent client and
494
+ * every runtime handle are disposed by Effect `Scope`.
495
+ */
496
+ const fromWorkspaceClient = (client) => {
497
+ const fs = makeFilesystem(client.fs);
498
+ const git = makeGit(client.git);
499
+ const runtime = makeRuntime(client);
500
+ return {
501
+ fs,
502
+ git,
503
+ runtime,
504
+ artifacts: fromClient(client.artifacts, { binding: "ComputerWorkspace.artifacts" }),
505
+ assets: makeAssets(client.assets),
506
+ think: makeThink(client),
507
+ readFile: fs.readFile,
508
+ stat: fs.stat,
509
+ lstat: fs.lstat,
510
+ exists: fs.exists,
511
+ readlink: fs.readlink,
512
+ readdir: fs.readdir,
513
+ listDirectory: fs.readdir,
514
+ find: fs.find,
515
+ ls: fs.ls,
516
+ grep: fs.grep,
517
+ writeFile: fs.writeFile,
518
+ mkdir: fs.mkdir,
519
+ rm: fs.rm,
520
+ removePath: fs.rm,
521
+ chmod: fs.chmod,
522
+ symlink: fs.symlink,
523
+ exec: runtime.exec,
524
+ execCollect: runtime.execCollect,
525
+ getExec: runtime.getExec,
526
+ killExec: runtime.killExec,
527
+ disposeExec: runtime.disposeExec
528
+ };
529
+ };
530
+ /** Effect service for the workspace owned by the enclosing Durable Object. */
531
+ var ComputerWorkspace = class ComputerWorkspace extends Context.Service()("effect-cf/ComputerWorkspace") {
532
+ /**
533
+ * Acquires the single workspace registered by `withComputerWorkspace` and
534
+ * releases its RPC client when the layer scope closes.
535
+ */
536
+ static layer = Layer.effect(ComputerWorkspace, Effect.gen(function* () {
537
+ const host = lookup((yield* DurableObjectState).raw);
538
+ if (host === void 0) return yield* Effect.die("ComputerWorkspace.layer requires a Durable Object class built with withComputerWorkspace");
539
+ const computer = yield* Effect.promise(() => import("@cloudflare/computer"));
540
+ const client = yield* Effect.acquireRelease(Effect.promise(() => computer.getWorkspace(host)), (workspace) => Effect.sync(() => workspace[Symbol.dispose]()));
541
+ return ComputerWorkspace.of(fromWorkspaceClient(client));
542
+ }));
543
+ };
544
+ //#endregion
545
+ export { ComputerWorkspace, WorkspaceAssetsError, WorkspaceExecError, WorkspaceFsError, WorkspaceGitError, fromWorkspaceClient };
@@ -0,0 +1,71 @@
1
+ import { t as ArtifactsBinding } from "./Artifacts-DcoXcRP5.mjs";
2
+ import { GitClientFactory } from "@cloudflare/computer/git";
3
+ import { DurableObjectStorageLike, SyncRetryIntent, SyncRetryOptions, SyncRetryScheduler, WithWorkspaceCtor, WorkspaceAttributeValue, WorkspaceAttributes, WorkspaceObserver, WorkspaceOptions, WorkspaceRegisteredBackend, WorkspaceRetryPendingSyncResult, WorkspaceServiceProxy, WorkspaceSpan } from "@cloudflare/computer";
4
+ import { ShellModuleGroup, WorkerShellBackendOptions, WorkerShellLoader, WorkspaceEgressPolicy } from "@cloudflare/computer/backends/worker-shell";
5
+ //#region src/ComputerWorkspaceHost.d.ts
6
+ /** The value of a `worker_loaders` binding. */
7
+ type DynamicWorkerLoader = WorkerShellLoader;
8
+ /** Default author and committer identity for workspace Git operations. */
9
+ interface ComputerWorkspaceGitIdentity {
10
+ readonly name: string;
11
+ readonly email: string;
12
+ }
13
+ /** Session-scoped Artifacts configuration passed through to `Workspace`. */
14
+ interface ComputerWorkspaceArtifactsOptions {
15
+ readonly binding: ArtifactsBinding;
16
+ /**
17
+ * Session prefix for repository names. When omitted, `sessionId` from the
18
+ * enclosing host configuration is used.
19
+ */
20
+ readonly sessionId?: string;
21
+ }
22
+ /**
23
+ * Worker-shell backend options with the loopback workspace wiring named in
24
+ * Durable Object terms.
25
+ */
26
+ interface ComputerWorkspaceShellOptions extends Omit<WorkerShellBackendOptions, "source" | "loader" | "workspace" | "ctx" | "egress"> {
27
+ readonly loader: DynamicWorkerLoader;
28
+ /** Durable Object namespace binding that points back to the wrapped class. */
29
+ readonly hostBinding: string;
30
+ /** Current Durable Object id, normally `ctx.id.toString()`. */
31
+ readonly hostId: string;
32
+ /** Current Durable Object execution context, normally `ctx`. */
33
+ readonly executionContext: unknown;
34
+ /** Dynamic Worker egress policy. Defaults to `{ mode: "none" }`. */
35
+ readonly egress?: WorkspaceEgressPolicy;
36
+ }
37
+ /** Configuration accepted by {@link withComputerWorkspace}. */
38
+ interface ComputerWorkspaceHostConfig {
39
+ /** Native SQLite-backed Durable Object storage (`ctx.storage`). */
40
+ readonly storage: globalThis.DurableObjectStorage | DurableObjectStorageLike;
41
+ /** Stable workspace id used by mounts and as the default Artifacts session. */
42
+ readonly sessionId?: string;
43
+ readonly gitIdentity?: ComputerWorkspaceGitIdentity;
44
+ /** Override the default `createGitClient()` factory. */
45
+ readonly git?: GitClientFactory;
46
+ /** Additional container, Worker JavaScript, shell, or custom backends. */
47
+ readonly backends?: ReadonlyArray<WorkspaceRegisteredBackend>;
48
+ /** Convenience wiring for one Worker Shell backend. */
49
+ readonly shell?: ComputerWorkspaceShellOptions;
50
+ readonly mounts?: WorkspaceOptions["mounts"];
51
+ readonly observer?: WorkspaceOptions["observer"];
52
+ readonly retryScheduler?: WorkspaceOptions["retryScheduler"];
53
+ readonly retry?: WorkspaceOptions["retry"];
54
+ readonly assets?: WorkspaceOptions["assets"];
55
+ readonly artifacts?: ComputerWorkspaceArtifactsOptions;
56
+ readonly now?: WorkspaceOptions["now"];
57
+ readonly useThink?: WorkspaceOptions["useThink"];
58
+ }
59
+ type DurableObjectConstructor = new (...args: Array<any>) => object;
60
+ /**
61
+ * Wraps a Durable Object class with one SQLite-backed Cloudflare Computer
62
+ * workspace and registers that local workspace for {@link ComputerWorkspace}
63
+ * to acquire through its Effect layer.
64
+ *
65
+ * The class must use a `new_sqlite_classes` migration. If `shell` is present,
66
+ * its Worker must also configure a `worker_loaders` binding, enable the
67
+ * `experimental` compatibility flag, and export `WorkspaceServiceProxy`.
68
+ */
69
+ declare const withComputerWorkspace: <TBase extends DurableObjectConstructor>(Base: TBase, config: (self: InstanceType<TBase>, state: globalThis.DurableObjectState, env: ConstructorParameters<TBase>[1]) => ComputerWorkspaceHostConfig) => WithWorkspaceCtor<TBase>;
70
+ //#endregion
71
+ export { ComputerWorkspaceArtifactsOptions, ComputerWorkspaceGitIdentity, ComputerWorkspaceHostConfig, ComputerWorkspaceShellOptions, DynamicWorkerLoader, type ShellModuleGroup, type SyncRetryIntent, type SyncRetryOptions, type SyncRetryScheduler, type WorkspaceAttributeValue, type WorkspaceAttributes, type WorkspaceEgressPolicy, type WorkspaceObserver, type WorkspaceRetryPendingSyncResult, WorkspaceServiceProxy, type WorkspaceSpan, withComputerWorkspace };
@@ -0,0 +1,74 @@
1
+ import { n as register } from "./ComputerWorkspaceHostRegistry-CY5Fv4Ng.mjs";
2
+ import { createGitClient } from "@cloudflare/computer/git";
3
+ import { WorkspaceServiceProxy, withWorkspace } from "@cloudflare/computer";
4
+ import { WorkerShellBackend } from "@cloudflare/computer/backends/worker-shell";
5
+ //#region src/ComputerWorkspaceHost.ts
6
+ const toWorkspaceOptions = (config) => {
7
+ const backends = [...config.backends ?? []];
8
+ if (config.shell !== void 0) {
9
+ const { egress, executionContext, hostBinding, hostId, loader, ...shellOptions } = config.shell;
10
+ backends.push(new WorkerShellBackend({
11
+ ...shellOptions,
12
+ loader,
13
+ workspace: {
14
+ binding: hostBinding,
15
+ id: hostId
16
+ },
17
+ ctx: executionContext,
18
+ egress: egress ?? { mode: "none" }
19
+ }));
20
+ }
21
+ return {
22
+ storage: config.storage,
23
+ git: config.git ?? createGitClient(),
24
+ ...config.gitIdentity === void 0 ? {} : { defaultGitIdentity: config.gitIdentity },
25
+ ...backends.length === 0 ? {} : { backends },
26
+ ...config.sessionId === void 0 ? {} : { sessionId: config.sessionId },
27
+ ...config.mounts === void 0 ? {} : { mounts: config.mounts },
28
+ ...config.observer === void 0 ? {} : { observer: config.observer },
29
+ ...config.retryScheduler === void 0 ? {} : { retryScheduler: config.retryScheduler },
30
+ ...config.retry === void 0 ? {} : { retry: config.retry },
31
+ ...config.assets === void 0 ? {} : { assets: config.assets },
32
+ ...config.artifacts === void 0 ? {} : { artifacts: {
33
+ binding: config.artifacts.binding,
34
+ ...config.artifacts.sessionId === void 0 ? {} : { sessionId: config.artifacts.sessionId }
35
+ } },
36
+ ...config.now === void 0 ? {} : { now: config.now },
37
+ ...config.useThink === void 0 ? {} : { useThink: config.useThink }
38
+ };
39
+ };
40
+ const HostArguments = Symbol("effect-cf/ComputerWorkspaceHost/arguments");
41
+ /**
42
+ * Wraps a Durable Object class with one SQLite-backed Cloudflare Computer
43
+ * workspace and registers that local workspace for {@link ComputerWorkspace}
44
+ * to acquire through its Effect layer.
45
+ *
46
+ * The class must use a `new_sqlite_classes` migration. If `shell` is present,
47
+ * its Worker must also configure a `worker_loaders` binding, enable the
48
+ * `experimental` compatibility flag, and export `WorkspaceServiceProxy`.
49
+ */
50
+ const withComputerWorkspace = (Base, config) => {
51
+ const CapturedBase = class extends Base {
52
+ [HostArguments];
53
+ constructor(...args) {
54
+ super(...args);
55
+ this[HostArguments] = {
56
+ state: args[0],
57
+ env: args[1]
58
+ };
59
+ }
60
+ };
61
+ const WithWorkspace = withWorkspace(CapturedBase, (self) => {
62
+ const { env, state } = self[HostArguments];
63
+ return toWorkspaceOptions(config(self, state, env));
64
+ });
65
+ class WithComputerWorkspace extends WithWorkspace {
66
+ constructor(...args) {
67
+ super(...args);
68
+ register(args[0], this);
69
+ }
70
+ }
71
+ return WithComputerWorkspace;
72
+ };
73
+ //#endregion
74
+ export { WorkspaceServiceProxy, withComputerWorkspace };