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

refactor(cli): drop redundant explicit Effect.ensuring(store.dispose) (#25503)

Kit Langton 3 месяцев назад
Родитель
Сommit
68b3448b09

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

@@ -11,7 +11,6 @@ import { Permission } from "../../../permission"
 import { iife } from "../../../util/iife"
 import { effectCmd, fail } from "../../effect-cmd"
 import { InstanceRef } from "@/effect/instance-ref"
-import { InstanceStore } from "@/project/instance-store"
 import type { InstanceContext } from "@/project/instance"
 
 export const AgentCommand = effectCmd({
@@ -35,8 +34,7 @@ export const AgentCommand = effectCmd({
   handler: Effect.fn("Cli.debug.agent")(function* (args) {
     const ctx = yield* InstanceRef
     if (!ctx) return
-    const store = yield* InstanceStore.Service
-    return yield* run(args, ctx).pipe(Effect.ensuring(store.dispose(ctx)))
+    return yield* run(args, ctx)
   }),
 })
 

+ 2 - 9
packages/opencode/src/cli/cmd/debug/config.ts

@@ -2,20 +2,13 @@ import { EOL } from "os"
 import { Effect } from "effect"
 import { Config } from "@/config/config"
 import { effectCmd } from "../../effect-cmd"
-import { InstanceRef } from "@/effect/instance-ref"
-import { InstanceStore } from "@/project/instance-store"
 
 export const ConfigCommand = effectCmd({
   command: "config",
   describe: "show resolved configuration",
   builder: (yargs) => yargs,
   handler: Effect.fn("Cli.debug.config")(function* () {
-    const ctx = yield* InstanceRef
-    if (!ctx) return
-    const store = yield* InstanceStore.Service
-    return yield* Effect.gen(function* () {
-      const config = yield* Config.Service.use((cfg) => cfg.get())
-      process.stdout.write(JSON.stringify(config, null, 2) + EOL)
-    }).pipe(Effect.ensuring(store.dispose(ctx)))
+    const config = yield* Config.Service.use((cfg) => cfg.get())
+    process.stdout.write(JSON.stringify(config, null, 2) + EOL)
   }),
 })

+ 10 - 37
packages/opencode/src/cli/cmd/debug/file.ts

@@ -4,8 +4,6 @@ import { File } from "../../../file"
 import { Ripgrep } from "@/file/ripgrep"
 import { effectCmd } from "../../effect-cmd"
 import { cmd } from "../cmd"
-import { InstanceRef } from "@/effect/instance-ref"
-import { InstanceStore } from "@/project/instance-store"
 
 const FileSearchCommand = effectCmd({
   command: "search <query>",
@@ -17,13 +15,8 @@ const FileSearchCommand = effectCmd({
       description: "Search query",
     }),
   handler: Effect.fn("Cli.debug.file.search")(function* (args) {
-    const ctx = yield* InstanceRef
-    if (!ctx) return
-    const store = yield* InstanceStore.Service
-    return yield* Effect.gen(function* () {
-      const results = yield* File.Service.use((svc) => svc.search({ query: args.query }))
-      process.stdout.write(results.join(EOL) + EOL)
-    }).pipe(Effect.ensuring(store.dispose(ctx)))
+    const results = yield* File.Service.use((svc) => svc.search({ query: args.query }))
+    process.stdout.write(results.join(EOL) + EOL)
   }),
 })
 
@@ -37,13 +30,8 @@ const FileReadCommand = effectCmd({
       description: "File path to read",
     }),
   handler: Effect.fn("Cli.debug.file.read")(function* (args) {
-    const ctx = yield* InstanceRef
-    if (!ctx) return
-    const store = yield* InstanceStore.Service
-    return yield* Effect.gen(function* () {
-      const content = yield* File.Service.use((svc) => svc.read(args.path))
-      process.stdout.write(JSON.stringify(content, null, 2) + EOL)
-    }).pipe(Effect.ensuring(store.dispose(ctx)))
+    const content = yield* File.Service.use((svc) => svc.read(args.path))
+    process.stdout.write(JSON.stringify(content, null, 2) + EOL)
   }),
 })
 
@@ -52,13 +40,8 @@ const FileStatusCommand = effectCmd({
   describe: "show file status information",
   builder: (yargs) => yargs,
   handler: Effect.fn("Cli.debug.file.status")(function* () {
-    const ctx = yield* InstanceRef
-    if (!ctx) return
-    const store = yield* InstanceStore.Service
-    return yield* Effect.gen(function* () {
-      const status = yield* File.Service.use((svc) => svc.status())
-      process.stdout.write(JSON.stringify(status, null, 2) + EOL)
-    }).pipe(Effect.ensuring(store.dispose(ctx)))
+    const status = yield* File.Service.use((svc) => svc.status())
+    process.stdout.write(JSON.stringify(status, null, 2) + EOL)
   }),
 })
 
@@ -72,13 +55,8 @@ const FileListCommand = effectCmd({
       description: "File path to list",
     }),
   handler: Effect.fn("Cli.debug.file.list")(function* (args) {
-    const ctx = yield* InstanceRef
-    if (!ctx) return
-    const store = yield* InstanceStore.Service
-    return yield* Effect.gen(function* () {
-      const files = yield* File.Service.use((svc) => svc.list(args.path))
-      process.stdout.write(JSON.stringify(files, null, 2) + EOL)
-    }).pipe(Effect.ensuring(store.dispose(ctx)))
+    const files = yield* File.Service.use((svc) => svc.list(args.path))
+    process.stdout.write(JSON.stringify(files, null, 2) + EOL)
   }),
 })
 
