Skip to content

perf: supply AIR diff counts from Claude structured patches - #1122

Merged
nikita-ashihmin merged 4 commits into
mainfrom
nikita.ashikhmin/diff-statistics
Sep 15, 2026
Merged

nikita-ashihmin merged 4 commits into
mainfrom
nikita.ashikhmin/diff-statistics

Conversation

@nikita-ashihmin

Copy link
Copy Markdown
Collaborator

Claude supplies structured patches for Edit and Write, but ACP diff blocks previously carried only the reconstructed texts. AIR had to compare those texts again to display added and removed counts.

Count patch operations in the existing conversion loop and publish _meta.jetbrains.air.diffStats on each diff block. This uses the same contract as agentclientprotocol/codex-acp#501. Each block has its own counts. No extra traversal, full file comparison, or navigation calculation is needed.

Omit statistics when patches are absent or inconsistent, so clients retain their existing fallback. Exclude EOF markers from the displayed texts. Document the extension and cover per-block counts, Edit and Write hooks, EOF changes, and fallback behavior.

Validation:

  • npm run build
  • npm run check
  • env -u ANTHROPIC_BASE_URL npm run test:run (the local endpoint override affects unrelated provider tests)

Count additions and deletions while building each ACP diff block.
AIR can use these counts without comparing the hunk texts again.
No extra traversal or full file comparison is needed.

Keep the existing fallback when patches are absent or inconsistent.
Exclude EOF markers from the displayed text and the counts.

Validation: build, lint, formatting, and 1308 tests pass.
Run the tests without the local ANTHROPIC_BASE_URL override.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Malformed hunks can still receive authoritative statistics instead of triggering client fallback.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds AIR diff statistics to avoid redundant client-side diff calculations.

Changes:

  • Counts additions/removals per structured patch hunk.
  • Adds metadata, fallback, EOF, Edit, and Write coverage.
  • Documents the AIR extension contract.
File summaries
File Description
src/tools.ts Calculates and publishes per-block statistics.
src/air-extension.ts Defines the diff statistics key.
src/tests/diff-statistics.test.ts Tests counting and fallback behavior.
src/tests/tools.test.ts Updates Edit and Write hook expectations.
src/tests/acp-agent.test.ts Updates conversion expectations.
docs/diff-statistics-extension.md Documents metadata and behavior.
Review details
  • Files reviewed: 6/6 changed files
  • Comments generated: 1
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/tools.ts Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Coordinate consistency validation is incomplete, allowing statistics on malformed multi-hunk patches.

Review details

Suppressed comments (2)

Previously missed (1) — in code that hasn't changed since the last review.

docs/diff-statistics-extension.md:14

  • The wire example omits the _meta level even though the documented path and emitted code use _meta.jetbrains.air.diffStats. As written, copying this example places jetbrains directly on the diff block and AIR will not find the statistics.

src/tools.ts:1427

  • The coordinate validation only checks that the old and new axes are independently monotonic. It still publishes metadata for an inconsistent patch where an earlier hunk changes the line delta but a later hunk's newStart does not reflect that shift. Track the accumulated added/removed delta (accounting for zero-line hunk coordinates) and omit _meta when the old/new starts disagree.
  async (input: any, toolUseID: string | undefined): Promise<{ continue: boolean }> => {
    if (input.hook_event_name === "PostToolUse") {
      // Handle EnterPlanMode tool - notify client of mode change after successful execution
      if (input.tool_name === "EnterPlanMode" && options?.onEnterPlanMode) {
  • Files reviewed: 8/8 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The implementation is focused, validates malformed patches, preserves fallback behavior, and has comprehensive coverage.

Review details
  • Files reviewed: 8/8 changed files
  • Comments generated: 0 new
  • Review effort level: Balanced

@nikita-ashihmin
nikita-ashihmin merged commit 735950a into main Sep 15, 2026
7 checks passed
@nikita-ashihmin
nikita-ashihmin deleted the nikita.ashikhmin/diff-statistics branch September 15, 2026 08:39
nikita-ashihmin pushed a commit that referenced this pull request Sep 15, 2026
🤖 I have created a release *beep* *boop*
---


##
[0.78.0](v0.77.0...v0.78.0)
(2026-09-15)


### Features

* Add experimental ACP compaction update support
([#1134](#1134))
([543a9a2](543a9a2))


### Bug Fixes

* keep the picked option when AskUserQuestion custom text is also
supplied
([#1131](#1131))
([8823ea6](8823ea6))


### Performance Improvements

* report file changes from Claude checkpoints
([#1138](#1138))
([91f1699](91f1699))
* supply AIR diff counts from Claude structured patches
([#1122](#1122))
([735950a](735950a))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: acp-release-bot[bot] <246668977+acp-release-bot[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants