Files
opencode/packages/core/test/command.test.ts
T
2026-08-19 20:13:52 -04:00

72 lines
2.4 KiB
TypeScript

import { describe, expect } from "bun:test"
import { Command } from "@opencode-ai/core/command"
import { AppNodeBuilder } from "@opencode-ai/core/effect/app-node-builder"
import { Session } from "@opencode-ai/schema/session"
import { Effect } from "effect"
import { testEffect } from "./lib/effect"
const it = testEffect(AppNodeBuilder.build(Command.node))
describe("Command", () => {
it.effect("registers and executes callback commands", () =>
Effect.gen(function* () {
const command = yield* Command.Service
const calls: Command.Invocation[] = []
yield* command.transform((draft) => {
draft.add({
name: "goal",
description: "Manage the session goal",
execute: (input) => Effect.sync(() => calls.push(input)),
})
})
expect(yield* command.get("goal")).toEqual(
Command.Info.make({ name: "goal", description: "Manage the session goal" }),
)
const invocation = {
sessionID: Session.ID.make("ses_test"),
prompt: { text: "ship it", files: [{ uri: "file:///tmp/plan.md" }] },
delivery: "steer" as const,
}
yield* command.execute({ name: "goal", invocation })
expect(calls).toEqual([invocation])
}),
)
it.effect("replaces commands with later definitions", () =>
Effect.gen(function* () {
const command = yield* Command.Service
yield* command.transform((draft) => {
draft.add({ name: "goal", description: "First", execute: () => Effect.void })
draft.add({ name: "goal", description: "Second", execute: () => Effect.void })
})
expect(yield* command.list()).toEqual([Command.Info.make({ name: "goal", description: "Second" })])
}),
)
it.effect("returns callback error messages without stack traces", () =>
Effect.gen(function* () {
const command = yield* Command.Service
yield* command.transform((draft) => {
draft.add({
name: "fail",
execute: () => Effect.fail(new Error("command failed")),
})
})
const error = yield* command
.execute({
name: "fail",
invocation: {
sessionID: Session.ID.make("ses_test"),
prompt: { text: "" },
delivery: "steer",
},
})
.pipe(Effect.flip)
expect(error).toMatchObject({ _tag: "Command.ExecutionError", message: "command failed" })
}),
)
})