@@ -92,13 +70,8 @@ const FileTreeCommand = effectCmd({
       default: process.cwd(),
     }),
   handler: Effect.fn("Cli.debug.file.tree")(function* (args) {
-    const ctx = yield* InstanceRef
-    if (!ctx) return
-    const store = yield* InstanceStore.Service
-    return yield* Effect.gen(function* () {
-      const tree = yield* Effect.orDie(Ripgrep.Service.use((svc) => svc.tree({ cwd: args.dir, limit: 200 })))
-      console.log(JSON.stringify(tree, null, 2))
-    }).pipe(Effect.ensuring(store.dispose(ctx)))
+    const tree = yield* Effect.orDie(Ripgrep.Service.use((svc) => svc.tree({ cwd: args.dir, limit: 200 })))
+    console.log(JSON.stringify(tree, null, 2))
   }),
 })
 

+ 13 - 30
packages/opencode/src/cli/cmd/debug/lsp.ts

@@ -4,8 +4,6 @@ import { effectCmd } from "../../effect-cmd"
 import { cmd } from "../cmd"
 import * as Log from "@opencode-ai/core/util/log"
 import { EOL } from "os"
-import { InstanceRef } from "@/effect/instance-ref"
-import { InstanceStore } from "@/project/instance-store"
 
 export const LSPCommand = cmd({
   command: "lsp",
@@ -20,18 +18,13 @@ const DiagnosticsCommand = effectCmd({
   describe: "get diagnostics for a file",
   builder: (yargs) => yargs.positional("file", { type: "string", demandOption: true }),
   handler: Effect.fn("Cli.debug.lsp.diagnostics")(function* (args) {
-    const ctx = yield* InstanceRef
-    if (!ctx) return
-    const store = yield* InstanceStore.Service
-    return yield* Effect.gen(function* () {
-      const out = yield* LSP.Service.use((lsp) =>
-        Effect.gen(function* () {
-          yield* lsp.touchFile(args.file, "full")
-          return yield* lsp.diagnostics()
-        }),
-      )
-      process.stdout.write(JSON.stringify(out, null, 2) + EOL)
-    }).pipe(Effect.ensuring(store.dispose(ctx)))
+    const out = yield* LSP.Service.use((lsp) =>
+      Effect.gen(function* () {
+        yield* lsp.touchFile(args.file, "full")
+        return yield* lsp.diagnostics()
+      }),
+    )
+    process.stdout.write(JSON.stringify(out, null, 2) + EOL)
   }),
 })
 
@@ -40,14 +33,9 @@ export const SymbolsCommand = effectCmd({
   describe: "search workspace symbols",
   builder: (yargs) => yargs.positional("query", { type: "string", demandOption: true }),
   handler: Effect.fn("Cli.debug.lsp.symbols")(function* (args) {
-    const ctx = yield* InstanceRef
-    if (!ctx) return
-    const store = yield* InstanceStore.Service
-    return yield* Effect.gen(function* () {
-      using _ = Log.Default.time("symbols")
-      const results = yield* LSP.Service.use((lsp) => lsp.workspaceSymbol(args.query))
-      process.stdout.write(JSON.stringify(results, null, 2) + EOL)
-    }).pipe(Effect.ensuring(store.dispose(ctx)))
+    using _ = Log.Default.time("symbols")
+    const results = yield* LSP.Service.use((lsp) => lsp.workspaceSymbol(args.query))
+    process.stdout.write(JSON.stringify(results, null, 2) + EOL)
   }),
 })
 
@@ -56,13 +44,8 @@ export const DocumentSymbolsCommand = effectCmd({
   describe: "get symbols from a document",
   builder: (yargs) => yargs.positional("uri", { type: "string", demandOption: true }),
   handler: Effect.fn("Cli.debug.lsp.documentSymbols")(function* (args) {
-    const ctx = yield* InstanceRef
-    if (!ctx) return
-    const store = yield* InstanceStore.Service
-    return yield* Effect.gen(function* () {
-      using _ = Log.Default.time("document-symbols")
-      const results = yield* LSP.Service.use((lsp) => lsp.documentSymbol(args.uri))
-      process.stdout.write(JSON.stringify(results, null, 2) + EOL)
-    }).pipe(Effect.ensuring(store.dispose(ctx)))
+    using _ = Log.Default.time("document-symbols")
+    const results = yield* LSP.Service.use((lsp) => lsp.documentSymbol(args.uri))
+    process.stdout.write(JSON.stringify(results, null, 2) + EOL)
   }),
 })

+ 28 - 38
packages/opencode/src/cli/cmd/debug/ripgrep.ts

@@ -4,7 +4,6 @@ import { Ripgrep } from "../../../file/ripgrep"
 import { effectCmd } from "../../effect-cmd"
 import { cmd } from "../cmd"
 import { InstanceRef } from "@/effect/instance-ref"
-import { InstanceStore } from "@/project/instance-store"
 
 export const RipgrepCommand = cmd({
   command: "rg",
@@ -23,13 +22,10 @@ const TreeCommand = effectCmd({
   handler: Effect.fn("Cli.debug.rg.tree")(function* (args) {
     const ctx = yield* InstanceRef
     if (!ctx) return
-    const store = yield* InstanceStore.Service
-    return yield* Effect.gen(function* () {
-      const tree = yield* Effect.orDie(
-        Ripgrep.Service.use((svc) => svc.tree({ cwd: ctx.directory, limit: args.limit })),
-      )
-      process.stdout.write(tree + EOL)
-    }).pipe(Effect.ensuring(store.dispose(ctx)))
+    const tree = yield* Effect.orDie(
+      Ripgrep.Service.use((svc) => svc.tree({ cwd: ctx.directory, limit: args.limit })),
+    )
+    process.stdout.write(tree + EOL)
   }),
 })
 
@@ -53,22 +49,19 @@ const FilesCommand = effectCmd({
   handler: Effect.fn("Cli.debug.rg.files")(function* (args) {
     const ctx = yield* InstanceRef
     if (!ctx) return
-    const store = yield* InstanceStore.Service
-    return yield* Effect.gen(function* () {
-      const rg = yield* Ripgrep.Service
-      const files = yield* rg
-        .files({
-          cwd: ctx.directory,
-          glob: args.glob ? [args.glob] : undefined,
-        })
-        .pipe(
-          Stream.take(args.limit ?? Infinity),
-          Stream.runCollect,
-          Effect.map((c) => [...c]),
-          Effect.orDie,
-        )
-      process.stdout.write(files.join(EOL) + EOL)
-    }).pipe(Effect.ensuring(store.dispose(ctx)))
+    const rg = yield* Ripgrep.Service
+    const files = yield* rg
+      .files({
+        cwd: ctx.directory,
+        glob: args.glob ? [args.glob] : undefined,
+      })
+      .pipe(
+        Stream.take(args.limit ?? Infinity),
+        Stream.runCollect,
+        Effect.map((c) => [...c]),
+        Effect.orDie,
+      )
+    process.stdout.write(files.join(EOL) + EOL)
   }),
 })
 
@@ -93,19 +86,16 @@ const SearchCommand = effectCmd({
   handler: Effect.fn("Cli.debug.rg.search")(function* (args) {
     const ctx = yield* InstanceRef
     if (!ctx) return
-    const store = yield* InstanceStore.Service
-    return yield* Effect.gen(function* () {
-      const results = yield* Effect.orDie(
-        Ripgrep.Service.use((svc) =>
-          svc.search({
-            cwd: ctx.directory,
-            pattern: args.pattern,
-            glob: args.glob as string[] | undefined,
-            limit: args.limit,
-          }),
-        ),
-      )
-      process.stdout.write(JSON.stringify(results.items, null, 2) + EOL)
-    }).pipe(Effect.ensuring(store.dispose(ctx)))
+    const results = yield* Effect.orDie(
+      Ripgrep.Service.use((svc) =>
+        svc.search({
+          cwd: ctx.directory,
+          pattern: args.pattern,
+          glob: args.glob as string[] | undefined,
+          limit: args.limit,
+        }),
+      ),
+    )
+    process.stdout.write(JSON.stringify(results.items, null, 2) + EOL)
   }),
 })

+ 3 - 10
packages/opencode/src/cli/cmd/debug/skill.ts

@@ -2,21 +2,14 @@ import { EOL } from "os"
 import { Effect } from "effect"
 import { Skill } from "../../../skill"
 import { effectCmd } from "../../effect-cmd"
-import { InstanceRef } from "@/effect/instance-ref"
-import { InstanceStore } from "@/project/instance-store"
 
 export const SkillCommand = effectCmd({
   command: "skill",
   describe: "list all available skills",
   builder: (yargs) => yargs,
   handler: Effect.fn("Cli.debug.skill")(function* () {
-    const ctx = yield* InstanceRef
-    if (!ctx) return
-    const store = yield* InstanceStore.Service
-    return yield* Effect.gen(function* () {
-      const skill = yield* Skill.Service
-      const skills = yield* skill.all()
-      process.stdout.write(JSON.stringify(skills, null, 2) + EOL)
-    }).pipe(Effect.ensuring(store.dispose(ctx)))
+    const skill = yield* Skill.Service
+    const skills = yield* skill.all()
+    process.stdout.write(JSON.stringify(skills, null, 2) + EOL)
   }),
 })

+ 6 - 23
packages/opencode/src/cli/cmd/debug/snapshot.ts

@@ -2,8 +2,6 @@ import { Effect } from "effect"
 import { Snapshot } from "../../../snapshot"
 import { effectCmd } from "../../effect-cmd"
 import { cmd } from "../cmd"
-import { InstanceRef } from "@/effect/instance-ref"
-import { InstanceStore } from "@/project/instance-store"
 
 export const SnapshotCommand = cmd({
   command: "snapshot",
@@ -16,13 +14,8 @@ const TrackCommand = effectCmd({
   command: "track",
   describe: "track current snapshot state",
   handler: Effect.fn("Cli.debug.snapshot.track")(function* () {
-    const ctx = yield* InstanceRef
-    if (!ctx) return
-    const store = yield* InstanceStore.Service
-    return yield* Effect.gen(function* () {
-      const out = yield* Snapshot.Service.use((svc) => svc.track())
-      console.log(out)
-    }).pipe(Effect.ensuring(store.dispose(ctx)))
+    const out = yield* Snapshot.Service.use((svc) => svc.track())
+    console.log(out)
   }),
 })
 
@@ -36,13 +29,8 @@ const PatchCommand = effectCmd({
       demandOption: true,
     }),
   handler: Effect.fn("Cli.debug.snapshot.patch")(function* (args) {
-    const ctx = yield* InstanceRef
-    if (!ctx) return
-    const store = yield* InstanceStore.Service
-    return yield* Effect.gen(function* () {
-      const out = yield* Snapshot.Service.use((svc) => svc.patch(args.hash))
-      console.log(out)
-    }).pipe(Effect.ensuring(store.dispose(ctx)))
+    const out = yield* Snapshot.Service.use((svc) => svc.patch(args.hash))
+    console.log(out)
   }),
 })
 
@@ -56,12 +44,7 @@ const DiffCommand = effectCmd({
       demandOption: true,
     }),
   handler: Effect.fn("Cli.debug.snapshot.diff")(function* (args) {
-    const ctx = yield* InstanceRef
-    if (!ctx) return
-    const store = yield* InstanceStore.Service
-    return yield* Effect.gen(function* () {
-      const out = yield* Snapshot.Service.use((svc) => svc.diff(args.hash))
-      console.log(out)
-    }).pipe(Effect.ensuring(store.dispose(ctx)))
+    const out = yield* Snapshot.Service.use((svc) => svc.diff(args.hash))
+    console.log(out)
   }),
 })

+ 1 - 6
packages/opencode/src/cli/cmd/export.ts

@@ -6,8 +6,6 @@ import { UI } from "../ui"
 import * as prompts from "@clack/prompts"
 import { EOL } from "os"
 import { Effect } from "effect"
-import { InstanceRef } from "@/effect/instance-ref"
-import { InstanceStore } from "@/project/instance-store"
 
 function redact(kind: string, id: string, value: string) {
   return value.trim() ? `[redacted:${kind}:${id}]` : value
@@ -234,10 +232,7 @@ export const ExportCommand = effectCmd({
         type: "boolean",
       }),
   handler: Effect.fn("Cli.export")(function* (args) {
-    const ctx = yield* InstanceRef
-    if (!ctx) return
-    const store = yield* InstanceStore.Service
-    return yield* run(args).pipe(Effect.ensuring(store.dispose(ctx)))
+    return yield* run(args)
   }),
 })
 

+ 1 - 6
packages/opencode/src/cli/cmd/import.ts

@@ -5,7 +5,6 @@ import { CliError, effectCmd } from "../effect-cmd"
 import { Database } from "@/storage/db"
 import { SessionTable, MessageTable, PartTable } from "../../session/session.sql"
 import { InstanceRef } from "@/effect/instance-ref"
-import { InstanceStore } from "@/project/instance-store"
 import { ShareNext } from "@/share/share-next"
 import { EOL } from "os"
 import { Filesystem } from "@/util/filesystem"
@@ -88,13 +87,9 @@ export const ImportCommand = effectCmd({
       demandOption: true,
     }),
   handler: Effect.fn("Cli.import")(function* (args) {
-    // effectCmd always provides InstanceRef via InstanceStore.Service.provide; this is an invariant.
     const ctx = yield* InstanceRef
     if (!ctx) return yield* Effect.die("InstanceRef not provided")
-    const store = yield* InstanceStore.Service
-    // Ensure store.dispose runs disposers and emits server.instance.disposed
-    // on every exit path: success, early return, typed failure, defect, interrupt.
-    return yield* runImport(args.file, ctx.project.id).pipe(Effect.ensuring(store.dispose(ctx)))
+    return yield* runImport(args.file, ctx.project.id)
   }),
 })
 

