summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--packages/opencode/src/cli/cmd/tui/app.tsx9
-rw-r--r--packages/opencode/src/cli/cmd/tui/routes/session/index.tsx87
-rw-r--r--packages/opencode/src/file/index.ts5
3 files changed, 89 insertions, 12 deletions
diff --git a/packages/opencode/src/cli/cmd/tui/app.tsx b/packages/opencode/src/cli/cmd/tui/app.tsx
index 989defd94..03aa5df60 100644
--- a/packages/opencode/src/cli/cmd/tui/app.tsx
+++ b/packages/opencode/src/cli/cmd/tui/app.tsx
@@ -177,17 +177,14 @@ function App() {
const exit = useExit()
useKeyboard(async (evt) => {
+ if (!Installation.isLocal()) return
if (evt.meta && evt.name === "t") {
- if (process.env.DEBUG) {
- renderer.toggleDebugOverlay()
- }
+ renderer.toggleDebugOverlay()
return
}
if (evt.meta && evt.name === "d") {
- if (process.env.DEBUG) {
- renderer.console.toggle()
- }
+ renderer.console.toggle()
return
}
})
diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
index c3846b55a..5cd2e6712 100644
--- a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
+++ b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
@@ -64,7 +64,6 @@ import { LANGUAGE_EXTENSIONS } from "@/lsp/language"
import parsers from "../../../../../../parsers-config.ts"
import { Clipboard } from "../../util/clipboard"
import { Toast, useToast } from "../../ui/toast"
-import { DialogSessionRename } from "../../component/dialog-session-rename"
import { useKV } from "../../context/kv.tsx"
addDefaultParsers(parsers.parsers)
@@ -401,12 +400,49 @@ export function Session() {
},
},
{
- title: "Rename session",
- value: "session.rename",
- keybind: "session_rename",
+ title: "Copy last assistant message",
+ value: "messages.copy",
+ keybind: "messages_copy",
category: "Session",
onSelect: (dialog) => {
- dialog.replace(() => <DialogSessionRename session={route.sessionID} />)
+ const lastAssistantMessage = messages().findLast((msg) => msg.role === "assistant")
+ if (!lastAssistantMessage) {
+ toast.show({ message: "No assistant messages found", variant: "error" })
+ dialog.clear()
+ return
+ }
+
+ const parts = sync.data.part[lastAssistantMessage.id] ?? []
+ const textParts = parts.filter((part) => part.type === "text")
+ if (textParts.length === 0) {
+ toast.show({ message: "No text parts found in last assistant message", variant: "error" })
+ dialog.clear()
+ return
+ }
+
+ const text = textParts
+ .map((part) => part.text)
+ .join("\n")
+ .trim()
+ if (!text) {
+ toast.show({
+ message: "No text content found in last assistant message",
+ variant: "error",
+ })
+ dialog.clear()
+ return
+ }
+
+ console.log(text)
+ const base64 = Buffer.from(text).toString("base64")
+ const osc52 = `\x1b]52;c;${base64}\x07`
+ const finalOsc52 = process.env["TMUX"] ? `\x1bPtmux;\x1b${osc52}\x1b\\` : osc52
+ /* @ts-expect-error */
+ renderer.writeOut(finalOsc52)
+ Clipboard.copy(text)
+ .then(() => toast.show({ message: "Message copied to clipboard!", variant: "success" }))
+ .catch(() => toast.show({ message: "Failed to copy to clipboard", variant: "error" }))
+ dialog.clear()
},
},
{
@@ -431,6 +467,47 @@ export function Session() {
dialog.clear()
},
},
+ {
+ title: "Copy last assistant message",
+ value: "messages.copy",
+ keybind: "messages_copy",
+ category: "Session",
+ onSelect: (dialog) => {
+ const lastAssistantMessage = messages().findLast((msg) => msg.role === "assistant")
+ if (lastAssistantMessage) {
+ const parts = sync.data.part[lastAssistantMessage.id] ?? []
+ const textParts = parts.filter((part) => part.type === "text")
+ if (textParts.length > 0) {
+ const text = textParts
+ .map((part) => part.text)
+ .join("\n")
+ .trim()
+ if (text) {
+ Clipboard.copy(text)
+ .then(() =>
+ toast.show({ message: "Message copied to clipboard!", variant: "success" }),
+ )
+ .catch(() =>
+ toast.show({ message: "Failed to copy to clipboard", variant: "error" }),
+ )
+ } else {
+ toast.show({
+ message: "No text content found in last assistant message",
+ variant: "error",
+ })
+ }
+ } else {
+ toast.show({
+ message: "No text parts found in last assistant message",
+ variant: "error",
+ })
+ }
+ } else {
+ toast.show({ message: "No assistant messages found", variant: "error" })
+ }
+ dialog.clear()
+ },
+ },
])
const revert = createMemo(() => {
diff --git a/packages/opencode/src/file/index.ts b/packages/opencode/src/file/index.ts
index 020b3568e..3a143d072 100644
--- a/packages/opencode/src/file/index.ts
+++ b/packages/opencode/src/file/index.ts
@@ -320,7 +320,10 @@ export namespace File {
log.info("search", { query: input.query })
const limit = input.limit ?? 100
const result = await state().then((x) => x.files())
- if (!input.query) return input.dirs !== false ? result.dirs.toSorted().slice(0, limit) : []
+ if (!input.query)
+ return input.dirs !== false
+ ? result.dirs.toSorted().slice(0, limit)
+ : result.files.slice(0, limit)
const items = input.dirs !== false ? [...result.files, ...result.dirs] : result.files
const sorted = fuzzysort.go(input.query, items, { limit: limit }).map((r) => r.target)
log.info("search", { query: input.query, results: sorted.length })