Fixes a file-corruption bug in rename_symbol (#12, reported by @V0idk), makes speculative confidence honest about still-indexing servers, and upgrades gcf-go to v1.5.0.
Fixed
- rename_symbol file corruption (#12):
rename_symbol(non-dry-run) used to return the raw WorkspaceEdit and rely on the caller copying it back intoapply_edit— the only edit tool that did so;replace_symbol_body,insert_after_symbol,insert_before_symbol, andsafe_delete_symbolall apply server-side. That round-trip corrupted files: underAGENT_LSP_OUTPUT_FORMAT=gcfthe edit was GCF-encoded (a summary format that flattens each TextEdit's range into positional path columns likerange>end>characterand requires the verbatimnewTextto be copied out of tool output and back into a tool argument), so LLM callers transposed the range offsets and truncated a largenewText, overwriting the file. gcf-go itself encodes and decodes these WorkspaceEdits losslessly (verified), so this was an agent-lsp wire-format and round-trip bug, not a gcf-go bug. Reported by @V0idk.
Changed
- BREAKING:
rename_symbolnow applies the edit itself and returns a summary instead of returning a WorkspaceEdit for the caller to apply. The result isRenamed to "X" across N location(s) in M file(s): ...plus a post-rename diagnostics count, consistent with the other edit tools — the WorkspaceEdit never leaves the server as data to reconstruct, which eliminates the round-trip that corrupted files (#12). A separateapply_editcall after a non-dry-run rename is no longer needed (or wanted);apply_editremains for its text-match mode. Thedry_run=truepreview is unchanged in intent (returns the edit for inspection) but now serializes as self-labeling JSON regardless ofAGENT_LSP_OUTPUT_FORMAT, plus file/location counts. Thelsp-renameskill's execute phase is updated accordingly. - gcf-go upgraded to v1.5.0. Brings nested-null flatten losslessness (a nested object null at an intermediate level, e.g.
{meta:{owner:null}}, is no longer silently dropped on round-trip) and deterministic graph edge ordering (edges sorted by source, then target, then type). Generic-profile delta encoding and labeled streaming trailer counts are available as opt-in APIs; agent-lsp does not use them yet, so default output is byte-identical. No API changes required.
Added
confidence: "low"for unindexed speculative results.evaluate_session/preview_editnow reportconfidence: "low"when a clean result (net_delta <= 0) is read while the language server still has active$/progresswork (indexing, cache priming,cargo check). Previously such results were reported asconfidence: "high", so a still-priming server (notably rust-analyzer) could return a false all-clear — "no errors introduced" when the diagnostics simply had not been computed yet. Results that surface errors (net_delta > 0) are never downgraded, since diagnostics do not appear spuriously. NewLSPClient.HasActiveProgress()exposes the signal.
Tests
- Added a live end-to-end regression (
TestRenameSymbol_LiveGopls) that drives a realtextDocument/renamethrough gopls and the full handler, asserting the file is renamed on disk and the tool returns a summary with no raw edit leaked. Skips cleanly when gopls is absent; CI'sunit-and-smokejob now installs gopls so it runs there. Added unit coverage for the apply path against the pathological single-big-edit shape from #12 (TestApplyWorkspaceEdit_*), the JSON edit-encoding guard (TestEncodeResultJSON_*), and the rename summary counter (TestSummarizeWorkspaceEdit_*).