mirror of
https://github.com/anomalyco/opencode.git
synced 2026-05-23 21:04:36 +00:00
chore: generate
This commit is contained in:
@@ -191,8 +191,8 @@ describe("run entry body", () => {
|
||||
deletions: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
] satisfies Array<{ name: string; commit: StreamCommit; snapshot: ToolSnapshot }>) {
|
||||
test(item.name, () => {
|
||||
expect(structured(item.commit)).toEqual(item.snapshot)
|
||||
@@ -335,26 +335,16 @@ describe("run entry body", () => {
|
||||
tool: "bash",
|
||||
phase: "progress",
|
||||
toolState: "completed",
|
||||
text: [
|
||||
"/tmp/demo",
|
||||
"git status",
|
||||
"On branch demo",
|
||||
"nothing to commit, working tree clean",
|
||||
"",
|
||||
].join("\n"),
|
||||
text: ["/tmp/demo", "git status", "On branch demo", "nothing to commit, working tree clean", ""].join("\n"),
|
||||
state: {
|
||||
status: "completed",
|
||||
input: {
|
||||
command: "git status",
|
||||
workdir: "/tmp/demo",
|
||||
},
|
||||
output: [
|
||||
"/tmp/demo",
|
||||
"git status",
|
||||
"On branch demo",
|
||||
"nothing to commit, working tree clean",
|
||||
"",
|
||||
].join("\n"),
|
||||
output: ["/tmp/demo", "git status", "On branch demo", "nothing to commit, working tree clean", ""].join(
|
||||
"\n",
|
||||
),
|
||||
title: "git status",
|
||||
metadata: {
|
||||
exitCode: 0,
|
||||
|
||||
@@ -2,7 +2,12 @@
|
||||
import { expect, test } from "bun:test"
|
||||
import { testRender } from "@opentui/solid"
|
||||
import { createSignal } from "solid-js"
|
||||
import { RUN_COMMAND_PANEL_ROWS, RunCommandMenuBody, RunModelSelectBody, RunVariantSelectBody } from "@/cli/cmd/run/footer.command"
|
||||
import {
|
||||
RUN_COMMAND_PANEL_ROWS,
|
||||
RunCommandMenuBody,
|
||||
RunModelSelectBody,
|
||||
RunVariantSelectBody,
|
||||
} from "@/cli/cmd/run/footer.command"
|
||||
import { RunEntryContent } from "@/cli/cmd/run/scrollback.writer"
|
||||
import { RUN_THEME_FALLBACK } from "@/cli/cmd/run/theme"
|
||||
import type { FooterKeybinds, RunCommand, RunInput, RunProvider, StreamCommit } from "@/cli/cmd/run/types"
|
||||
@@ -117,14 +122,17 @@ test("run entry content updates when live commit text changes", async () => {
|
||||
tool: "bash",
|
||||
})
|
||||
|
||||
const app = await testRender(() => (
|
||||
<box width={80} height={4}>
|
||||
<RunEntryContent commit={commit()} theme={RUN_THEME_FALLBACK} width={80} />
|
||||
</box>
|
||||
), {
|
||||
width: 80,
|
||||
height: 4,
|
||||
})
|
||||
const app = await testRender(
|
||||
() => (
|
||||
<box width={80} height={4}>
|
||||
<RunEntryContent commit={commit()} theme={RUN_THEME_FALLBACK} width={80} />
|
||||
</box>
|
||||
),
|
||||
{
|
||||
width: 80,
|
||||
height: 4,
|
||||
},
|
||||
)
|
||||
|
||||
try {
|
||||
await app.renderOnce()
|
||||
@@ -155,26 +163,29 @@ test("direct command panel renders grouped command palette", async () => {
|
||||
])
|
||||
const [variants] = createSignal(["high", "minimal"])
|
||||
|
||||
const app = await testRender(() => (
|
||||
<box width={100} height={RUN_COMMAND_PANEL_ROWS}>
|
||||
<RunCommandMenuBody
|
||||
theme={() => RUN_THEME_FALLBACK.footer}
|
||||
commands={commands}
|
||||
variants={variants}
|
||||
keybinds={keybinds}
|
||||
onClose={() => {}}
|
||||
onModel={() => {}}
|
||||
onVariant={() => {}}
|
||||
onVariantCycle={() => {}}
|
||||
onCommand={() => {}}
|
||||
onNew={() => {}}
|
||||
onExit={() => {}}
|
||||
/>
|
||||
</box>
|
||||
), {
|
||||
width: 100,
|
||||
height: RUN_COMMAND_PANEL_ROWS,
|
||||
})
|
||||
const app = await testRender(
|
||||
() => (
|
||||
<box width={100} height={RUN_COMMAND_PANEL_ROWS}>
|
||||
<RunCommandMenuBody
|
||||
theme={() => RUN_THEME_FALLBACK.footer}
|
||||
commands={commands}
|
||||
variants={variants}
|
||||
keybinds={keybinds}
|
||||
onClose={() => {}}
|
||||
onModel={() => {}}
|
||||
onVariant={() => {}}
|
||||
onVariantCycle={() => {}}
|
||||
onCommand={() => {}}
|
||||
onNew={() => {}}
|
||||
onExit={() => {}}
|
||||
/>
|
||||
</box>
|
||||
),
|
||||
{
|
||||
width: 100,
|
||||
height: RUN_COMMAND_PANEL_ROWS,
|
||||
},
|
||||
)
|
||||
|
||||
try {
|
||||
await app.renderOnce()
|
||||
@@ -207,20 +218,23 @@ test("direct model panel renders current model selector", async () => {
|
||||
const [providers] = createSignal<RunProvider[] | undefined>([provider()])
|
||||
const [current] = createSignal<RunInput["model"]>({ providerID: "opencode", modelID: "gpt-5" })
|
||||
|
||||
const app = await testRender(() => (
|
||||
<box width={100} height={RUN_COMMAND_PANEL_ROWS}>
|
||||
<RunModelSelectBody
|
||||
theme={() => RUN_THEME_FALLBACK.footer}
|
||||
providers={providers}
|
||||
current={current}
|
||||
onClose={() => {}}
|
||||
onSelect={() => {}}
|
||||
/>
|
||||
</box>
|
||||
), {
|
||||
width: 100,
|
||||
height: RUN_COMMAND_PANEL_ROWS,
|
||||
})
|
||||
const app = await testRender(
|
||||
() => (
|
||||
<box width={100} height={RUN_COMMAND_PANEL_ROWS}>
|
||||
<RunModelSelectBody
|
||||
theme={() => RUN_THEME_FALLBACK.footer}
|
||||
providers={providers}
|
||||
current={current}
|
||||
onClose={() => {}}
|
||||
onSelect={() => {}}
|
||||
/>
|
||||
</box>
|
||||
),
|
||||
{
|
||||
width: 100,
|
||||
height: RUN_COMMAND_PANEL_ROWS,
|
||||
},
|
||||
)
|
||||
|
||||
try {
|
||||
await app.renderOnce()
|
||||
@@ -243,20 +257,23 @@ test("direct variant panel renders current variant selector", async () => {
|
||||
const [variants] = createSignal(["high", "minimal"])
|
||||
const [current] = createSignal<string | undefined>("high")
|
||||
|
||||
const app = await testRender(() => (
|
||||
<box width={100} height={RUN_COMMAND_PANEL_ROWS}>
|
||||
<RunVariantSelectBody
|
||||
theme={() => RUN_THEME_FALLBACK.footer}
|
||||
variants={variants}
|
||||
current={current}
|
||||
onClose={() => {}}
|
||||
onSelect={() => {}}
|
||||
/>
|
||||
</box>
|
||||
), {
|
||||
width: 100,
|
||||
height: RUN_COMMAND_PANEL_ROWS,
|
||||
})
|
||||
const app = await testRender(
|
||||
() => (
|
||||
<box width={100} height={RUN_COMMAND_PANEL_ROWS}>
|
||||
<RunVariantSelectBody
|
||||
theme={() => RUN_THEME_FALLBACK.footer}
|
||||
variants={variants}
|
||||
current={current}
|
||||
onClose={() => {}}
|
||||
onSelect={() => {}}
|
||||
/>
|
||||
</box>
|
||||
),
|
||||
{
|
||||
width: 100,
|
||||
height: RUN_COMMAND_PANEL_ROWS,
|
||||
},
|
||||
)
|
||||
|
||||
try {
|
||||
await app.renderOnce()
|
||||
|
||||
@@ -7,11 +7,7 @@ import { TuiConfig, type Resolved } from "@/cli/cmd/tui/config/tui"
|
||||
import { formatBindings } from "@/cli/cmd/run/keymap.shared"
|
||||
import { KeymapSectionNames, keymapBindingDefaults, type KeymapSection } from "@/cli/cmd/tui/config/tui-schema"
|
||||
import { ConfigKeybinds } from "@/config/keybinds"
|
||||
import {
|
||||
resolveDiffStyle,
|
||||
resolveFooterKeybinds,
|
||||
resolveModelInfo,
|
||||
} from "@/cli/cmd/run/runtime.boot"
|
||||
import { resolveDiffStyle, resolveFooterKeybinds, resolveModelInfo } from "@/cli/cmd/run/runtime.boot"
|
||||
|
||||
type RunBinding = Binding<Renderable, KeyEvent>
|
||||
|
||||
@@ -299,5 +295,4 @@ describe("run runtime boot", () => {
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
@@ -58,10 +58,12 @@ function destroy(commits: ClaimedCommit[]) {
|
||||
}
|
||||
}
|
||||
|
||||
async function setup(input: {
|
||||
width?: number
|
||||
wrote?: boolean
|
||||
} = {}) {
|
||||
async function setup(
|
||||
input: {
|
||||
width?: number
|
||||
wrote?: boolean
|
||||
} = {},
|
||||
) {
|
||||
const out = await createTestRenderer({
|
||||
width: input.width ?? 80,
|
||||
screenMode: "split-footer",
|
||||
@@ -150,7 +152,8 @@ function toolCommit(input: {
|
||||
}
|
||||
|
||||
test("finalizes markdown tables for streamed and coalesced input", async () => {
|
||||
const text = "| Column 1 | Column 2 | Column 3 |\n|---|---|---|\n| Row 1 | Value 1 | Value 2 |\n| Row 2 | Value 3 | Value 4 |"
|
||||
const text =
|
||||
"| Column 1 | Column 2 | Column 3 |\n|---|---|---|\n| Row 1 | Value 1 | Value 2 |\n| Row 2 | Value 3 | Value 4 |"
|
||||
|
||||
for (const chunks of [[text], [...text]]) {
|
||||
const out = await setup()
|
||||
@@ -182,7 +185,9 @@ test("holds markdown code blocks until final commit and keeps newline ownership"
|
||||
|
||||
try {
|
||||
await out.scrollback.append(
|
||||
assistant('# Markdown Sample\n\n- Item 1\n- Item 2\n\n```js\nconst message = "Hello, markdown"\nconsole.log(message)\n```'),
|
||||
assistant(
|
||||
'# Markdown Sample\n\n- Item 1\n- Item 2\n\n```js\nconst message = "Hello, markdown"\nconsole.log(message)\n```',
|
||||
),
|
||||
)
|
||||
|
||||
const progress = claim(out.renderer)
|
||||
@@ -543,7 +548,7 @@ test("inserts a spacer before the next tool after completed multiline bash outpu
|
||||
take()
|
||||
|
||||
const output = lines.join("\n")
|
||||
expect(output).toContain("total 4\n\n✱ Glob \"**/*tool*\" in src/cli/cmd")
|
||||
expect(output).toContain('total 4\n\n✱ Glob "**/*tool*" in src/cli/cmd')
|
||||
} finally {
|
||||
out.scrollback.destroy()
|
||||
}
|
||||
|
||||
@@ -48,12 +48,7 @@ function user(id: string) {
|
||||
}
|
||||
}
|
||||
|
||||
function text(input: {
|
||||
id: string
|
||||
messageID: string
|
||||
text: string
|
||||
time?: Record<string, number>
|
||||
}) {
|
||||
function text(input: { id: string; messageID: string; text: string; time?: Record<string, number> }) {
|
||||
return {
|
||||
type: "message.part.updated",
|
||||
properties: {
|
||||
@@ -98,13 +93,7 @@ function delta(messageID: string, partID: string, value: string) {
|
||||
}
|
||||
}
|
||||
|
||||
function tool(input: {
|
||||
id: string
|
||||
messageID: string
|
||||
tool: string
|
||||
state: Record<string, unknown>
|
||||
callID?: string
|
||||
}) {
|
||||
function tool(input: { id: string; messageID: string; tool: string; state: Record<string, unknown>; callID?: string }) {
|
||||
return {
|
||||
type: "message.part.updated",
|
||||
properties: {
|
||||
|
||||
@@ -144,11 +144,7 @@ function statusMap(busy: boolean): SessionStatusMap {
|
||||
return {}
|
||||
}
|
||||
|
||||
function assistantMessage(input: {
|
||||
sessionID: string
|
||||
id: string
|
||||
parts: SessionMessage["parts"]
|
||||
}): SessionMessage {
|
||||
function assistantMessage(input: { sessionID: string; id: string; parts: SessionMessage["parts"] }): SessionMessage {
|
||||
return {
|
||||
info: {
|
||||
id: input.id,
|
||||
@@ -334,16 +330,18 @@ function footer(fn?: (commit: StreamCommit) => void) {
|
||||
return { api, commits, events }
|
||||
}
|
||||
|
||||
function sdk(input: {
|
||||
stream?: EventStream
|
||||
subscribe?: OpencodeClient["event"]["subscribe"]
|
||||
promptAsync?: OpencodeClient["session"]["promptAsync"]
|
||||
status?: OpencodeClient["session"]["status"]
|
||||
messages?: OpencodeClient["session"]["messages"]
|
||||
children?: OpencodeClient["session"]["children"]
|
||||
permissions?: OpencodeClient["permission"]["list"]
|
||||
questions?: OpencodeClient["question"]["list"]
|
||||
} = {}) {
|
||||
function sdk(
|
||||
input: {
|
||||
stream?: EventStream
|
||||
subscribe?: OpencodeClient["event"]["subscribe"]
|
||||
promptAsync?: OpencodeClient["session"]["promptAsync"]
|
||||
status?: OpencodeClient["session"]["status"]
|
||||
messages?: OpencodeClient["session"]["messages"]
|
||||
children?: OpencodeClient["session"]["children"]
|
||||
permissions?: OpencodeClient["permission"]["list"]
|
||||
questions?: OpencodeClient["question"]["list"]
|
||||
} = {},
|
||||
) {
|
||||
const client = new OpencodeClient()
|
||||
|
||||
const subscribe: OpencodeClient["event"]["subscribe"] = input.subscribe ?? (() => sse(input.stream ?? emptyStream()))
|
||||
@@ -375,51 +373,52 @@ describe("run stream transport", () => {
|
||||
messages: async ({ sessionID }) => {
|
||||
if (sessionID === "session-1") {
|
||||
return ok([
|
||||
assistantMessage({
|
||||
sessionID: "session-1",
|
||||
id: "msg-1",
|
||||
parts: [
|
||||
runningTool({
|
||||
sessionID: "session-1",
|
||||
messageID: "msg-1",
|
||||
id: "task-1",
|
||||
callID: "call-1",
|
||||
tool: "task",
|
||||
body: {
|
||||
description: "Explore run folder",
|
||||
subagent_type: "explore",
|
||||
},
|
||||
metadata: {
|
||||
sessionId: "child-1",
|
||||
},
|
||||
}),
|
||||
],
|
||||
}),
|
||||
])
|
||||
}
|
||||
|
||||
return ok([
|
||||
assistantMessage({
|
||||
sessionID: "child-1",
|
||||
id: "msg-child-1",
|
||||
sessionID: "session-1",
|
||||
id: "msg-1",
|
||||
parts: [
|
||||
runningTool({
|
||||
sessionID: "child-1",
|
||||
messageID: "msg-child-1",
|
||||
id: "edit-1",
|
||||
callID: "call-edit-1",
|
||||
tool: "edit",
|
||||
sessionID: "session-1",
|
||||
messageID: "msg-1",
|
||||
id: "task-1",
|
||||
callID: "call-1",
|
||||
tool: "task",
|
||||
body: {
|
||||
filePath: "src/run/subagent-data.ts",
|
||||
diff: "@@ -1 +1 @@",
|
||||
description: "Explore run folder",
|
||||
subagent_type: "explore",
|
||||
},
|
||||
metadata: {
|
||||
sessionId: "child-1",
|
||||
},
|
||||
}),
|
||||
],
|
||||
}),
|
||||
])
|
||||
}
|
||||
|
||||
return ok([
|
||||
assistantMessage({
|
||||
sessionID: "child-1",
|
||||
id: "msg-child-1",
|
||||
parts: [
|
||||
runningTool({
|
||||
sessionID: "child-1",
|
||||
messageID: "msg-child-1",
|
||||
id: "edit-1",
|
||||
callID: "call-edit-1",
|
||||
tool: "edit",
|
||||
body: {
|
||||
filePath: "src/run/subagent-data.ts",
|
||||
diff: "@@ -1 +1 @@",
|
||||
},
|
||||
}),
|
||||
],
|
||||
}),
|
||||
])
|
||||
},
|
||||
children: async () => ok([child("child-1")]),
|
||||
permissions: async () => ok([
|
||||
permissions: async () =>
|
||||
ok([
|
||||
{
|
||||
id: "perm-1",
|
||||
sessionID: "child-1",
|
||||
@@ -743,7 +742,8 @@ describe("run stream transport", () => {
|
||||
|
||||
expect(
|
||||
ui.events.some(
|
||||
(event) => event.type === "stream.view" && event.view.type === "question" && event.view.request.id === request.id,
|
||||
(event) =>
|
||||
event.type === "stream.view" && event.view.type === "question" && event.view.request.id === request.id,
|
||||
),
|
||||
).toBe(false)
|
||||
|
||||
@@ -982,11 +982,14 @@ describe("run stream transport", () => {
|
||||
|
||||
const transport = await createSessionTransport({
|
||||
sdk: sdk({
|
||||
subscribe: () => sse((async function* (): AsyncGenerator<SdkEvent> {
|
||||
await ready.promise
|
||||
yield busy()
|
||||
throw new Error("boom")
|
||||
})()),
|
||||
subscribe: () =>
|
||||
sse(
|
||||
(async function* (): AsyncGenerator<SdkEvent> {
|
||||
await ready.promise
|
||||
yield busy()
|
||||
throw new Error("boom")
|
||||
})(),
|
||||
),
|
||||
promptAsync: async () => {
|
||||
ready.resolve()
|
||||
return ok(undefined)
|
||||
|
||||
@@ -2,16 +2,7 @@ import { expect, test } from "bun:test"
|
||||
import { RGBA, type CliRenderer, type TerminalColors } from "@opentui/core"
|
||||
import { RUN_THEME_FALLBACK, generateSystem, resolveRunTheme, resolveTheme } from "@/cli/cmd/run/theme"
|
||||
|
||||
const palette = [
|
||||
"#15161e",
|
||||
"#f7768e",
|
||||
"#9ece6a",
|
||||
"#e0af68",
|
||||
"#7aa2f7",
|
||||
"#bb9af7",
|
||||
"#7dcfff",
|
||||
"#c0caf5",
|
||||
] as const
|
||||
const palette = ["#15161e", "#f7768e", "#9ece6a", "#e0af68", "#7aa2f7", "#bb9af7", "#7dcfff", "#c0caf5"] as const
|
||||
|
||||
function terminalColors(input: Partial<TerminalColors> = {}): TerminalColors {
|
||||
return {
|
||||
@@ -28,11 +19,13 @@ function terminalColors(input: Partial<TerminalColors> = {}): TerminalColors {
|
||||
}
|
||||
}
|
||||
|
||||
function renderer(input: {
|
||||
themeMode?: "dark" | "light"
|
||||
colors?: TerminalColors
|
||||
fail?: boolean
|
||||
} = {}) {
|
||||
function renderer(
|
||||
input: {
|
||||
themeMode?: "dark" | "light"
|
||||
colors?: TerminalColors
|
||||
fail?: boolean
|
||||
} = {},
|
||||
) {
|
||||
return {
|
||||
themeMode: input.themeMode,
|
||||
getPalette: async () => {
|
||||
|
||||
@@ -79,7 +79,10 @@ const providers: RunProvider[] = [
|
||||
},
|
||||
]
|
||||
|
||||
function userMessage(id: string, input: { providerID: string; modelID: string; variant?: string }): SessionMessages[number] {
|
||||
function userMessage(
|
||||
id: string,
|
||||
input: { providerID: string; modelID: string; variant?: string },
|
||||
): SessionMessages[number] {
|
||||
return {
|
||||
info: {
|
||||
id,
|
||||
|
||||
Reference in New Issue
Block a user