| @@ -22,7 +22,7 @@ import { · 21 unmodified lines |
| 22 | type SqlControlPlaneRuntime, | 22 | type SqlControlPlaneRuntime, |
| 23 | } from "@executor-v3/control-plane"; | 23 | } from "@executor-v3/control-plane"; |
| 24 | import type { ToolCatalog } from "@executor-v3/codemode-core"; | 24 | import type { ToolCatalog } from "@executor-v3/codemode-core"; |
| 25 | import { isDenoAvailable } from "@executor-v3/runtime-deno-subprocess"; | 25 | |
| 26 | import * as Effect from "effect/Effect"; | 26 | import * as Effect from "effect/Effect"; |
| 27 | import * as Schema from "effect/Schema"; | 27 | import * as Schema from "effect/Schema"; |
| 28 | import * as Option from "effect/Option"; | 28 | import * as Option from "effect/Option"; |
| @@ -1188,27 +1188,11 @@ const getDenoVersion = (): Effect.Effect<string | null, never, never> => · 1159 unmodified lines |
| 1188 | catch: () => null, | 1188 | catch: () => null, |
| 1189 | }).pipe(Effect.catchAll(() => Effect.succeed(null))); | 1189 | }).pipe(Effect.catchAll(() => Effect.succeed(null))); |
| 1190 | | 1190 | |
| 1191 | const installDeno = (): Effect.Effect<boolean, Error, never> => | | |
| 1192 | Effect.tryPromise({ | | |
| 1193 | try: () => | | |
| 1194 | new Promise<boolean>((resolve, reject) => { | | |
| 1195 | const child = spawn("sh", ["-c", "curl -fsSL https://deno.land/install.sh | sh"], { | | |
| 1196 | stdio: ["ignore", "inherit", "inherit"], | | |
| 1197 | }); | | |
| 1198 | | | |
| 1199 | child.once("error", (err) => reject(err)); | | |
| 1200 | child.once("close", (code) => resolve(code === 0)); | | |
| 1201 | }), | | |
| 1202 | catch: toError, | | |
| 1203 | }); | | |
| 1204 | | | |
| 1205 | const sandboxCommand = Command.make( | 1191 | const sandboxCommand = Command.make( |
| 1206 | "sandbox", | 1192 | "sandbox", |
| 1207 | {}, | 1193 | {}, |
| 1208 | () => | 1194 | () => |
| 1209 | Effect.gen(function* () { | 1195 | Effect.gen(function* () { |
| 1210 | yield* printText("Checking Deno sandbox runtime..."); | | |
| 1211 | | | |
| 1212 | const version = yield* getDenoVersion(); | 1196 | const version = yield* getDenoVersion(); |
| 1213 | | 1197 | |
| 1214 | if (version !== null) { | 1198 | if (version !== null) { |
| @@ -1216,29 +1200,22 @@ const sandboxCommand = Command.make( · 1 unmodified line |
| 1216 | return; | 1200 | return; |
| 1217 | } | 1201 | } |
| 1218 | | 1202 | |
| 1219 | if (!isDenoAvailable()) { | 1203 | yield* printText( |
| 1220 | yield* printText("Deno is not installed. Installing..."); | 1204 | [ |
| 1221 | } else { | 1205 | "Deno is not installed.", |
| 1222 | yield* printText("Deno binary found but did not respond. Reinstalling..."); | 1206 | "", |
| 1223 | } | 1207 | "The executor sandbox requires Deno to run code in a secure, isolated subprocess.", |
| 1224 | | 1208 | "", |
| 1225 | const installed = yield* installDeno(); | 1209 | "Install Deno:", |
| 1226 | if (!installed) { | 1210 | " curl -fsSL https://deno.land/install.sh | sh", |
| 1227 | return yield* Effect.fail( | 1211 | "", |
| 1228 | new Error("Deno installation failed. Install manually: https://docs.deno.com/runtime/getting_started/installation/"), | 1212 | "Or see: https://docs.deno.com/runtime/getting_started/installation/", |
| 1229 | ); | 1213 | ].join("\n"), |
| 1230 | } | 1214 | ); |
| 1231 | | | |
| 1232 | const postVersion = yield* getDenoVersion(); | | |
| 1233 | if (postVersion === null) { | | |
| 1234 | return yield* Effect.fail( | | |
| 1235 | new Error("Deno was installed but could not be verified. You may need to restart your shell."), | | |
| 1236 | ); | | |
| 1237 | } | | |
| 1238 | | 1215 | |
| 1239 | yield* printText(`Deno sandbox installed successfully (deno ${postVersion}).`); | 1216 | process.exitCode = 1; |
| 1240 | }), | 1217 | }), |
| 1241 | ).pipe(Command.withDescription("Check and install the Deno sandbox runtime")); | 1218 | ).pipe(Command.withDescription("Check whether the Deno sandbox runtime is available")); |
| 1242 | | 1219 | |
| 1243 | | 1220 | |
| 1244 | const callCommand = Command.make( | 1221 | const callCommand = Command.make( |