feat: /diff command to view git diff (#426)

Adds `/diff` command to view git diff
This commit is contained in:
Fouad Matin
2025-04-19 16:23:27 -07:00
committed by GitHub
parent 419f085cc4
commit b3b195351e
12 changed files with 232 additions and 7 deletions

View File

@@ -42,6 +42,7 @@ export default function TerminalChatInput({
openModelOverlay,
openApprovalOverlay,
openHelpOverlay,
openDiffOverlay,
onCompact,
interruptAgent,
active,
@@ -64,6 +65,7 @@ export default function TerminalChatInput({
openModelOverlay: () => void;
openApprovalOverlay: () => void;
openHelpOverlay: () => void;
openDiffOverlay: () => void;
onCompact: () => void;
interruptAgent: () => void;
active: boolean;
@@ -270,6 +272,12 @@ export default function TerminalChatInput({
return;
}
if (inputValue === "/diff") {
setInput("");
openDiffOverlay();
return;
}
if (inputValue === "/compact") {
setInput("");
onCompact();
@@ -494,6 +502,7 @@ export default function TerminalChatInput({
openApprovalOverlay,
openModelOverlay,
openHelpOverlay,
openDiffOverlay,
history,
onCompact,
skipNextSubmit,

View File

@@ -52,6 +52,7 @@ export default function TerminalChatInput({
openModelOverlay,
openApprovalOverlay,
openHelpOverlay,
openDiffOverlay,
interruptAgent,
active,
thinkingSeconds,
@@ -72,6 +73,7 @@ export default function TerminalChatInput({
openModelOverlay: () => void;
openApprovalOverlay: () => void;
openHelpOverlay: () => void;
openDiffOverlay: () => void;
interruptAgent: () => void;
active: boolean;
thinkingSeconds: number;
@@ -230,6 +232,12 @@ export default function TerminalChatInput({
return;
}
if (inputValue === "/diff") {
setInput("");
openDiffOverlay();
return;
}
if (inputValue.startsWith("/model")) {
setInput("");
openModelOverlay();
@@ -337,6 +345,7 @@ export default function TerminalChatInput({
openApprovalOverlay,
openModelOverlay,
openHelpOverlay,
openDiffOverlay,
history, // Add history to the dependency array
],
);

View File

@@ -19,12 +19,15 @@ import { isLoggingEnabled, log } from "../../utils/agent/log.js";
import { ReviewDecision } from "../../utils/agent/review.js";
import { generateCompactSummary } from "../../utils/compact-summary.js";
import { OPENAI_BASE_URL } from "../../utils/config.js";
import { extractAppliedPatches as _extractAppliedPatches } from "../../utils/extract-applied-patches.js";
import { getGitDiff } from "../../utils/get-diff.js";
import { createInputItem } from "../../utils/input-utils.js";
import { getAvailableModels } from "../../utils/model-utils.js";
import { CLI_VERSION } from "../../utils/session.js";
import { shortCwd } from "../../utils/short-path.js";
import { saveRollout } from "../../utils/storage/save-rollout.js";
import ApprovalModeOverlay from "../approval-mode-overlay.js";
import DiffOverlay from "../diff-overlay.js";
import HelpOverlay from "../help-overlay.js";
import HistoryOverlay from "../history-overlay.js";
import ModelOverlay from "../model-overlay.js";
@@ -180,9 +183,16 @@ export default function TerminalChat({
submitConfirmation,
} = useConfirmation();
const [overlayMode, setOverlayMode] = useState<
"none" | "history" | "model" | "approval" | "help"
"none" | "history" | "model" | "approval" | "help" | "diff"
>("none");
// Store the diff text when opening the diff overlay so the view isnt
// recomputed on every rerender while it is open.
// diffText is passed down to the DiffOverlay component. The setter is
// currently unused but retained for potential future updates. Prefix with
// an underscore so eslint ignores the unused variable.
const [diffText, _setDiffText] = useState<string>("");
const [initialPrompt, setInitialPrompt] = useState(_initialPrompt);
const [initialImagePaths, setInitialImagePaths] =
useState(_initialImagePaths);
@@ -497,6 +507,26 @@ export default function TerminalChat({
openModelOverlay={() => setOverlayMode("model")}
openApprovalOverlay={() => setOverlayMode("approval")}
openHelpOverlay={() => setOverlayMode("help")}
openDiffOverlay={() => {
const { isGitRepo, diff } = getGitDiff();
let text: string;
if (isGitRepo) {
text = diff;
} else {
text = "`/diff` — _not inside a git repository_";
}
setItems((prev) => [
...prev,
{
id: `diff-${Date.now()}`,
type: "message",
role: "system",
content: [{ type: "input_text", text }],
},
]);
// Ensure no overlay is shown.
setOverlayMode("none");
}}
onCompact={handleCompact}
active={overlayMode === "none"}
interruptAgent={() => {
@@ -622,6 +652,13 @@ export default function TerminalChat({
{overlayMode === "help" && (
<HelpOverlay onExit={() => setOverlayMode("none")} />
)}
{overlayMode === "diff" && (
<DiffOverlay
diffText={diffText}
onExit={() => setOverlayMode("none")}
/>
)}
</Box>
</Box>
);