fix(tui): treat absolute file paths as plain text, not commands

This commit is contained in:
Tibsfox 2026-04-05 10:34:34 -07:00
parent 092d1c0a9e
commit 31e20e0fe3
2 changed files with 43 additions and 1 deletions

View file

@ -154,3 +154,30 @@ test("input-controller: truly unknown slash commands stop before session.prompt"
);
assert.equal(getEditorText(), "", "unknown slash commands should clear the editor after showing the error");
});
test("input-controller: absolute file paths are not treated as slash commands (#3478)", async () => {
const { host, prompted, errors } = createHost();
await host.defaultEditor.onSubmit("/Users/name/Desktop/screenshot.png");
assert.deepEqual(errors, [], "file paths should not trigger unknown command error");
assert.deepEqual(prompted, ["/Users/name/Desktop/screenshot.png"], "file paths should be sent as plain input");
});
test("input-controller: Linux absolute paths are not treated as slash commands (#3478)", async () => {
const { host, prompted, errors } = createHost();
await host.defaultEditor.onSubmit("/home/user/documents/file.txt");
assert.deepEqual(errors, [], "Linux paths should not trigger unknown command error");
assert.deepEqual(prompted, ["/home/user/documents/file.txt"], "Linux paths should be sent as plain input");
});
test("input-controller: /tmp paths are not treated as slash commands (#3478)", async () => {
const { host, prompted, errors } = createHost();
await host.defaultEditor.onSubmit("/tmp/some-file.log");
assert.deepEqual(errors, []);
assert.deepEqual(prompted, ["/tmp/some-file.log"]);
});

View file

@ -18,7 +18,7 @@ export function setupEditorSubmitHandler(host: InteractiveModeStateHost & {
text = text.trim();
if (!text) return;
if (text.startsWith("/")) {
if (text.startsWith("/") && !looksLikeFilePath(text)) {
const handled = await dispatchSlashCommand(text, host.getSlashCommandContext());
if (handled) {
host.editor.setText("");
@ -104,3 +104,18 @@ export function setupEditorSubmitHandler(host: InteractiveModeStateHost & {
}
};
}
/**
* Distinguish absolute file paths from slash commands (#3478).
* Drag-and-drop inserts paths like "/Users/name/Desktop/file.png" which
* should be treated as plain text input, not a /Users command.
*
* Heuristic: a slash command is a single token like "/help" or "/gsd auto".
* File paths have a second "/" within the first token (e.g., "/Users/...").
*/
function looksLikeFilePath(text: string): boolean {
const firstToken = text.split(/\s/)[0];
// Slash commands: /help, /gsd, /commit — single "/" at start only.
// File paths: /Users/name/file, /home/user/file, /tmp/x — contain "/" after position 0.
return firstToken.indexOf("/", 1) !== -1;
}