From 2f66055d25e9024a9b43e1ec078a05aa7d2d4125 Mon Sep 17 00:00:00 2001 From: Cheol Kang Date: Tue, 21 Oct 2025 13:25:54 +0900 Subject: [PATCH] feat: add -f/--file flag to opencode run command (#3295) Co-authored-by: opencode-agent[bot] Co-authored-by: rekram1-node Co-authored-by: Aiden Cline --- packages/opencode/src/cli/cmd/run.ts | 37 ++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/packages/opencode/src/cli/cmd/run.ts b/packages/opencode/src/cli/cmd/run.ts index 7d0e68de..9a6445a2 100644 --- a/packages/opencode/src/cli/cmd/run.ts +++ b/packages/opencode/src/cli/cmd/run.ts @@ -1,4 +1,5 @@ import type { Argv } from "yargs" +import path from "path" import { Bus } from "../../bus" import { Provider } from "../../provider/provider" import { Session } from "../../session" @@ -70,10 +71,45 @@ export const RunCommand = cmd({ default: "default", describe: "format: default (formatted) or json (raw JSON events)", }) + .option("file", { + alias: ["f"], + type: "string", + array: true, + describe: "file(s) to attach to message", + }) }, handler: async (args) => { let message = args.message.join(" ") + let fileParts: any[] = [] + if (args.file) { + const files = Array.isArray(args.file) ? args.file : [args.file] + + for (const filePath of files) { + const resolvedPath = path.resolve(process.cwd(), filePath) + const file = Bun.file(resolvedPath) + const stats = await file.stat().catch(() => {}) + if (!stats) { + UI.error(`File not found: ${filePath}`) + process.exit(1) + } + if (!(await file.exists())) { + UI.error(`File not found: ${filePath}`) + process.exit(1) + } + + const stat = await file.stat() + const mime = stat.isDirectory() ? "application/x-directory" : "text/plain" + + fileParts.push({ + type: "file", + url: `file://${resolvedPath}`, + filename: path.basename(resolvedPath), + mime, + }) + } + } + if (!process.stdin.isTTY) message += "\n" + (await Bun.stdin.text()) if (message.trim().length === 0 && !args.command) { @@ -244,6 +280,7 @@ export const RunCommand = cmd({ }, agent: agent.name, parts: [ + ...fileParts, { id: Identifier.ascending("part"), type: "text",