+ 33 - 45
packages/opencode/src/cli/cmd/session.ts

@@ -12,8 +12,6 @@ import { Process } from "@/util/process"
 import { EOL } from "os"
 import path from "path"
 import { which } from "../../util/which"
-import { InstanceRef } from "@/effect/instance-ref"
-import { InstanceStore } from "@/project/instance-store"
 
 function pagerCmd(): string[] {
   const lessOptions = ["-R", "-S"]
@@ -59,17 +57,12 @@ export const SessionDeleteCommand = effectCmd({
       demandOption: true,
     }),
   handler: Effect.fn("Cli.session.delete")(function* (args) {
-    const ctx = yield* InstanceRef
-    if (!ctx) return
-    const store = yield* InstanceStore.Service
-    return yield* Effect.gen(function* () {
-      const svc = yield* Session.Service
-      const sessionID = SessionID.make(args.sessionID)
-      // Match legacy try/catch — Session.get surfaces NotFoundError as a defect.
-      yield* svc.get(sessionID).pipe(Effect.catchCause(() => fail(`Session not found: ${args.sessionID}`)))
-      yield* svc.remove(sessionID)
-      UI.println(UI.Style.TEXT_SUCCESS_BOLD + `Session ${args.sessionID} deleted` + UI.Style.TEXT_NORMAL)
-    }).pipe(Effect.ensuring(store.dispose(ctx)))
+    const svc = yield* Session.Service
+    const sessionID = SessionID.make(args.sessionID)
+    // Match legacy try/catch — Session.get surfaces NotFoundError as a defect.
+    yield* svc.get(sessionID).pipe(Effect.catchCause(() => fail(`Session not found: ${args.sessionID}`)))
+    yield* svc.remove(sessionID)
+    UI.println(UI.Style.TEXT_SUCCESS_BOLD + `Session ${args.sessionID} deleted` + UI.Style.TEXT_NORMAL)
   }),
 })
 
