opencode-hashline 1.0.1 → 1.0.2

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.md CHANGED
@@ -5,8 +5,12 @@
5
5
  **Content-addressable line hashing for precise AI code editing**
6
6
 
7
7
  [![CI](https://github.com/izzzzzi/opencode-hashline/actions/workflows/ci.yml/badge.svg)](https://github.com/izzzzzi/opencode-hashline/actions/workflows/ci.yml)
8
+ [![Release](https://github.com/izzzzzi/opencode-hashline/actions/workflows/release.yml/badge.svg)](https://github.com/izzzzzi/opencode-hashline/actions/workflows/release.yml)
8
9
  [![npm version](https://img.shields.io/npm/v/opencode-hashline.svg?style=flat&colorA=18181B&colorB=28CF8D)](https://www.npmjs.com/package/opencode-hashline)
10
+ [![npm downloads](https://img.shields.io/npm/dm/opencode-hashline.svg?style=flat&colorA=18181B&colorB=28CF8D)](https://www.npmjs.com/package/opencode-hashline)
11
+ [![GitHub release](https://img.shields.io/github/v/release/izzzzzi/opencode-hashline?style=flat&colorA=18181B&colorB=28CF8D)](https://github.com/izzzzzi/opencode-hashline/releases)
9
12
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg?style=flat&colorA=18181B&colorB=28CF8D)](LICENSE)
13
+ [![semantic-release](https://img.shields.io/badge/semantic--release-auto-e10079?style=flat&colorA=18181B)](https://github.com/semantic-release/semantic-release)
10
14
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.9-blue?style=flat&colorA=18181B&colorB=3178C6)](https://www.typescriptlang.org/)
11
15
  [![Node.js](https://img.shields.io/badge/Node.js-ESM-green?style=flat&colorA=18181B&colorB=339933)](https://nodejs.org/)
12
16
 
package/README.ru.md CHANGED
@@ -5,8 +5,12 @@
5
5
  **Контентно-адресуемое хеширование строк для точного редактирования кода с помощью AI**
6
6
 
7
7
  [![CI](https://github.com/izzzzzi/opencode-hashline/actions/workflows/ci.yml/badge.svg)](https://github.com/izzzzzi/opencode-hashline/actions/workflows/ci.yml)
8
+ [![Release](https://github.com/izzzzzi/opencode-hashline/actions/workflows/release.yml/badge.svg)](https://github.com/izzzzzi/opencode-hashline/actions/workflows/release.yml)
8
9
  [![npm version](https://img.shields.io/npm/v/opencode-hashline.svg?style=flat&colorA=18181B&colorB=28CF8D)](https://www.npmjs.com/package/opencode-hashline)
10
+ [![npm downloads](https://img.shields.io/npm/dm/opencode-hashline.svg?style=flat&colorA=18181B&colorB=28CF8D)](https://www.npmjs.com/package/opencode-hashline)
11
+ [![GitHub release](https://img.shields.io/github/v/release/izzzzzi/opencode-hashline?style=flat&colorA=18181B&colorB=28CF8D)](https://github.com/izzzzzi/opencode-hashline/releases)
9
12
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg?style=flat&colorA=18181B&colorB=28CF8D)](LICENSE)
13
+ [![semantic-release](https://img.shields.io/badge/semantic--release-auto-e10079?style=flat&colorA=18181B)](https://github.com/semantic-release/semantic-release)
10
14
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.9-blue?style=flat&colorA=18181B&colorB=3178C6)](https://www.typescriptlang.org/)
11
15
  [![Node.js](https://img.shields.io/badge/Node.js-ESM-green?style=flat&colorA=18181B&colorB=339933)](https://nodejs.org/)
12
16
 
@@ -20,7 +20,7 @@ function debug(...args) {
20
20
  }
21
21
  }
22
22
  var FILE_READ_TOOLS = ["read", "file_read", "read_file", "cat", "view"];
23
- var FILE_EDIT_TOOLS = ["write", "file_write", "file_edit", "edit", "edit_file", "patch", "apply_patch", "multiedit"];
23
+ var FILE_EDIT_TOOLS = ["write", "file_write", "file_edit", "edit", "edit_file", "patch", "apply_patch", "multiedit", "batch"];
24
24
  function isFileReadTool(toolName, args) {
25
25
  const lower = toolName.toLowerCase();
26
26
  const nameMatch = FILE_READ_TOOLS.some(
@@ -40,8 +40,16 @@ function createFileReadAfterHook(cache, config) {
40
40
  const resolved = config ?? resolveConfig();
41
41
  const hashLen = resolved.hashLength || 0;
42
42
  const prefix = resolved.prefix;
43
+ const processedCallIds = /* @__PURE__ */ new Set();
43
44
  return async (input, output) => {
44
45
  debug("tool.execute.after:", input.tool, "args:", input.args);
46
+ if (input.callID) {
47
+ if (processedCallIds.has(input.callID)) {
48
+ debug("skipped: duplicate callID", input.callID);
49
+ return;
50
+ }
51
+ processedCallIds.add(input.callID);
52
+ }
45
53
  if (!isFileReadTool(input.tool, input.args)) {
46
54
  debug("skipped: not a file-read tool");
47
55
  return;
@@ -79,7 +87,14 @@ function createFileReadAfterHook(cache, config) {
79
87
  function createFileEditBeforeHook(config) {
80
88
  const resolved = config ?? resolveConfig();
81
89
  const prefix = resolved.prefix;
90
+ const processedCallIds = /* @__PURE__ */ new Set();
82
91
  return async (input, output) => {
92
+ if (input.callID) {
93
+ if (processedCallIds.has(input.callID)) {
94
+ return;
95
+ }
96
+ processedCallIds.add(input.callID);
97
+ }
83
98
  const toolName = input.tool.toLowerCase();
84
99
  const isFileEdit = FILE_EDIT_TOOLS.some(
85
100
  (name) => toolName === name || toolName.endsWith(`.${name}`)
package/dist/index.cjs CHANGED
@@ -476,7 +476,7 @@ function debug(...args) {
476
476
  }
477
477
  }
478
478
  var FILE_READ_TOOLS = ["read", "file_read", "read_file", "cat", "view"];
479
- var FILE_EDIT_TOOLS = ["write", "file_write", "file_edit", "edit", "edit_file", "patch", "apply_patch", "multiedit"];
479
+ var FILE_EDIT_TOOLS = ["write", "file_write", "file_edit", "edit", "edit_file", "patch", "apply_patch", "multiedit", "batch"];
480
480
  function isFileReadTool(toolName, args) {
481
481
  const lower = toolName.toLowerCase();
482
482
  const nameMatch = FILE_READ_TOOLS.some(
@@ -496,8 +496,16 @@ function createFileReadAfterHook(cache, config) {
496
496
  const resolved = config ?? resolveConfig();
497
497
  const hashLen = resolved.hashLength || 0;
498
498
  const prefix = resolved.prefix;
499
+ const processedCallIds = /* @__PURE__ */ new Set();
499
500
  return async (input, output) => {
500
501
  debug("tool.execute.after:", input.tool, "args:", input.args);
502
+ if (input.callID) {
503
+ if (processedCallIds.has(input.callID)) {
504
+ debug("skipped: duplicate callID", input.callID);
505
+ return;
506
+ }
507
+ processedCallIds.add(input.callID);
508
+ }
501
509
  if (!isFileReadTool(input.tool, input.args)) {
502
510
  debug("skipped: not a file-read tool");
503
511
  return;
@@ -535,7 +543,14 @@ function createFileReadAfterHook(cache, config) {
535
543
  function createFileEditBeforeHook(config) {
536
544
  const resolved = config ?? resolveConfig();
537
545
  const prefix = resolved.prefix;
546
+ const processedCallIds = /* @__PURE__ */ new Set();
538
547
  return async (input, output) => {
548
+ if (input.callID) {
549
+ if (processedCallIds.has(input.callID)) {
550
+ return;
551
+ }
552
+ processedCallIds.add(input.callID);
553
+ }
539
554
  const toolName = input.tool.toLowerCase();
540
555
  const isFileEdit = FILE_EDIT_TOOLS.some(
541
556
  (name) => toolName === name || toolName.endsWith(`.${name}`)
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  createFileEditBeforeHook,
3
3
  createFileReadAfterHook,
4
4
  createSystemPromptHook
5
- } from "./chunk-C2EVIAGV.js";
5
+ } from "./chunk-VW5NAHEY.js";
6
6
  import {
7
7
  HashlineCache,
8
8
  applyHashEdit,
package/dist/utils.cjs CHANGED
@@ -460,7 +460,7 @@ function debug(...args) {
460
460
  }
461
461
  }
462
462
  var FILE_READ_TOOLS = ["read", "file_read", "read_file", "cat", "view"];
463
- var FILE_EDIT_TOOLS = ["write", "file_write", "file_edit", "edit", "edit_file", "patch", "apply_patch", "multiedit"];
463
+ var FILE_EDIT_TOOLS = ["write", "file_write", "file_edit", "edit", "edit_file", "patch", "apply_patch", "multiedit", "batch"];
464
464
  function isFileReadTool(toolName, args) {
465
465
  const lower = toolName.toLowerCase();
466
466
  const nameMatch = FILE_READ_TOOLS.some(
@@ -480,8 +480,16 @@ function createFileReadAfterHook(cache, config) {
480
480
  const resolved = config ?? resolveConfig();
481
481
  const hashLen = resolved.hashLength || 0;
482
482
  const prefix = resolved.prefix;
483
+ const processedCallIds = /* @__PURE__ */ new Set();
483
484
  return async (input, output) => {
484
485
  debug("tool.execute.after:", input.tool, "args:", input.args);
486
+ if (input.callID) {
487
+ if (processedCallIds.has(input.callID)) {
488
+ debug("skipped: duplicate callID", input.callID);
489
+ return;
490
+ }
491
+ processedCallIds.add(input.callID);
492
+ }
485
493
  if (!isFileReadTool(input.tool, input.args)) {
486
494
  debug("skipped: not a file-read tool");
487
495
  return;
@@ -519,7 +527,14 @@ function createFileReadAfterHook(cache, config) {
519
527
  function createFileEditBeforeHook(config) {
520
528
  const resolved = config ?? resolveConfig();
521
529
  const prefix = resolved.prefix;
530
+ const processedCallIds = /* @__PURE__ */ new Set();
522
531
  return async (input, output) => {
532
+ if (input.callID) {
533
+ if (processedCallIds.has(input.callID)) {
534
+ return;
535
+ }
536
+ processedCallIds.add(input.callID);
537
+ }
523
538
  const toolName = input.tool.toLowerCase();
524
539
  const isFileEdit = FILE_EDIT_TOOLS.some(
525
540
  (name) => toolName === name || toolName.endsWith(`.${name}`)
package/dist/utils.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  createFileReadAfterHook,
4
4
  createSystemPromptHook,
5
5
  isFileReadTool
6
- } from "./chunk-C2EVIAGV.js";
6
+ } from "./chunk-VW5NAHEY.js";
7
7
  import {
8
8
  DEFAULT_CONFIG,
9
9
  DEFAULT_EXCLUDE_PATTERNS,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-hashline",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Hashline plugin for OpenCode — content-addressable line hashing for precise AI code editing",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",
@@ -45,8 +45,11 @@
45
45
  },
46
46
  "devDependencies": {
47
47
  "@opencode-ai/plugin": "^1.2.2",
48
+ "@semantic-release/changelog": "^6.0.3",
49
+ "@semantic-release/git": "^10.0.1",
48
50
  "@types/node": "^25.2.3",
49
51
  "@types/picomatch": "^4.0.2",
52
+ "semantic-release": "^25.0.3",
50
53
  "tsup": "^8.5.1",
51
54
  "typescript": "^5.9.3",
52
55
  "vitest": "^4.0.18",
@@ -54,5 +57,27 @@
54
57
  },
55
58
  "dependencies": {
56
59
  "picomatch": "^4.0.3"
60
+ },
61
+ "release": {
62
+ "branches": [
63
+ "main"
64
+ ],
65
+ "plugins": [
66
+ "@semantic-release/commit-analyzer",
67
+ "@semantic-release/release-notes-generator",
68
+ "@semantic-release/changelog",
69
+ "@semantic-release/npm",
70
+ "@semantic-release/github",
71
+ [
72
+ "@semantic-release/git",
73
+ {
74
+ "assets": [
75
+ "package.json",
76
+ "CHANGELOG.md"
77
+ ],
78
+ "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
79
+ }
80
+ ]
81
+ ]
57
82
  }
58
83
  }