@ai-hero/sandcastle 0.0.1

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.
Files changed (133) hide show
  1. package/README.md +284 -0
  2. package/dist/AgentProvider.d.ts +8 -0
  3. package/dist/AgentProvider.d.ts.map +1 -0
  4. package/dist/AgentProvider.js +60 -0
  5. package/dist/AgentProvider.js.map +1 -0
  6. package/dist/Config.d.ts +35 -0
  7. package/dist/Config.d.ts.map +1 -0
  8. package/dist/Config.js +56 -0
  9. package/dist/Config.js.map +1 -0
  10. package/dist/CopyToSandbox.d.ts +8 -0
  11. package/dist/CopyToSandbox.d.ts.map +1 -0
  12. package/dist/CopyToSandbox.js +32 -0
  13. package/dist/CopyToSandbox.js.map +1 -0
  14. package/dist/Display.d.ts +52 -0
  15. package/dist/Display.d.ts.map +1 -0
  16. package/dist/Display.js +132 -0
  17. package/dist/Display.js.map +1 -0
  18. package/dist/DockerLifecycle.d.ts +37 -0
  19. package/dist/DockerLifecycle.d.ts.map +1 -0
  20. package/dist/DockerLifecycle.js +109 -0
  21. package/dist/DockerLifecycle.js.map +1 -0
  22. package/dist/DockerSandbox.d.ts +6 -0
  23. package/dist/DockerSandbox.d.ts.map +1 -0
  24. package/dist/DockerSandbox.js +122 -0
  25. package/dist/DockerSandbox.js.map +1 -0
  26. package/dist/EnvResolver.d.ts +11 -0
  27. package/dist/EnvResolver.d.ts.map +1 -0
  28. package/dist/EnvResolver.js +43 -0
  29. package/dist/EnvResolver.js.map +1 -0
  30. package/dist/ErrorHandler.d.ts +15 -0
  31. package/dist/ErrorHandler.d.ts.map +1 -0
  32. package/dist/ErrorHandler.js +58 -0
  33. package/dist/ErrorHandler.js.map +1 -0
  34. package/dist/FilesystemSandbox.d.ts +6 -0
  35. package/dist/FilesystemSandbox.d.ts.map +1 -0
  36. package/dist/FilesystemSandbox.js +83 -0
  37. package/dist/FilesystemSandbox.js.map +1 -0
  38. package/dist/InitService.d.ts +11 -0
  39. package/dist/InitService.d.ts.map +1 -0
  40. package/dist/InitService.js +111 -0
  41. package/dist/InitService.js.map +1 -0
  42. package/dist/Orchestrator.d.ts +49 -0
  43. package/dist/Orchestrator.d.ts.map +1 -0
  44. package/dist/Orchestrator.js +155 -0
  45. package/dist/Orchestrator.js.map +1 -0
  46. package/dist/PromptArgumentSubstitution.d.ts +6 -0
  47. package/dist/PromptArgumentSubstitution.d.ts.map +1 -0
  48. package/dist/PromptArgumentSubstitution.js +33 -0
  49. package/dist/PromptArgumentSubstitution.js.map +1 -0
  50. package/dist/PromptPreprocessor.d.ts +7 -0
  51. package/dist/PromptPreprocessor.d.ts.map +1 -0
  52. package/dist/PromptPreprocessor.js +34 -0
  53. package/dist/PromptPreprocessor.js.map +1 -0
  54. package/dist/PromptResolver.d.ts +9 -0
  55. package/dist/PromptResolver.d.ts.map +1 -0
  56. package/dist/PromptResolver.js +26 -0
  57. package/dist/PromptResolver.js.map +1 -0
  58. package/dist/RecoveryMessage.d.ts +15 -0
  59. package/dist/RecoveryMessage.d.ts.map +1 -0
  60. package/dist/RecoveryMessage.js +81 -0
  61. package/dist/RecoveryMessage.js.map +1 -0
  62. package/dist/Sandbox.d.ts +23 -0
  63. package/dist/Sandbox.d.ts.map +1 -0
  64. package/dist/Sandbox.js +5 -0
  65. package/dist/Sandbox.js.map +1 -0
  66. package/dist/SandboxFactory.d.ts +56 -0
  67. package/dist/SandboxFactory.d.ts.map +1 -0
  68. package/dist/SandboxFactory.js +219 -0
  69. package/dist/SandboxFactory.js.map +1 -0
  70. package/dist/SandboxLifecycle.d.ts +32 -0
  71. package/dist/SandboxLifecycle.d.ts.map +1 -0
  72. package/dist/SandboxLifecycle.js +152 -0
  73. package/dist/SandboxLifecycle.js.map +1 -0
  74. package/dist/SyncService.d.ts +20 -0
  75. package/dist/SyncService.d.ts.map +1 -0
  76. package/dist/SyncService.js +504 -0
  77. package/dist/SyncService.js.map +1 -0
  78. package/dist/TokenResolver.d.ts +6 -0
  79. package/dist/TokenResolver.d.ts.map +1 -0
  80. package/dist/TokenResolver.js +43 -0
  81. package/dist/TokenResolver.js.map +1 -0
  82. package/dist/WorktreeManager.d.ts +42 -0
  83. package/dist/WorktreeManager.d.ts.map +1 -0
  84. package/dist/WorktreeManager.js +170 -0
  85. package/dist/WorktreeManager.js.map +1 -0
  86. package/dist/cli.d.ts +22 -0
  87. package/dist/cli.d.ts.map +1 -0
  88. package/dist/cli.js +217 -0
  89. package/dist/cli.js.map +1 -0
  90. package/dist/errors.d.ts +95 -0
  91. package/dist/errors.d.ts.map +1 -0
  92. package/dist/errors.js +35 -0
  93. package/dist/errors.js.map +1 -0
  94. package/dist/index.d.ts +4 -0
  95. package/dist/index.d.ts.map +1 -0
  96. package/dist/index.js +2 -0
  97. package/dist/index.js.map +1 -0
  98. package/dist/main.d.ts +3 -0
  99. package/dist/main.d.ts.map +1 -0
  100. package/dist/main.js +16 -0
  101. package/dist/main.js.map +1 -0
  102. package/dist/run.d.ts +91 -0
  103. package/dist/run.d.ts.map +1 -0
  104. package/dist/run.js +155 -0
  105. package/dist/run.js.map +1 -0
  106. package/dist/templates/blank/main.ts +9 -0
  107. package/dist/templates/blank/prompt.md +12 -0
  108. package/dist/templates/blank/template.json +4 -0
  109. package/dist/templates/parallel-planner/implement-prompt.md +62 -0
  110. package/dist/templates/parallel-planner/main.ts +200 -0
  111. package/dist/templates/parallel-planner/merge-prompt.md +22 -0
  112. package/dist/templates/parallel-planner/plan-prompt.md +33 -0
  113. package/dist/templates/parallel-planner/template.json +4 -0
  114. package/dist/templates/sequential-reviewer/implement-prompt.md +62 -0
  115. package/dist/templates/sequential-reviewer/main.ts +102 -0
  116. package/dist/templates/sequential-reviewer/review-prompt.md +43 -0
  117. package/dist/templates/sequential-reviewer/template.json +4 -0
  118. package/dist/templates/simple-loop/main.ts +37 -0
  119. package/dist/templates/simple-loop/prompt.md +51 -0
  120. package/dist/templates/simple-loop/template.json +4 -0
  121. package/dist/templates.d.ts +2 -0
  122. package/dist/templates.d.ts.map +1 -0
  123. package/dist/templates.js +26 -0
  124. package/dist/templates.js.map +1 -0
  125. package/dist/terminalCleanup.d.ts +30 -0
  126. package/dist/terminalCleanup.d.ts.map +1 -0
  127. package/dist/terminalCleanup.js +37 -0
  128. package/dist/terminalCleanup.js.map +1 -0
  129. package/dist/testSandbox.d.ts +8 -0
  130. package/dist/testSandbox.d.ts.map +1 -0
  131. package/dist/testSandbox.js +101 -0
  132. package/dist/testSandbox.js.map +1 -0
  133. package/package.json +62 -0