@@ -90,39 +83,34 @@ export const SessionListCommand = effectCmd({
         default: "table",
       }),
   handler: Effect.fn("Cli.session.list")(function* (args) {
-    const ctx = yield* InstanceRef
-    if (!ctx) return
-    const store = yield* InstanceStore.Service
-    return yield* Effect.gen(function* () {
-      const sessions = yield* Session.Service.use((svc) => svc.list({ roots: true, limit: args.maxCount }))
-
-      if (sessions.length === 0) return
-
-      const output = args.format === "json" ? formatSessionJSON(sessions) : formatSessionTable(sessions)
-
-      const shouldPaginate = process.stdout.isTTY && !args.maxCount && args.format === "table"
-
-      if (shouldPaginate) {
-        yield* Effect.promise(async () => {
-          const proc = Process.spawn(pagerCmd(), {
-            stdin: "pipe",
-            stdout: "inherit",
-            stderr: "inherit",
-          })
-
-          if (!proc.stdin) {
-            console.log(output)
-            return
-          }
-
-          proc.stdin.write(output)
-          proc.stdin.end()
-          await proc.exited
+    const sessions = yield* Session.Service.use((svc) => svc.list({ roots: true, limit: args.maxCount }))
+
+    if (sessions.length === 0) return
+
+    const output = args.format === "json" ? formatSessionJSON(sessions) : formatSessionTable(sessions)
+
+    const shouldPaginate = process.stdout.isTTY && !args.maxCount && args.format === "table"
+
+    if (shouldPaginate) {
+      yield* Effect.promise(async () => {
+        const proc = Process.spawn(pagerCmd(), {
+          stdin: "pipe",
+          stdout: "inherit",
+          stderr: "inherit",
         })
-      } else {
-        console.log(output)
-      }
-    }).pipe(Effect.ensuring(store.dispose(ctx)))
+
+        if (!proc.stdin) {
+          console.log(output)
+          return
+        }
+
+        proc.stdin.write(output)
+        proc.stdin.end()
+        await proc.exited
+      })
+    } else {
+      console.log(output)
+    }
   }),
 })
 

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

@@ -5,7 +5,6 @@ import { Database } from "@/storage/db"
 import { SessionTable } from "../../session/session.sql"
 import { Project } from "@/project/project"
 import { InstanceRef } from "@/effect/instance-ref"
-import { InstanceStore } from "@/project/instance-store"
 import { AppRuntime } from "@/effect/app-runtime"
 
 interface SessionStats {
@@ -70,8 +69,7 @@ export const StatsCommand = effectCmd({
   handler: Effect.fn("Cli.stats")(function* (args) {
     const ctx = yield* InstanceRef
     if (!ctx) return
-    const store = yield* InstanceStore.Service
-    return yield* run(args, ctx.project).pipe(Effect.ensuring(store.dispose(ctx)))
+    return yield* run(args, ctx.project)
   }),
 })