summaryrefslogtreecommitdiffhomepage
path: root/packages
diff options
context:
space:
mode:
authorKit Langton <[email protected]>2026-05-02 18:15:28 -0400
committerGitHub <[email protected]>2026-05-02 18:15:28 -0400
commit1986a6e81775b5a716c44ae0b6fc4ba8d1ef32cc (patch)
tree8056a0f9a0a33f4b71e948a1c812b7763ccfdae8 /packages
parentdfe1325fca27612bab879102eb8974270cc13407 (diff)
downloadopencode-1986a6e81775b5a716c44ae0b6fc4ba8d1ef32cc.tar.gz
opencode-1986a6e81775b5a716c44ae0b6fc4ba8d1ef32cc.zip
refactor(cli): convert session subcommands to effectCmd (#25483)
Diffstat (limited to 'packages')
-rw-r--r--packages/opencode/src/cli/cmd/session.ts102
1 files changed, 49 insertions, 53 deletions
diff --git a/packages/opencode/src/cli/cmd/session.ts b/packages/opencode/src/cli/cmd/session.ts
index 52a3d7204..dbf27ccc6 100644
--- a/packages/opencode/src/cli/cmd/session.ts
+++ b/packages/opencode/src/cli/cmd/session.ts
@@ -1,8 +1,9 @@
import type { Argv } from "yargs"
+import { Effect } from "effect"
import { cmd } from "./cmd"
+import { effectCmd, fail } from "../effect-cmd"
import { Session } from "@/session/session"
import { SessionID } from "../../session/schema"
-import { bootstrap } from "../bootstrap"
import { UI } from "../ui"
import { Locale } from "@/util/locale"
import { Flag } from "@opencode-ai/core/flag/flag"
@@ -11,7 +12,8 @@ import { Process } from "@/util/process"
import { EOL } from "os"
import path from "path"
import { which } from "../../util/which"
-import { AppRuntime } from "@/effect/app-runtime"
+import { InstanceRef } from "@/effect/instance-ref"
+import { InstanceStore } from "@/project/instance-store"
function pagerCmd(): string[] {
const lessOptions = ["-R", "-S"]
@@ -47,36 +49,35 @@ export const SessionCommand = cmd({
async handler() {},
})
-export const SessionDeleteCommand = cmd({
+export const SessionDeleteCommand = effectCmd({
command: "delete <sessionID>",
describe: "delete a session",
- builder: (yargs: Argv) => {
- return yargs.positional("sessionID", {
+ builder: (yargs) =>
+ yargs.positional("sessionID", {
describe: "session ID to delete",
type: "string",
demandOption: true,
- })
- },
- handler: async (args) => {
- await bootstrap(process.cwd(), async () => {
+ }),
+ 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)
- try {
- await AppRuntime.runPromise(Session.Service.use((svc) => svc.get(sessionID)))
- } catch {
- UI.error(`Session not found: ${args.sessionID}`)
- process.exit(1)
- }
- await AppRuntime.runPromise(Session.Service.use((svc) => svc.remove(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)))
+ }),
})
-export const SessionListCommand = cmd({
+export const SessionListCommand = effectCmd({
command: "list",
describe: "list sessions",
- builder: (yargs: Argv) => {
- return yargs
+ builder: (yargs) =>
+ yargs
.option("max-count", {
alias: "n",
describe: "limit to N most recent sessions",
@@ -87,47 +88,42 @@ export const SessionListCommand = cmd({
type: "string",
choices: ["table", "json"],
default: "table",
- })
- },
- handler: async (args) => {
- await bootstrap(process.cwd(), async () => {
- const sessions = await AppRuntime.runPromise(
- Session.Service.use((svc) => svc.list({ roots: true, limit: args.maxCount })),
- )
-
- if (sessions.length === 0) {
- return
- }
+ }),
+ 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 }))
- let output: string
- if (args.format === "json") {
- output = formatSessionJSON(sessions)
- } else {
- output = formatSessionTable(sessions)
- }
+ 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) {
- const proc = Process.spawn(pagerCmd(), {
- stdin: "pipe",
- stdout: "inherit",
- stderr: "inherit",
+ 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
})
-
- if (!proc.stdin) {
- console.log(output)
- return
- }
-
- proc.stdin.write(output)
- proc.stdin.end()
- await proc.exited
} else {
console.log(output)
}
- })
- },
+ }).pipe(Effect.ensuring(store.dispose(ctx)))
+ }),
})
function formatSessionTable(sessions: Session.Info[]): string {