aws-runtime-bridge 1.9.40 → 1.9.45
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/adapter/AcodeSdkAdapter.d.ts +31 -4
- package/dist/adapter/AcodeSdkAdapter.d.ts.map +1 -1
- package/dist/adapter/AcodeSdkAdapter.js +382 -57
- package/dist/adapter/ClaudeSdkAdapter.d.ts.map +1 -1
- package/dist/adapter/ClaudeSdkAdapter.js +1 -0
- package/dist/adapter/OpencodeSdkAdapter.d.ts +19 -0
- package/dist/adapter/OpencodeSdkAdapter.d.ts.map +1 -1
- package/dist/adapter/OpencodeSdkAdapter.js +62 -0
- package/dist/adapter/types.d.ts +21 -6
- package/dist/adapter/types.d.ts.map +1 -1
- package/dist/adapter/types.js +10 -1
- package/dist/index.js +11 -0
- package/dist/routes/ai-sources.js +4 -1
- package/dist/routes/dashboard.d.ts.map +1 -1
- package/dist/routes/dashboard.js +1 -1
- package/dist/routes/file-browser.d.ts.map +1 -1
- package/dist/routes/file-browser.js +47 -1
- package/dist/routes/processes.d.ts.map +1 -1
- package/dist/routes/processes.js +7 -0
- package/dist/routes/runtime-binding.d.ts.map +1 -1
- package/dist/routes/runtime-binding.js +6 -3
- package/dist/routes/sessions.js +93 -5
- package/dist/routes/sub-agents.js +15 -1
- package/dist/routes/terminal.d.ts +15 -0
- package/dist/routes/terminal.d.ts.map +1 -1
- package/dist/routes/terminal.js +162 -5
- package/dist/services/acode-package.d.ts +8 -1
- package/dist/services/acode-package.d.ts.map +1 -1
- package/dist/services/acode-package.js +33 -4
- package/dist/services/aws-client-agent-mcp.d.ts.map +1 -1
- package/dist/services/aws-client-agent-mcp.js +11 -4
- package/dist/services/fileSnapshotStore.js +1 -1
- package/dist/services/legacy-path-migration.d.ts +3 -0
- package/dist/services/legacy-path-migration.d.ts.map +1 -0
- package/dist/services/legacy-path-migration.js +66 -0
- package/dist/services/lifecycle-state.d.ts.map +1 -1
- package/dist/services/lifecycle-state.js +1 -1
- package/dist/services/runtime-binding.d.ts +5 -0
- package/dist/services/runtime-binding.d.ts.map +1 -1
- package/dist/services/runtime-binding.js +33 -1
- package/dist/services/session-output.d.ts +7 -1
- package/dist/services/session-output.d.ts.map +1 -1
- package/dist/services/session-output.js +16 -2
- package/dist/services/workspace-files.d.ts +48 -0
- package/dist/services/workspace-files.d.ts.map +1 -1
- package/dist/services/workspace-files.js +285 -0
- package/package/acode/dist/built-in-file-tools.d.ts.map +1 -1
- package/package/acode/dist/built-in-file-tools.js +504 -3
- package/package/acode/dist/compaction.d.ts +43 -7
- package/package/acode/dist/compaction.d.ts.map +1 -1
- package/package/acode/dist/compaction.js +286 -31
- package/package/acode/dist/runtime.d.ts +130 -0
- package/package/acode/dist/runtime.d.ts.map +1 -1
- package/package/acode/dist/runtime.js +972 -71
- package/package/acode/dist/sub-agent-manager.d.ts +96 -1
- package/package/acode/dist/sub-agent-manager.d.ts.map +1 -1
- package/package/acode/dist/sub-agent-manager.js +293 -3
- package/package/acode/dist/sub-agent-store.d.ts +8 -1
- package/package/acode/dist/sub-agent-store.d.ts.map +1 -1
- package/package/acode/dist/sub-agent-store.js +55 -0
- package/package/acode/dist/sub-agent-tools.d.ts.map +1 -1
- package/package/acode/dist/sub-agent-tools.js +5 -4
- package/package/acode/dist/sub-agent-types.d.ts +4 -0
- package/package/acode/dist/sub-agent-types.d.ts.map +1 -1
- package/package/acode/dist/types.d.ts +19 -0
- package/package/acode/dist/types.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/agent-client.d.ts +9 -0
- package/package/aws-client-agent-mcp/dist/agent-client.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/agent-client.js +69 -10
- package/package/aws-client-agent-mcp/dist/agent-client.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/config.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/config.js +4 -0
- package/package/aws-client-agent-mcp/dist/config.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/constants.d.ts +2 -0
- package/package/aws-client-agent-mcp/dist/constants.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/constants.js +3 -1
- package/package/aws-client-agent-mcp/dist/constants.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/context-manager.d.ts +4 -1
- package/package/aws-client-agent-mcp/dist/context-manager.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/context-manager.js +6 -2
- package/package/aws-client-agent-mcp/dist/context-manager.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/context-manager.test.js +5 -0
- package/package/aws-client-agent-mcp/dist/context-manager.test.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/http-client.d.ts +5 -0
- package/package/aws-client-agent-mcp/dist/http-client.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/http-client.js +15 -1
- package/package/aws-client-agent-mcp/dist/http-client.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/mcp-server.d.ts +102 -34
- package/package/aws-client-agent-mcp/dist/mcp-server.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/mcp-server.js +637 -209
- package/package/aws-client-agent-mcp/dist/mcp-server.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/mcp-server.test.js +151 -51
- package/package/aws-client-agent-mcp/dist/mcp-server.test.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/mcp-tools.d.ts +7 -0
- package/package/aws-client-agent-mcp/dist/mcp-tools.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/mcp-tools.js +18 -0
- package/package/aws-client-agent-mcp/dist/mcp-tools.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/memory-store.d.ts +32 -9
- package/package/aws-client-agent-mcp/dist/memory-store.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/memory-store.js +58 -19
- package/package/aws-client-agent-mcp/dist/memory-store.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/memory-tools.js +3 -3
- package/package/aws-client-agent-mcp/dist/memory-tools.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/message-buffer.d.ts +21 -1
- package/package/aws-client-agent-mcp/dist/message-buffer.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/message-buffer.js +47 -21
- package/package/aws-client-agent-mcp/dist/message-buffer.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/server-memory-store.d.ts +13 -0
- package/package/aws-client-agent-mcp/dist/server-memory-store.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/server-memory-store.js +18 -0
- package/package/aws-client-agent-mcp/dist/server-memory-store.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/types.d.ts +9 -0
- package/package/aws-client-agent-mcp/dist/types.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/types.js.map +1 -1
- package/package/aws-client-agent-mcp/dist/websocket-client.d.ts +34 -1
- package/package/aws-client-agent-mcp/dist/websocket-client.d.ts.map +1 -1
- package/package/aws-client-agent-mcp/dist/websocket-client.js +146 -18
- package/package/aws-client-agent-mcp/dist/websocket-client.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,7 +1,36 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
|
-
import { promises as fs } from "node:fs";
|
|
2
|
+
import { promises as fs, createReadStream } from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
|
+
import readline from "node:readline";
|
|
4
5
|
import { runShellCommand, } from "./builtins/shellCommandRunner.js";
|
|
6
|
+
// ── read_file pagination & truncation constants ──────────────────────────────
|
|
7
|
+
const DEFAULT_READ_LIMIT = 2000;
|
|
8
|
+
const MAX_LINE_LENGTH = 2000;
|
|
9
|
+
const MAX_READ_BYTES = 50 * 1024; // 50 KB
|
|
10
|
+
const BINARY_SAMPLE_BYTES = 4096;
|
|
11
|
+
const BINARY_NON_PRINTABLE_RATIO = 0.3;
|
|
12
|
+
const BINARY_EXTENSIONS = new Set([
|
|
13
|
+
".png", ".jpg", ".jpeg", ".gif", ".bmp", ".ico", ".webp", ".tiff", ".tif",
|
|
14
|
+
".zip", ".gz", ".tar", ".rar", ".7z", ".bz2", ".xz", ".lz",
|
|
15
|
+
".exe", ".dll", ".so", ".dylib", ".bin", ".o", ".a",
|
|
16
|
+
".pdf", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx",
|
|
17
|
+
".mp3", ".mp4", ".avi", ".mov", ".wav", ".flv", ".mkv", ".ogg",
|
|
18
|
+
".woff", ".woff2", ".ttf", ".otf", ".eot",
|
|
19
|
+
".class", ".jar", ".war", ".ear",
|
|
20
|
+
".pyc", ".pyo", ".node",
|
|
21
|
+
".sqlite", ".db", ".mdb",
|
|
22
|
+
".wasm",
|
|
23
|
+
]);
|
|
24
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
25
|
+
// ── grep search constants ────────────────────────────────────────────────────
|
|
26
|
+
const MAX_GREP_FILES = 1000;
|
|
27
|
+
const MAX_GREP_FILE_SIZE = 1024 * 1024; // 1 MB – skip larger files
|
|
28
|
+
const MAX_GREP_OUTPUT_BYTES = 256 * 1024; // 256 KB – cap total output
|
|
29
|
+
const DEFAULT_GREP_MAX_RESULTS = 1000;
|
|
30
|
+
const GREP_SKIP_DIRS = new Set([
|
|
31
|
+
".git", "node_modules", "dist", "build", ".next", ".nuxt",
|
|
32
|
+
".cache", ".turbo", ".output", "coverage", ".nyc_output",
|
|
33
|
+
]);
|
|
5
34
|
function toDisplayPath(targetPath) {
|
|
6
35
|
return targetPath.replace(/\\/g, "/");
|
|
7
36
|
}
|
|
@@ -58,6 +87,42 @@ function readOptionalPositiveIntegerArg(args, names, fallback) {
|
|
|
58
87
|
}
|
|
59
88
|
return fallback;
|
|
60
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* 检测文件是否为二进制文件。
|
|
92
|
+
* 主流程:先查扩展名黑名单 -> 再采样前 4KB 检测 NUL 字节或高比例不可见字符。
|
|
93
|
+
*/
|
|
94
|
+
async function isBinaryFile(filePath) {
|
|
95
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
96
|
+
if (BINARY_EXTENSIONS.has(ext)) {
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
const handle = await fs.open(filePath, "r");
|
|
100
|
+
try {
|
|
101
|
+
const buffer = Buffer.alloc(BINARY_SAMPLE_BYTES);
|
|
102
|
+
const { bytesRead } = await handle.read(buffer, 0, BINARY_SAMPLE_BYTES, 0);
|
|
103
|
+
if (bytesRead === 0) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
const sample = buffer.subarray(0, bytesRead);
|
|
107
|
+
// NUL byte = definitely binary
|
|
108
|
+
if (sample.includes(0)) {
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
// >30% non-printable characters = likely binary
|
|
112
|
+
let nonPrintable = 0;
|
|
113
|
+
for (let i = 0; i < bytesRead; i++) {
|
|
114
|
+
const byte = sample[i];
|
|
115
|
+
// Allow: tab(0x09), LF(0x0a), CR(0x0d), printable ASCII (0x20-0x7e), UTF-8 high bytes (0x80-0xff)
|
|
116
|
+
if (byte < 0x09 || (byte > 0x0d && byte < 0x20)) {
|
|
117
|
+
nonPrintable++;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return nonPrintable / bytesRead > BINARY_NON_PRINTABLE_RATIO;
|
|
121
|
+
}
|
|
122
|
+
finally {
|
|
123
|
+
await handle.close();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
61
126
|
function ensureInsideWorkspace(workspaceRoot, targetPath) {
|
|
62
127
|
const resolvedTargetPath = path.resolve(targetPath);
|
|
63
128
|
const relativePath = path.relative(workspaceRoot, resolvedTargetPath);
|
|
@@ -178,6 +243,249 @@ async function readFileInsideWorkspace(workingDirectory, filePath) {
|
|
|
178
243
|
content: await fs.readFile(realTargetPath, "utf-8"),
|
|
179
244
|
};
|
|
180
245
|
}
|
|
246
|
+
/**
|
|
247
|
+
* 分页流式读取工作区内文本文件,带行号前缀、双重截断上限和续读提示。
|
|
248
|
+
*
|
|
249
|
+
* 主流程:
|
|
250
|
+
* 1. 路径解析与安全校验(复用 resolveWorkspaceTarget + ensureInsideWorkspace + realpath)
|
|
251
|
+
* 2. 二进制检测(扩展名黑名单 + 4KB 采样)
|
|
252
|
+
* 3. createReadStream + readline 逐行流式读取,跳过 offset 前行
|
|
253
|
+
* 4. 收集 limit 行,同时持续计数总行数(用于底部提示)
|
|
254
|
+
* 5. 双重上限:行数 2000 + 字节 50KB,先触发先截断
|
|
255
|
+
* 6. 拼装行号前缀 + 底部续读提示
|
|
256
|
+
*
|
|
257
|
+
* 不修改 readFileInsideWorkspace,edit_file 仍使用全量读取。
|
|
258
|
+
*/
|
|
259
|
+
async function readFileWithPagination(workingDirectory, filePath, offset, limit) {
|
|
260
|
+
const target = await resolveWorkspaceTarget(workingDirectory, filePath);
|
|
261
|
+
const realTargetPath = ensureInsideWorkspace(target.workspaceRoot, await fs.realpath(target.targetPath));
|
|
262
|
+
const stat = await fs.stat(realTargetPath);
|
|
263
|
+
if (!stat.isFile()) {
|
|
264
|
+
throw new Error(`Path is not a file: ${realTargetPath}`);
|
|
265
|
+
}
|
|
266
|
+
// ── 二进制检测 ──
|
|
267
|
+
if (await isBinaryFile(realTargetPath)) {
|
|
268
|
+
return {
|
|
269
|
+
workspaceRoot: target.workspaceRoot,
|
|
270
|
+
targetPath: realTargetPath,
|
|
271
|
+
content: "[Binary file, content skipped]",
|
|
272
|
+
isBinary: true,
|
|
273
|
+
truncated: false,
|
|
274
|
+
totalLines: 0,
|
|
275
|
+
shownFromLine: 0,
|
|
276
|
+
shownToLine: 0,
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
// ── 流式逐行读取 ──
|
|
280
|
+
const stream = createReadStream(realTargetPath, { encoding: "utf-8" });
|
|
281
|
+
const rl = readline.createInterface({
|
|
282
|
+
input: stream,
|
|
283
|
+
crlfDelay: Infinity,
|
|
284
|
+
});
|
|
285
|
+
try {
|
|
286
|
+
const outputLines = [];
|
|
287
|
+
let lineNumber = 0; // 0-indexed 内部计数
|
|
288
|
+
let totalLines = 0;
|
|
289
|
+
let bytes = 0;
|
|
290
|
+
let truncatedByLines = false;
|
|
291
|
+
let truncatedByBytes = false;
|
|
292
|
+
const startIndex = offset - 1; // 转为 0-indexed
|
|
293
|
+
for await (const text of rl) {
|
|
294
|
+
totalLines++;
|
|
295
|
+
// 跳过 offset 前的行
|
|
296
|
+
if (lineNumber < startIndex) {
|
|
297
|
+
lineNumber++;
|
|
298
|
+
continue;
|
|
299
|
+
}
|
|
300
|
+
// 已达 limit 上限:停止收集但继续计数
|
|
301
|
+
if (outputLines.length >= limit) {
|
|
302
|
+
truncatedByLines = true;
|
|
303
|
+
lineNumber++;
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
306
|
+
// 单行截断
|
|
307
|
+
let line = text;
|
|
308
|
+
if (line.length > MAX_LINE_LENGTH) {
|
|
309
|
+
line =
|
|
310
|
+
line.slice(0, MAX_LINE_LENGTH) +
|
|
311
|
+
`... (line truncated to ${MAX_LINE_LENGTH} chars)`;
|
|
312
|
+
}
|
|
313
|
+
const numberedLine = `${lineNumber + 1}: ${line}`;
|
|
314
|
+
const lineBytes = Buffer.byteLength(numberedLine, "utf-8") + 1; // +1 for \n
|
|
315
|
+
// 字节上限:停止读取(totalLines 不再准确)
|
|
316
|
+
if (bytes + lineBytes > MAX_READ_BYTES) {
|
|
317
|
+
truncatedByBytes = true;
|
|
318
|
+
break;
|
|
319
|
+
}
|
|
320
|
+
outputLines.push(numberedLine);
|
|
321
|
+
bytes += lineBytes;
|
|
322
|
+
lineNumber++;
|
|
323
|
+
}
|
|
324
|
+
// offset 超出文件总行数(空文件除外)
|
|
325
|
+
if (totalLines > 0 &&
|
|
326
|
+
outputLines.length === 0 &&
|
|
327
|
+
!truncatedByLines &&
|
|
328
|
+
!truncatedByBytes &&
|
|
329
|
+
startIndex >= totalLines) {
|
|
330
|
+
throw new Error(`offset ${offset} exceeds total line count ${totalLines} in file: ${realTargetPath}`);
|
|
331
|
+
}
|
|
332
|
+
const shownFromLine = outputLines.length > 0 ? offset : 0;
|
|
333
|
+
const shownToLine = outputLines.length > 0 ? offset + outputLines.length - 1 : 0;
|
|
334
|
+
// ── 底部续读提示 ──
|
|
335
|
+
let footer;
|
|
336
|
+
if (truncatedByBytes) {
|
|
337
|
+
footer = `Output capped at 50 KB. Showing lines ${shownFromLine}-${shownToLine}. Use offset=${shownToLine + 1} to continue.`;
|
|
338
|
+
}
|
|
339
|
+
else if (truncatedByLines) {
|
|
340
|
+
footer = `Showing lines ${shownFromLine}-${shownToLine} of ${totalLines}. Use offset=${shownToLine + 1} to continue.`;
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
footer = `End of file - total ${totalLines} lines`;
|
|
344
|
+
}
|
|
345
|
+
const content = outputLines.length > 0
|
|
346
|
+
? outputLines.join("\n") + "\n" + footer
|
|
347
|
+
: footer;
|
|
348
|
+
return {
|
|
349
|
+
workspaceRoot: target.workspaceRoot,
|
|
350
|
+
targetPath: realTargetPath,
|
|
351
|
+
content,
|
|
352
|
+
isBinary: false,
|
|
353
|
+
truncated: truncatedByLines || truncatedByBytes,
|
|
354
|
+
totalLines: truncatedByBytes ? -1 : totalLines,
|
|
355
|
+
shownFromLine,
|
|
356
|
+
shownToLine,
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
finally {
|
|
360
|
+
rl.close();
|
|
361
|
+
stream.destroy();
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
// ── grep helpers ──────────────────────────────────────────────────────────────
|
|
365
|
+
/**
|
|
366
|
+
* 将 glob 通配符转换为 RegExp(匹配文件 basename)。
|
|
367
|
+
* 支持:* (不跨 / ), ? (单个非 / 字符), {a,b} (分组), [abc] (字符类)。
|
|
368
|
+
*/
|
|
369
|
+
function globToRegex(pattern) {
|
|
370
|
+
let regex = "";
|
|
371
|
+
let i = 0;
|
|
372
|
+
while (i < pattern.length) {
|
|
373
|
+
const char = pattern[i];
|
|
374
|
+
if (char === "*") {
|
|
375
|
+
regex += "[^/]*";
|
|
376
|
+
}
|
|
377
|
+
else if (char === "?") {
|
|
378
|
+
regex += "[^/]";
|
|
379
|
+
}
|
|
380
|
+
else if (char === "{") {
|
|
381
|
+
const end = pattern.indexOf("}", i);
|
|
382
|
+
if (end >= 0) {
|
|
383
|
+
const content = pattern.slice(i + 1, end);
|
|
384
|
+
regex += `(${content.split(",").join("|")})`;
|
|
385
|
+
i = end;
|
|
386
|
+
}
|
|
387
|
+
else {
|
|
388
|
+
regex += "\\{";
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
else if (char === "[") {
|
|
392
|
+
const end = pattern.indexOf("]", i);
|
|
393
|
+
if (end >= 0) {
|
|
394
|
+
regex += pattern.slice(i, end + 1);
|
|
395
|
+
i = end;
|
|
396
|
+
}
|
|
397
|
+
else {
|
|
398
|
+
regex += "\\[";
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
else if ("+^$.()|\\".includes(char)) {
|
|
402
|
+
regex += "\\" + char;
|
|
403
|
+
}
|
|
404
|
+
else {
|
|
405
|
+
regex += char;
|
|
406
|
+
}
|
|
407
|
+
i++;
|
|
408
|
+
}
|
|
409
|
+
return new RegExp(`^${regex}$`);
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* 递归遍历目录,返回所有匹配 include/exclude 的文件路径。
|
|
413
|
+
* 主流程:readdir -> 跳过 GREP_SKIP_DIRS 和隐藏目录 -> 递归子目录 -> 过滤文件名。
|
|
414
|
+
*/
|
|
415
|
+
async function walkDirectory(dir, includeRegex, excludeRegex, maxFiles) {
|
|
416
|
+
const results = [];
|
|
417
|
+
async function walk(currentDir) {
|
|
418
|
+
if (results.length >= maxFiles)
|
|
419
|
+
return;
|
|
420
|
+
const entries = await fs.readdir(currentDir, { withFileTypes: true });
|
|
421
|
+
for (const entry of entries) {
|
|
422
|
+
if (results.length >= maxFiles)
|
|
423
|
+
return;
|
|
424
|
+
if (entry.name.startsWith(".") && entry.isDirectory())
|
|
425
|
+
continue;
|
|
426
|
+
const fullPath = path.join(currentDir, entry.name);
|
|
427
|
+
if (entry.isDirectory()) {
|
|
428
|
+
if (GREP_SKIP_DIRS.has(entry.name))
|
|
429
|
+
continue;
|
|
430
|
+
await walk(fullPath);
|
|
431
|
+
}
|
|
432
|
+
else if (entry.isFile()) {
|
|
433
|
+
if (includeRegex && !includeRegex.test(entry.name))
|
|
434
|
+
continue;
|
|
435
|
+
if (excludeRegex && excludeRegex.test(entry.name))
|
|
436
|
+
continue;
|
|
437
|
+
results.push(fullPath);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
await walk(dir);
|
|
442
|
+
return results;
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* 在单个文件中搜索正则匹配,返回匹配行(含行号)或计数。
|
|
446
|
+
* 主流程:文件大小检查 -> 二进制检测 -> 流式逐行读取 -> 正则匹配 -> 收集结果。
|
|
447
|
+
*/
|
|
448
|
+
async function searchInFile(filePath, workspaceRoot, options) {
|
|
449
|
+
const stat = await fs.stat(filePath);
|
|
450
|
+
if (stat.size > MAX_GREP_FILE_SIZE) {
|
|
451
|
+
return { matches: [], count: 0 };
|
|
452
|
+
}
|
|
453
|
+
if (await isBinaryFile(filePath)) {
|
|
454
|
+
return { matches: [], count: 0 };
|
|
455
|
+
}
|
|
456
|
+
const relativePath = path.relative(workspaceRoot, filePath).replace(/\\/g, "/");
|
|
457
|
+
const matches = [];
|
|
458
|
+
let count = 0;
|
|
459
|
+
const stream = createReadStream(filePath, { encoding: "utf-8" });
|
|
460
|
+
const rl = readline.createInterface({ input: stream, crlfDelay: Infinity });
|
|
461
|
+
try {
|
|
462
|
+
let lineNumber = 0;
|
|
463
|
+
for await (const text of rl) {
|
|
464
|
+
lineNumber++;
|
|
465
|
+
if (options.regex.test(text)) {
|
|
466
|
+
count++;
|
|
467
|
+
if (options.collectContent) {
|
|
468
|
+
let content = text;
|
|
469
|
+
if (content.length > MAX_LINE_LENGTH) {
|
|
470
|
+
content =
|
|
471
|
+
content.slice(0, MAX_LINE_LENGTH) +
|
|
472
|
+
`... (line truncated to ${MAX_LINE_LENGTH} chars)`;
|
|
473
|
+
}
|
|
474
|
+
matches.push({ file: relativePath, line: lineNumber, content });
|
|
475
|
+
if (matches.length >= options.maxResults)
|
|
476
|
+
break;
|
|
477
|
+
}
|
|
478
|
+
if (options.stopOnFirstMatch)
|
|
479
|
+
break;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
finally {
|
|
484
|
+
rl.close();
|
|
485
|
+
stream.destroy();
|
|
486
|
+
}
|
|
487
|
+
return { matches, count };
|
|
488
|
+
}
|
|
181
489
|
const MAX_COMMAND_TIMEOUT_MS = 10 * 60_000;
|
|
182
490
|
const DEFAULT_COMMAND_TIMEOUT_MS = MAX_COMMAND_TIMEOUT_MS;
|
|
183
491
|
const DEFAULT_COMMAND_INACTIVITY_TIMEOUT_MS = 60_000;
|
|
@@ -273,7 +581,12 @@ function readFileTool(workingDirectory) {
|
|
|
273
581
|
kind: "builtin",
|
|
274
582
|
toolName: "read_file",
|
|
275
583
|
exposedName: "read_file",
|
|
276
|
-
description: "Read a UTF-8 text file inside the current workspace."
|
|
584
|
+
description: "Read a UTF-8 text file inside the current workspace. " +
|
|
585
|
+
"Returns content with line numbers in the format '<line>: <content>'. " +
|
|
586
|
+
"Supports offset (1-indexed line number to start from) and limit (max lines to return, default 2000). " +
|
|
587
|
+
"Output is capped at 2000 lines or 50 KB, whichever is reached first. " +
|
|
588
|
+
"Individual lines longer than 2000 characters are truncated. " +
|
|
589
|
+
"Avoid tiny repeated slices (e.g. 30-line chunks); read a larger window if more context is needed.",
|
|
277
590
|
inputSchema: {
|
|
278
591
|
type: "object",
|
|
279
592
|
properties: {
|
|
@@ -281,19 +594,34 @@ function readFileTool(workingDirectory) {
|
|
|
281
594
|
type: "string",
|
|
282
595
|
description: "Workspace-relative file path to read.",
|
|
283
596
|
},
|
|
597
|
+
offset: {
|
|
598
|
+
type: "number",
|
|
599
|
+
description: "Line number to start reading from (1-indexed). Defaults to 1.",
|
|
600
|
+
},
|
|
601
|
+
limit: {
|
|
602
|
+
type: "number",
|
|
603
|
+
description: "Maximum number of lines to return. Defaults to 2000.",
|
|
604
|
+
},
|
|
284
605
|
},
|
|
285
606
|
required: ["file_path"],
|
|
286
607
|
additionalProperties: false,
|
|
287
608
|
},
|
|
288
609
|
async execute(args) {
|
|
289
610
|
const filePath = readStringArg(args, ["file_path", "filePath"], "file_path");
|
|
290
|
-
const
|
|
611
|
+
const offset = readOptionalPositiveIntegerArg(args, ["offset"], 1);
|
|
612
|
+
const limit = readOptionalPositiveIntegerArg(args, ["limit"], DEFAULT_READ_LIMIT);
|
|
613
|
+
const result = await readFileWithPagination(workingDirectory, filePath, offset, limit);
|
|
291
614
|
return {
|
|
292
615
|
ok: true,
|
|
293
616
|
tool: "read_file",
|
|
294
617
|
workspacePath: toDisplayPath(result.workspaceRoot),
|
|
295
618
|
filePath: toDisplayPath(result.targetPath),
|
|
296
619
|
content: result.content,
|
|
620
|
+
isBinary: result.isBinary,
|
|
621
|
+
truncated: result.truncated,
|
|
622
|
+
totalLines: result.totalLines,
|
|
623
|
+
shownFromLine: result.shownFromLine,
|
|
624
|
+
shownToLine: result.shownToLine,
|
|
297
625
|
};
|
|
298
626
|
},
|
|
299
627
|
};
|
|
@@ -371,12 +699,185 @@ function bashTool(workingDirectory, agentId) {
|
|
|
371
699
|
},
|
|
372
700
|
};
|
|
373
701
|
}
|
|
702
|
+
function grepTool(workingDirectory) {
|
|
703
|
+
return {
|
|
704
|
+
kind: "builtin",
|
|
705
|
+
toolName: "grep",
|
|
706
|
+
exposedName: "grep",
|
|
707
|
+
description: "Search file contents using regular expressions within the workspace. " +
|
|
708
|
+
"Returns matched lines with file paths and line numbers. " +
|
|
709
|
+
"Supports include/exclude glob patterns, case-insensitive matching, and three output modes " +
|
|
710
|
+
"(content, files_with_matches, count). Searches recursively through directories, " +
|
|
711
|
+
"skipping binary files, hidden directories, and common build/dependency directories (node_modules, .git, dist, etc.).",
|
|
712
|
+
inputSchema: {
|
|
713
|
+
type: "object",
|
|
714
|
+
properties: {
|
|
715
|
+
pattern: {
|
|
716
|
+
type: "string",
|
|
717
|
+
description: "Regular expression pattern to search for in file contents.",
|
|
718
|
+
},
|
|
719
|
+
path: {
|
|
720
|
+
type: "string",
|
|
721
|
+
description: "Workspace-relative file or directory path to search in. Defaults to the workspace root.",
|
|
722
|
+
},
|
|
723
|
+
include: {
|
|
724
|
+
type: "string",
|
|
725
|
+
description: "Glob pattern to filter files by name (e.g. '*.ts', '*.{js,ts}'). Only matching files are searched.",
|
|
726
|
+
},
|
|
727
|
+
exclude: {
|
|
728
|
+
type: "string",
|
|
729
|
+
description: "Glob pattern to exclude files by name (e.g. '*.test.ts'). Matching files are skipped.",
|
|
730
|
+
},
|
|
731
|
+
case_insensitive: {
|
|
732
|
+
type: "boolean",
|
|
733
|
+
description: "Case-insensitive matching. Default false.",
|
|
734
|
+
},
|
|
735
|
+
output_mode: {
|
|
736
|
+
type: "string",
|
|
737
|
+
enum: ["content", "files_with_matches", "count"],
|
|
738
|
+
description: "Output format: 'content' returns matched lines with line numbers (default), " +
|
|
739
|
+
"'files_with_matches' returns only file paths with matches, " +
|
|
740
|
+
"'count' returns match counts per file.",
|
|
741
|
+
},
|
|
742
|
+
max_results: {
|
|
743
|
+
type: "number",
|
|
744
|
+
description: "Maximum number of matched lines to return (content mode). Default 1000.",
|
|
745
|
+
},
|
|
746
|
+
},
|
|
747
|
+
required: ["pattern"],
|
|
748
|
+
additionalProperties: false,
|
|
749
|
+
},
|
|
750
|
+
/**
|
|
751
|
+
* grep 工具执行主流程:
|
|
752
|
+
* 1. 解析参数(pattern, path, include/exclude, output_mode 等)
|
|
753
|
+
* 2. 编译正则(含 case_insensitive 标志)
|
|
754
|
+
* 3. 解析搜索路径并校验 workspace 边界
|
|
755
|
+
* 4. 收集待搜索文件列表(单文件或递归遍历目录)
|
|
756
|
+
* 5. 逐文件搜索(流式读取 + 正则匹配)
|
|
757
|
+
* 6. 根据 output_mode 构建响应
|
|
758
|
+
*/
|
|
759
|
+
async execute(args) {
|
|
760
|
+
const pattern = readStringArg(args, ["pattern"], "pattern");
|
|
761
|
+
const searchPath = readOptionalStringArg(args, ["path"]) || ".";
|
|
762
|
+
const includeGlob = readOptionalStringArg(args, ["include"]);
|
|
763
|
+
const excludeGlob = readOptionalStringArg(args, ["exclude"]);
|
|
764
|
+
const caseInsensitive = args.case_insensitive === true;
|
|
765
|
+
const outputMode = (() => {
|
|
766
|
+
const mode = args.output_mode;
|
|
767
|
+
if (mode === "files_with_matches" || mode === "count")
|
|
768
|
+
return mode;
|
|
769
|
+
return "content";
|
|
770
|
+
})();
|
|
771
|
+
const maxResults = readOptionalPositiveIntegerArg(args, ["max_results"], DEFAULT_GREP_MAX_RESULTS);
|
|
772
|
+
// ── 编译正则 ──
|
|
773
|
+
const flags = caseInsensitive ? "i" : "";
|
|
774
|
+
let regex;
|
|
775
|
+
try {
|
|
776
|
+
regex = new RegExp(pattern, flags);
|
|
777
|
+
}
|
|
778
|
+
catch (error) {
|
|
779
|
+
throw new Error(`Invalid regex pattern: ${error instanceof Error ? error.message : String(error)}`);
|
|
780
|
+
}
|
|
781
|
+
const includeRegex = includeGlob ? globToRegex(includeGlob) : null;
|
|
782
|
+
const excludeRegex = excludeGlob ? globToRegex(excludeGlob) : null;
|
|
783
|
+
// ── 解析搜索路径(复用 workspace 安全校验) ──
|
|
784
|
+
const target = await resolveWorkspaceTarget(workingDirectory, searchPath);
|
|
785
|
+
const realTargetPath = ensureInsideWorkspace(target.workspaceRoot, await fs.realpath(target.targetPath));
|
|
786
|
+
const targetStat = await fs.stat(realTargetPath);
|
|
787
|
+
// ── 收集文件列表 ──
|
|
788
|
+
let files;
|
|
789
|
+
if (targetStat.isFile()) {
|
|
790
|
+
files = [realTargetPath];
|
|
791
|
+
}
|
|
792
|
+
else if (targetStat.isDirectory()) {
|
|
793
|
+
files = await walkDirectory(realTargetPath, includeRegex, excludeRegex, MAX_GREP_FILES);
|
|
794
|
+
}
|
|
795
|
+
else {
|
|
796
|
+
throw new Error(`Path is neither a file nor a directory: ${realTargetPath}`);
|
|
797
|
+
}
|
|
798
|
+
// ── 逐文件搜索 ──
|
|
799
|
+
const allMatches = [];
|
|
800
|
+
const fileCounts = [];
|
|
801
|
+
const matchedFiles = [];
|
|
802
|
+
let totalMatches = 0;
|
|
803
|
+
let outputBytes = 0;
|
|
804
|
+
let truncated = false;
|
|
805
|
+
for (const filePath of files) {
|
|
806
|
+
// content 模式:全局 maxResults 上限
|
|
807
|
+
if (outputMode === "content" && allMatches.length >= maxResults) {
|
|
808
|
+
truncated = true;
|
|
809
|
+
break;
|
|
810
|
+
}
|
|
811
|
+
const searchOptions = {
|
|
812
|
+
regex,
|
|
813
|
+
maxResults: outputMode === "content"
|
|
814
|
+
? maxResults - allMatches.length
|
|
815
|
+
: Number.MAX_SAFE_INTEGER,
|
|
816
|
+
collectContent: outputMode === "content",
|
|
817
|
+
stopOnFirstMatch: outputMode === "files_with_matches",
|
|
818
|
+
};
|
|
819
|
+
const result = await searchInFile(filePath, target.workspaceRoot, searchOptions);
|
|
820
|
+
if (result.count > 0) {
|
|
821
|
+
const relativePath = path
|
|
822
|
+
.relative(target.workspaceRoot, filePath)
|
|
823
|
+
.replace(/\\/g, "/");
|
|
824
|
+
matchedFiles.push(relativePath);
|
|
825
|
+
totalMatches += result.count;
|
|
826
|
+
if (outputMode === "content") {
|
|
827
|
+
for (const match of result.matches) {
|
|
828
|
+
const matchBytes = Buffer.byteLength(match.content, "utf-8") + 64;
|
|
829
|
+
if (outputBytes + matchBytes > MAX_GREP_OUTPUT_BYTES) {
|
|
830
|
+
truncated = true;
|
|
831
|
+
break;
|
|
832
|
+
}
|
|
833
|
+
outputBytes += matchBytes;
|
|
834
|
+
allMatches.push(match);
|
|
835
|
+
}
|
|
836
|
+
if (truncated)
|
|
837
|
+
break;
|
|
838
|
+
// max_results 截断:收集完本文件匹配后检查是否已达上限
|
|
839
|
+
if (allMatches.length >= maxResults) {
|
|
840
|
+
truncated = true;
|
|
841
|
+
break;
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
else if (outputMode === "count") {
|
|
845
|
+
fileCounts.push({ file: relativePath, count: result.count });
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
// ── 构建响应 ──
|
|
850
|
+
const response = {
|
|
851
|
+
ok: true,
|
|
852
|
+
tool: "grep",
|
|
853
|
+
pattern,
|
|
854
|
+
searchPath: toDisplayPath(target.targetPath),
|
|
855
|
+
outputMode,
|
|
856
|
+
filesSearched: files.length,
|
|
857
|
+
filesMatched: matchedFiles.length,
|
|
858
|
+
totalMatches,
|
|
859
|
+
truncated,
|
|
860
|
+
};
|
|
861
|
+
if (outputMode === "content") {
|
|
862
|
+
response.matches = allMatches;
|
|
863
|
+
}
|
|
864
|
+
else if (outputMode === "files_with_matches") {
|
|
865
|
+
response.matches = matchedFiles;
|
|
866
|
+
}
|
|
867
|
+
else {
|
|
868
|
+
response.matches = fileCounts;
|
|
869
|
+
}
|
|
870
|
+
return response;
|
|
871
|
+
},
|
|
872
|
+
};
|
|
873
|
+
}
|
|
374
874
|
export function createBuiltInFileTools(workingDirectory, agentId) {
|
|
375
875
|
const resolvedAgentId = agentId || "unknown";
|
|
376
876
|
return [
|
|
377
877
|
readFileTool(workingDirectory),
|
|
378
878
|
writeFileTool(workingDirectory),
|
|
379
879
|
editFileTool(workingDirectory),
|
|
880
|
+
grepTool(workingDirectory),
|
|
380
881
|
bashTool(workingDirectory, resolvedAgentId),
|
|
381
882
|
];
|
|
382
883
|
}
|
|
@@ -14,8 +14,13 @@
|
|
|
14
14
|
*/
|
|
15
15
|
/** 压缩缓冲区:保留这么多 token 的空闲空间,避免压缩过程中溢出 */
|
|
16
16
|
export declare const COMPACTION_BUFFER = 20000;
|
|
17
|
-
/**
|
|
17
|
+
/**
|
|
18
|
+
* 基础压缩触发比例(兜底默认值,仅用于 contextLimit <= 0 的异常场景)。
|
|
19
|
+
* 正常情况下通过 {@link getCompactionTriggerRatio} 按窗口大小动态分级。
|
|
20
|
+
*/
|
|
18
21
|
export declare const COMPACTION_TRIGGER_RATIO = 0.55;
|
|
22
|
+
/** 按上下文窗口大小返回压缩触发比例(大窗口更高,充分利用空间)。 */
|
|
23
|
+
export declare function getCompactionTriggerRatio(contextLimit: number): number;
|
|
19
24
|
/** Prune 保护线默认值:保留最近 PRUNE_PROTECT token 的工具输出完整。
|
|
20
25
|
* 注意:实际使用时会按 contextLimit 比例调整(见 pruneToolOutputs),
|
|
21
26
|
* 避免在小上下文窗口(如 60k)下保护线过高导致 prune 永不触发。
|
|
@@ -49,6 +54,10 @@ export interface CompactionResult {
|
|
|
49
54
|
sizeBeforeKB: number;
|
|
50
55
|
/** 压缩后对话大小(KB) */
|
|
51
56
|
sizeAfterKB: number;
|
|
57
|
+
/** 压缩前估算 token 数 */
|
|
58
|
+
tokensBefore: number;
|
|
59
|
+
/** 压缩后估算 token 数 */
|
|
60
|
+
tokensAfter: number;
|
|
52
61
|
/** 压缩前消息数 */
|
|
53
62
|
messageCountBefore: number;
|
|
54
63
|
/** 压缩后消息数 */
|
|
@@ -85,9 +94,9 @@ export type LLMSummarizer = (input: {
|
|
|
85
94
|
contextLimit: number;
|
|
86
95
|
}) => Promise<string>;
|
|
87
96
|
/**
|
|
88
|
-
* 计算压缩触发阈值:取 min(contextLimit ×
|
|
97
|
+
* 计算压缩触发阈值:取 min(contextLimit × 动态比例, hardLimit - reserved)。
|
|
89
98
|
*
|
|
90
|
-
* - ratioBased = contextLimit ×
|
|
99
|
+
* - ratioBased = contextLimit × getCompactionTriggerRatio(contextLimit)(按窗口大小动态分级)
|
|
91
100
|
* - hardLimit = inputLimit ?? contextLimit(provider 显式 inputLimit 优先)
|
|
92
101
|
* - reserved = min(COMPACTION_BUFFER, maxOutput)(buffer 不超过输出上限)
|
|
93
102
|
*
|
|
@@ -109,13 +118,19 @@ export declare function lookupModelLimits(modelName: string, configOverrides?: {
|
|
|
109
118
|
maxOutput: number;
|
|
110
119
|
};
|
|
111
120
|
/**
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
121
|
+
* 中英文分离的文本 token 估算。
|
|
122
|
+
* 对纯 ASCII 约 4 字符/token,对中文约 1.5 字符/token。
|
|
123
|
+
* 参考:context-manager.ts 的同名方法。
|
|
124
|
+
*/
|
|
125
|
+
export declare function estimateTextTokens(text: string): number;
|
|
126
|
+
/**
|
|
127
|
+
* 粗略估算文本的 token 数(保留向后兼容)。
|
|
128
|
+
* 使用 estimateTextTokens 的中英文分离 + 安全填充。
|
|
115
129
|
*/
|
|
116
130
|
export declare function estimateTokens(text: string): number;
|
|
117
131
|
/**
|
|
118
132
|
* 估算整个对话的 token 数。
|
|
133
|
+
* 使用块级识别 + 中英文分离 + 安全填充。
|
|
119
134
|
*/
|
|
120
135
|
export declare function estimateConversationTokens(messages: readonly ChatMessageLike[]): number;
|
|
121
136
|
/**
|
|
@@ -137,7 +152,7 @@ export declare function isOverflow(messages: readonly ChatMessageLike[], context
|
|
|
137
152
|
* provider 每次请求都会返回实际 token 计数(input + output),
|
|
138
153
|
* 这个计数比基于文本的估算(estimateConversationTokens)要准确得多。
|
|
139
154
|
*
|
|
140
|
-
* 触发条件:累积 tokens >= contextLimit *
|
|
155
|
+
* 触发条件:累积 tokens >= contextLimit * getCompactionTriggerRatio(contextLimit)
|
|
141
156
|
* 使用显式传入的 contextLimit,不依赖模型名查找表。
|
|
142
157
|
*
|
|
143
158
|
* @param accumulatedInput provider 实际累积的 input tokens
|
|
@@ -185,6 +200,19 @@ export declare function summarizeConversation(messages: ChatMessageLike[], optio
|
|
|
185
200
|
llmSummarizer?: LLMSummarizer;
|
|
186
201
|
contextLimit?: number;
|
|
187
202
|
}): Promise<number>;
|
|
203
|
+
/**
|
|
204
|
+
* Snip:删除最旧的一组消息(从第一个非 system 消息到下一个 user 消息之前)。
|
|
205
|
+
*
|
|
206
|
+
* 作为压缩的最终手段——当 prune 和 summarize 都无法释放足够空间时使用。
|
|
207
|
+
* 能确保:
|
|
208
|
+
* 1. 不删除 system 消息
|
|
209
|
+
* 2. 删除的组不跨 user 边界(保证一个完整轮次)
|
|
210
|
+
* 3. 删除后至少保留 1 组非 system 消息
|
|
211
|
+
*
|
|
212
|
+
* @param messages 对话消息数组(会被原地修改,通过 splice 删除)
|
|
213
|
+
* @returns 删除的消息数
|
|
214
|
+
*/
|
|
215
|
+
export declare function snipOldestMessageGroup(messages: ChatMessageLike[]): number;
|
|
188
216
|
/**
|
|
189
217
|
* 执行完整压缩流程:Prune → 若仍溢出则 Summarize。
|
|
190
218
|
*
|
|
@@ -201,6 +229,14 @@ export declare function summarizeConversation(messages: ChatMessageLike[], optio
|
|
|
201
229
|
export declare function performCompaction(messages: ChatMessageLike[], contextLimit: number, maxOutput?: number, options?: {
|
|
202
230
|
llmSummarizer?: LLMSummarizer;
|
|
203
231
|
onPhase?: (event: CompactionPhaseEvent) => void;
|
|
232
|
+
/**
|
|
233
|
+
* Provider 实际累积 token 用量(来自 AI 请求返回的 usage)。
|
|
234
|
+
* 文本估算(estimateConversationTokens)可能低估实际 token 数,
|
|
235
|
+
* 导致 prune 后 isOverflow 返回 false 而跳过 summarize,最终策略为 "none"。
|
|
236
|
+
* 传入此值后,post-prune overflow 检测使用 textEstimated 与 actualUsed 的较大值,
|
|
237
|
+
* 避免因估算偏差导致压缩失效。
|
|
238
|
+
*/
|
|
239
|
+
actualUsedTokens?: number;
|
|
204
240
|
}): Promise<CompactionResult>;
|
|
205
241
|
export {};
|
|
206
242
|
//# sourceMappingURL=compaction.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compaction.d.ts","sourceRoot":"","sources":["../src/compaction.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,wCAAwC;AACxC,eAAO,MAAM,iBAAiB,QAAS,CAAC;AAExC
|
|
1
|
+
{"version":3,"file":"compaction.d.ts","sourceRoot":"","sources":["../src/compaction.ts"],"names":[],"mappings":"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"}
|