From 8459f803525b5eef85ae0653477165e963f06b75 Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 26 Nov 2025 16:18:35 +0000 Subject: [PATCH 1/3] feat: add CLI flags support to attach command Add support for --model, --session, --continue, --prompt, --agent, --title, and --command flags to the 'opencode attach' command, bringing feature parity with the main TUI and run commands. Changes: - Added all missing CLI flags to AttachCommand builder - Updated Args interface to include title and command properties - Implemented stdin piping support for prompts - Added command pre-fill support (prepends / to command name) - Updated documentation with complete flag reference and examples This allows users to attach to a running server with pre-configured settings like: opencode attach http://localhost:4096 --model anthropic/claude-3-5-sonnet --agent build opencode attach http://localhost:4096 --command commit --prompt 'with conventional format' --- packages/opencode/src/cli/cmd/tui/attach.ts | 50 ++++++++++++++++++- .../opencode/src/cli/cmd/tui/context/args.tsx | 2 + .../opencode/src/cli/cmd/tui/routes/home.tsx | 5 +- packages/web/src/content/docs/cli.mdx | 39 +++++++++++++++ 4 files changed, 94 insertions(+), 2 deletions(-) diff --git a/packages/opencode/src/cli/cmd/tui/attach.ts b/packages/opencode/src/cli/cmd/tui/attach.ts index 7da6507ea01..1285fadb10a 100644 --- a/packages/opencode/src/cli/cmd/tui/attach.ts +++ b/packages/opencode/src/cli/cmd/tui/attach.ts @@ -1,5 +1,6 @@ import { cmd } from "../cmd" import { tui } from "./app" +import { iife } from "@/util/iife" export const AttachCommand = cmd({ command: "attach ", @@ -14,12 +15,59 @@ export const AttachCommand = cmd({ .option("dir", { type: "string", description: "directory to run in", + }) + .option("model", { + type: "string", + alias: ["m"], + describe: "model to use in the format of provider/model", + }) + .option("continue", { + alias: ["c"], + describe: "continue the last session", + type: "boolean", + }) + .option("session", { + alias: ["s"], + type: "string", + describe: "session id to continue", + }) + .option("prompt", { + alias: ["p"], + type: "string", + describe: "prompt to use", + }) + .option("agent", { + type: "string", + describe: "agent to use", + }) + .option("title", { + type: "string", + describe: "title for the session (uses truncated prompt if no value provided)", + }) + .option("command", { + type: "string", + describe: "the command to run, use prompt for args", }), handler: async (args) => { if (args.dir) process.chdir(args.dir) + + const prompt = await iife(async () => { + const piped = !process.stdin.isTTY ? await Bun.stdin.text() : undefined + if (!args.prompt) return piped + return piped ? piped + "\n" + args.prompt : args.prompt + }) + await tui({ url: args.url, - args: {}, + args: { + continue: args.continue, + sessionID: args.session, + agent: args.agent, + model: args.model, + prompt, + title: args.title, + command: args.command, + }, }) }, }) diff --git a/packages/opencode/src/cli/cmd/tui/context/args.tsx b/packages/opencode/src/cli/cmd/tui/context/args.tsx index ffd43009a41..afc295368bf 100644 --- a/packages/opencode/src/cli/cmd/tui/context/args.tsx +++ b/packages/opencode/src/cli/cmd/tui/context/args.tsx @@ -6,6 +6,8 @@ export interface Args { prompt?: string continue?: boolean sessionID?: string + title?: string + command?: string } export const { use: useArgs, provider: ArgsProvider } = createSimpleContext({ diff --git a/packages/opencode/src/cli/cmd/tui/routes/home.tsx b/packages/opencode/src/cli/cmd/tui/routes/home.tsx index 6f63258b9d6..ce0c9e4ea54 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/home.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/home.tsx @@ -42,7 +42,10 @@ export function Home() { const args = useArgs() onMount(() => { if (once) return - if (args.prompt) { + if (args.command) { + prompt.set({ input: `/${args.command} ${args.prompt || ""}`.trim(), parts: [] }) + once = true + } else if (args.prompt) { prompt.set({ input: args.prompt, parts: [] }) once = true } diff --git a/packages/web/src/content/docs/cli.mdx b/packages/web/src/content/docs/cli.mdx index 083db369b1b..4bc33326500 100644 --- a/packages/web/src/content/docs/cli.mdx +++ b/packages/web/src/content/docs/cli.mdx @@ -69,6 +69,45 @@ This command will guide you through creating a new agent with a custom system pr --- +### attach + +Attach to a running opencode server with a full terminal interface. + +```bash +opencode attach +``` + +This command connects to an existing `opencode serve` or `opencode spawn` instance and provides the full TUI experience, allowing you to interact with the server as if you started opencode directly. + +```bash +# Start a headless server in one terminal +opencode serve + +# In another terminal, attach with the TUI +opencode attach http://localhost:4096 +``` + +This is useful when you want to: + +- Connect to a long-running opencode server +- Avoid MCP server cold boot times +- Share a server instance across multiple sessions + +#### Flags + +| Flag | Short | Description | +| ------------ | ----- | ------------------------------------------------------------------ | +| `--dir` | | Directory to run in | +| `--model` | `-m` | Model to use in the form of provider/model | +| `--continue` | `-c` | Continue the last session | +| `--session` | `-s` | Session ID to continue | +| `--prompt` | `-p` | Prompt to use | +| `--agent` | | Agent to use | +| `--title` | | Title for the session (uses truncated prompt if no value provided) | +| `--command` | | The command to run, use prompt for args | + +--- + ### auth Command to manage credentials and login for providers. From 8f04b7bc66011e4d317032fc1061e480a43a9072 Mon Sep 17 00:00:00 2001 From: Simon D'Morias Date: Tue, 23 Dec 2025 18:09:22 +0000 Subject: [PATCH 2/3] Update packages/opencode/src/cli/cmd/tui/routes/home.tsx Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- packages/opencode/src/cli/cmd/tui/routes/home.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/opencode/src/cli/cmd/tui/routes/home.tsx b/packages/opencode/src/cli/cmd/tui/routes/home.tsx index a53ec8e0e53..5433268c9c4 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/home.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/home.tsx @@ -51,8 +51,11 @@ export function Home() { const args = useArgs() onMount(() => { if (once) return + if (args.command) { if (args.command) { prompt.set({ input: `/${args.command} ${args.prompt || ""}`.trim(), parts: [] }) + once = true + } else if (route.initialPrompt) { } else if (route.initialPrompt) { prompt.set(route.initialPrompt) once = true From 6cbdf680af07433504c181550e7e3c3690a3c003 Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 23 Dec 2025 18:15:28 +0000 Subject: [PATCH 3/3] fix: remove duplicate lines in home.tsx --- packages/opencode/src/cli/cmd/tui/routes/home.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/opencode/src/cli/cmd/tui/routes/home.tsx b/packages/opencode/src/cli/cmd/tui/routes/home.tsx index 5433268c9c4..d2e3077f49a 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/home.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/home.tsx @@ -51,11 +51,9 @@ export function Home() { const args = useArgs() onMount(() => { if (once) return - if (args.command) { if (args.command) { prompt.set({ input: `/${args.command} ${args.prompt || ""}`.trim(), parts: [] }) once = true - } else if (route.initialPrompt) { } else if (route.initialPrompt) { prompt.set(route.initialPrompt) once = true