diff --git a/packages/console/app/public/theme.json b/packages/console/app/public/theme.json index b3e97f7ca897..d0715536c22b 100644 --- a/packages/console/app/public/theme.json +++ b/packages/console/app/public/theme.json @@ -46,6 +46,7 @@ "info": { "$ref": "#/definitions/colorValue" }, "text": { "$ref": "#/definitions/colorValue" }, "textMuted": { "$ref": "#/definitions/colorValue" }, + "placeholderText": { "$ref": "#/definitions/colorValue" }, "background": { "$ref": "#/definitions/colorValue" }, "backgroundPanel": { "$ref": "#/definitions/colorValue" }, "backgroundElement": { "$ref": "#/definitions/colorValue" }, diff --git a/packages/opencode/src/cli/cmd/session.ts b/packages/opencode/src/cli/cmd/session.ts index c8b5b0336607..01d028c8d505 100644 --- a/packages/opencode/src/cli/cmd/session.ts +++ b/packages/opencode/src/cli/cmd/session.ts @@ -5,11 +5,14 @@ import { bootstrap } from "../bootstrap" import { UI } from "../ui" import { Locale } from "../../util/locale" import { EOL } from "os" +import { createOpencodeClient } from "@opencode-ai/sdk" +import { Server } from "../../server/server" +import { tui } from "./tui/app" export const SessionCommand = cmd({ command: "session", describe: "manage sessions", - builder: (yargs: Argv) => yargs.command(SessionListCommand).demandCommand(), + builder: (yargs: Argv) => yargs.command(SessionListCommand).command(SessionForkCommand).demandCommand(), async handler() {}, }) @@ -104,3 +107,57 @@ function formatSessionJSON(sessions: Session.Info[]): string { })) return JSON.stringify(jsonData, null, 2) } + +export const SessionForkCommand = cmd({ + command: "fork", + describe: "fork a session to explore parallel conversation branches", + builder: (yargs: Argv) => { + return yargs + .option("session", { + alias: "s", + describe: "session ID to fork", + type: "string", + demandOption: true, + }) + .option("message", { + alias: "m", + describe: "fork up to this message ID", + type: "string", + }) + }, + handler: async (args) => { + await bootstrap(process.cwd(), async () => { + const server = Server.listen({ port: 0, hostname: "127.0.0.1" }) + const sdk = createOpencodeClient({ baseUrl: `http://${server.hostname}:${server.port}` }) + + const result = await sdk.session + .fork({ + path: { id: args.session }, + body: { messageID: args.message }, + }) + .catch((error) => { + server.stop() + const errorMessage = error.message || String(error) + UI.error(`Failed to fork session: ${errorMessage}`) + process.exit(1) + }) + + if (!result.data) { + server.stop() + UI.error("Failed to fork session") + process.exit(1) + } + + const forkedSessionID = result.data.id + UI.println(UI.Style.TEXT_INFO_BOLD + `Forked session: ${forkedSessionID}`) + UI.println() + + await tui({ + url: `http://${server.hostname}:${server.port}`, + args: { sessionID: forkedSessionID }, + }) + + server.stop() + }) + }, +}) diff --git a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx index 7d5bbb9f06a0..1b13264df8dd 100644 --- a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx @@ -656,7 +656,7 @@ export function Prompt(props: PromptProps) { flexGrow={1} >