@@ -0,0 +1,132 @@
1
+ import * as clack from "@clack/prompts";
2
+ import { FileSystem } from "@effect/platform";
3
+ import { dirname } from "node:path";
4
+ import { Context, Effect, Layer, Ref } from "effect";
5
+ import { styleText } from "node:util";
6
+ export class Display extends Context.Tag("Display")() {
7
+ }
8
+ export const SilentDisplay = {
9
+ layer: (ref) => Layer.succeed(Display, {
10
+ intro: (title) => Ref.update(ref, (entries) => [
11
+ ...entries,
12
+ { _tag: "intro", title },
13
+ ]),
14
+ status: (message, severity) => Ref.update(ref, (entries) => [
15
+ ...entries,
16
+ { _tag: "status", message, severity },
17
+ ]),
18
+ spinner: (message, effect) => Effect.flatMap(Ref.update(ref, (entries) => [
19
+ ...entries,
20
+ { _tag: "spinner", message },
21
+ ]), () => effect),
22
+ summary: (title, rows) => Ref.update(ref, (entries) => [
23
+ ...entries,
24
+ { _tag: "summary", title, rows },
25
+ ]),
26
+ taskLog: (title, effect) => {
27
+ const messages = [];
28
+ return Effect.flatMap(effect((msg) => messages.push(msg)), (result) => Effect.map(Ref.update(ref, (entries) => [
29
+ ...entries,
30
+ {
31
+ _tag: "taskLog",
32
+ title,
33
+ messages: [...messages],
34
+ },
35
+ ]), () => result));
36
+ },
37
+ text: (message) => Ref.update(ref, (entries) => [
38
+ ...entries,
39
+ { _tag: "text", message },
40
+ ]),
41
+ }),
42
+ };
43
+ export const FileDisplay = {
44
+ layer: (filePath) => Layer.effect(Display, Effect.gen(function* () {
45
+ const fs = yield* FileSystem.FileSystem;
46
+ yield* fs
47
+ .makeDirectory(dirname(filePath), { recursive: true })
48
+ .pipe(Effect.orDie);
49
+ yield* fs.writeFileString(filePath, "").pipe(Effect.orDie);
50
+ const appendToLog = (line) => fs
51
+ .writeFileString(filePath, line + "\n", { flag: "a" })
52
+ .pipe(Effect.orDie);
53
+ return {
54
+ intro: () => Effect.void,
55
+ status: (message, _severity) => appendToLog(message.replace(/^\[[^\]]+\] /, "")),
56
+ spinner: (message, effect) => Effect.gen(function* () {
57
+ yield* appendToLog(`${message}...`);
58
+ const start = Date.now();
59
+ const result = yield* effect;
60
+ const elapsed = ((Date.now() - start) / 1000).toFixed(1);
61
+ yield* appendToLog(`${message} done (${elapsed}s)`);
62
+ return result;
63
+ }),
64
+ summary: (title, rows) => {
65
+ const lines = Object.entries(rows)
66
+ .map(([key, value]) => ` ${key}: ${value}`)
67
+ .join("\n");
68
+ return appendToLog(`${title}\n${lines}`);
69
+ },
70
+ taskLog: (title, effect) => Effect.gen(function* () {
71
+ yield* appendToLog(title);
72
+ const start = Date.now();
73
+ const messages = [];
74
+ const result = yield* effect((msg) => {
75
+ messages.push(msg);
76
+ });
77
+ const elapsed = ((Date.now() - start) / 1000).toFixed(1);
78
+ for (const msg of messages) {
79
+ yield* appendToLog(` ${msg}`);
80
+ }
81
+ yield* appendToLog(`${title} done (${elapsed}s)`);
82
+ return result;
83
+ }),
84
+ text: (message) => appendToLog(message),
85
+ };
86
+ })),
87
+ };
88
+ const severityToClack = {
89
+ info: clack.log.info,
90
+ success: clack.log.success,
91
+ warn: clack.log.warning,
92
+ error: clack.log.error,
93
+ };
94
+ export const terminalStyle = {
95
+ status: (message) => styleText("bold", message),
96
+ summaryTitle: (title) => styleText("bold", title),
97
+ summaryRow: (key, value) => `${styleText("bold", key)}: ${styleText("dim", value)}`,
98
+ };
99
+ export const ClackDisplay = {
100
+ layer: Layer.succeed(Display, {
101
+ intro: (title) => Effect.sync(() => clack.intro(styleText("inverse", ` ${title} `))),
102
+ status: (message, severity) => Effect.sync(() => severityToClack[severity](terminalStyle.status(message))),
103
+ spinner: (message, effect) => Effect.acquireUseRelease(Effect.sync(() => {
104
+ const s = clack.spinner();
105
+ s.start(message);
106
+ return s;
107
+ }), () => effect, (s, exit) => Effect.sync(() => {
108
+ if (exit._tag === "Success") {
109
+ s.stop(message);
110
+ }
111
+ else {
112
+ s.stop(`${message} (failed)`);
113
+ }
114
+ })),
115
+ summary: (title, rows) => Effect.sync(() => {
116
+ const lines = Object.entries(rows)
117
+ .map(([key, value]) => terminalStyle.summaryRow(key, value))
118
+ .join("\n");
119
+ clack.note(lines, terminalStyle.summaryTitle(title));
120
+ }),
121
+ taskLog: (title, effect) => Effect.acquireUseRelease(Effect.sync(() => clack.taskLog({ title })), (log) => effect((msg) => log.message(msg)), (log, exit) => Effect.sync(() => {
122
+ if (exit._tag === "Success") {
123
+ log.success(title, { showLog: true });
124
+ }
125
+ else {
126
+ log.error(title, { showLog: true });
127
+ }
128
+ })),
129
+ text: (message) => Effect.sync(() => clack.log.message(message)),
130
+ }),
131
+ };
132
+ //# sourceMappingURL=Display.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Display.js","sourceRoot":"","sources":["../src/Display.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import { Effect } from "effect";
2
+ import { DockerError } from "./errors.js";
3
+ /**
4
+ * Build the sandcastle Docker image.
5
+ *
6
+ * When `dockerfile` is provided, uses `docker build -f <dockerfile> <cwd>`
7
+ * so COPY instructions resolve relative to the current working directory.
8
+ * Otherwise, uses `docker build <dockerfileDir>` (the default .sandcastle/ directory).
9
+ */
10
+ export declare const buildImage: (imageName: string, dockerfileDir: string, options?: {
11
+ readonly dockerfile?: string | undefined;
12
+ } | undefined) => Effect.Effect<void, DockerError, never>;
13
+ export interface StartContainerOptions {
14
+ readonly volumeMounts?: readonly string[];
15
+ readonly workdir?: string;
16
+ /** Run the container as this uid:gid instead of the Dockerfile's USER. */
17
+ readonly user?: string;
18
+ }
19
+ /**
20
+ * Start a new container with environment variables injected.
21
+ */
22
+ export declare const startContainer: (containerName: string, imageName: string, env: Record<string, string>, options?: StartContainerOptions | undefined) => Effect.Effect<void, DockerError, never>;
23
+ /**
24
+ * Fix ownership of a directory inside the container.
25
+ * Runs as root so the target owner can write to the path.
26
+ * @param owner - chown-compatible owner spec, e.g. "1000:1000" or "agent"
27
+ */
28
+ export declare const chownInContainer: (containerName: string, owner: string, path: string) => Effect.Effect<void, DockerError, never>;
29
+ /**
30
+ * Stop and remove a container without removing the image.
31
+ */
32
+ export declare const removeContainer: (containerName: string) => Effect.Effect<void, DockerError, never>;
33
+ /**
34
+ * Remove a Docker image.
35
+ */
36
+ export declare const removeImage: (imageName: string) => Effect.Effect<void, DockerError, never>;
37
+ //# sourceMappingURL=DockerLifecycle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DockerLifecycle.d.ts","sourceRoot":"","sources":["../src/DockerLifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGhC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAwB1C;;;;;;GAMG;AACH,eAAO,MAAM,UAAU;;yDAkBnB,CAAC;AAEL,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,0EAA0E;IAC1E,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,iKAiDvB,CAAC;AAEL;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,iGAgB1B,CAAC;AAEJ;;GAEG;AACH,eAAO,MAAM,eAAe,oEAQxB,CAAC;AAEL;;GAEG;AACH,eAAO,MAAM,WAAW,gEAKpB,CAAC"}
@@ -0,0 +1,109 @@
1
+ import { Effect } from "effect";
2
+ import { execFile } from "node:child_process";
3
+ import { resolve } from "node:path";
4
+ import { DockerError } from "./errors.js";
5
+ const dockerExec = (args) => Effect.async((resume) => {
6
+ execFile("docker", args, { maxBuffer: 10 * 1024 * 1024 }, (error, stdout, stderr) => {
7
+ if (error) {
8
+ resume(Effect.fail(new DockerError({
9
+ message: `docker ${args[0]} failed: ${stderr?.toString() || error.message}`,
10
+ })));
11
+ }
12
+ else {
13
+ resume(Effect.succeed(stdout.toString()));
14
+ }
15
+ });
16
+ });
17
+ /**
18
+ * Build the sandcastle Docker image.
19
+ *
20
+ * When `dockerfile` is provided, uses `docker build -f <dockerfile> <cwd>`
21
+ * so COPY instructions resolve relative to the current working directory.
22
+ * Otherwise, uses `docker build <dockerfileDir>` (the default .sandcastle/ directory).
23
+ */
24
+ export const buildImage = (imageName, dockerfileDir, options) => Effect.gen(function* () {
25
+ if (options?.dockerfile) {
26
+ yield* dockerExec([
27
+ "build",
28
+ "-t",
29
+ imageName,
30
+ "-f",
31
+ resolve(options.dockerfile),
32
+ process.cwd(),
33
+ ]);
34
+ }
35
+ else {
36
+ yield* dockerExec(["build", "-t", imageName, resolve(dockerfileDir)]);
37
+ }
38
+ });
39
+ /**
40
+ * Start a new container with environment variables injected.
41
+ */
42
+ export const startContainer = (containerName, imageName, env, options) => Effect.gen(function* () {
43
+ // Check if container already exists
44
+ const existing = yield* dockerExec([
45
+ "ps",
46
+ "-a",
47
+ "--filter",
48
+ `name=^${containerName}$`,
49
+ "--format",
50
+ "{{.Names}}",
51
+ ]);
52
+ if (existing.trim() === containerName) {
53
+ yield* Effect.fail(new DockerError({
54
+ message: `Container '${containerName}' already exists. Run cleanup first.`,
55
+ }));
56
+ }
57
+ const envFlags = Object.entries(env).flatMap(([k, v]) => [
58
+ "-e",
59
+ `${k}=${v}`,
60
+ ]);
61
+ const volumeFlags = (options?.volumeMounts ?? []).flatMap((mount) => [
62
+ "-v",
63
+ mount,
64
+ ]);
65
+ const workdirFlags = options?.workdir ? ["-w", options.workdir] : [];
66
+ const userFlags = options?.user ? ["--user", options.user] : [];
67
+ yield* dockerExec([
68
+ "run",
69
+ "-d",
70
+ "--name",
71
+ containerName,
72
+ ...envFlags,
73
+ ...volumeFlags,
74
+ ...workdirFlags,
75
+ ...userFlags,
76
+ imageName,
77
+ ]);
78
+ });
79
+ /**
80
+ * Fix ownership of a directory inside the container.
81
+ * Runs as root so the target owner can write to the path.
82
+ * @param owner - chown-compatible owner spec, e.g. "1000:1000" or "agent"
83
+ */
84
+ export const chownInContainer = (containerName, owner, path) => Effect.asVoid(dockerExec([
85
+ "exec",
86
+ "-u",
87
+ "root",
88
+ containerName,
89
+ "chown",
90
+ "-R",
91
+ owner,
92
+ path,
93
+ ]));
94
+ /**
95
+ * Stop and remove a container without removing the image.
96
+ */
97
+ export const removeContainer = (containerName) => Effect.gen(function* () {
98
+ // Stop container (ignore errors if already stopped)
99
+ yield* Effect.ignore(dockerExec(["stop", containerName]));
100
+ // Remove container (ignore errors if not found)
101
+ yield* Effect.ignore(dockerExec(["rm", containerName]));
102
+ });
103
+ /**
104
+ * Remove a Docker image.
105
+ */
106
+ export const removeImage = (imageName) => Effect.gen(function* () {
107
+ yield* dockerExec(["rmi", imageName]);
108
+ });
109
+ //# sourceMappingURL=DockerLifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DockerLifecycle.js","sourceRoot":"","sources":["../src/DockerLifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,UAAU,GAAG,CAAC,IAAc,EAAsC,EAAE,CACxE,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE;IACtB,QAAQ,CACN,QAAQ,EACR,IAAI,EACJ,EAAE,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI,EAAE,EAC/B,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;QACxB,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,CACJ,MAAM,CAAC,IAAI,CACT,IAAI,WAAW,CAAC;gBACd,OAAO,EAAE,UAAU,IAAI,CAAC,CAAC,CAAC,YAAY,MAAM,EAAE,QAAQ,EAAE,IAAI,KAAK,CAAC,OAAO,EAAE;aAC5E,CAAC,CACH,CACF,CAAC;QACJ,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEL;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CACxB,SAAiB,EACjB,aAAqB,EACrB,OAA0C,EACR,EAAE,CACpC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,IAAI,OAAO,EAAE,UAAU,EAAE,CAAC;QACxB,KAAK,CAAC,CAAC,UAAU,CAAC;YAChB,OAAO;YACP,IAAI;YACJ,SAAS;YACT,IAAI;YACJ,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC;YAC3B,OAAO,CAAC,GAAG,EAAE;SACd,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,KAAK,CAAC,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;IACxE,CAAC;AACH,CAAC,CAAC,CAAC;AASL;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAC5B,aAAqB,EACrB,SAAiB,EACjB,GAA2B,EAC3B,OAA+B,EACG,EAAE,CACpC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,oCAAoC;IACpC,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC;QACjC,IAAI;QACJ,IAAI;QACJ,UAAU;QACV,SAAS,aAAa,GAAG;QACzB,UAAU;QACV,YAAY;KACb,CAAC,CAAC;IAEH,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,aAAa,EAAE,CAAC;QACtC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAChB,IAAI,WAAW,CAAC;YACd,OAAO,EAAE,cAAc,aAAa,sCAAsC;SAC3E,CAAC,CACH,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;QACvD,IAAI;QACJ,GAAG,CAAC,IAAI,CAAC,EAAE;KACZ,CAAC,CAAC;IAEH,MAAM,WAAW,GAAG,CAAC,OAAO,EAAE,YAAY,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;QACnE,IAAI;QACJ,KAAK;KACN,CAAC,CAAC;IAEH,MAAM,YAAY,GAAG,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACrE,MAAM,SAAS,GAAG,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAEhE,KAAK,CAAC,CAAC,UAAU,CAAC;QAChB,KAAK;QACL,IAAI;QACJ,QAAQ;QACR,aAAa;QACb,GAAG,QAAQ;QACX,GAAG,WAAW;QACd,GAAG,YAAY;QACf,GAAG,SAAS;QACZ,SAAS;KACV,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEL;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,aAAqB,EACrB,KAAa,EACb,IAAY,EACsB,EAAE,CACpC,MAAM,CAAC,MAAM,CACX,UAAU,CAAC;IACT,MAAM;IACN,IAAI;IACJ,MAAM;IACN,aAAa;IACb,OAAO;IACP,IAAI;IACJ,KAAK;IACL,IAAI;CACL,CAAC,CACH,CAAC;AAEJ;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,CAC7B,aAAqB,EACa,EAAE,CACpC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,oDAAoD;IACpD,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;IAC1D,gDAAgD;IAChD,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;AAC1D,CAAC,CAAC,CAAC;AAEL;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CACzB,SAAiB,EACiB,EAAE,CACpC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,KAAK,CAAC,CAAC,UAAU,CAAC,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;AACxC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { Layer } from "effect";
2
+ import { Sandbox } from "./Sandbox.js";
3
+ export declare const DockerSandbox: {
4
+ layer: (containerName: string) => Layer.Layer<Sandbox, never, never>;
5
+ };
6
+ //# sourceMappingURL=DockerSandbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DockerSandbox.d.ts","sourceRoot":"","sources":["../src/DockerSandbox.ts"],"names":[],"mappings":"AAEA,OAAO,EAAU,KAAK,EAAE,MAAM,QAAQ,CAAC;AAKvC,OAAO,EAAE,OAAO,EAAuB,MAAM,cAAc,CAAC;AA+K5D,eAAO,MAAM,aAAa;;CAKzB,CAAC"}
@@ -0,0 +1,122 @@
1
+ import { FileSystem } from "@effect/platform";
2
+ import { NodeFileSystem } from "@effect/platform-node";
3
+ import { Effect, Layer } from "effect";
4
+ import { execFile, spawn } from "node:child_process";
5
+ import { dirname } from "node:path";
6
+ import { createInterface } from "node:readline";
7
+ import { CopyError, ExecError } from "./errors.js";
8
+ import { Sandbox } from "./Sandbox.js";
9
+ const makeDockerSandbox = (containerName) => Effect.gen(function* () {
10
+ const fs = yield* FileSystem.FileSystem;
11
+ return {
12
+ exec: (command, options) => Effect.async((resume) => {
13
+ const args = ["exec"];
14
+ if (options?.cwd) {
15
+ args.push("-w", options.cwd);
16
+ }
17
+ args.push(containerName, "sh", "-c", command);
18
+ execFile("docker", args, { maxBuffer: 10 * 1024 * 1024 }, (error, stdout, stderr) => {
19
+ if (error && error.code === undefined) {
20
+ resume(Effect.fail(new ExecError({
21
+ command,
22
+ message: `docker exec failed: ${error.message}`,
23
+ })));
24
+ }
25
+ else {
26
+ resume(Effect.succeed({
27
+ stdout: stdout.toString(),
28
+ stderr: stderr.toString(),
29
+ exitCode: typeof error?.code === "number"
30
+ ? error.code
31
+ : 0,
32
+ }));
33
+ }
34
+ });
35
+ }),
36
+ execStreaming: (command, onStdoutLine, options) => Effect.async((resume) => {
37
+ const args = ["exec"];
38
+ if (options?.cwd) {
39
+ args.push("-w", options.cwd);
40
+ }
41
+ args.push(containerName, "sh", "-c", command);
42
+ const proc = spawn("docker", args, {
43
+ stdio: ["ignore", "pipe", "pipe"],
44
+ });
45
+ const stdoutChunks = [];
46
+ const stderrChunks = [];
47
+ const rl = createInterface({ input: proc.stdout });
48
+ rl.on("line", (line) => {
49
+ stdoutChunks.push(line);
50
+ onStdoutLine(line);
51
+ });
52
+ proc.stderr.on("data", (chunk) => {
53
+ stderrChunks.push(chunk.toString());
54
+ });
55
+ proc.on("error", (error) => {
56
+ resume(Effect.fail(new ExecError({
57
+ command,
58
+ message: `docker exec streaming failed: ${error.message}`,
59
+ })));
60
+ });
61
+ proc.on("close", (code) => {
62
+ resume(Effect.succeed({
63
+ stdout: stdoutChunks.join("\n"),
64
+ stderr: stderrChunks.join(""),
65
+ exitCode: code ?? 0,
66
+ }));
67
+ });
68
+ }),
69
+ copyIn: (hostPath, sandboxPath) => Effect.gen(function* () {
70
+ // Ensure parent directory exists in container
71
+ const parentDir = dirname(sandboxPath);
72
+ yield* Effect.async((resume) => {
73
+ execFile("docker", ["exec", containerName, "mkdir", "-p", parentDir], (error) => {
74
+ if (error) {
75
+ resume(Effect.fail(new CopyError({
76
+ message: `Failed to create dir ${parentDir}: ${error.message}`,
77
+ })));
78
+ }
79
+ else {
80
+ resume(Effect.succeed(undefined));
81
+ }
82
+ });
83
+ });
84
+ // docker cp hostPath containerName:sandboxPath
85
+ yield* Effect.async((resume) => {
86
+ execFile("docker", ["cp", hostPath, `${containerName}:${sandboxPath}`], (error) => {
87
+ if (error) {
88
+ resume(Effect.fail(new CopyError({
89
+ message: `Failed to copy ${hostPath} -> ${containerName}:${sandboxPath}: ${error.message}`,
90
+ })));
91
+ }
92
+ else {
93
+ resume(Effect.succeed(undefined));
94
+ }
95
+ });
96
+ });
97
+ }),
98
+ copyOut: (sandboxPath, hostPath) => Effect.gen(function* () {
99
+ // Ensure parent directory exists on host
100
+ yield* fs.makeDirectory(dirname(hostPath), { recursive: true }).pipe(Effect.mapError((error) => new CopyError({
101
+ message: `Failed to create host dir ${dirname(hostPath)}: ${error}`,
102
+ })));
103
+ // docker cp containerName:sandboxPath hostPath
104
+ yield* Effect.async((resume) => {
105
+ execFile("docker", ["cp", `${containerName}:${sandboxPath}`, hostPath], (error) => {
106
+ if (error) {
107
+ resume(Effect.fail(new CopyError({
108
+ message: `Failed to copy ${containerName}:${sandboxPath} -> ${hostPath}: ${error.message}`,
109
+ })));
110
+ }
111
+ else {
112
+ resume(Effect.succeed(undefined));
113
+ }
114
+ });
115
+ });
116
+ }),
117
+ };
118
+ });
119
+ export const DockerSandbox = {
120
+ layer: (containerName) => Layer.effect(Sandbox, makeDockerSandbox(containerName)).pipe(Layer.provide(NodeFileSystem.layer)),
121
+ };
122
+ //# sourceMappingURL=DockerSandbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DockerSandbox.js","sourceRoot":"","sources":["../src/DockerSandbox.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,OAAO,EAAuB,MAAM,cAAc,CAAC;AAE5D,MAAM,iBAAiB,GAAG,CACxB,aAAqB,EACwC,EAAE,CAC/D,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC;IACxC,OAAO;QACL,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CACzB,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE;YACtB,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;YACtB,IAAI,OAAO,EAAE,GAAG,EAAE,CAAC;gBACjB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;YAC/B,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;YAE9C,QAAQ,CACN,QAAQ,EACR,IAAI,EACJ,EAAE,SAAS,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI,EAAE,EAC/B,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;gBACxB,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;oBACtC,MAAM,CACJ,MAAM,CAAC,IAAI,CACT,IAAI,SAAS,CAAC;wBACZ,OAAO;wBACP,OAAO,EAAE,uBAAuB,KAAK,CAAC,OAAO,EAAE;qBAChD,CAAC,CACH,CACF,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACN,MAAM,CACJ,MAAM,CAAC,OAAO,CAAC;wBACb,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE;wBACzB,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE;wBACzB,QAAQ,EACN,OAAO,KAAK,EAAE,IAAI,KAAK,QAAQ;4BAC7B,CAAC,CAAC,KAAK,CAAC,IAAI;4BACZ,CAAC,CAAE,CAAY;qBACpB,CAAC,CACH,CAAC;gBACJ,CAAC;YACH,CAAC,CACF,CAAC;QACJ,CAAC,CAAC;QAEJ,aAAa,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,EAAE,CAChD,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE;YACtB,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;YACtB,IAAI,OAAO,EAAE,GAAG,EAAE,CAAC;gBACjB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;YAC/B,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;YAE9C,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE;gBACjC,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;aAClC,CAAC,CAAC;YAEH,MAAM,YAAY,GAAa,EAAE,CAAC;YAClC,MAAM,YAAY,GAAa,EAAE,CAAC;YAElC,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,MAAO,EAAE,CAAC,CAAC;YACpD,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;gBACrB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACxB,YAAY,CAAC,IAAI,CAAC,CAAC;YACrB,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,MAAO,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;gBACxC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;YACtC,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;gBACzB,MAAM,CACJ,MAAM,CAAC,IAAI,CACT,IAAI,SAAS,CAAC;oBACZ,OAAO;oBACP,OAAO,EAAE,iCAAiC,KAAK,CAAC,OAAO,EAAE;iBAC1D,CAAC,CACH,CACF,CAAC;YACJ,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;gBACxB,MAAM,CACJ,MAAM,CAAC,OAAO,CAAC;oBACb,MAAM,EAAE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;oBAC/B,MAAM,EAAE,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;oBAC7B,QAAQ,EAAE,IAAI,IAAI,CAAC;iBACpB,CAAC,CACH,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QAEJ,MAAM,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,CAChC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,8CAA8C;YAC9C,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;YACvC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAkB,CAAC,MAAM,EAAE,EAAE;gBAC9C,QAAQ,CACN,QAAQ,EACR,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,CAAC,EACjD,CAAC,KAAK,EAAE,EAAE;oBACR,IAAI,KAAK,EAAE,CAAC;wBACV,MAAM,CACJ,MAAM,CAAC,IAAI,CACT,IAAI,SAAS,CAAC;4BACZ,OAAO,EAAE,wBAAwB,SAAS,KAAK,KAAK,CAAC,OAAO,EAAE;yBAC/D,CAAC,CACH,CACF,CAAC;oBACJ,CAAC;yBAAM,CAAC;wBACN,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;oBACpC,CAAC;gBACH,CAAC,CACF,CAAC;YACJ,CAAC,CAAC,CAAC;YAEH,+CAA+C;YAC/C,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAkB,CAAC,MAAM,EAAE,EAAE;gBAC9C,QAAQ,CACN,QAAQ,EACR,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,aAAa,IAAI,WAAW,EAAE,CAAC,EACnD,CAAC,KAAK,EAAE,EAAE;oBACR,IAAI,KAAK,EAAE,CAAC;wBACV,MAAM,CACJ,MAAM,CAAC,IAAI,CACT,IAAI,SAAS,CAAC;4BACZ,OAAO,EAAE,kBAAkB,QAAQ,OAAO,aAAa,IAAI,WAAW,KAAK,KAAK,CAAC,OAAO,EAAE;yBAC3F,CAAC,CACH,CACF,CAAC;oBACJ,CAAC;yBAAM,CAAC;wBACN,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;oBACpC,CAAC;gBACH,CAAC,CACF,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QAEJ,OAAO,EAAE,CAAC,WAAW,EAAE,QAAQ,EAAE,EAAE,CACjC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,yCAAyC;YACzC,KAAK,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAClE,MAAM,CAAC,QAAQ,CACb,CAAC,KAAK,EAAE,EAAE,CACR,IAAI,SAAS,CAAC;gBACZ,OAAO,EAAE,6BAA6B,OAAO,CAAC,QAAQ,CAAC,KAAK,KAAK,EAAE;aACpE,CAAC,CACL,CACF,CAAC;YAEF,+CAA+C;YAC/C,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAkB,CAAC,MAAM,EAAE,EAAE;gBAC9C,QAAQ,CACN,QAAQ,EACR,CAAC,IAAI,EAAE,GAAG,aAAa,IAAI,WAAW,EAAE,EAAE,QAAQ,CAAC,EACnD,CAAC,KAAK,EAAE,EAAE;oBACR,IAAI,KAAK,EAAE,CAAC;wBACV,MAAM,CACJ,MAAM,CAAC,IAAI,CACT,IAAI,SAAS,CAAC;4BACZ,OAAO,EAAE,kBAAkB,aAAa,IAAI,WAAW,OAAO,QAAQ,KAAK,KAAK,CAAC,OAAO,EAAE;yBAC3F,CAAC,CACH,CACF,CAAC;oBACJ,CAAC;yBAAM,CAAC;wBACN,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;oBACpC,CAAC;gBACH,CAAC,CACF,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;KACL,CAAC;AACJ,CAAC,CAAC,CAAC;AAEL,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,KAAK,EAAE,CAAC,aAAqB,EAAwB,EAAE,CACrD,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,iBAAiB,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAC1D,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,CACpC;CACJ,CAAC"}
@@ -0,0 +1,11 @@
1
+ import { FileSystem } from "@effect/platform";
2
+ import { Effect } from "effect";
3
+ /**
4
+ * Resolve all env vars from .env files with process.env fallback.
5
+ *
6
+ * Precedence: .sandcastle/.env > process.env
7
+ * Only keys declared in .sandcastle/.env are resolved from process.env.
8
+ * Repo root .env is not part of the resolution chain.
9
+ */
10
+ export declare const resolveEnv: (repoDir: string) => Effect.Effect<Record<string, string>, never, FileSystem.FileSystem>;
11
+ //# sourceMappingURL=EnvResolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EnvResolver.d.ts","sourceRoot":"","sources":["../src/EnvResolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAyBhC;;;;;;GAMG;AACH,eAAO,MAAM,UAAU,0FAiBnB,CAAC"}
@@ -0,0 +1,43 @@
1
+ import { FileSystem } from "@effect/platform";
2
+ import { Effect } from "effect";
3
+ import { join } from "node:path";
4
+ const parseEnvFile = (filePath) => Effect.gen(function* () {
5
+ const fs = yield* FileSystem.FileSystem;
6
+ const content = yield* fs
7
+ .readFileString(filePath)
8
+ .pipe(Effect.catchAll(() => Effect.succeed(null)));
9
+ if (content === null)
10
+ return {};
11
+ const vars = {};
12
+ for (const line of content.split("\n")) {
13
+ const trimmed = line.trim();
14
+ if (!trimmed || trimmed.startsWith("#"))
15
+ continue;
16
+ const eqIndex = trimmed.indexOf("=");
17
+ if (eqIndex === -1)
18
+ continue;
19
+ const key = trimmed.slice(0, eqIndex).trim();
20
+ const value = trimmed.slice(eqIndex + 1).trim();
21
+ vars[key] = value;
22
+ }
23
+ return vars;
24
+ });
25
+ /**
26
+ * Resolve all env vars from .env files with process.env fallback.
27
+ *
28
+ * Precedence: .sandcastle/.env > process.env
29
+ * Only keys declared in .sandcastle/.env are resolved from process.env.
30
+ * Repo root .env is not part of the resolution chain.
31
+ */
32
+ export const resolveEnv = (repoDir) => Effect.gen(function* () {
33
+ const sandcastleEnv = yield* parseEnvFile(join(repoDir, ".sandcastle", ".env"));
34
+ const result = {};
35
+ for (const key of Object.keys(sandcastleEnv)) {
36
+ const value = sandcastleEnv[key] || process.env[key];
37
+ if (value) {
38
+ result[key] = value;
39
+ }
40
+ }
41
+ return result;
42
+ });
43
+ //# sourceMappingURL=EnvResolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EnvResolver.js","sourceRoot":"","sources":["../src/EnvResolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,YAAY,GAAG,CACnB,QAAgB,EACqD,EAAE,CACvE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC;IACxC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,EAAE;SACtB,cAAc,CAAC,QAAQ,CAAC;SACxB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACrD,IAAI,OAAO,KAAK,IAAI;QAAE,OAAO,EAAE,CAAC;IAChC,MAAM,IAAI,GAA2B,EAAE,CAAC;IACxC,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAClD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,OAAO,KAAK,CAAC,CAAC;YAAE,SAAS;QAC7B,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAChD,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACpB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC,CAAC;AAEL;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,CACxB,OAAe,EACsD,EAAE,CACvE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,YAAY,CACvC,IAAI,CAAC,OAAO,EAAE,aAAa,EAAE,MAAM,CAAC,CACrC,CAAC;IAEF,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;QAC7C,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACrD,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACtB,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { Effect } from "effect";
2
+ import { Display } from "./Display.js";
3
+ import type { SandboxError } from "./errors.js";
4
+ /**
5
+ * Formats a tagged SandboxError into a user-friendly message with
6
+ * context-specific hints about what went wrong and how to recover.
7
+ */
8
+ export declare const formatErrorMessage: (error: SandboxError) => string;
9
+ /**
10
+ * Wraps an effect so that any SandboxError is caught, displayed via the
11
+ * Display service as an error-severity status message, then exits the process
12
+ * with code 1. Non-SandboxError errors pass through unchanged.
13
+ */
14
+ export declare const withFriendlyErrors: <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, Exclude<E, SandboxError>, R | Display>;
15
+ //# sourceMappingURL=ErrorHandler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ErrorHandler.d.ts","sourceRoot":"","sources":["../src/ErrorHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD;;;GAGG;AACH,eAAO,MAAM,kBAAkB,iCAyB9B,CAAC;AASF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,GAAI,CAAC,EAAE,CAAC,EAAE,CAAC,4FAgBqB,CAAC"}
@@ -0,0 +1,58 @@
1
+ import { Effect } from "effect";
2
+ import { Display } from "./Display.js";
3
+ /**
4
+ * Formats a tagged SandboxError into a user-friendly message with
5
+ * context-specific hints about what went wrong and how to recover.
6
+ */
7
+ export const formatErrorMessage = (error) => {
8
+ switch (error._tag) {
9
+ case "ExecError":
10
+ return `Command failed in sandbox (${error.command}): ${error.message}`;
11
+ case "ExecHostError":
12
+ return `Command failed on host (${error.command}): ${error.message}`;
13
+ case "CopyError":
14
+ return `File copy failed: ${error.message}`;
15
+ case "DockerError":
16
+ return `Docker operation failed: ${error.message}. Is Docker running?`;
17
+ case "SyncError":
18
+ return `Git sync failed: ${error.message}`;
19
+ case "WorktreeError":
20
+ return `Git worktree operation failed: ${error.message}`;
21
+ case "PromptError":
22
+ return `Failed to resolve prompt: ${error.message}`;
23
+ case "AgentError":
24
+ return `Agent invocation failed: ${error.message}`;
25
+ case "ConfigDirError":
26
+ return `${error.message}`;
27
+ case "InitError":
28
+ return `${error.message}`;
29
+ case "TimeoutError":
30
+ return `Run timed out after ${error.timeoutSeconds}s. Consider increasing the timeout with --timeout.`;
31
+ }
32
+ };
33
+ const showErrorAndExit = (error) => Effect.gen(function* () {
34
+ const d = yield* Display;
35
+ yield* d.status(formatErrorMessage(error), "error");
36
+ return yield* Effect.sync(() => process.exit(1));
37
+ });
38
+ /**
39
+ * Wraps an effect so that any SandboxError is caught, displayed via the
40
+ * Display service as an error-severity status message, then exits the process
41
+ * with code 1. Non-SandboxError errors pass through unchanged.
42
+ */
43
+ export const withFriendlyErrors = (effect) =>
44
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
45
+ Effect.catchTags(effect, {
46
+ ExecError: showErrorAndExit,
47
+ ExecHostError: showErrorAndExit,
48
+ CopyError: showErrorAndExit,
49
+ DockerError: showErrorAndExit,
50
+ SyncError: showErrorAndExit,
51
+ WorktreeError: showErrorAndExit,
52
+ PromptError: showErrorAndExit,
53
+ AgentError: showErrorAndExit,
54
+ ConfigDirError: showErrorAndExit,
55
+ InitError: showErrorAndExit,
56
+ TimeoutError: showErrorAndExit,
57
+ });
58
+ //# sourceMappingURL=ErrorHandler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ErrorHandler.js","sourceRoot":"","sources":["../src/ErrorHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,KAAmB,EAAU,EAAE;IAChE,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,WAAW;YACd,OAAO,8BAA8B,KAAK,CAAC,OAAO,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;QAC1E,KAAK,eAAe;YAClB,OAAO,2BAA2B,KAAK,CAAC,OAAO,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;QACvE,KAAK,WAAW;YACd,OAAO,qBAAqB,KAAK,CAAC,OAAO,EAAE,CAAC;QAC9C,KAAK,aAAa;YAChB,OAAO,4BAA4B,KAAK,CAAC,OAAO,sBAAsB,CAAC;QACzE,KAAK,WAAW;YACd,OAAO,oBAAoB,KAAK,CAAC,OAAO,EAAE,CAAC;QAC7C,KAAK,eAAe;YAClB,OAAO,kCAAkC,KAAK,CAAC,OAAO,EAAE,CAAC;QAC3D,KAAK,aAAa;YAChB,OAAO,6BAA6B,KAAK,CAAC,OAAO,EAAE,CAAC;QACtD,KAAK,YAAY;YACf,OAAO,4BAA4B,KAAK,CAAC,OAAO,EAAE,CAAC;QACrD,KAAK,gBAAgB;YACnB,OAAO,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;QAC5B,KAAK,WAAW;YACd,OAAO,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;QAC5B,KAAK,cAAc;YACjB,OAAO,uBAAuB,KAAK,CAAC,cAAc,oDAAoD,CAAC;IAC3G,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,gBAAgB,GAAG,CAAC,KAAmB,EAAE,EAAE,CAC/C,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC;IACzB,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC;IACpD,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAU,CAAC,CAAC;AAC5D,CAAC,CAAC,CAAC;AAEL;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAChC,MAA8B,EAC2B,EAAE;AAC3D,8DAA8D;AAC9D,MAAM,CAAC,SAAS,CAAC,MAA2C,EAAE;IAC5D,SAAS,EAAE,gBAAgB;IAC3B,aAAa,EAAE,gBAAgB;IAC/B,SAAS,EAAE,gBAAgB;IAC3B,WAAW,EAAE,gBAAgB;IAC7B,SAAS,EAAE,gBAAgB;IAC3B,aAAa,EAAE,gBAAgB;IAC/B,WAAW,EAAE,gBAAgB;IAC7B,UAAU,EAAE,gBAAgB;IAC5B,cAAc,EAAE,gBAAgB;IAChC,SAAS,EAAE,gBAAgB;IAC3B,YAAY,EAAE,gBAAgB;CAC/B,CAA4D,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { Layer } from "effect";
2
+ import { Sandbox } from "./Sandbox.js";
3
+ export declare const FilesystemSandbox: {
4
+ layer: (sandboxDir: string) => Layer.Layer<Sandbox, never, never>;
5
+ };
6
+ //# sourceMappingURL=FilesystemSandbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FilesystemSandbox.d.ts","sourceRoot":"","sources":["../src/FilesystemSandbox.ts"],"names":[],"mappings":"AAEA,OAAO,EAAU,KAAK,EAAE,MAAM,QAAQ,CAAC;AAKvC,OAAO,EAAE,OAAO,EAAuB,MAAM,cAAc,CAAC;AA8H5D,eAAO,MAAM,iBAAiB;;CAK7B,CAAC"}