Hmbown / Hmbown/Codewhale

v0.9.14: Embed ast-grep-core in the tools edit path to reject syntax-breaking file edits

Open
#6,202 2 comments 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

Agent file edits currently land as pure text patches. When the model produces a
patch whose result does not parse — unbalanced delimiters, truncated blocks,
stray conflict markers — the defect is only discovered by the next compile,
test run, or reviewer. Every such failure costs a turn cycle and erodes trust
in autonomous edits. A fast, dependency-light structural check at the edit
boundary converts this class of error into a clean, retryable tool result.

`ast-grep-core` gives us tree-sitter-quality parsing for a bounded language set
without shipping per-language servers or a full structural-search feature.

## Current behavior

- `crates/tui/src/tools/apply_patch.rs` parses unified-diff shape and applies
hunks textually; `file.rs`/`file_tool.rs` write content directly. Neither
path parses the post-edit file.
- `crates/tui/src/tools/lsp.rs` exposes model-callable LSP diagnostics, but it
requires a spawned language server and is not consulted automatically on
edits — no syntax gate exists on the edit path.
- No `ast-grep`/`tree-sitter` dependency exists anywhere in the workspace
(verified via grep of all Cargo.tomls at `31146342b`).

## Desired behavior

1. Add `ast-grep-core` (pinned, conservative version) as a dependency of
`crates/tools` — the shared tool-contracts crate — exposing a small
`syntax_check(language, source)` helper crate-side.
2. The file-edit tools (`apply_patch`, `edit_file`/`file_tool` writes) run the
check on the post-edit content for supported languages before reporting
success.
3. A syntax failure returns a typed tool error naming the offending region
(line/column where available) instead of silently writing a broken file.
Decide explicitly whether the file write is rolled back or written with a
visible diagnostic; record the choice in the tool result.
4. Unsupported languages fail open — the check is skipped and the edit proceeds
as today, with no new failure mode.
5. Start with Rust + TypeScript/JavaScript; the helper's language set is
explicitly enumerable so adding grammars is a one-line change.

## Evidence

- Edit path with no post-write parse: `crates/tui/src/tools/apply_patch.rs:232`,
`crates/tui/src/tools/file.rs`, `crates/tui/src/tools/file_tool.rs`.
- Shared contracts crate to host the dependency: `crates/tools/Cargo.toml`
(currently protocol/serde/tokio only).
- LSP tool is opt-in, not a gate: `crates/tui/src/tools/lsp.rs:1`.

## Acceptance criteria

- [ ] `ast-grep-core` builds in `crates/tools` and is exercised by a unit test
over a deliberately broken Rust and TS fixture.
- [ ] An `apply_patch` edit that produces unparsable Rust returns a typed tool
error naming the region; the failure is observable to the model so it can
retry.
- [ ] A syntactically valid edit reports success unchanged (no regression in
`cargo test -p codewhale-tui` tool tests).
- [ ] Unsupported file types proceed exactly as today.
- [ ] No model-visible payloads, paths, or file contents leak into logs beyond
existing tool-result conventions.

## Related

- #3980 proposed the broader structural code search + AST-backed edit-preview
scope and was closed as not planned (2026-09-11). This issue is deliberately
narrower: syntax validation on the existing edit path, no new search surface.

Contributor guide

Open the contributing guide

Research direction

Read crates/tools/Cargo.toml and trace the edit flow through crates/tui/src/tools/apply_patch.rs, file.rs, and file_tool.rs; compare the existing LSP handling in lsp.rs. Run the relevant workspace tests, then verify Rust and TypeScript/JavaScript fixtures report typed syntax failures while valid edits and unsupported file types retain their current behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, rust, typescript
Domain
cli, testing, tooling
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
66/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.