diff --git a/.changeset/tidy-apes-drive.md b/.changeset/tidy-apes-drive.md new file mode 100644 index 0000000..e2cb2e7 --- /dev/null +++ b/.changeset/tidy-apes-drive.md @@ -0,0 +1,5 @@ +--- +"opencode-drive": patch +--- + +Support current OpenCode V2 development checkouts and reject checkouts without simulation support. diff --git a/packages/drive/src/instance/dev.ts b/packages/drive/src/instance/dev.ts index 9ffe966..fb630a4 100644 --- a/packages/drive/src/instance/dev.ts +++ b/packages/drive/src/instance/dev.ts @@ -14,12 +14,17 @@ export const prepareDev = Effect.fn("OpenCodeInstance.prepareDev")(function* ( const root = resolve(directory) const entrypoint = join(root, "packages", "cli", "src", "index.ts") const solid = join(root, "packages", "tui", "node_modules", "@opentui", "solid") + const simulation = join(root, "packages", "simulation", "package.json") const standalone = yield* Effect.tryPromise({ try: async () => { if (!(await Bun.file(entrypoint).exists())) throw new Error(`OpenCode development entrypoint not found: ${entrypoint}`) if (!(await Bun.file(join(solid, "package.json")).exists())) throw new Error(`OpenCode development dependency not found: ${solid}; run bun install in ${root}`) + if (!(await Bun.file(simulation).exists())) + throw new Error( + `OpenCode development checkout does not include simulation support: ${simulation}; --dev requires a V2 checkout with packages/simulation`, + ) const preload = join(artifacts, "node_modules", "@opentui", "solid") await mkdir(join(artifacts, "node_modules", "@opentui"), { recursive: true, @@ -38,6 +43,7 @@ export const prepareDev = Effect.fn("OpenCodeInstance.prepareDev")(function* ( return { command: [...base, ...(standalone ? ["--standalone"] : [])], scriptedCommand: base, + serviceFlag: standalone ? "--service" : "--register", preloads, } }) diff --git a/packages/drive/src/instance/runtime.ts b/packages/drive/src/instance/runtime.ts index fe6d316..328d49b 100644 --- a/packages/drive/src/instance/runtime.ts +++ b/packages/drive/src/instance/runtime.ts @@ -261,7 +261,7 @@ export const make = Effect.fn("OpenCodeInstance.make")(function* ( const serverCommand = [ ...scriptedCommand, "serve", - "--service", + dev?.serviceFlag ?? "--service", "--port", String(yield* freePort), ] diff --git a/packages/drive/test/instance/dev.test.ts b/packages/drive/test/instance/dev.test.ts index 31672c0..e511e99 100644 --- a/packages/drive/test/instance/dev.test.ts +++ b/packages/drive/test/instance/dev.test.ts @@ -17,18 +17,54 @@ test("uses standalone mode and inheritable preloads for V2 development checkouts directories.push(root, artifacts) await mkdir(join(root, "packages", "cli", "src", "services"), { recursive: true }) await mkdir(join(root, "packages", "tui", "node_modules", "@opentui", "solid"), { recursive: true }) + await mkdir(join(root, "packages", "simulation"), { recursive: true }) await Promise.all([ Bun.write(join(root, "packages", "cli", "src", "index.ts"), ""), Bun.write(join(root, "packages", "cli", "src", "services", "standalone.ts"), ""), Bun.write(join(root, "packages", "tui", "node_modules", "@opentui", "solid", "package.json"), "{}"), + Bun.write(join(root, "packages", "simulation", "package.json"), "{}"), ]) const result = await Effect.runPromise(prepareDev(artifacts, root)) expect(result.command.at(-1)).toBe("--standalone") expect(result.scriptedCommand.at(-1)).toBe(join(root, "packages", "cli", "src", "index.ts")) + expect(result.serviceFlag).toBe("--service") expect(result.preloads).toContain("--conditions=browser") expect(result.preloads).toContain( `--preload=${join(root, "packages", "tui", "node_modules", "@opentui", "solid", "scripts", "preload.js")}`, ) }) + +test("uses the register serve dialect for current V2 development checkouts", async () => { + const root = await mkdtemp(join(tmpdir(), "opencode-drive-dev-")) + const artifacts = await mkdtemp(join(tmpdir(), "opencode-drive-artifacts-")) + directories.push(root, artifacts) + await mkdir(join(root, "packages", "cli", "src"), { recursive: true }) + await mkdir(join(root, "packages", "tui", "node_modules", "@opentui", "solid"), { recursive: true }) + await mkdir(join(root, "packages", "simulation"), { recursive: true }) + await Promise.all([ + Bun.write(join(root, "packages", "cli", "src", "index.ts"), ""), + Bun.write(join(root, "packages", "tui", "node_modules", "@opentui", "solid", "package.json"), "{}"), + Bun.write(join(root, "packages", "simulation", "package.json"), "{}"), + ]) + + const result = await Effect.runPromise(prepareDev(artifacts, root)) + + expect(result.command.at(-1)).toBe(join(root, "packages", "cli", "src", "index.ts")) + expect(result.serviceFlag).toBe("--register") +}) + +test("rejects development checkouts without simulation support", async () => { + const root = await mkdtemp(join(tmpdir(), "opencode-drive-dev-")) + const artifacts = await mkdtemp(join(tmpdir(), "opencode-drive-artifacts-")) + directories.push(root, artifacts) + await mkdir(join(root, "packages", "cli", "src"), { recursive: true }) + await mkdir(join(root, "packages", "tui", "node_modules", "@opentui", "solid"), { recursive: true }) + await Promise.all([ + Bun.write(join(root, "packages", "cli", "src", "index.ts"), ""), + Bun.write(join(root, "packages", "tui", "node_modules", "@opentui", "solid", "package.json"), "{}"), + ]) + + await expect(Effect.runPromise(prepareDev(artifacts, root))).rejects.toThrow("does not include simulation support") +})