feat: /diff command to view git diff (#426)
Adds `/diff` command to view git diff
This commit is contained in:
36
codex-cli/src/utils/extract-applied-patches.ts
Normal file
36
codex-cli/src/utils/extract-applied-patches.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import type { ResponseItem } from "openai/resources/responses/responses.mjs";
|
||||
|
||||
/**
|
||||
* Extracts the patch texts of all `apply_patch` tool calls from the given
|
||||
* message history. Returns an empty string when none are found.
|
||||
*/
|
||||
export function extractAppliedPatches(items: Array<ResponseItem>): string {
|
||||
const patches: Array<string> = [];
|
||||
|
||||
for (const item of items) {
|
||||
if (item.type !== "function_call") {
|
||||
continue;
|
||||
}
|
||||
|
||||
const { name: toolName, arguments: argsString } = item as unknown as {
|
||||
name: unknown;
|
||||
arguments: unknown;
|
||||
};
|
||||
|
||||
if (toolName !== "apply_patch" || typeof argsString !== "string") {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
const args = JSON.parse(argsString) as { patch?: string };
|
||||
if (typeof args.patch === "string" && args.patch.length > 0) {
|
||||
patches.push(args.patch.trim());
|
||||
}
|
||||
} catch {
|
||||
// Ignore malformed JSON – we never want to crash the overlay.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return patches.join("\n\n");
|
||||
}
|
||||
29
codex-cli/src/utils/get-diff.ts
Normal file
29
codex-cli/src/utils/get-diff.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { execSync } from "node:child_process";
|
||||
|
||||
/**
|
||||
* Returns the current Git diff for the working directory. If the current
|
||||
* working directory is not inside a Git repository, `isGitRepo` will be
|
||||
* false and `diff` will be an empty string.
|
||||
*/
|
||||
export function getGitDiff(): {
|
||||
isGitRepo: boolean;
|
||||
diff: string;
|
||||
} {
|
||||
try {
|
||||
// First check whether we are inside a git repository. `rev‑parse` exits
|
||||
// with a non‑zero status code if not.
|
||||
execSync("git rev-parse --is-inside-work-tree", { stdio: "ignore" });
|
||||
|
||||
// If the above call didn’t throw, we are inside a git repo. Retrieve the
|
||||
// diff including color codes so that the overlay can render them.
|
||||
const output = execSync("git diff --color", {
|
||||
encoding: "utf8",
|
||||
maxBuffer: 10 * 1024 * 1024, // 10 MB ought to be enough for now
|
||||
});
|
||||
|
||||
return { isGitRepo: true, diff: output };
|
||||
} catch {
|
||||
// Either git is not installed or we’re not inside a repository.
|
||||
return { isGitRepo: false, diff: "" };
|
||||
}
|
||||
}
|
||||
@@ -24,4 +24,9 @@ export const SLASH_COMMANDS: Array<SlashCommand> = [
|
||||
{ command: "/model", description: "Open model selection panel" },
|
||||
{ command: "/approval", description: "Open approval mode selection panel" },
|
||||
{ command: "/bug", description: "Generate a prefilled GitHub bug report" },
|
||||
{
|
||||
command: "/diff",
|
||||
description:
|
||||
"Show git diff of the working directory (or applied patches if not in git)",
|
||||
},
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user