Files
llmx/codex-cli/src/format-command.ts
2025-04-16 14:16:53 -07:00

54 lines
1.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { quote } from "shell-quote";
/**
* Format the args of an exec command for display as a single string. Prefer
* this to doing `args.join(" ")` as this will handle quoting and escaping
* correctly. See unit test for details.
*/
export function formatCommandForDisplay(command: Array<string>): string {
// The model often wraps arbitrary shell commands in an invocation that looks
// like:
//
// ["bash", "-lc", "'<actual command>'"]
//
// When displaying these back to the user, we do NOT want to show the
// boilerplate "bash -lc" wrapper. Instead, we want to surface only the
// actual command that bash will evaluate.
// Historically we detected this by first quoting the entire command array
// with `shellquote` and then using a regular expression to peel off the
// `bash -lc '…'` prefix. However, that approach was brittle (it depended on
// the exact quoting behavior of `shell-quote`) and unnecessarily
// inefficient.
// A simpler and more robust approach is to look at the raw command array
// itself. If it matches the shape produced by our exec helpers—exactly three
// entries where the first two are «bash» and «-lc»—then we can return the
// third entry directly (after stripping surrounding single quotes if they
// are present).
try {
if (
command.length === 3 &&
command[0] === "bash" &&
command[1] === "-lc" &&
typeof command[2] === "string"
) {
let inner = command[2];
// Some callers wrap the actual command in single quotes (e.g. `'echo foo'`).
// For display purposes we want to drop those outer quotes so that the
// rendered command looks exactly like what the user typed.
if (inner.startsWith("'") && inner.endsWith("'")) {
inner = inner.slice(1, -1);
}
return inner;
}
return quote(command);
} catch (err) {
return command.join(" ");
}
}