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

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 https://github.com/agentclientprotocol/codex-acp/pull/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)
This commit is contained in:
nikita-ashihmin
2026-09-15 12:39:39 +04:00
committed by GitHub
parent 543a9a2f97
commit 735950a83e
8 changed files with 361 additions and 102 deletions

View File

@@ -0,0 +1,30 @@
# AIR diff statistics
The adapter supplies counts in each ACP diff block through `_meta.jetbrains.air.diffStats`.
This uses the same contract as the Codex adapter. No capability negotiation is required.
```json
{
"_meta": {
"jetbrains": {
"air": {
"version": 1,
"diffStats": { "version": 1, "added": 20, "removed": 30 }
}
}
}
}
```
Both counts are nonnegative integers. They describe the operations in that block's patch.
Context lines and EOF markers do not increase the counts.
The extension carries no navigation position.
For `Edit` and `Write`, the adapter counts operations while it builds diff texts from the SDK's `structuredPatch`.
Each hunk produces one block with its own counts. The adapter does not compare or scan the full file texts for statistics.
When a patch has unsafe, unordered, or mutually inconsistent coordinates, inconsistent line counts,
misplaced EOF markers, or unsupported prefixes, the adapter omits the statistics.
Empty patches, initial tool inputs, and history without structured patches retain their existing behavior.
They provide no statistics because the adapter has no patch operations to count.
AIR uses its existing comparison when statistics are absent.