opencode-hashline 1.1.3 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.en.md +19 -11
  2. package/README.md +19 -11
  3. package/package.json +1 -1
package/README.en.md CHANGED
@@ -44,7 +44,12 @@ The AI model can then reference lines by their hash tags for precise editing:
44
44
 
45
45
  ### 🤔 Why does this help?
46
46
 
47
- Traditional line numbers shift as edits are made, causing off-by-one errors and stale references. Hashline tags are **content-addressable** — they're derived from both the line index and the line's content, so they serve as a stable, verifiable reference that the AI can use to communicate about code locations with precision.
47
+ Hashline solves the fundamental problems of the two existing AI file-editing approaches:
48
+
49
+ - **`str_replace`** requires an absolutely exact match of `old_string`. Any extra whitespace, wrong indentation, or duplicate lines in the file — and the edit fails with "String to replace not found". This is so common it has a [mega-thread of 27+ related issues on GitHub](https://github.com/anthropics/claude-code/issues).
50
+ - **`apply_patch`** (unified diff) only works on models specifically trained for this format. On other models the results are catastrophic: Grok 4 fails **50.7%** of patches, GLM-4.7 fails **46.2%** ([source](https://habr.com/ru/companies/bothub/news/995986/)).
51
+
52
+ Hashline addresses each line with a unique `lineNumber:hash`. No string matching, no model-specific training dependency — just precise, verifiable line addressing.
48
53
 
49
54
  ---
50
55
 
@@ -355,22 +360,25 @@ const hl = createHashline({ cacheSize: 50, hashLength: 3 });
355
360
 
356
361
  ## 📊 Benchmark
357
362
 
358
- ### Correctness: hashline vs str_replace
363
+ ### Correctness: hashline vs str_replace vs apply_patch
364
+
365
+ We tested all three approaches on **60 fixtures from [react-edit-benchmark](https://github.com/can1357/oh-my-pi/tree/main/packages/react-edit-benchmark)** — mutated React source files with known bugs (flipped booleans, swapped operators, removed guard clauses, etc.):
359
366
 
360
- We tested both approaches on **60 fixtures from [react-edit-benchmark](https://github.com/can1357/oh-my-pi/tree/main/packages/react-edit-benchmark)** — mutated React source files with known bugs (flipped booleans, swapped operators, removed guard clauses, etc.):
367
+ | | hashline | str_replace | apply_patch |
368
+ |---|:---:|:---:|:---:|
369
+ | **Passed** | **60/60 (100%)** | 58/60 (96.7%) | **60/60 (100%)** |
370
+ | **Failed** | 0 | 2 | 0 |
371
+ | **Ambiguous edits** | 0 | 4 | 0 |
361
372
 
362
- | | hashline | str_replace |
363
- |---|:---:|:---:|
364
- | **Passed** | **60/60 (100%)** | 58/60 (96.7%) |
365
- | **Failed** | 0 | 2 |
366
- | **Ambiguous edits** | 0 | 4 |
373
+ `apply_patch` with context lines matches hashline's reliability **when the model generates the patch correctly**. The key weakness of `apply_patch` is its dependency on model-specific training: models not trained on this format produce malformed diffs (missing context lines, wrong indentation), causing patch application to fail.
367
374
 
368
- str_replace fails when the `old_string` appears multiple times in the file (e.g. repeated guard clauses, similar code blocks). Hashline addresses each line uniquely via `lineNumber:hash`, so ambiguity is impossible.
375
+ `str_replace` fails when `old_string` appears multiple times in the file (repeated guard clauses, similar code blocks). Hashline addresses each line uniquely via `lineNumber:hash` ambiguity is impossible and no model-specific format is required.
369
376
 
370
377
  ```bash
371
378
  # Run yourself:
372
- npx tsx benchmark/run.ts # hashline mode
373
- npx tsx benchmark/run.ts --no-hash # str_replace mode
379
+ npx tsx benchmark/run.ts # hashline mode
380
+ npx tsx benchmark/run.ts --no-hash # str_replace mode
381
+ npx tsx benchmark/run.ts --apply-patch # apply_patch mode
374
382
  ```
375
383
 
376
384
  <details>
package/README.md CHANGED
@@ -44,7 +44,12 @@ AI-модель может ссылаться на строки по их хеш
44
44
 
45
45
  ### 🤔 Почему это помогает?
46
46
 
47
- Традиционные номера строк сдвигаются при редактировании, вызывая ошибки смещения и устаревшие ссылки. Хеш-теги Hashline **контентно-адресуемы** они вычисляются из индекса строки и её содержимого, что делает их стабильной, верифицируемой ссылкой для точной коммуникации о местоположении в коде.
47
+ Hashline решает фундаментальные проблемы двух существующих подходов к редактированию файлов AI:
48
+
49
+ - **`str_replace`** требует абсолютно точного совпадения `old_string`. Любой лишний пробел, неверный отступ или дублирующиеся строки в файле — и редактирование завершается ошибкой «String to replace not found». Это настолько распространённая проблема, что у неё есть [мегатред на 27+ тикетов на GitHub](https://github.com/anthropics/claude-code/issues).
50
+ - **`apply_patch`** (unified diff) работает только на моделях, специально обученных этому формату. На других моделях результаты катастрофические: Grok 4 проваливает **50.7%** патчей, GLM-4.7 — **46.2%** ([источник](https://habr.com/ru/companies/bothub/news/995986/)).
51
+
52
+ Hashline адресует каждую строку уникальным хешем `lineNumber:hash`. Никакого строкового совпадения, никакой зависимости от специального обучения модели — только точная, верифицируемая адресация.
48
53
 
49
54
  ---
50
55
 
@@ -330,22 +335,25 @@ const hl = createHashline({ cacheSize: 50, hashLength: 3 });
330
335
 
331
336
  ## 📊 Бенчмарк
332
337
 
333
- ### Корректность: hashline vs str_replace
338
+ ### Корректность: hashline vs str_replace vs apply_patch
339
+
340
+ Все три подхода протестированы на **60 фикстурах из [react-edit-benchmark](https://github.com/can1357/oh-my-pi/tree/main/packages/react-edit-benchmark)** — мутированных файлах React с известными багами (инвертированные булевы, перепутанные операторы, удалённые guard-клаузы и т.д.):
334
341
 
335
- Оба подхода протестированы на **60 фикстурах из [react-edit-benchmark](https://github.com/can1357/oh-my-pi/tree/main/packages/react-edit-benchmark)** — мутированных файлах React с известными багами (инвертированные булевы, перепутанные операторы, удалённые guard-клаузы и т.д.):
342
+ | | hashline | str_replace | apply_patch |
343
+ |---|:---:|:---:|:---:|
344
+ | **Прошло** | **60/60 (100%)** | 58/60 (96.7%) | **60/60 (100%)** |
345
+ | **Провалено** | 0 | 2 | 0 |
346
+ | **Неоднозначные правки** | 0 | 4 | 0 |
336
347
 
337
- | | hashline | str_replace |
338
- |---|:---:|:---:|
339
- | **Прошло** | **60/60 (100%)** | 58/60 (96.7%) |
340
- | **Провалено** | 0 | 2 |
341
- | **Неоднозначные правки** | 0 | 4 |
348
+ `apply_patch` с контекстными строками работает так же надёжно, как hashline **при условии, что модель правильно генерирует патч**. Слабое место `apply_patch` — зависимость от обучения конкретной модели: не обученные под этот формат модели производят некорректные diff-ы (пропускают контекст, путают отступы), что приводит к провалу применения патча.
342
349
 
343
- str_replace ломается, когда `old_string` встречается в файле несколько раз (например, повторяющиеся guard-клаузы, похожие блоки кода). Hashline адресует каждую строку уникально через `lineNumber:hash`, поэтому неоднозначность исключена.
350
+ `str_replace` ломается, когда `old_string` встречается в файле несколько раз (повторяющиеся guard-клаузы, похожие блоки кода). Hashline адресует каждую строку уникально через `lineNumber:hash` неоднозначность исключена, модельный формат не нужен.
344
351
 
345
352
  ```bash
346
353
  # Запустите сами:
347
- npx tsx benchmark/run.ts # режим hashline
348
- npx tsx benchmark/run.ts --no-hash # режим str_replace
354
+ npx tsx benchmark/run.ts # режим hashline
355
+ npx tsx benchmark/run.ts --no-hash # режим str_replace
356
+ npx tsx benchmark/run.ts --apply-patch # режим apply_patch
349
357
  ```
350
358
 
351
359
  <details>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-hashline",
3
- "version": "1.1.3",
3
+ "version": "1.2.0",
4
4
  "description": "Hashline plugin for OpenCode — content-addressable line hashing for precise AI code editing",
5
5
  "main": "dist/opencode-hashline.cjs",
6
6
  "module": "dist/opencode-hashline.js",