reasonix 0.33.1 → 0.34.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/dashboard/dist/app.js +1 -21
- package/dashboard/dist/app.js.map +1 -1
- package/dist/cli/{chat-Q5ZCVIOO.js → chat-TL4HMNEQ.js} +15 -13
- package/dist/cli/chunk-2EBODRRO.js +149 -0
- package/dist/cli/chunk-2EBODRRO.js.map +1 -0
- package/dist/cli/{chunk-DULSP7JH.js → chunk-5JXXEPDM.js} +34 -1
- package/dist/cli/chunk-5JXXEPDM.js.map +1 -0
- package/dist/cli/{chunk-MDHVWCJ4.js → chunk-5SAMVHA3.js} +591 -299
- package/dist/cli/chunk-5SAMVHA3.js.map +1 -0
- package/dist/cli/chunk-DAEAAVDF.js +199 -0
- package/dist/cli/chunk-DAEAAVDF.js.map +1 -0
- package/dist/cli/{chunk-D5DKXIP5.js → chunk-F3ILWP2L.js} +18 -27
- package/dist/cli/chunk-F3ILWP2L.js.map +1 -0
- package/dist/cli/{chunk-SDE5U32Z.js → chunk-KZHMKOJH.js} +13 -8
- package/dist/cli/{chunk-SDE5U32Z.js.map → chunk-KZHMKOJH.js.map} +1 -1
- package/dist/cli/{chunk-Q6YFXW7H.js → chunk-LNTORE5K.js} +246 -339
- package/dist/cli/chunk-LNTORE5K.js.map +1 -0
- package/dist/cli/chunk-MRLXEMZ7.js +26 -0
- package/dist/cli/chunk-MRLXEMZ7.js.map +1 -0
- package/dist/cli/{chunk-WBDE4IRI.js → chunk-OERAGRJX.js} +2 -2
- package/dist/cli/{chunk-QGE6AF76.js → chunk-Q36KBLSU.js} +207 -8
- package/dist/cli/chunk-Q36KBLSU.js.map +1 -0
- package/dist/cli/{chunk-RZILUXUC.js → chunk-RXGEGA7K.js} +2 -2
- package/dist/cli/{chunk-FXGQ5NHE.js → chunk-SA4UGZPG.js} +21 -1
- package/dist/cli/chunk-SA4UGZPG.js.map +1 -0
- package/dist/cli/{chunk-J5VLP23S.js → chunk-SW3CCXEV.js} +2 -2
- package/dist/cli/{chunk-W4LDFAZ6.js → chunk-SX6L4HZZ.js} +2 -2
- package/dist/cli/chunk-WUI3P4RA.js +319 -0
- package/dist/cli/chunk-WUI3P4RA.js.map +1 -0
- package/dist/cli/{code-DLR77NPZ.js → code-V6F4BKMG.js} +16 -14
- package/dist/cli/{code-DLR77NPZ.js.map → code-V6F4BKMG.js.map} +1 -1
- package/dist/cli/{commands-JWT2MWVH.js → commands-MEZPSEHV.js} +4 -3
- package/dist/cli/{commands-JWT2MWVH.js.map → commands-MEZPSEHV.js.map} +1 -1
- package/dist/cli/{commit-RPZBOZS2.js → commit-CE4EFTUQ.js} +3 -2
- package/dist/cli/{commit-RPZBOZS2.js.map → commit-CE4EFTUQ.js.map} +1 -1
- package/dist/cli/{doctor-3TGB2NZN.js → doctor-YASM64X6.js} +8 -6
- package/dist/cli/index.js +23 -21
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/{mcp-ARTNQ24O.js → mcp-LDFK5QJI.js} +3 -2
- package/dist/cli/{mcp-ARTNQ24O.js.map → mcp-LDFK5QJI.js.map} +1 -1
- package/dist/cli/{mcp-browse-HLO2ENDL.js → mcp-browse-FYHEITCM.js} +3 -2
- package/dist/cli/{mcp-browse-HLO2ENDL.js.map → mcp-browse-FYHEITCM.js.map} +1 -1
- package/dist/cli/{replay-Q43DSMG6.js → replay-JEDLU7F2.js} +8 -6
- package/dist/cli/{replay-Q43DSMG6.js.map → replay-JEDLU7F2.js.map} +1 -1
- package/dist/cli/{run-JMEOTQCG.js → run-NHD2RSTD.js} +8 -6
- package/dist/cli/{run-JMEOTQCG.js.map → run-NHD2RSTD.js.map} +1 -1
- package/dist/cli/{server-SYC3OVOP.js → server-MC4A4WAJ.js} +9 -8
- package/dist/cli/{server-SYC3OVOP.js.map → server-MC4A4WAJ.js.map} +1 -1
- package/dist/cli/{sessions-MOJAALJI.js → sessions-ZHWJEW4L.js} +8 -6
- package/dist/cli/{sessions-MOJAALJI.js.map → sessions-ZHWJEW4L.js.map} +1 -1
- package/dist/cli/{setup-CCJZAWTY.js → setup-DK43MT47.js} +6 -5
- package/dist/cli/{setup-CCJZAWTY.js.map → setup-DK43MT47.js.map} +1 -1
- package/dist/cli/{version-3MYFE4G6.js → version-O362UKPM.js} +8 -6
- package/dist/cli/{version-3MYFE4G6.js.map → version-O362UKPM.js.map} +1 -1
- package/dist/index.d.ts +45 -1
- package/dist/index.js +569 -27
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/cli/chunk-63KAV5DX.js +0 -106
- package/dist/cli/chunk-63KAV5DX.js.map +0 -1
- package/dist/cli/chunk-D5DKXIP5.js.map +0 -1
- package/dist/cli/chunk-DULSP7JH.js.map +0 -1
- package/dist/cli/chunk-FXGQ5NHE.js.map +0 -1
- package/dist/cli/chunk-MDHVWCJ4.js.map +0 -1
- package/dist/cli/chunk-Q6YFXW7H.js.map +0 -1
- package/dist/cli/chunk-QGE6AF76.js.map +0 -1
- package/dist/cli/chunk-ZPTSJGX5.js +0 -88
- package/dist/cli/chunk-ZPTSJGX5.js.map +0 -1
- /package/dist/cli/{chat-Q5ZCVIOO.js.map → chat-TL4HMNEQ.js.map} +0 -0
- /package/dist/cli/{chunk-WBDE4IRI.js.map → chunk-OERAGRJX.js.map} +0 -0
- /package/dist/cli/{chunk-RZILUXUC.js.map → chunk-RXGEGA7K.js.map} +0 -0
- /package/dist/cli/{chunk-J5VLP23S.js.map → chunk-SW3CCXEV.js.map} +0 -0
- /package/dist/cli/{chunk-W4LDFAZ6.js.map → chunk-SX6L4HZZ.js.map} +0 -0
- /package/dist/cli/{doctor-3TGB2NZN.js.map → doctor-YASM64X6.js.map} +0 -0
|
@@ -3,12 +3,17 @@ import {
|
|
|
3
3
|
MemoryStore,
|
|
4
4
|
sanitizeMemoryName
|
|
5
5
|
} from "./chunk-6TMHAK5D.js";
|
|
6
|
+
import {
|
|
7
|
+
countTokens,
|
|
8
|
+
estimateConversationTokens,
|
|
9
|
+
estimateRequestTokens
|
|
10
|
+
} from "./chunk-DAEAAVDF.js";
|
|
6
11
|
import {
|
|
7
12
|
Usage
|
|
8
13
|
} from "./chunk-KMWKGPFZ.js";
|
|
9
14
|
import {
|
|
10
15
|
pauseGate
|
|
11
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-SX6L4HZZ.js";
|
|
12
17
|
import {
|
|
13
18
|
ESCALATION_CONTRACT,
|
|
14
19
|
NEGATIVE_CLAIM_RULE,
|
|
@@ -17,7 +22,7 @@ import {
|
|
|
17
22
|
import {
|
|
18
23
|
formatHookOutcomeMessage,
|
|
19
24
|
runHooks
|
|
20
|
-
} from "./chunk-
|
|
25
|
+
} from "./chunk-OERAGRJX.js";
|
|
21
26
|
import {
|
|
22
27
|
ignoredByLayers,
|
|
23
28
|
loadGitignoreAt,
|
|
@@ -31,208 +36,18 @@ import {
|
|
|
31
36
|
} from "./chunk-DFP4YSVM.js";
|
|
32
37
|
import {
|
|
33
38
|
t
|
|
34
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-Q36KBLSU.js";
|
|
35
40
|
import {
|
|
36
41
|
DEFAULT_INDEX_EXCLUDES,
|
|
37
42
|
webSearchEndpoint,
|
|
38
43
|
webSearchEngine
|
|
39
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-5JXXEPDM.js";
|
|
40
45
|
import {
|
|
41
46
|
DEEPSEEK_CONTEXT_TOKENS,
|
|
42
47
|
DEFAULT_CONTEXT_TOKENS,
|
|
43
48
|
SessionStats
|
|
44
49
|
} from "./chunk-ORM6PK57.js";
|
|
45
50
|
|
|
46
|
-
// src/tokenizer.ts
|
|
47
|
-
import { existsSync, readFileSync } from "fs";
|
|
48
|
-
import { createRequire } from "module";
|
|
49
|
-
import { dirname, join } from "path";
|
|
50
|
-
import { fileURLToPath } from "url";
|
|
51
|
-
import { gunzipSync } from "zlib";
|
|
52
|
-
function buildByteToChar() {
|
|
53
|
-
const result = new Array(256);
|
|
54
|
-
const bs = [];
|
|
55
|
-
for (let b = 33; b <= 126; b++) bs.push(b);
|
|
56
|
-
for (let b = 161; b <= 172; b++) bs.push(b);
|
|
57
|
-
for (let b = 174; b <= 255; b++) bs.push(b);
|
|
58
|
-
const cs = bs.slice();
|
|
59
|
-
let n = 0;
|
|
60
|
-
for (let b = 0; b < 256; b++) {
|
|
61
|
-
if (!bs.includes(b)) {
|
|
62
|
-
bs.push(b);
|
|
63
|
-
cs.push(256 + n);
|
|
64
|
-
n++;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
for (let i = 0; i < bs.length; i++) {
|
|
68
|
-
result[bs[i]] = String.fromCodePoint(cs[i]);
|
|
69
|
-
}
|
|
70
|
-
return result;
|
|
71
|
-
}
|
|
72
|
-
var cached = null;
|
|
73
|
-
function resolveDataPath() {
|
|
74
|
-
if (process.env.REASONIX_TOKENIZER_PATH) return process.env.REASONIX_TOKENIZER_PATH;
|
|
75
|
-
const candidates = [];
|
|
76
|
-
try {
|
|
77
|
-
const here = dirname(fileURLToPath(import.meta.url));
|
|
78
|
-
candidates.push(join(here, "..", "data", "deepseek-tokenizer.json.gz"));
|
|
79
|
-
candidates.push(join(here, "..", "..", "data", "deepseek-tokenizer.json.gz"));
|
|
80
|
-
} catch {
|
|
81
|
-
}
|
|
82
|
-
try {
|
|
83
|
-
const req = createRequire(import.meta.url);
|
|
84
|
-
candidates.push(
|
|
85
|
-
join(dirname(req.resolve("reasonix/package.json")), "data", "deepseek-tokenizer.json.gz")
|
|
86
|
-
);
|
|
87
|
-
} catch {
|
|
88
|
-
}
|
|
89
|
-
for (const p of candidates) {
|
|
90
|
-
if (existsSync(p)) return p;
|
|
91
|
-
}
|
|
92
|
-
return candidates[0] ?? join(process.cwd(), "data", "deepseek-tokenizer.json.gz");
|
|
93
|
-
}
|
|
94
|
-
function loadTokenizer() {
|
|
95
|
-
if (cached) return cached;
|
|
96
|
-
const buf = readFileSync(resolveDataPath());
|
|
97
|
-
const json = gunzipSync(buf).toString("utf8");
|
|
98
|
-
const data = JSON.parse(json);
|
|
99
|
-
const mergeRank = /* @__PURE__ */ new Map();
|
|
100
|
-
for (let i = 0; i < data.model.merges.length; i++) {
|
|
101
|
-
mergeRank.set(data.model.merges[i], i);
|
|
102
|
-
}
|
|
103
|
-
const splitRegexes = [];
|
|
104
|
-
for (const p of data.pre_tokenizer.pretokenizers) {
|
|
105
|
-
if (p.type === "Split") {
|
|
106
|
-
splitRegexes.push(new RegExp(p.pattern.Regex, "gu"));
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
const addedMap = /* @__PURE__ */ new Map();
|
|
110
|
-
const addedContents = [];
|
|
111
|
-
for (const t2 of data.added_tokens) {
|
|
112
|
-
if (!t2.special) {
|
|
113
|
-
addedMap.set(t2.content, t2.id);
|
|
114
|
-
addedContents.push(t2.content);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
addedContents.sort((a, b) => b.length - a.length);
|
|
118
|
-
const addedPattern = addedContents.length ? new RegExp(addedContents.map(escapeRegex).join("|"), "g") : null;
|
|
119
|
-
cached = {
|
|
120
|
-
vocab: data.model.vocab,
|
|
121
|
-
mergeRank,
|
|
122
|
-
splitRegexes,
|
|
123
|
-
byteToChar: buildByteToChar(),
|
|
124
|
-
addedPattern,
|
|
125
|
-
addedMap
|
|
126
|
-
};
|
|
127
|
-
return cached;
|
|
128
|
-
}
|
|
129
|
-
function escapeRegex(s) {
|
|
130
|
-
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
131
|
-
}
|
|
132
|
-
function applySplit(chunks, re) {
|
|
133
|
-
const out = [];
|
|
134
|
-
for (const chunk of chunks) {
|
|
135
|
-
if (!chunk) continue;
|
|
136
|
-
re.lastIndex = 0;
|
|
137
|
-
let last = 0;
|
|
138
|
-
for (const m of chunk.matchAll(re)) {
|
|
139
|
-
const idx = m.index ?? 0;
|
|
140
|
-
if (idx > last) out.push(chunk.slice(last, idx));
|
|
141
|
-
if (m[0].length > 0) out.push(m[0]);
|
|
142
|
-
last = idx + m[0].length;
|
|
143
|
-
}
|
|
144
|
-
if (last < chunk.length) out.push(chunk.slice(last));
|
|
145
|
-
}
|
|
146
|
-
return out;
|
|
147
|
-
}
|
|
148
|
-
function byteLevelEncode(s, byteToChar) {
|
|
149
|
-
const bytes = new TextEncoder().encode(s);
|
|
150
|
-
let out = "";
|
|
151
|
-
for (let i = 0; i < bytes.length; i++) out += byteToChar[bytes[i]];
|
|
152
|
-
return out;
|
|
153
|
-
}
|
|
154
|
-
function bpeEncode(piece, mergeRank) {
|
|
155
|
-
if (piece.length <= 1) return piece ? [piece] : [];
|
|
156
|
-
let word = Array.from(piece);
|
|
157
|
-
while (true) {
|
|
158
|
-
let bestIdx = -1;
|
|
159
|
-
let bestRank = Number.POSITIVE_INFINITY;
|
|
160
|
-
for (let i = 0; i < word.length - 1; i++) {
|
|
161
|
-
const pair = `${word[i]} ${word[i + 1]}`;
|
|
162
|
-
const rank = mergeRank.get(pair);
|
|
163
|
-
if (rank !== void 0 && rank < bestRank) {
|
|
164
|
-
bestRank = rank;
|
|
165
|
-
bestIdx = i;
|
|
166
|
-
if (rank === 0) break;
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
if (bestIdx < 0) break;
|
|
170
|
-
word = [
|
|
171
|
-
...word.slice(0, bestIdx),
|
|
172
|
-
word[bestIdx] + word[bestIdx + 1],
|
|
173
|
-
...word.slice(bestIdx + 2)
|
|
174
|
-
];
|
|
175
|
-
if (word.length === 1) break;
|
|
176
|
-
}
|
|
177
|
-
return word;
|
|
178
|
-
}
|
|
179
|
-
function encode(text) {
|
|
180
|
-
if (!text) return [];
|
|
181
|
-
const t2 = loadTokenizer();
|
|
182
|
-
const ids = [];
|
|
183
|
-
const process2 = (segment) => {
|
|
184
|
-
if (!segment) return;
|
|
185
|
-
let chunks = [segment];
|
|
186
|
-
for (const re of t2.splitRegexes) chunks = applySplit(chunks, re);
|
|
187
|
-
for (const chunk of chunks) {
|
|
188
|
-
if (!chunk) continue;
|
|
189
|
-
const byteLevel = byteLevelEncode(chunk, t2.byteToChar);
|
|
190
|
-
const pieces = bpeEncode(byteLevel, t2.mergeRank);
|
|
191
|
-
for (const p of pieces) {
|
|
192
|
-
const id = t2.vocab[p];
|
|
193
|
-
if (id !== void 0) ids.push(id);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
};
|
|
197
|
-
if (t2.addedPattern) {
|
|
198
|
-
t2.addedPattern.lastIndex = 0;
|
|
199
|
-
let last = 0;
|
|
200
|
-
for (const m of text.matchAll(t2.addedPattern)) {
|
|
201
|
-
const idx = m.index ?? 0;
|
|
202
|
-
if (idx > last) process2(text.slice(last, idx));
|
|
203
|
-
const id = t2.addedMap.get(m[0]);
|
|
204
|
-
if (id !== void 0) ids.push(id);
|
|
205
|
-
last = idx + m[0].length;
|
|
206
|
-
}
|
|
207
|
-
if (last < text.length) process2(text.slice(last));
|
|
208
|
-
} else {
|
|
209
|
-
process2(text);
|
|
210
|
-
}
|
|
211
|
-
return ids;
|
|
212
|
-
}
|
|
213
|
-
function countTokens(text) {
|
|
214
|
-
return encode(text).length;
|
|
215
|
-
}
|
|
216
|
-
function estimateConversationTokens(messages) {
|
|
217
|
-
let total = 0;
|
|
218
|
-
for (const m of messages) {
|
|
219
|
-
if (typeof m.content === "string" && m.content) {
|
|
220
|
-
total += countTokens(m.content);
|
|
221
|
-
}
|
|
222
|
-
if (m.tool_calls && Array.isArray(m.tool_calls) && m.tool_calls.length > 0) {
|
|
223
|
-
total += countTokens(JSON.stringify(m.tool_calls));
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
return total;
|
|
227
|
-
}
|
|
228
|
-
function estimateRequestTokens(messages, toolSpecs) {
|
|
229
|
-
let total = estimateConversationTokens(messages);
|
|
230
|
-
if (toolSpecs && toolSpecs.length > 0) {
|
|
231
|
-
total += countTokens(JSON.stringify(toolSpecs));
|
|
232
|
-
}
|
|
233
|
-
return total;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
51
|
// src/mcp/latency.ts
|
|
237
52
|
var SAMPLE_SIZE = 5;
|
|
238
53
|
var DEFAULT_THRESHOLD_MS = 4e3;
|
|
@@ -4021,9 +3836,115 @@ ${i + 1}. ${r.title}`);
|
|
|
4021
3836
|
}
|
|
4022
3837
|
|
|
4023
3838
|
// src/at-mentions.ts
|
|
4024
|
-
import { existsSync
|
|
3839
|
+
import { existsSync, readFileSync, readdirSync, statSync } from "fs";
|
|
4025
3840
|
import { readdir, stat } from "fs/promises";
|
|
4026
|
-
import { isAbsolute as isAbsolute2, join as
|
|
3841
|
+
import { isAbsolute as isAbsolute2, join as join4, relative as relative5, resolve as resolve2 } from "path";
|
|
3842
|
+
|
|
3843
|
+
// src/at-mentions-url.ts
|
|
3844
|
+
var AT_URL_PATTERN = /(?<=^|\s)@(https?:\/\/\S+)/g;
|
|
3845
|
+
var DEFAULT_AT_URL_MAX_CHARS = 32e3;
|
|
3846
|
+
async function expandAtUrls(text, opts = {}) {
|
|
3847
|
+
const maxChars = opts.maxChars ?? DEFAULT_AT_URL_MAX_CHARS;
|
|
3848
|
+
const fetcher = opts.fetcher;
|
|
3849
|
+
if (!fetcher) {
|
|
3850
|
+
throw new Error("expandAtUrls: fetcher option is required (wire src/tools/web.ts:webFetch)");
|
|
3851
|
+
}
|
|
3852
|
+
const seen = /* @__PURE__ */ new Map();
|
|
3853
|
+
const bodies = /* @__PURE__ */ new Map();
|
|
3854
|
+
const order = [];
|
|
3855
|
+
for (const match of text.matchAll(AT_URL_PATTERN)) {
|
|
3856
|
+
const rawUrl = match[1] ?? "";
|
|
3857
|
+
const url = stripUrlTail(rawUrl);
|
|
3858
|
+
if (!url) continue;
|
|
3859
|
+
if (seen.has(url)) continue;
|
|
3860
|
+
const cached = opts.cache?.get(url);
|
|
3861
|
+
if (cached) {
|
|
3862
|
+
seen.set(url, cached);
|
|
3863
|
+
if (cached.body) bodies.set(url, cached.body);
|
|
3864
|
+
order.push(url);
|
|
3865
|
+
continue;
|
|
3866
|
+
}
|
|
3867
|
+
let expansion;
|
|
3868
|
+
let body = "";
|
|
3869
|
+
try {
|
|
3870
|
+
const page = await fetcher(url, {
|
|
3871
|
+
maxChars,
|
|
3872
|
+
timeoutMs: opts.timeoutMs,
|
|
3873
|
+
signal: opts.signal
|
|
3874
|
+
});
|
|
3875
|
+
body = page.text;
|
|
3876
|
+
expansion = {
|
|
3877
|
+
token: `@${url}`,
|
|
3878
|
+
url,
|
|
3879
|
+
ok: true,
|
|
3880
|
+
title: page.title,
|
|
3881
|
+
chars: body.length,
|
|
3882
|
+
truncated: page.truncated
|
|
3883
|
+
};
|
|
3884
|
+
} catch (err) {
|
|
3885
|
+
const message = err.message ?? String(err);
|
|
3886
|
+
let skip = "fetch-error";
|
|
3887
|
+
if (/aborted|timeout/i.test(message)) skip = "timeout";
|
|
3888
|
+
else if (/40\d|forbidden|access denied|captcha/i.test(message)) skip = "blocked";
|
|
3889
|
+
expansion = {
|
|
3890
|
+
token: `@${url}`,
|
|
3891
|
+
url,
|
|
3892
|
+
ok: false,
|
|
3893
|
+
skip,
|
|
3894
|
+
error: message
|
|
3895
|
+
};
|
|
3896
|
+
}
|
|
3897
|
+
seen.set(url, expansion);
|
|
3898
|
+
if (body) bodies.set(url, body);
|
|
3899
|
+
if (opts.cache) opts.cache.set(url, { ...expansion, body });
|
|
3900
|
+
order.push(url);
|
|
3901
|
+
}
|
|
3902
|
+
if (seen.size === 0) return { text, expansions: [] };
|
|
3903
|
+
const expansions = order.map((u) => seen.get(u)).filter(Boolean);
|
|
3904
|
+
const blocks = [];
|
|
3905
|
+
for (const ex of expansions) {
|
|
3906
|
+
if (ex.ok) {
|
|
3907
|
+
const titleAttr = ex.title ? ` title="${escapeAttr(ex.title)}"` : "";
|
|
3908
|
+
const truncTag = ex.truncated ? ' truncated="true"' : "";
|
|
3909
|
+
const body = bodies.get(ex.url) ?? "";
|
|
3910
|
+
blocks.push(`<url href="${ex.url}"${titleAttr}${truncTag}>
|
|
3911
|
+
${body}
|
|
3912
|
+
</url>`);
|
|
3913
|
+
} else {
|
|
3914
|
+
const reasonAttr = ex.skip ?? "fetch-error";
|
|
3915
|
+
blocks.push(`<url href="${ex.url}" skipped="${reasonAttr}" />`);
|
|
3916
|
+
}
|
|
3917
|
+
}
|
|
3918
|
+
const augmented = `${text}
|
|
3919
|
+
|
|
3920
|
+
[Referenced URLs]
|
|
3921
|
+
${blocks.join("\n\n")}`;
|
|
3922
|
+
return { text: augmented, expansions };
|
|
3923
|
+
}
|
|
3924
|
+
function stripUrlTail(raw) {
|
|
3925
|
+
let s = raw;
|
|
3926
|
+
while (s.length > 0) {
|
|
3927
|
+
const last = s[s.length - 1];
|
|
3928
|
+
if (".,;:!?".includes(last)) {
|
|
3929
|
+
s = s.slice(0, -1);
|
|
3930
|
+
continue;
|
|
3931
|
+
}
|
|
3932
|
+
if (")]}>".includes(last)) {
|
|
3933
|
+
const open = { ")": "(", "]": "[", "}": "{", ">": "<" }[last];
|
|
3934
|
+
if (!s.includes(open)) {
|
|
3935
|
+
s = s.slice(0, -1);
|
|
3936
|
+
continue;
|
|
3937
|
+
}
|
|
3938
|
+
}
|
|
3939
|
+
break;
|
|
3940
|
+
}
|
|
3941
|
+
return s;
|
|
3942
|
+
}
|
|
3943
|
+
function escapeAttr(s) {
|
|
3944
|
+
return s.replace(/"/g, """).replace(/[\r\n]+/g, " ").trim();
|
|
3945
|
+
}
|
|
3946
|
+
|
|
3947
|
+
// src/at-mentions.ts
|
|
4027
3948
|
var DEFAULT_AT_MENTION_MAX_BYTES = 64 * 1024;
|
|
4028
3949
|
var DEFAULT_AT_DIR_MAX_ENTRIES = 200;
|
|
4029
3950
|
var DEFAULT_PICKER_IGNORE_DIRS = [
|
|
@@ -4068,7 +3989,7 @@ function listFilesWithStatsSync(root, opts = {}) {
|
|
|
4068
3989
|
for (const ent of entries) {
|
|
4069
3990
|
if (out.length >= maxResults) return;
|
|
4070
3991
|
const relPath = dirRel ? `${dirRel}/${ent.name}` : ent.name;
|
|
4071
|
-
const absPath =
|
|
3992
|
+
const absPath = join4(dirAbs, ent.name);
|
|
4072
3993
|
if (ent.isDirectory()) {
|
|
4073
3994
|
if (ent.name.startsWith(".") || ignoreDirs.has(ent.name)) continue;
|
|
4074
3995
|
if (ignoredByLayers(effectiveLayers, absPath, true)) continue;
|
|
@@ -4097,14 +4018,30 @@ function listFilesWithStatsSync(root, opts = {}) {
|
|
|
4097
4018
|
walk2(rootAbs, "", []);
|
|
4098
4019
|
return out;
|
|
4099
4020
|
}
|
|
4100
|
-
async function
|
|
4101
|
-
const maxResults = Math.max(1, opts.maxResults ?? 2e3);
|
|
4021
|
+
async function walkFilesStream(root, opts) {
|
|
4102
4022
|
const ignoreDirs = new Set(opts.ignoreDirs ?? DEFAULT_PICKER_IGNORE_DIRS);
|
|
4103
|
-
const rootAbs = resolve2(root);
|
|
4104
4023
|
const respectGi = opts.respectGitignore !== false;
|
|
4105
|
-
const
|
|
4024
|
+
const rootAbs = resolve2(root);
|
|
4025
|
+
const progressGap = Math.max(0, opts.progressIntervalMs ?? 100);
|
|
4026
|
+
let scanned = 0;
|
|
4027
|
+
let halted = false;
|
|
4028
|
+
let lastProgress = 0;
|
|
4029
|
+
const reportProgress = (force) => {
|
|
4030
|
+
if (!opts.onProgress) return;
|
|
4031
|
+
const now = Date.now();
|
|
4032
|
+
if (force || now - lastProgress >= progressGap) {
|
|
4033
|
+
lastProgress = now;
|
|
4034
|
+
opts.onProgress(scanned);
|
|
4035
|
+
}
|
|
4036
|
+
};
|
|
4037
|
+
const emit = (entry) => {
|
|
4038
|
+
scanned++;
|
|
4039
|
+
if (halted) return;
|
|
4040
|
+
if (opts.onEntry(entry) === false) halted = true;
|
|
4041
|
+
reportProgress(false);
|
|
4042
|
+
};
|
|
4106
4043
|
const walk2 = async (dirAbs, dirRel, layers) => {
|
|
4107
|
-
if (
|
|
4044
|
+
if (halted || opts.signal?.aborted) return;
|
|
4108
4045
|
let effectiveLayers = layers;
|
|
4109
4046
|
if (respectGi) {
|
|
4110
4047
|
const ig = await loadGitignoreAt(dirAbs);
|
|
@@ -4119,52 +4056,123 @@ async function listFilesWithStatsAsync(root, opts = {}) {
|
|
|
4119
4056
|
entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
4120
4057
|
const fileEnts = [];
|
|
4121
4058
|
for (const ent of entries) {
|
|
4122
|
-
if (
|
|
4123
|
-
const
|
|
4124
|
-
const absPath = join5(dirAbs, ent.name);
|
|
4059
|
+
if (halted || opts.signal?.aborted) break;
|
|
4060
|
+
const absPath = join4(dirAbs, ent.name);
|
|
4125
4061
|
if (ent.isDirectory()) {
|
|
4126
4062
|
if (ent.name.startsWith(".") || ignoreDirs.has(ent.name)) continue;
|
|
4127
4063
|
if (ignoredByLayers(effectiveLayers, absPath, true)) continue;
|
|
4128
4064
|
if (fileEnts.length > 0) {
|
|
4129
|
-
await
|
|
4065
|
+
await flushFiles(fileEnts, dirAbs, dirRel, effectiveLayers, emit);
|
|
4130
4066
|
fileEnts.length = 0;
|
|
4131
|
-
if (
|
|
4067
|
+
if (halted || opts.signal?.aborted) return;
|
|
4132
4068
|
}
|
|
4133
|
-
await walk2(absPath,
|
|
4069
|
+
await walk2(absPath, dirRel ? `${dirRel}/${ent.name}` : ent.name, effectiveLayers);
|
|
4134
4070
|
} else if (ent.isFile() || ent.isSymbolicLink()) {
|
|
4135
4071
|
fileEnts.push(ent);
|
|
4136
4072
|
}
|
|
4137
4073
|
}
|
|
4138
|
-
if (fileEnts.length > 0 &&
|
|
4139
|
-
await
|
|
4074
|
+
if (fileEnts.length > 0 && !halted && !opts.signal?.aborted) {
|
|
4075
|
+
await flushFiles(fileEnts, dirAbs, dirRel, effectiveLayers, emit);
|
|
4140
4076
|
}
|
|
4141
4077
|
};
|
|
4142
4078
|
await walk2(rootAbs, "", []);
|
|
4143
|
-
|
|
4079
|
+
reportProgress(true);
|
|
4080
|
+
return { scanned, cancelled: !!opts.signal?.aborted };
|
|
4144
4081
|
}
|
|
4145
|
-
async function
|
|
4146
|
-
const accepted =
|
|
4147
|
-
for (const e of ents) {
|
|
4148
|
-
if (out.length + accepted.length >= maxResults) break;
|
|
4149
|
-
if (ignoredByLayers(layers, join5(dirAbs, e.name), false)) continue;
|
|
4150
|
-
accepted.push(e);
|
|
4151
|
-
}
|
|
4082
|
+
async function flushFiles(ents, dirAbs, dirRel, layers, emit) {
|
|
4083
|
+
const accepted = ents.filter((e) => !ignoredByLayers(layers, join4(dirAbs, e.name), false));
|
|
4152
4084
|
const stats = await Promise.all(
|
|
4153
4085
|
accepted.map(
|
|
4154
|
-
(e) => stat(
|
|
4086
|
+
(e) => stat(join4(dirAbs, e.name)).then((s) => ({ mtimeMs: s.mtimeMs, isFile: s.isFile() })).catch(() => null)
|
|
4155
4087
|
)
|
|
4156
4088
|
);
|
|
4157
4089
|
for (let i = 0; i < accepted.length; i++) {
|
|
4158
4090
|
const ent = accepted[i];
|
|
4159
4091
|
const s = stats[i];
|
|
4160
|
-
if (ent.isSymbolicLink())
|
|
4161
|
-
|
|
4092
|
+
if (ent.isSymbolicLink() && (!s || !s.isFile)) continue;
|
|
4093
|
+
emit({
|
|
4094
|
+
path: dirRel ? `${dirRel}/${ent.name}` : ent.name,
|
|
4095
|
+
mtimeMs: s?.mtimeMs ?? 0
|
|
4096
|
+
});
|
|
4097
|
+
}
|
|
4098
|
+
}
|
|
4099
|
+
async function listDirectory(root, relDir, opts = {}) {
|
|
4100
|
+
const ignoreDirs = new Set(opts.ignoreDirs ?? DEFAULT_PICKER_IGNORE_DIRS);
|
|
4101
|
+
const respectGi = opts.respectGitignore !== false;
|
|
4102
|
+
const rootAbs = resolve2(root);
|
|
4103
|
+
const dirAbs = resolve2(rootAbs, relDir);
|
|
4104
|
+
const rel = relative5(rootAbs, dirAbs);
|
|
4105
|
+
if (rel.startsWith("..") || isAbsolute2(rel)) return [];
|
|
4106
|
+
const layers = [];
|
|
4107
|
+
if (respectGi) {
|
|
4108
|
+
const segs = rel ? rel.split(/[\\/]/) : [];
|
|
4109
|
+
let cursor = rootAbs;
|
|
4110
|
+
const ig = await loadGitignoreAt(cursor);
|
|
4111
|
+
if (ig) layers.push({ dirAbs: cursor, ig });
|
|
4112
|
+
for (const seg of segs) {
|
|
4113
|
+
cursor = join4(cursor, seg);
|
|
4114
|
+
const igSeg = await loadGitignoreAt(cursor);
|
|
4115
|
+
if (igSeg) layers.push({ dirAbs: cursor, ig: igSeg });
|
|
4116
|
+
}
|
|
4117
|
+
}
|
|
4118
|
+
let raw;
|
|
4119
|
+
try {
|
|
4120
|
+
raw = await readdir(dirAbs, { withFileTypes: true });
|
|
4121
|
+
} catch {
|
|
4122
|
+
return [];
|
|
4123
|
+
}
|
|
4124
|
+
const dirRel = rel.split(/[\\/]/).join("/");
|
|
4125
|
+
const dirs = [];
|
|
4126
|
+
const files = [];
|
|
4127
|
+
for (const ent of raw) {
|
|
4128
|
+
const absPath = join4(dirAbs, ent.name);
|
|
4129
|
+
if (ent.isDirectory()) {
|
|
4130
|
+
if (ent.name.startsWith(".") || ignoreDirs.has(ent.name)) continue;
|
|
4131
|
+
if (ignoredByLayers(layers, absPath, true)) continue;
|
|
4132
|
+
dirs.push({
|
|
4133
|
+
name: ent.name,
|
|
4134
|
+
path: dirRel ? `${dirRel}/${ent.name}` : ent.name,
|
|
4135
|
+
isDir: true,
|
|
4136
|
+
mtimeMs: 0
|
|
4137
|
+
});
|
|
4138
|
+
} else if (ent.isFile() || ent.isSymbolicLink()) {
|
|
4139
|
+
if (ignoredByLayers(layers, absPath, false)) continue;
|
|
4140
|
+
files.push(ent);
|
|
4162
4141
|
}
|
|
4163
|
-
|
|
4142
|
+
}
|
|
4143
|
+
const stats = await Promise.all(
|
|
4144
|
+
files.map(
|
|
4145
|
+
(e) => stat(join4(dirAbs, e.name)).then((s) => ({ mtimeMs: s.mtimeMs, isFile: s.isFile() })).catch(() => null)
|
|
4146
|
+
)
|
|
4147
|
+
);
|
|
4148
|
+
const fileEntries = [];
|
|
4149
|
+
for (let i = 0; i < files.length; i++) {
|
|
4150
|
+
const ent = files[i];
|
|
4151
|
+
const s = stats[i];
|
|
4152
|
+
if (ent.isSymbolicLink() && (!s || !s.isFile)) continue;
|
|
4153
|
+
fileEntries.push({
|
|
4154
|
+
name: ent.name,
|
|
4164
4155
|
path: dirRel ? `${dirRel}/${ent.name}` : ent.name,
|
|
4156
|
+
isDir: false,
|
|
4165
4157
|
mtimeMs: s?.mtimeMs ?? 0
|
|
4166
4158
|
});
|
|
4167
4159
|
}
|
|
4160
|
+
dirs.sort((a, b) => a.name.localeCompare(b.name));
|
|
4161
|
+
fileEntries.sort((a, b) => a.name.localeCompare(b.name));
|
|
4162
|
+
return [...dirs, ...fileEntries];
|
|
4163
|
+
}
|
|
4164
|
+
function parseAtQuery(query) {
|
|
4165
|
+
const normalized = query.replace(/\\/g, "/");
|
|
4166
|
+
const trailingSlash = normalized.endsWith("/");
|
|
4167
|
+
const trimmed = trailingSlash ? normalized.slice(0, -1) : normalized;
|
|
4168
|
+
const lastSlash = trimmed.lastIndexOf("/");
|
|
4169
|
+
if (trailingSlash) return { dir: trimmed, filter: "", trailingSlash: true };
|
|
4170
|
+
if (lastSlash < 0) return { dir: "", filter: trimmed, trailingSlash: false };
|
|
4171
|
+
return {
|
|
4172
|
+
dir: trimmed.slice(0, lastSlash),
|
|
4173
|
+
filter: trimmed.slice(lastSlash + 1),
|
|
4174
|
+
trailingSlash: false
|
|
4175
|
+
};
|
|
4168
4176
|
}
|
|
4169
4177
|
var AT_PICKER_PREFIX = /(?:^|\s)@([a-zA-Z0-9_./\\-]*)$/;
|
|
4170
4178
|
function detectAtPicker(input) {
|
|
@@ -4342,7 +4350,7 @@ function readSafe(root, rawPath, fs5) {
|
|
|
4342
4350
|
}
|
|
4343
4351
|
}
|
|
4344
4352
|
var defaultFs = {
|
|
4345
|
-
exists: (p) =>
|
|
4353
|
+
exists: (p) => existsSync(p),
|
|
4346
4354
|
isFile: (p) => {
|
|
4347
4355
|
try {
|
|
4348
4356
|
return statSync(p).isFile();
|
|
@@ -4375,110 +4383,8 @@ var defaultFs = {
|
|
|
4375
4383
|
return 0;
|
|
4376
4384
|
}
|
|
4377
4385
|
},
|
|
4378
|
-
read: (p) =>
|
|
4386
|
+
read: (p) => readFileSync(p, "utf8")
|
|
4379
4387
|
};
|
|
4380
|
-
var AT_URL_PATTERN = /(?<=^|\s)@(https?:\/\/\S+)/g;
|
|
4381
|
-
var DEFAULT_AT_URL_MAX_CHARS = 32e3;
|
|
4382
|
-
async function expandAtUrls(text, opts = {}) {
|
|
4383
|
-
const maxChars = opts.maxChars ?? DEFAULT_AT_URL_MAX_CHARS;
|
|
4384
|
-
const fetcher = opts.fetcher;
|
|
4385
|
-
if (!fetcher) {
|
|
4386
|
-
throw new Error("expandAtUrls: fetcher option is required (wire src/tools/web.ts:webFetch)");
|
|
4387
|
-
}
|
|
4388
|
-
const seen = /* @__PURE__ */ new Map();
|
|
4389
|
-
const bodies = /* @__PURE__ */ new Map();
|
|
4390
|
-
const order = [];
|
|
4391
|
-
for (const match of text.matchAll(AT_URL_PATTERN)) {
|
|
4392
|
-
const rawUrl = match[1] ?? "";
|
|
4393
|
-
const url = stripUrlTail(rawUrl);
|
|
4394
|
-
if (!url) continue;
|
|
4395
|
-
if (seen.has(url)) continue;
|
|
4396
|
-
const cached2 = opts.cache?.get(url);
|
|
4397
|
-
if (cached2) {
|
|
4398
|
-
seen.set(url, cached2);
|
|
4399
|
-
if (cached2.body) bodies.set(url, cached2.body);
|
|
4400
|
-
order.push(url);
|
|
4401
|
-
continue;
|
|
4402
|
-
}
|
|
4403
|
-
let expansion;
|
|
4404
|
-
let body = "";
|
|
4405
|
-
try {
|
|
4406
|
-
const page = await fetcher(url, {
|
|
4407
|
-
maxChars,
|
|
4408
|
-
timeoutMs: opts.timeoutMs,
|
|
4409
|
-
signal: opts.signal
|
|
4410
|
-
});
|
|
4411
|
-
body = page.text;
|
|
4412
|
-
expansion = {
|
|
4413
|
-
token: `@${url}`,
|
|
4414
|
-
url,
|
|
4415
|
-
ok: true,
|
|
4416
|
-
title: page.title,
|
|
4417
|
-
chars: body.length,
|
|
4418
|
-
truncated: page.truncated
|
|
4419
|
-
};
|
|
4420
|
-
} catch (err) {
|
|
4421
|
-
const message = err.message ?? String(err);
|
|
4422
|
-
let skip = "fetch-error";
|
|
4423
|
-
if (/aborted|timeout/i.test(message)) skip = "timeout";
|
|
4424
|
-
else if (/40\d|forbidden|access denied|captcha/i.test(message)) skip = "blocked";
|
|
4425
|
-
expansion = {
|
|
4426
|
-
token: `@${url}`,
|
|
4427
|
-
url,
|
|
4428
|
-
ok: false,
|
|
4429
|
-
skip,
|
|
4430
|
-
error: message
|
|
4431
|
-
};
|
|
4432
|
-
}
|
|
4433
|
-
seen.set(url, expansion);
|
|
4434
|
-
if (body) bodies.set(url, body);
|
|
4435
|
-
if (opts.cache) opts.cache.set(url, { ...expansion, body });
|
|
4436
|
-
order.push(url);
|
|
4437
|
-
}
|
|
4438
|
-
if (seen.size === 0) return { text, expansions: [] };
|
|
4439
|
-
const expansions = order.map((u) => seen.get(u)).filter(Boolean);
|
|
4440
|
-
const blocks = [];
|
|
4441
|
-
for (const ex of expansions) {
|
|
4442
|
-
if (ex.ok) {
|
|
4443
|
-
const titleAttr = ex.title ? ` title="${escapeAttr(ex.title)}"` : "";
|
|
4444
|
-
const truncTag = ex.truncated ? ' truncated="true"' : "";
|
|
4445
|
-
const body = bodies.get(ex.url) ?? "";
|
|
4446
|
-
blocks.push(`<url href="${ex.url}"${titleAttr}${truncTag}>
|
|
4447
|
-
${body}
|
|
4448
|
-
</url>`);
|
|
4449
|
-
} else {
|
|
4450
|
-
const reasonAttr = ex.skip ?? "fetch-error";
|
|
4451
|
-
blocks.push(`<url href="${ex.url}" skipped="${reasonAttr}" />`);
|
|
4452
|
-
}
|
|
4453
|
-
}
|
|
4454
|
-
const augmented = `${text}
|
|
4455
|
-
|
|
4456
|
-
[Referenced URLs]
|
|
4457
|
-
${blocks.join("\n\n")}`;
|
|
4458
|
-
return { text: augmented, expansions };
|
|
4459
|
-
}
|
|
4460
|
-
function stripUrlTail(raw) {
|
|
4461
|
-
let s = raw;
|
|
4462
|
-
while (s.length > 0) {
|
|
4463
|
-
const last = s[s.length - 1];
|
|
4464
|
-
if (".,;:!?".includes(last)) {
|
|
4465
|
-
s = s.slice(0, -1);
|
|
4466
|
-
continue;
|
|
4467
|
-
}
|
|
4468
|
-
if (")]}>".includes(last)) {
|
|
4469
|
-
const open = { ")": "(", "]": "[", "}": "{", ">": "<" }[last];
|
|
4470
|
-
if (!s.includes(open)) {
|
|
4471
|
-
s = s.slice(0, -1);
|
|
4472
|
-
continue;
|
|
4473
|
-
}
|
|
4474
|
-
}
|
|
4475
|
-
break;
|
|
4476
|
-
}
|
|
4477
|
-
return s;
|
|
4478
|
-
}
|
|
4479
|
-
function escapeAttr(s) {
|
|
4480
|
-
return s.replace(/"/g, """).replace(/[\r\n]+/g, " ").trim();
|
|
4481
|
-
}
|
|
4482
4388
|
|
|
4483
4389
|
// src/tools/subagent-types.ts
|
|
4484
4390
|
var EXPLORE_SYSTEM = `You are an exploration subagent. Wide-net read-only investigation; return one distilled answer.
|
|
@@ -4770,18 +4676,18 @@ function forkRegistryWithAllowList(parent, allow, alsoExclude) {
|
|
|
4770
4676
|
// src/code/edit-blocks.ts
|
|
4771
4677
|
import {
|
|
4772
4678
|
closeSync,
|
|
4773
|
-
existsSync as
|
|
4679
|
+
existsSync as existsSync2,
|
|
4774
4680
|
fstatSync,
|
|
4775
4681
|
ftruncateSync,
|
|
4776
4682
|
mkdirSync,
|
|
4777
4683
|
openSync,
|
|
4778
|
-
readFileSync as
|
|
4684
|
+
readFileSync as readFileSync2,
|
|
4779
4685
|
readSync,
|
|
4780
4686
|
unlinkSync,
|
|
4781
4687
|
writeFileSync,
|
|
4782
4688
|
writeSync
|
|
4783
4689
|
} from "fs";
|
|
4784
|
-
import { dirname as
|
|
4690
|
+
import { dirname as dirname2, resolve as resolve3 } from "path";
|
|
4785
4691
|
var BLOCK_RE = /^(\S[^\n]*)\n<{7} SEARCH\n([\s\S]*?)\n?={7}\n([\s\S]*?)\n?>{7} REPLACE/gm;
|
|
4786
4692
|
function parseEditBlocks(text) {
|
|
4787
4693
|
const out = [];
|
|
@@ -4811,7 +4717,7 @@ function applyEditBlock(block, rootDir) {
|
|
|
4811
4717
|
const searchEmpty = block.search.length === 0;
|
|
4812
4718
|
if (searchEmpty) {
|
|
4813
4719
|
try {
|
|
4814
|
-
mkdirSync(
|
|
4720
|
+
mkdirSync(dirname2(absTarget), { recursive: true });
|
|
4815
4721
|
const fd = openSync(absTarget, "wx");
|
|
4816
4722
|
try {
|
|
4817
4723
|
writeSync(fd, block.replace);
|
|
@@ -4889,9 +4795,9 @@ function applyEditBlocks(blocks, rootDir) {
|
|
|
4889
4795
|
function toWholeFileEditBlock(path, content, rootDir) {
|
|
4890
4796
|
const abs = resolve3(rootDir, path);
|
|
4891
4797
|
let search = "";
|
|
4892
|
-
if (
|
|
4798
|
+
if (existsSync2(abs)) {
|
|
4893
4799
|
try {
|
|
4894
|
-
search =
|
|
4800
|
+
search = readFileSync2(abs, "utf8");
|
|
4895
4801
|
} catch {
|
|
4896
4802
|
search = "";
|
|
4897
4803
|
}
|
|
@@ -4906,12 +4812,12 @@ function snapshotBeforeEdits(blocks, rootDir) {
|
|
|
4906
4812
|
if (seen.has(b.path)) continue;
|
|
4907
4813
|
seen.add(b.path);
|
|
4908
4814
|
const abs = resolve3(absRoot, b.path);
|
|
4909
|
-
if (!
|
|
4815
|
+
if (!existsSync2(abs)) {
|
|
4910
4816
|
snapshots.push({ path: b.path, prevContent: null });
|
|
4911
4817
|
continue;
|
|
4912
4818
|
}
|
|
4913
4819
|
try {
|
|
4914
|
-
snapshots.push({ path: b.path, prevContent:
|
|
4820
|
+
snapshots.push({ path: b.path, prevContent: readFileSync2(abs, "utf8") });
|
|
4915
4821
|
} catch {
|
|
4916
4822
|
snapshots.push({ path: b.path, prevContent: null });
|
|
4917
4823
|
}
|
|
@@ -4931,7 +4837,7 @@ function restoreSnapshots(snapshots, rootDir) {
|
|
|
4931
4837
|
}
|
|
4932
4838
|
try {
|
|
4933
4839
|
if (snap.prevContent === null) {
|
|
4934
|
-
if (
|
|
4840
|
+
if (existsSync2(abs)) unlinkSync(abs);
|
|
4935
4841
|
return {
|
|
4936
4842
|
path: snap.path,
|
|
4937
4843
|
status: "applied",
|
|
@@ -4957,17 +4863,18 @@ function lineEndingOf(text) {
|
|
|
4957
4863
|
}
|
|
4958
4864
|
|
|
4959
4865
|
export {
|
|
4960
|
-
countTokens,
|
|
4961
4866
|
ToolRegistry,
|
|
4962
4867
|
registerSingleMcpTool,
|
|
4963
4868
|
bridgeMcpTools,
|
|
4964
4869
|
ImmutablePrefix,
|
|
4965
4870
|
CacheFirstLoop,
|
|
4966
|
-
|
|
4871
|
+
expandAtUrls,
|
|
4872
|
+
walkFilesStream,
|
|
4873
|
+
listDirectory,
|
|
4874
|
+
parseAtQuery,
|
|
4967
4875
|
detectAtPicker,
|
|
4968
4876
|
rankPickerCandidates,
|
|
4969
4877
|
expandAtMentions,
|
|
4970
|
-
expandAtUrls,
|
|
4971
4878
|
registerFilesystemTools,
|
|
4972
4879
|
registerMemoryTools,
|
|
4973
4880
|
registerChoiceTool,
|
|
@@ -4983,4 +4890,4 @@ export {
|
|
|
4983
4890
|
snapshotBeforeEdits,
|
|
4984
4891
|
restoreSnapshots
|
|
4985
4892
|
};
|
|
4986
|
-
//# sourceMappingURL=chunk-
|
|
4893
|
+
//# sourceMappingURL=chunk-LNTORE5K.js.map
|