opencode-hashline 1.0.2 → 1.0.3
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/dist/{chunk-VW5NAHEY.js → chunk-OJ2CHKQK.js} +34 -8
- package/dist/index.cjs +71 -14
- package/dist/index.js +41 -10
- package/dist/utils.cjs +34 -8
- package/dist/utils.js +1 -1
- package/package.json +1 -1
|
@@ -11,6 +11,19 @@ import { appendFileSync } from "fs";
|
|
|
11
11
|
import { join } from "path";
|
|
12
12
|
import { homedir } from "os";
|
|
13
13
|
var DEBUG_LOG = join(homedir(), ".config", "opencode", "hashline-debug.log");
|
|
14
|
+
var MAX_PROCESSED_IDS = 1e4;
|
|
15
|
+
function createBoundedSet(maxSize) {
|
|
16
|
+
const set = /* @__PURE__ */ new Set();
|
|
17
|
+
const originalAdd = set.add.bind(set);
|
|
18
|
+
set.add = (value) => {
|
|
19
|
+
if (set.size >= maxSize) {
|
|
20
|
+
const first = set.values().next().value;
|
|
21
|
+
if (first !== void 0) set.delete(first);
|
|
22
|
+
}
|
|
23
|
+
return originalAdd(value);
|
|
24
|
+
};
|
|
25
|
+
return set;
|
|
26
|
+
}
|
|
14
27
|
function debug(...args) {
|
|
15
28
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ")}
|
|
16
29
|
`;
|
|
@@ -40,7 +53,7 @@ function createFileReadAfterHook(cache, config) {
|
|
|
40
53
|
const resolved = config ?? resolveConfig();
|
|
41
54
|
const hashLen = resolved.hashLength || 0;
|
|
42
55
|
const prefix = resolved.prefix;
|
|
43
|
-
const processedCallIds =
|
|
56
|
+
const processedCallIds = createBoundedSet(MAX_PROCESSED_IDS);
|
|
44
57
|
return async (input, output) => {
|
|
45
58
|
debug("tool.execute.after:", input.tool, "args:", input.args);
|
|
46
59
|
if (input.callID) {
|
|
@@ -87,7 +100,7 @@ function createFileReadAfterHook(cache, config) {
|
|
|
87
100
|
function createFileEditBeforeHook(config) {
|
|
88
101
|
const resolved = config ?? resolveConfig();
|
|
89
102
|
const prefix = resolved.prefix;
|
|
90
|
-
const processedCallIds =
|
|
103
|
+
const processedCallIds = createBoundedSet(MAX_PROCESSED_IDS);
|
|
91
104
|
return async (input, output) => {
|
|
92
105
|
if (input.callID) {
|
|
93
106
|
if (processedCallIds.has(input.callID)) {
|
|
@@ -101,7 +114,7 @@ function createFileEditBeforeHook(config) {
|
|
|
101
114
|
);
|
|
102
115
|
if (!isFileEdit) return;
|
|
103
116
|
if (!output.args || typeof output.args !== "object") return;
|
|
104
|
-
const contentFields = [
|
|
117
|
+
const contentFields = /* @__PURE__ */ new Set([
|
|
105
118
|
"content",
|
|
106
119
|
"new_content",
|
|
107
120
|
"old_content",
|
|
@@ -111,13 +124,26 @@ function createFileEditBeforeHook(config) {
|
|
|
111
124
|
"text",
|
|
112
125
|
"diff",
|
|
113
126
|
"patch",
|
|
114
|
-
"patchText"
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
127
|
+
"patchText",
|
|
128
|
+
"body"
|
|
129
|
+
]);
|
|
130
|
+
function stripDeep(obj) {
|
|
131
|
+
for (const key of Object.keys(obj)) {
|
|
132
|
+
const val = obj[key];
|
|
133
|
+
if (typeof val === "string" && contentFields.has(key)) {
|
|
134
|
+
obj[key] = stripHashes(val, prefix);
|
|
135
|
+
} else if (Array.isArray(val)) {
|
|
136
|
+
for (const item of val) {
|
|
137
|
+
if (item && typeof item === "object" && !Array.isArray(item)) {
|
|
138
|
+
stripDeep(item);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
} else if (val && typeof val === "object" && !Array.isArray(val)) {
|
|
142
|
+
stripDeep(val);
|
|
143
|
+
}
|
|
119
144
|
}
|
|
120
145
|
}
|
|
146
|
+
stripDeep(output.args);
|
|
121
147
|
};
|
|
122
148
|
}
|
|
123
149
|
function createSystemPromptHook(config) {
|
package/dist/index.cjs
CHANGED
|
@@ -467,6 +467,19 @@ var import_path = require("path");
|
|
|
467
467
|
var import_os = require("os");
|
|
468
468
|
init_hashline();
|
|
469
469
|
var DEBUG_LOG = (0, import_path.join)((0, import_os.homedir)(), ".config", "opencode", "hashline-debug.log");
|
|
470
|
+
var MAX_PROCESSED_IDS = 1e4;
|
|
471
|
+
function createBoundedSet(maxSize) {
|
|
472
|
+
const set = /* @__PURE__ */ new Set();
|
|
473
|
+
const originalAdd = set.add.bind(set);
|
|
474
|
+
set.add = (value) => {
|
|
475
|
+
if (set.size >= maxSize) {
|
|
476
|
+
const first = set.values().next().value;
|
|
477
|
+
if (first !== void 0) set.delete(first);
|
|
478
|
+
}
|
|
479
|
+
return originalAdd(value);
|
|
480
|
+
};
|
|
481
|
+
return set;
|
|
482
|
+
}
|
|
470
483
|
function debug(...args) {
|
|
471
484
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ")}
|
|
472
485
|
`;
|
|
@@ -496,7 +509,7 @@ function createFileReadAfterHook(cache, config) {
|
|
|
496
509
|
const resolved = config ?? resolveConfig();
|
|
497
510
|
const hashLen = resolved.hashLength || 0;
|
|
498
511
|
const prefix = resolved.prefix;
|
|
499
|
-
const processedCallIds =
|
|
512
|
+
const processedCallIds = createBoundedSet(MAX_PROCESSED_IDS);
|
|
500
513
|
return async (input, output) => {
|
|
501
514
|
debug("tool.execute.after:", input.tool, "args:", input.args);
|
|
502
515
|
if (input.callID) {
|
|
@@ -543,7 +556,7 @@ function createFileReadAfterHook(cache, config) {
|
|
|
543
556
|
function createFileEditBeforeHook(config) {
|
|
544
557
|
const resolved = config ?? resolveConfig();
|
|
545
558
|
const prefix = resolved.prefix;
|
|
546
|
-
const processedCallIds =
|
|
559
|
+
const processedCallIds = createBoundedSet(MAX_PROCESSED_IDS);
|
|
547
560
|
return async (input, output) => {
|
|
548
561
|
if (input.callID) {
|
|
549
562
|
if (processedCallIds.has(input.callID)) {
|
|
@@ -557,7 +570,7 @@ function createFileEditBeforeHook(config) {
|
|
|
557
570
|
);
|
|
558
571
|
if (!isFileEdit) return;
|
|
559
572
|
if (!output.args || typeof output.args !== "object") return;
|
|
560
|
-
const contentFields = [
|
|
573
|
+
const contentFields = /* @__PURE__ */ new Set([
|
|
561
574
|
"content",
|
|
562
575
|
"new_content",
|
|
563
576
|
"old_content",
|
|
@@ -567,13 +580,26 @@ function createFileEditBeforeHook(config) {
|
|
|
567
580
|
"text",
|
|
568
581
|
"diff",
|
|
569
582
|
"patch",
|
|
570
|
-
"patchText"
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
583
|
+
"patchText",
|
|
584
|
+
"body"
|
|
585
|
+
]);
|
|
586
|
+
function stripDeep(obj) {
|
|
587
|
+
for (const key of Object.keys(obj)) {
|
|
588
|
+
const val = obj[key];
|
|
589
|
+
if (typeof val === "string" && contentFields.has(key)) {
|
|
590
|
+
obj[key] = stripHashes(val, prefix);
|
|
591
|
+
} else if (Array.isArray(val)) {
|
|
592
|
+
for (const item of val) {
|
|
593
|
+
if (item && typeof item === "object" && !Array.isArray(item)) {
|
|
594
|
+
stripDeep(item);
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
} else if (val && typeof val === "object" && !Array.isArray(val)) {
|
|
598
|
+
stripDeep(val);
|
|
599
|
+
}
|
|
575
600
|
}
|
|
576
601
|
}
|
|
602
|
+
stripDeep(output.args);
|
|
577
603
|
};
|
|
578
604
|
}
|
|
579
605
|
function createSystemPromptHook(config) {
|
|
@@ -661,15 +687,21 @@ function createHashlineEditTool(config, cache) {
|
|
|
661
687
|
async execute(args, context) {
|
|
662
688
|
const { path, operation, startRef, endRef, replacement } = args;
|
|
663
689
|
const absPath = (0, import_path2.isAbsolute)(path) ? path : (0, import_path2.resolve)(context.directory, path);
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
690
|
+
let realAbs;
|
|
691
|
+
try {
|
|
692
|
+
realAbs = (0, import_fs2.realpathSync)(absPath);
|
|
693
|
+
} catch {
|
|
694
|
+
realAbs = (0, import_path2.resolve)(absPath);
|
|
695
|
+
}
|
|
696
|
+
const realWorktree = (0, import_fs2.realpathSync)((0, import_path2.resolve)(context.worktree));
|
|
697
|
+
if (realAbs !== realWorktree && !realAbs.startsWith(realWorktree + import_path2.sep)) {
|
|
667
698
|
throw new Error(`Access denied: "${path}" resolves outside the project directory`);
|
|
668
699
|
}
|
|
700
|
+
const normalizedAbs = (0, import_path2.resolve)(absPath);
|
|
669
701
|
const displayPath = (0, import_path2.relative)(context.worktree, absPath) || path;
|
|
670
702
|
let current;
|
|
671
703
|
try {
|
|
672
|
-
current = (0, import_fs2.readFileSync)(
|
|
704
|
+
current = (0, import_fs2.readFileSync)(realAbs, "utf-8");
|
|
673
705
|
} catch (error) {
|
|
674
706
|
const reason = error instanceof Error ? error.message : String(error);
|
|
675
707
|
throw new Error(`Failed to read "${displayPath}": ${reason}`);
|
|
@@ -696,14 +728,15 @@ function createHashlineEditTool(config, cache) {
|
|
|
696
728
|
throw new Error(`Hashline edit failed for "${displayPath}": ${reason}`);
|
|
697
729
|
}
|
|
698
730
|
try {
|
|
699
|
-
(0, import_fs2.writeFileSync)(
|
|
731
|
+
(0, import_fs2.writeFileSync)(realAbs, nextContent, "utf-8");
|
|
700
732
|
} catch (error) {
|
|
701
733
|
const reason = error instanceof Error ? error.message : String(error);
|
|
702
734
|
throw new Error(`Failed to write "${displayPath}": ${reason}`);
|
|
703
735
|
}
|
|
704
736
|
if (cache) {
|
|
705
|
-
cache.invalidate(
|
|
737
|
+
cache.invalidate(realAbs);
|
|
706
738
|
cache.invalidate(normalizedAbs);
|
|
739
|
+
cache.invalidate(absPath);
|
|
707
740
|
if (path !== absPath) cache.invalidate(path);
|
|
708
741
|
if (displayPath !== absPath) cache.invalidate(displayPath);
|
|
709
742
|
}
|
|
@@ -751,6 +784,7 @@ function loadConfig(projectDir, userConfig) {
|
|
|
751
784
|
function createHashlinePlugin(userConfig) {
|
|
752
785
|
return async (input) => {
|
|
753
786
|
const projectDir = input.directory;
|
|
787
|
+
const worktree = input.worktree;
|
|
754
788
|
const fileConfig = loadConfig(projectDir, userConfig);
|
|
755
789
|
const config = resolveConfig(fileConfig);
|
|
756
790
|
const cache = new HashlineCache(config.cacheSize);
|
|
@@ -761,6 +795,17 @@ function createHashlinePlugin(userConfig) {
|
|
|
761
795
|
`);
|
|
762
796
|
} catch {
|
|
763
797
|
}
|
|
798
|
+
const tempFiles = /* @__PURE__ */ new Set();
|
|
799
|
+
const cleanupTempFiles = () => {
|
|
800
|
+
for (const f of tempFiles) {
|
|
801
|
+
try {
|
|
802
|
+
(0, import_fs3.unlinkSync)(f);
|
|
803
|
+
} catch {
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
tempFiles.clear();
|
|
807
|
+
};
|
|
808
|
+
process.on("exit", cleanupTempFiles);
|
|
764
809
|
return {
|
|
765
810
|
tool: {
|
|
766
811
|
hashline_edit: createHashlineEditTool(config, cache)
|
|
@@ -782,6 +827,17 @@ function createHashlinePlugin(userConfig) {
|
|
|
782
827
|
filePath = (0, import_url.fileURLToPath)(p.url);
|
|
783
828
|
}
|
|
784
829
|
if (!filePath) continue;
|
|
830
|
+
if (worktree) {
|
|
831
|
+
try {
|
|
832
|
+
const realFile = (0, import_fs3.realpathSync)(filePath);
|
|
833
|
+
const realWorktree = (0, import_fs3.realpathSync)((0, import_path3.resolve)(worktree));
|
|
834
|
+
if (realFile !== realWorktree && !realFile.startsWith(realWorktree + import_path3.sep)) {
|
|
835
|
+
continue;
|
|
836
|
+
}
|
|
837
|
+
} catch {
|
|
838
|
+
continue;
|
|
839
|
+
}
|
|
840
|
+
}
|
|
785
841
|
if (shouldExclude2(filePath, config.exclude)) continue;
|
|
786
842
|
let content;
|
|
787
843
|
try {
|
|
@@ -794,6 +850,7 @@ function createHashlinePlugin(userConfig) {
|
|
|
794
850
|
if (cached) {
|
|
795
851
|
const tmpPath2 = (0, import_path3.join)((0, import_os2.tmpdir)(), `hashline-${p.id}.txt`);
|
|
796
852
|
(0, import_fs3.writeFileSync)(tmpPath2, cached, "utf-8");
|
|
853
|
+
tempFiles.add(tmpPath2);
|
|
797
854
|
p.url = `file://${tmpPath2}`;
|
|
798
855
|
writeLog(debugLog, `[${(/* @__PURE__ */ new Date()).toISOString()}] chat.message annotated (cached): ${filePath}
|
|
799
856
|
`);
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
createFileEditBeforeHook,
|
|
3
3
|
createFileReadAfterHook,
|
|
4
4
|
createSystemPromptHook
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-OJ2CHKQK.js";
|
|
6
6
|
import {
|
|
7
7
|
HashlineCache,
|
|
8
8
|
applyHashEdit,
|
|
@@ -10,13 +10,13 @@ import {
|
|
|
10
10
|
} from "./chunk-IVZSANZ4.js";
|
|
11
11
|
|
|
12
12
|
// src/index.ts
|
|
13
|
-
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
14
|
-
import { join } from "path";
|
|
13
|
+
import { readFileSync as readFileSync2, realpathSync as realpathSync2, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
|
|
14
|
+
import { join, resolve as resolve2, sep as sep2 } from "path";
|
|
15
15
|
import { homedir, tmpdir } from "os";
|
|
16
16
|
import { fileURLToPath } from "url";
|
|
17
17
|
|
|
18
18
|
// src/hashline-tool.ts
|
|
19
|
-
import { readFileSync, writeFileSync } from "fs";
|
|
19
|
+
import { readFileSync, realpathSync, writeFileSync } from "fs";
|
|
20
20
|
import { isAbsolute, relative, resolve, sep } from "path";
|
|
21
21
|
import { z } from "zod";
|
|
22
22
|
function createHashlineEditTool(config, cache) {
|
|
@@ -32,15 +32,21 @@ function createHashlineEditTool(config, cache) {
|
|
|
32
32
|
async execute(args, context) {
|
|
33
33
|
const { path, operation, startRef, endRef, replacement } = args;
|
|
34
34
|
const absPath = isAbsolute(path) ? path : resolve(context.directory, path);
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
let realAbs;
|
|
36
|
+
try {
|
|
37
|
+
realAbs = realpathSync(absPath);
|
|
38
|
+
} catch {
|
|
39
|
+
realAbs = resolve(absPath);
|
|
40
|
+
}
|
|
41
|
+
const realWorktree = realpathSync(resolve(context.worktree));
|
|
42
|
+
if (realAbs !== realWorktree && !realAbs.startsWith(realWorktree + sep)) {
|
|
38
43
|
throw new Error(`Access denied: "${path}" resolves outside the project directory`);
|
|
39
44
|
}
|
|
45
|
+
const normalizedAbs = resolve(absPath);
|
|
40
46
|
const displayPath = relative(context.worktree, absPath) || path;
|
|
41
47
|
let current;
|
|
42
48
|
try {
|
|
43
|
-
current = readFileSync(
|
|
49
|
+
current = readFileSync(realAbs, "utf-8");
|
|
44
50
|
} catch (error) {
|
|
45
51
|
const reason = error instanceof Error ? error.message : String(error);
|
|
46
52
|
throw new Error(`Failed to read "${displayPath}": ${reason}`);
|
|
@@ -67,14 +73,15 @@ function createHashlineEditTool(config, cache) {
|
|
|
67
73
|
throw new Error(`Hashline edit failed for "${displayPath}": ${reason}`);
|
|
68
74
|
}
|
|
69
75
|
try {
|
|
70
|
-
writeFileSync(
|
|
76
|
+
writeFileSync(realAbs, nextContent, "utf-8");
|
|
71
77
|
} catch (error) {
|
|
72
78
|
const reason = error instanceof Error ? error.message : String(error);
|
|
73
79
|
throw new Error(`Failed to write "${displayPath}": ${reason}`);
|
|
74
80
|
}
|
|
75
81
|
if (cache) {
|
|
76
|
-
cache.invalidate(
|
|
82
|
+
cache.invalidate(realAbs);
|
|
77
83
|
cache.invalidate(normalizedAbs);
|
|
84
|
+
cache.invalidate(absPath);
|
|
78
85
|
if (path !== absPath) cache.invalidate(path);
|
|
79
86
|
if (displayPath !== absPath) cache.invalidate(displayPath);
|
|
80
87
|
}
|
|
@@ -122,6 +129,7 @@ function loadConfig(projectDir, userConfig) {
|
|
|
122
129
|
function createHashlinePlugin(userConfig) {
|
|
123
130
|
return async (input) => {
|
|
124
131
|
const projectDir = input.directory;
|
|
132
|
+
const worktree = input.worktree;
|
|
125
133
|
const fileConfig = loadConfig(projectDir, userConfig);
|
|
126
134
|
const config = resolveConfig(fileConfig);
|
|
127
135
|
const cache = new HashlineCache(config.cacheSize);
|
|
@@ -132,6 +140,17 @@ function createHashlinePlugin(userConfig) {
|
|
|
132
140
|
`);
|
|
133
141
|
} catch {
|
|
134
142
|
}
|
|
143
|
+
const tempFiles = /* @__PURE__ */ new Set();
|
|
144
|
+
const cleanupTempFiles = () => {
|
|
145
|
+
for (const f of tempFiles) {
|
|
146
|
+
try {
|
|
147
|
+
unlinkSync(f);
|
|
148
|
+
} catch {
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
tempFiles.clear();
|
|
152
|
+
};
|
|
153
|
+
process.on("exit", cleanupTempFiles);
|
|
135
154
|
return {
|
|
136
155
|
tool: {
|
|
137
156
|
hashline_edit: createHashlineEditTool(config, cache)
|
|
@@ -153,6 +172,17 @@ function createHashlinePlugin(userConfig) {
|
|
|
153
172
|
filePath = fileURLToPath(p.url);
|
|
154
173
|
}
|
|
155
174
|
if (!filePath) continue;
|
|
175
|
+
if (worktree) {
|
|
176
|
+
try {
|
|
177
|
+
const realFile = realpathSync2(filePath);
|
|
178
|
+
const realWorktree = realpathSync2(resolve2(worktree));
|
|
179
|
+
if (realFile !== realWorktree && !realFile.startsWith(realWorktree + sep2)) {
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
} catch {
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
156
186
|
if (shouldExclude(filePath, config.exclude)) continue;
|
|
157
187
|
let content;
|
|
158
188
|
try {
|
|
@@ -165,6 +195,7 @@ function createHashlinePlugin(userConfig) {
|
|
|
165
195
|
if (cached) {
|
|
166
196
|
const tmpPath2 = join(tmpdir(), `hashline-${p.id}.txt`);
|
|
167
197
|
writeFileSync2(tmpPath2, cached, "utf-8");
|
|
198
|
+
tempFiles.add(tmpPath2);
|
|
168
199
|
p.url = `file://${tmpPath2}`;
|
|
169
200
|
writeLog(debugLog, `[${(/* @__PURE__ */ new Date()).toISOString()}] chat.message annotated (cached): ${filePath}
|
|
170
201
|
`);
|
package/dist/utils.cjs
CHANGED
|
@@ -451,6 +451,19 @@ var import_fs = require("fs");
|
|
|
451
451
|
var import_path = require("path");
|
|
452
452
|
var import_os = require("os");
|
|
453
453
|
var DEBUG_LOG = (0, import_path.join)((0, import_os.homedir)(), ".config", "opencode", "hashline-debug.log");
|
|
454
|
+
var MAX_PROCESSED_IDS = 1e4;
|
|
455
|
+
function createBoundedSet(maxSize) {
|
|
456
|
+
const set = /* @__PURE__ */ new Set();
|
|
457
|
+
const originalAdd = set.add.bind(set);
|
|
458
|
+
set.add = (value) => {
|
|
459
|
+
if (set.size >= maxSize) {
|
|
460
|
+
const first = set.values().next().value;
|
|
461
|
+
if (first !== void 0) set.delete(first);
|
|
462
|
+
}
|
|
463
|
+
return originalAdd(value);
|
|
464
|
+
};
|
|
465
|
+
return set;
|
|
466
|
+
}
|
|
454
467
|
function debug(...args) {
|
|
455
468
|
const line = `[${(/* @__PURE__ */ new Date()).toISOString()}] ${args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" ")}
|
|
456
469
|
`;
|
|
@@ -480,7 +493,7 @@ function createFileReadAfterHook(cache, config) {
|
|
|
480
493
|
const resolved = config ?? resolveConfig();
|
|
481
494
|
const hashLen = resolved.hashLength || 0;
|
|
482
495
|
const prefix = resolved.prefix;
|
|
483
|
-
const processedCallIds =
|
|
496
|
+
const processedCallIds = createBoundedSet(MAX_PROCESSED_IDS);
|
|
484
497
|
return async (input, output) => {
|
|
485
498
|
debug("tool.execute.after:", input.tool, "args:", input.args);
|
|
486
499
|
if (input.callID) {
|
|
@@ -527,7 +540,7 @@ function createFileReadAfterHook(cache, config) {
|
|
|
527
540
|
function createFileEditBeforeHook(config) {
|
|
528
541
|
const resolved = config ?? resolveConfig();
|
|
529
542
|
const prefix = resolved.prefix;
|
|
530
|
-
const processedCallIds =
|
|
543
|
+
const processedCallIds = createBoundedSet(MAX_PROCESSED_IDS);
|
|
531
544
|
return async (input, output) => {
|
|
532
545
|
if (input.callID) {
|
|
533
546
|
if (processedCallIds.has(input.callID)) {
|
|
@@ -541,7 +554,7 @@ function createFileEditBeforeHook(config) {
|
|
|
541
554
|
);
|
|
542
555
|
if (!isFileEdit) return;
|
|
543
556
|
if (!output.args || typeof output.args !== "object") return;
|
|
544
|
-
const contentFields = [
|
|
557
|
+
const contentFields = /* @__PURE__ */ new Set([
|
|
545
558
|
"content",
|
|
546
559
|
"new_content",
|
|
547
560
|
"old_content",
|
|
@@ -551,13 +564,26 @@ function createFileEditBeforeHook(config) {
|
|
|
551
564
|
"text",
|
|
552
565
|
"diff",
|
|
553
566
|
"patch",
|
|
554
|
-
"patchText"
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
567
|
+
"patchText",
|
|
568
|
+
"body"
|
|
569
|
+
]);
|
|
570
|
+
function stripDeep(obj) {
|
|
571
|
+
for (const key of Object.keys(obj)) {
|
|
572
|
+
const val = obj[key];
|
|
573
|
+
if (typeof val === "string" && contentFields.has(key)) {
|
|
574
|
+
obj[key] = stripHashes(val, prefix);
|
|
575
|
+
} else if (Array.isArray(val)) {
|
|
576
|
+
for (const item of val) {
|
|
577
|
+
if (item && typeof item === "object" && !Array.isArray(item)) {
|
|
578
|
+
stripDeep(item);
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
} else if (val && typeof val === "object" && !Array.isArray(val)) {
|
|
582
|
+
stripDeep(val);
|
|
583
|
+
}
|
|
559
584
|
}
|
|
560
585
|
}
|
|
586
|
+
stripDeep(output.args);
|
|
561
587
|
};
|
|
562
588
|
}
|
|
563
589
|
function createSystemPromptHook(config) {
|
package/dist/utils.js
CHANGED
package/package.json
CHANGED