Просмотр исходного кода

fix(cli): preserve instance context in async commands

Dax Raad 3 месяцев назад
Родитель
Сommit
6d2219e001
2 измененных файлов с 13 добавлено и 8 удалено
  1. 3 1
      packages/opencode/src/cli/cmd/agent.ts
  2. 10 7
      packages/opencode/src/cli/cmd/github.ts

+ 3 - 1
packages/opencode/src/cli/cmd/agent.ts

@@ -66,6 +66,8 @@ const AgentCreateCommand = effectCmd({
     if (!maybeCtx) return yield* Effect.die("InstanceRef not provided")
     const ctx = maybeCtx
     const agentSvc = yield* Agent.Service
+    const runLocalEffect = <A, E>(effect: Effect.Effect<A, E>) =>
+      Effect.runPromise(effect.pipe(Effect.provideService(InstanceRef, ctx)))
     yield* Effect.promise(async () => {
       const cliPath = args.path
       const cliDescription = args.description
@@ -127,7 +129,7 @@ const AgentCreateCommand = effectCmd({
       const spinner = prompts.spinner()
       spinner.start("Generating agent configuration...")
       const model = args.model ? Provider.parseModel(args.model) : undefined
-      const generated = await Effect.runPromise(agentSvc.generate({ description, model })).catch((error) => {
+      const generated = await runLocalEffect(agentSvc.generate({ description, model })).catch((error) => {
         spinner.stop(`LLM failed to generate agent: ${error.message}`, 1)
         if (isFullyNonInteractive) process.exit(1)
         throw new UI.CancelledError()

+ 10 - 7
packages/opencode/src/cli/cmd/github.ts

@@ -435,6 +435,9 @@ export const GithubRunCommand = effectCmd({
     const sessionSvc = yield* Session.Service
     const sessionShare = yield* SessionShare.Service
     const sessionPrompt = yield* SessionPrompt.Service
+    const busSvc = yield* Bus.Service
+    const runLocalEffect = <A, E>(effect: Effect.Effect<A, E>) =>
+      Effect.runPromise(effect.pipe(Effect.provideService(InstanceRef, ctx)))
     yield* Effect.promise(async () => {
       const isMock = args.token || args.event
 
@@ -548,7 +551,7 @@ export const GithubRunCommand = effectCmd({
 
         // Setup opencode session
         const repoData = await fetchRepo()
-        session = await Effect.runPromise(
+        session = await runLocalEffect(
           sessionSvc.create({
             permission: [
               {
@@ -559,11 +562,11 @@ export const GithubRunCommand = effectCmd({
             ],
           }),
         )
-        subscribeSessionEvents()
+        await subscribeSessionEvents()
         shareId = await (async () => {
           if (share === false) return
           if (!share && repoData.data.private) return
-          await Effect.runPromise(sessionShare.share(session.id))
+          await runLocalEffect(sessionShare.share(session.id))
           return session.id.slice(-8)
         })()
         console.log("opencode session", session.id)
@@ -870,7 +873,7 @@ export const GithubRunCommand = effectCmd({
         return { userPrompt: prompt, promptFiles: imgData }
       }
 
-      function subscribeSessionEvents() {
+      async function subscribeSessionEvents() {
         const TOOL: Record<string, [string, string]> = {
           todowrite: ["Todo", UI.Style.TEXT_WARNING_BOLD],
           bash: ["Shell", UI.Style.TEXT_DANGER_BOLD],
@@ -893,7 +896,7 @@ export const GithubRunCommand = effectCmd({
         }
 
         let text = ""
-        Bus.subscribe(MessageV2.Event.PartUpdated, (evt) => {
+        await runLocalEffect(busSvc.subscribeCallback(MessageV2.Event.PartUpdated, (evt) => {
           if (evt.properties.part.sessionID !== session.id) return
           //if (evt.properties.part.messageID === messageID) return
           const part = evt.properties.part
@@ -919,7 +922,7 @@ export const GithubRunCommand = effectCmd({
               return
             }
           }
-        })
+        }))
       }
 
       async function summarize(response: string) {
@@ -936,7 +939,7 @@ export const GithubRunCommand = effectCmd({
       async function chat(message: string, files: PromptFiles = []) {
         console.log("Sending message to opencode...")
 
-        return Effect.runPromise(
+        return runLocalEffect(
           Effect.gen(function* () {
             const prompt = sessionPrompt
             const result = yield* prompt.prompt({