Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions packages/opencode/src/cli/cmd/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { ReadTool } from "../../tool/read"
import { WebFetchTool } from "../../tool/webfetch"
import { EditTool } from "../../tool/edit"
import { WriteTool } from "../../tool/write"
import { ApplyPatchTool } from "../../tool/apply_patch"
import { CodeSearchTool } from "../../tool/codesearch"
import { WebSearchTool } from "../../tool/websearch"
import { TaskTool } from "../../tool/task"
Expand Down Expand Up @@ -153,6 +154,38 @@ function edit(info: ToolProps<typeof EditTool>) {
)
}

function applypatch(info: ToolProps<typeof ApplyPatchTool>) {
const files = Array.isArray(info.metadata.files) ? info.metadata.files : []
if (!files.length) {
block(
{
icon: "%",
title: "Patch",
},
info.metadata.diff,
)
return
}

for (const file of files) {
const title =
file.type === "delete"
? `Deleted ${file.relativePath}`
: file.type === "add"
? `Created ${file.relativePath}`
: file.type === "move"
? `Moved ${normalizePath(file.filePath)} -> ${file.relativePath}`
: `Patched ${file.relativePath}`
block(
{
icon: "%",
title,
},
file.diff,
)
}
}

function codesearch(info: ToolProps<typeof CodeSearchTool>) {
inline({
icon: "◇",
Expand Down Expand Up @@ -419,6 +452,7 @@ export const RunCommand = cmd({
if (part.tool === "write") return write(props<typeof WriteTool>(part))
if (part.tool === "webfetch") return webfetch(props<typeof WebFetchTool>(part))
if (part.tool === "edit") return edit(props<typeof EditTool>(part))
if (part.tool === "apply_patch") return applypatch(props<typeof ApplyPatchTool>(part))
if (part.tool === "codesearch") return codesearch(props<typeof CodeSearchTool>(part))
if (part.tool === "websearch") return websearch(props<typeof WebSearchTool>(part))
if (part.tool === "task") return task(props<typeof TaskTool>(part))
Expand Down
57 changes: 55 additions & 2 deletions packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ function EditBody(props: { request: PermissionRequest }) {

const filepath = createMemo(() => (props.request.metadata?.filepath as string) ?? "")
const diff = createMemo(() => (props.request.metadata?.diff as string) ?? "")
const files = createMemo(() => {
const value = props.request.metadata?.files
return Array.isArray(value) ? value : []
})

const view = createMemo(() => {
const diffStyle = config.diff_style
Expand All @@ -63,9 +67,58 @@ function EditBody(props: { request: PermissionRequest }) {

const ft = createMemo(() => filetype(filepath()))

function title(file: { type: string; relativePath: string; filePath: string }) {
if (file.type === "delete") return "# Deleted " + file.relativePath
if (file.type === "add") return "# Created " + file.relativePath
if (file.type === "move") return "# Moved " + normalizePath(file.filePath) + " -> " + file.relativePath
return "# Patched " + file.relativePath
}

return (
<box flexDirection="column" gap={1}>
<Show when={diff()}>
<Show when={files().length > 0}>
<scrollbox
height="100%"
verticalScrollbarOptions={{
trackOptions: {
backgroundColor: theme.background,
foregroundColor: theme.borderActive,
},
}}
>
<box flexDirection="column" gap={1}>
<For each={files()}>
{(file) => (
<box flexDirection="column" gap={1}>
<box paddingLeft={1}>
<text fg={theme.textMuted}>{title(file)}</text>
</box>
<diff
diff={file.diff}
view={view()}
filetype={filetype(file.filePath)}
syntaxStyle={syntax()}
showLineNumbers={true}
width="100%"
wrapMode="word"
fg={theme.text}
addedBg={theme.diffAddedBg}
removedBg={theme.diffRemovedBg}
contextBg={theme.diffContextBg}
addedSignColor={theme.diffHighlightAdded}
removedSignColor={theme.diffHighlightRemoved}
lineNumberFg={theme.diffLineNumber}
lineNumberBg={theme.diffContextBg}
addedLineNumberBg={theme.diffAddedLineNumberBg}
removedLineNumberBg={theme.diffRemovedLineNumberBg}
/>
</box>
)}
</For>
</box>
</scrollbox>
</Show>
<Show when={!files().length && diff()}>
<scrollbox
height="100%"
verticalScrollbarOptions={{
Expand Down Expand Up @@ -96,7 +149,7 @@ function EditBody(props: { request: PermissionRequest }) {
/>
</scrollbox>
</Show>
<Show when={!diff()}>
<Show when={!files().length && !diff()}>
<box paddingLeft={1}>
<text fg={theme.textMuted}>No diff provided</text>
</box>
Expand Down
Loading