Hmbown / Hmbown/Codewhale

v0.9.14: Add AST-resolved symbol-targeted edits (edit_symbol) so anchoring stops failing on text matching

Open
#6,203 1 comment 0 reactions 0 assignees View on GitHub
enhancement rust tools
Dominant language
Rust
Stars
41k
Forks
3.6k
Avg merge
13h 59m
Merged PRs (30d)
299

Description

## Why this matters

The dominant edit-tool failure mode is anchoring, not syntax: `edit_file`'s
`old_string` is not found, is not unique, or matches stale whitespace after a
format change. Each failure costs a turn and a re-read. Letting the model
address code by *name* — "replace `impl Foo::bar`" — removes the failure class
entirely instead of detecting it after the fact.

## Current behavior

- `edit_file` does exact-string replacement with fidelity checks
(`crates/tui/src/tools/file.rs:1607`); `apply_patch` applies unified-diff
hunks textually (`crates/tui/src/tools/apply_patch.rs:232`).
- Symbol knowledge exists only through the opt-in LSP tool
(`crates/tui/src/tools/lsp.rs`), which requires a spawned server and cannot
return edit-ready spans offline.
- No structural resolver exists for offline, deterministic span lookup.

## Desired behavior

1. New tool (e.g. `edit_symbol`) taking `{ path, symbol, replacement }` where
`symbol` names a Rust/TS item: `fn name`, `impl Type::method`,
`struct Name`, `const NAME`, etc.
2. Resolve the item's full byte span — including doc comments and attributes —
via `ast-grep-core` (same dependency as #6202), then splice the replacement
and run the post-edit syntax gate before reporting success.
3. Ambiguous matches return a typed error listing candidate items (name +
kind + line), never a silent first-match.
4. Unsupported languages return a clear error pointing at
`edit_file`/`apply_patch` as the fallback.
5. All writes flow through the existing approval/sandbox/write policy
unchanged; a diff preview is returned in the tool result.

## Evidence

- Exact-match edit path: `crates/tui/src/tools/file.rs:1607-2270`.
- Unified-diff path: `crates/tui/src/tools/apply_patch.rs:232`.
- LSP symbols exist but are server-bound: `crates/tui/src/tools/lsp.rs`,
`crates/tui/src/lsp/registry.rs:100`.

## Acceptance criteria

- [ ] `edit_symbol` replaces a named `fn`/`impl` block on a Rust fixture,
including its doc comments, verified by a unit test.
- [ ] Two same-named functions produce an ambiguity error listing both
candidates, not a blind first match.
- [ ] Post-edit output passes the syntax gate from #6202; a syntactically
broken replacement is rejected before write.
- [ ] Unsupported file types fail with explicit fallback guidance.
- [ ] `cargo test -p codewhale-tui` edit-tool tests stay green.

## Related

- #6202 — the ast-grep-core dependency and post-edit syntax gate this builds on.
- #3980 — broader structural search/preview scope, closed not planned; this is
the narrower edit-only slice.

Contributor guide

Open the contributing guide

Research direction

Start by reading crates/tui/src/tools/file.rs, crates/tui/src/tools/apply_patch.rs, crates/tui/src/tools/lsp.rs, and the ast-grep-core and syntax-gate work in #6202. Run the existing edit-tool tests with cargo test -p codewhale-tui, then use Rust fixtures to verify named replacement, ambiguity errors, syntax rejection, unsupported-language guidance, and unchanged approval/write policy.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust, typescript
Domain
cli, testing-qa, tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.