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.
- package/README.en.md +19 -11
- package/README.md +19 -11
- 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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
373
|
-
npx tsx benchmark/run.ts --no-hash
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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` встречается в файле несколько раз (
|
|
350
|
+
`str_replace` ломается, когда `old_string` встречается в файле несколько раз (повторяющиеся guard-клаузы, похожие блоки кода). Hashline адресует каждую строку уникально через `lineNumber:hash` — неоднозначность исключена, модельный формат не нужен.
|
|
344
351
|
|
|
345
352
|
```bash
|
|
346
353
|
# Запустите сами:
|
|
347
|
-
npx tsx benchmark/run.ts
|
|
348
|
-
npx tsx benchmark/run.ts --no-hash
|
|
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.
|
|
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",
|