Dax Raad 3 months ago
parent
commit
421d89b96d

+ 20 - 4
packages/opencode/src/cli/cmd/tui/routes/session/index.tsx

@@ -1112,7 +1112,7 @@ export function Session() {
                 <Match when={permissions().length > 0}>
                   <PermissionPrompt request={permissions()[0]} />
                 </Match>
-                <Match when={true}>
+                <Match when={!session()?.parentID}>
                   <Prompt
                     ref={(r) => {
                       prompt = r
@@ -1537,8 +1537,10 @@ function InlineTool(props: { icon: string; complete: any; pending: string; child
   )
 }
 
-function BlockTool(props: { title: string; children: JSX.Element }) {
+function BlockTool(props: { title: string; children: JSX.Element; onClick?: () => void }) {
   const { theme } = useTheme()
+  const renderer = useRenderer()
+  const [hover, setHover] = createSignal(false)
   return (
     <box
       border={["left"]}
@@ -1547,9 +1549,15 @@ function BlockTool(props: { title: string; children: JSX.Element }) {
       paddingLeft={2}
       marginTop={1}
       gap={1}
-      backgroundColor={theme.backgroundPanel}
+      backgroundColor={hover() ? theme.backgroundMenu : theme.backgroundPanel}
       customBorderChars={SplitBorder.customBorderChars}
       borderColor={theme.background}
+      onMouseOver={() => props.onClick && setHover(true)}
+      onMouseOut={() => setHover(false)}
+      onMouseUp={() => {
+        if (renderer.getSelection()?.getSelectedText()) return
+        props.onClick?.()
+      }}
     >
       <text paddingLeft={3} fg={theme.textMuted}>
         {props.title}
@@ -1697,13 +1705,21 @@ function WebSearch(props: ToolProps<any>) {
 function Task(props: ToolProps<typeof TaskTool>) {
   const { theme } = useTheme()
   const keybind = useKeybind()
+  const { navigate } = useRoute()
 
   const current = createMemo(() => props.metadata.summary?.findLast((x) => x.state.status !== "pending"))
 
   return (
     <Switch>
       <Match when={props.metadata.summary?.length}>
-        <BlockTool title={"# " + Locale.titlecase(props.input.subagent_type ?? "unknown") + " Task"}>
+        <BlockTool
+          title={"# " + Locale.titlecase(props.input.subagent_type ?? "unknown") + " Task"}
+          onClick={
+            props.metadata.sessionId
+              ? () => navigate({ type: "session", sessionID: props.metadata.sessionId! })
+              : undefined
+          }
+        >
           <box>
             <text style={{ fg: theme.textMuted }}>
               {props.input.description} ({props.metadata.summary?.length} toolcalls)

+ 3 - 1
packages/opencode/src/cli/cmd/tui/routes/session/permission.tsx

@@ -49,7 +49,7 @@ function EditBody(props: { request: PermissionRequest }) {
         <text fg={theme.textMuted}>Edit {normalizePath(filepath())}</text>
       </box>
       <Show when={diff()}>
-        <box>
+        <box maxHeight={Math.floor(dimensions().height / 4)} overflow="scroll">
           <diff
             diff={diff()}
             view={view()}
@@ -252,7 +252,9 @@ function Prompt<const T extends Record<string, string>>(props: {
       </box>
       <box
         flexDirection="row"
+        flexShrink={0}
         gap={1}
+        paddingTop={1}
         paddingLeft={2}
         paddingRight={3}
         paddingBottom={1}

+ 8 - 1
packages/opencode/src/tool/write.ts

@@ -2,12 +2,14 @@ import z from "zod"
 import * as path from "path"
 import { Tool } from "./tool"
 import { LSP } from "../lsp"
+import { createTwoFilesPatch } from "diff"
 import DESCRIPTION from "./write.txt"
 import { Bus } from "../bus"
 import { File } from "../file"
 import { FileTime } from "../file/time"
 import { Filesystem } from "../util/filesystem"
 import { Instance } from "../project/instance"
+import { trimDiff } from "./edit"
 
 const MAX_DIAGNOSTICS_PER_FILE = 20
 const MAX_PROJECT_DIAGNOSTICS_FILES = 5
@@ -29,13 +31,18 @@ export const WriteTool = Tool.define("write", {
 
     const file = Bun.file(filepath)
     const exists = await file.exists()
+    const contentOld = exists ? await file.text() : ""
     if (exists) await FileTime.assert(ctx.sessionID, filepath)
 
+    const diff = trimDiff(createTwoFilesPatch(filepath, filepath, contentOld, params.content))
     await ctx.ask({
       permission: "edit",
       patterns: [path.relative(Instance.worktree, filepath)],
       always: ["*"],
-      metadata: {},
+      metadata: {
+        filepath,
+        diff,
+      },
     })
 
     await Bun.write(filepath, params.content)