diff --git a/packages/opencode/src/session/instruction.ts b/packages/opencode/src/session/instruction.ts
index 9b01c9524f..04f2610dfe 100644
--- a/packages/opencode/src/session/instruction.ts
+++ b/packages/opencode/src/session/instruction.ts
@@ -4,7 +4,6 @@ import { Effect, Layer, Context } from "effect"
import { FetchHttpClient, HttpClient, HttpClientRequest } from "effect/unstable/http"
import { Config } from "@/config/config"
import { InstanceState } from "@/effect/instance-state"
-import { makeRuntime } from "@/effect/run-service"
import { Flag } from "@/flag/flag"
import { AppFileSystem } from "@/filesystem"
import { withTransientReadRetry } from "@/util/effect-http-client"
@@ -238,21 +237,7 @@ export namespace Instruction {
Layer.provide(FetchHttpClient.layer),
)
- const { runPromise } = makeRuntime(Service, defaultLayer)
-
- export function clear(messageID: MessageID) {
- return runPromise((svc) => svc.clear(messageID))
- }
-
- export async function systemPaths() {
- return runPromise((svc) => svc.systemPaths())
- }
-
export function loaded(messages: MessageV2.WithParts[]) {
return extract(messages)
}
-
- export async function resolve(messages: MessageV2.WithParts[], filepath: string, messageID: MessageID) {
- return runPromise((svc) => svc.resolve(messages, filepath, messageID))
- }
}
diff --git a/packages/opencode/test/session/instruction.test.ts b/packages/opencode/test/session/instruction.test.ts
index a8c25c6f0e..4ba3b78e42 100644
--- a/packages/opencode/test/session/instruction.test.ts
+++ b/packages/opencode/test/session/instruction.test.ts
@@ -1,5 +1,6 @@
import { afterEach, beforeEach, describe, expect, test } from "bun:test"
import path from "path"
+import { Effect } from "effect"
import { ModelID, ProviderID } from "../../src/provider/schema"
import { Instruction } from "../../src/session/instruction"
import type { MessageV2 } from "../../src/session/message-v2"
@@ -8,6 +9,9 @@ import { MessageID, PartID, SessionID } from "../../src/session/schema"
import { Global } from "../../src/global"
import { tmpdir } from "../fixture/fixture"
+const run = (effect: Effect.Effect) =>
+ Effect.runPromise(effect.pipe(Effect.provide(Instruction.defaultLayer)))
+
function loaded(filepath: string): MessageV2.WithParts[] {
const sessionID = SessionID.make("session-loaded-1")
const messageID = MessageID.make("message-loaded-1")
@@ -57,17 +61,22 @@ describe("Instruction.resolve", () => {
})
await Instance.provide({
directory: tmp.path,
- fn: async () => {
- const system = await Instruction.systemPaths()
- expect(system.has(path.join(tmp.path, "AGENTS.md"))).toBe(true)
+ fn: () =>
+ run(
+ Instruction.Service.use((svc) =>
+ Effect.gen(function* () {
+ const system = yield* svc.systemPaths()
+ expect(system.has(path.join(tmp.path, "AGENTS.md"))).toBe(true)
- const results = await Instruction.resolve(
- [],
- path.join(tmp.path, "src", "file.ts"),
- MessageID.make("message-test-1"),
- )
- expect(results).toEqual([])
- },
+ const results = yield* svc.resolve(
+ [],
+ path.join(tmp.path, "src", "file.ts"),
+ MessageID.make("message-test-1"),
+ )
+ expect(results).toEqual([])
+ }),
+ ),
+ ),
})
})
@@ -80,18 +89,23 @@ describe("Instruction.resolve", () => {
})
await Instance.provide({
directory: tmp.path,
- fn: async () => {
- const system = await Instruction.systemPaths()
- expect(system.has(path.join(tmp.path, "subdir", "AGENTS.md"))).toBe(false)
+ fn: () =>
+ run(
+ Instruction.Service.use((svc) =>
+ Effect.gen(function* () {
+ const system = yield* svc.systemPaths()
+ expect(system.has(path.join(tmp.path, "subdir", "AGENTS.md"))).toBe(false)
- const results = await Instruction.resolve(
- [],
- path.join(tmp.path, "subdir", "nested", "file.ts"),
- MessageID.make("message-test-2"),
- )
- expect(results.length).toBe(1)
- expect(results[0].filepath).toBe(path.join(tmp.path, "subdir", "AGENTS.md"))
- },
+ const results = yield* svc.resolve(
+ [],
+ path.join(tmp.path, "subdir", "nested", "file.ts"),
+ MessageID.make("message-test-2"),
+ )
+ expect(results.length).toBe(1)
+ expect(results[0].filepath).toBe(path.join(tmp.path, "subdir", "AGENTS.md"))
+ }),
+ ),
+ ),
})
})
@@ -104,14 +118,19 @@ describe("Instruction.resolve", () => {
})
await Instance.provide({
directory: tmp.path,
- fn: async () => {
- const filepath = path.join(tmp.path, "subdir", "AGENTS.md")
- const system = await Instruction.systemPaths()
- expect(system.has(filepath)).toBe(false)
+ fn: () =>
+ run(
+ Instruction.Service.use((svc) =>
+ Effect.gen(function* () {
+ const filepath = path.join(tmp.path, "subdir", "AGENTS.md")
+ const system = yield* svc.systemPaths()
+ expect(system.has(filepath)).toBe(false)
- const results = await Instruction.resolve([], filepath, MessageID.make("message-test-3"))
- expect(results).toEqual([])
- },
+ const results = yield* svc.resolve([], filepath, MessageID.make("message-test-3"))
+ expect(results).toEqual([])
+ }),
+ ),
+ ),
})
})
@@ -124,17 +143,22 @@ describe("Instruction.resolve", () => {
})
await Instance.provide({
directory: tmp.path,
- fn: async () => {
- const filepath = path.join(tmp.path, "subdir", "nested", "file.ts")
- const id = MessageID.make("message-claim-1")
+ fn: () =>
+ run(
+ Instruction.Service.use((svc) =>
+ Effect.gen(function* () {
+ const filepath = path.join(tmp.path, "subdir", "nested", "file.ts")
+ const id = MessageID.make("message-claim-1")
- const first = await Instruction.resolve([], filepath, id)
- const second = await Instruction.resolve([], filepath, id)
+ const first = yield* svc.resolve([], filepath, id)
+ const second = yield* svc.resolve([], filepath, id)
- expect(first).toHaveLength(1)
- expect(first[0].filepath).toBe(path.join(tmp.path, "subdir", "AGENTS.md"))
- expect(second).toEqual([])
- },
+ expect(first).toHaveLength(1)
+ expect(first[0].filepath).toBe(path.join(tmp.path, "subdir", "AGENTS.md"))
+ expect(second).toEqual([])
+ }),
+ ),
+ ),
})
})
@@ -147,18 +171,23 @@ describe("Instruction.resolve", () => {
})
await Instance.provide({
directory: tmp.path,
- fn: async () => {
- const filepath = path.join(tmp.path, "subdir", "nested", "file.ts")
- const id = MessageID.make("message-claim-2")
+ fn: () =>
+ run(
+ Instruction.Service.use((svc) =>
+ Effect.gen(function* () {
+ const filepath = path.join(tmp.path, "subdir", "nested", "file.ts")
+ const id = MessageID.make("message-claim-2")
- const first = await Instruction.resolve([], filepath, id)
- await Instruction.clear(id)
- const second = await Instruction.resolve([], filepath, id)
+ const first = yield* svc.resolve([], filepath, id)
+ yield* svc.clear(id)
+ const second = yield* svc.resolve([], filepath, id)
- expect(first).toHaveLength(1)
- expect(second).toHaveLength(1)
- expect(second[0].filepath).toBe(path.join(tmp.path, "subdir", "AGENTS.md"))
- },
+ expect(first).toHaveLength(1)
+ expect(second).toHaveLength(1)
+ expect(second[0].filepath).toBe(path.join(tmp.path, "subdir", "AGENTS.md"))
+ }),
+ ),
+ ),
})
})
@@ -171,15 +200,19 @@ describe("Instruction.resolve", () => {
})
await Instance.provide({
directory: tmp.path,
- fn: async () => {
- const agents = path.join(tmp.path, "subdir", "AGENTS.md")
- const filepath = path.join(tmp.path, "subdir", "nested", "file.ts")
- const id = MessageID.make("message-claim-3")
+ fn: () =>
+ run(
+ Instruction.Service.use((svc) =>
+ Effect.gen(function* () {
+ const agents = path.join(tmp.path, "subdir", "AGENTS.md")
+ const filepath = path.join(tmp.path, "subdir", "nested", "file.ts")
+ const id = MessageID.make("message-claim-3")
- const results = await Instruction.resolve(loaded(agents), filepath, id)
-
- expect(results).toEqual([])
- },
+ const results = yield* svc.resolve(loaded(agents), filepath, id)
+ expect(results).toEqual([])
+ }),
+ ),
+ ),
})
})
@@ -221,11 +254,16 @@ describe("Instruction.systemPaths OPENCODE_CONFIG_DIR", () => {
try {
await Instance.provide({
directory: projectTmp.path,
- fn: async () => {
- const paths = await Instruction.systemPaths()
- expect(paths.has(path.join(profileTmp.path, "AGENTS.md"))).toBe(true)
- expect(paths.has(path.join(globalTmp.path, "AGENTS.md"))).toBe(false)
- },
+ fn: () =>
+ run(
+ Instruction.Service.use((svc) =>
+ Effect.gen(function* () {
+ const paths = yield* svc.systemPaths()
+ expect(paths.has(path.join(profileTmp.path, "AGENTS.md"))).toBe(true)
+ expect(paths.has(path.join(globalTmp.path, "AGENTS.md"))).toBe(false)
+ }),
+ ),
+ ),
})
} finally {
;(Global.Path as { config: string }).config = originalGlobalConfig
@@ -248,11 +286,16 @@ describe("Instruction.systemPaths OPENCODE_CONFIG_DIR", () => {
try {
await Instance.provide({
directory: projectTmp.path,
- fn: async () => {
- const paths = await Instruction.systemPaths()
- expect(paths.has(path.join(profileTmp.path, "AGENTS.md"))).toBe(false)
- expect(paths.has(path.join(globalTmp.path, "AGENTS.md"))).toBe(true)
- },
+ fn: () =>
+ run(
+ Instruction.Service.use((svc) =>
+ Effect.gen(function* () {
+ const paths = yield* svc.systemPaths()
+ expect(paths.has(path.join(profileTmp.path, "AGENTS.md"))).toBe(false)
+ expect(paths.has(path.join(globalTmp.path, "AGENTS.md"))).toBe(true)
+ }),
+ ),
+ ),
})
} finally {
;(Global.Path as { config: string }).config = originalGlobalConfig
@@ -274,10 +317,15 @@ describe("Instruction.systemPaths OPENCODE_CONFIG_DIR", () => {
try {
await Instance.provide({
directory: projectTmp.path,
- fn: async () => {
- const paths = await Instruction.systemPaths()
- expect(paths.has(path.join(globalTmp.path, "AGENTS.md"))).toBe(true)
- },
+ fn: () =>
+ run(
+ Instruction.Service.use((svc) =>
+ Effect.gen(function* () {
+ const paths = yield* svc.systemPaths()
+ expect(paths.has(path.join(globalTmp.path, "AGENTS.md"))).toBe(true)
+ }),
+ ),
+ ),
})
} finally {
;(Global.Path as { config: string }).config = originalGlobalConfig