diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index db7952b7..32848945 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -2,6 +2,14 @@ ## [Unreleased] +## [0.25.1] - 2025-12-21 + +### Fixed + +- **Gemini image reading broken**: Fixed the `read` tool returning images causing flaky/broken responses with Gemini models. Images in tool results are now properly formatted per the Gemini API spec. + +- **Tab completion for absolute paths**: Fixed tab completion for absolute paths like `/tmp` producing `//tmp`. Also fixed inability to continue tabbing through subdirectories after completing an absolute path. + ## [0.25.0] - 2025-12-20 ### Added diff --git a/packages/tui/src/autocomplete.ts b/packages/tui/src/autocomplete.ts index a33435ad..9dd6988c 100644 --- a/packages/tui/src/autocomplete.ts +++ b/packages/tui/src/autocomplete.ts @@ -1,5 +1,5 @@ import { spawnSync } from "child_process"; -import { readdirSync } from "fs"; +import { readdirSync, statSync } from "fs"; import { homedir } from "os"; import { basename, dirname, join } from "path"; @@ -197,8 +197,10 @@ export class CombinedAutocompleteProvider implements AutocompleteProvider { const beforePrefix = currentLine.slice(0, cursorCol - prefix.length); const afterCursor = currentLine.slice(cursorCol); - // Check if we're completing a slash command (prefix starts with "/") - if (prefix.startsWith("/")) { + // Check if we're completing a slash command (prefix starts with "/" but NOT a file path) + // Slash commands are at the start of the line and don't contain path separators after the first / + const isSlashCommand = prefix.startsWith("/") && beforePrefix.trim() === "" && !prefix.slice(1).includes("/"); + if (isSlashCommand) { // This is a command name completion const newLine = beforePrefix + "/" + item.value + " " + afterCursor; const newLines = [...lines]; @@ -367,7 +369,16 @@ export class CombinedAutocompleteProvider implements AutocompleteProvider { continue; } - const isDirectory = entry.isDirectory(); + // Check if entry is a directory (or a symlink pointing to a directory) + let isDirectory = entry.isDirectory(); + if (!isDirectory && entry.isSymbolicLink()) { + try { + const fullPath = join(searchDir, entry.name); + isDirectory = statSync(fullPath).isDirectory(); + } catch { + // Broken symlink or permission error - treat as file + } + } let relativePath: string; const name = entry.name; diff --git a/packages/tui/src/components/editor.ts b/packages/tui/src/components/editor.ts index 2c7e5b1f..ae4b5118 100644 --- a/packages/tui/src/components/editor.ts +++ b/packages/tui/src/components/editor.ts @@ -1245,7 +1245,7 @@ export class Editor implements Component { const beforeCursor = currentLine.slice(0, this.state.cursorCol); // Check if we're in a slash command context - if (beforeCursor.trimStart().startsWith("/")) { + if (beforeCursor.trimStart().startsWith("/") && !beforeCursor.trimStart().includes(" ")) { this.handleSlashCommandCompletion(); } else { this.forceFileAutocomplete(); @@ -1253,8 +1253,6 @@ export class Editor implements Component { } private handleSlashCommandCompletion(): void { - // For now, fall back to regular autocomplete (slash commands) - // This can be extended later to handle command-specific argument completion this.tryTriggerAutocomplete(true); }