@kenkaiiii/ggcoder 4.13.0 → 4.13.1
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/app-sidecar.js +158 -35
- package/dist/app-sidecar.js.map +1 -1
- package/dist/core/mcp/client.d.ts.map +1 -1
- package/dist/core/mcp/client.js +11 -2
- package/dist/core/mcp/client.js.map +1 -1
- package/dist/core/mcp/defaults.d.ts.map +1 -1
- package/dist/core/mcp/defaults.js +5 -0
- package/dist/core/mcp/defaults.js.map +1 -1
- package/dist/core/mcp/resolve-stdio.d.ts +27 -0
- package/dist/core/mcp/resolve-stdio.d.ts.map +1 -0
- package/dist/core/mcp/resolve-stdio.js +149 -0
- package/dist/core/mcp/resolve-stdio.js.map +1 -0
- package/dist/core/mcp/resolve-stdio.test.d.ts +2 -0
- package/dist/core/mcp/resolve-stdio.test.d.ts.map +1 -0
- package/dist/core/mcp/resolve-stdio.test.js +63 -0
- package/dist/core/mcp/resolve-stdio.test.js.map +1 -0
- package/dist/core/radio.d.ts +7 -2
- package/dist/core/radio.d.ts.map +1 -1
- package/dist/core/radio.js.map +1 -1
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +10 -2
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/code-skeleton.d.ts +29 -0
- package/dist/tools/code-skeleton.d.ts.map +1 -0
- package/dist/tools/code-skeleton.js +115 -0
- package/dist/tools/code-skeleton.js.map +1 -0
- package/dist/tools/code-skeleton.test.d.ts +2 -0
- package/dist/tools/code-skeleton.test.d.ts.map +1 -0
- package/dist/tools/code-skeleton.test.js +115 -0
- package/dist/tools/code-skeleton.test.js.map +1 -0
- package/dist/tools/compress-integration.test.d.ts +2 -0
- package/dist/tools/compress-integration.test.d.ts.map +1 -0
- package/dist/tools/compress-integration.test.js +59 -0
- package/dist/tools/compress-integration.test.js.map +1 -0
- package/dist/tools/compress.d.ts +57 -0
- package/dist/tools/compress.d.ts.map +1 -0
- package/dist/tools/compress.js +181 -0
- package/dist/tools/compress.js.map +1 -0
- package/dist/tools/compress.test.d.ts +2 -0
- package/dist/tools/compress.test.d.ts.map +1 -0
- package/dist/tools/compress.test.js +60 -0
- package/dist/tools/compress.test.js.map +1 -0
- package/dist/tools/task-output.d.ts.map +1 -1
- package/dist/tools/task-output.js +13 -3
- package/dist/tools/task-output.js.map +1 -1
- package/package.json +6 -5
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
const BODY_STUB = "{ /* … */ }";
|
|
3
|
+
function stubSignature(node, sf) {
|
|
4
|
+
const full = node.getText(sf);
|
|
5
|
+
if (ts.isFunctionDeclaration(node) ||
|
|
6
|
+
ts.isMethodDeclaration(node) ||
|
|
7
|
+
ts.isConstructorDeclaration(node) ||
|
|
8
|
+
ts.isGetAccessorDeclaration(node) ||
|
|
9
|
+
ts.isSetAccessorDeclaration(node)) {
|
|
10
|
+
const body = node.body;
|
|
11
|
+
if (body) {
|
|
12
|
+
const head = full.slice(0, body.getStart(sf) - node.getStart(sf)).trimEnd();
|
|
13
|
+
return `${head} ${BODY_STUB}`;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return full;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* For `export const x = (a: A): R => {…}` or `= function (…) {…}`, keep the
|
|
20
|
+
* callable head (everything up to the body) and stub the body. For non-callable
|
|
21
|
+
* initializers, keep the declared/annotated type and stub the value. This is
|
|
22
|
+
* what fixes the "name kept but signature lost" hole.
|
|
23
|
+
*/
|
|
24
|
+
function stubVariable(decl, sf, exported) {
|
|
25
|
+
const prefix = exported ? "export const " : "const ";
|
|
26
|
+
const name = decl.name.getText(sf);
|
|
27
|
+
const init = decl.initializer;
|
|
28
|
+
if (init && (ts.isArrowFunction(init) || ts.isFunctionExpression(init))) {
|
|
29
|
+
// Slice the initializer's text up to its body so params + return type
|
|
30
|
+
// survive — whether the body is a block `{…}` or an expression `=> x`.
|
|
31
|
+
const initFull = init.getText(sf);
|
|
32
|
+
const head = initFull.slice(0, init.body.getStart(sf) - init.getStart(sf)).trimEnd();
|
|
33
|
+
return `${prefix}${name} = ${head} ${BODY_STUB};`;
|
|
34
|
+
}
|
|
35
|
+
const type = decl.type ? `: ${decl.type.getText(sf)}` : "";
|
|
36
|
+
return `${prefix}${name}${type} = /* … */;`;
|
|
37
|
+
}
|
|
38
|
+
export function extractSkeleton(source, fileName = "module.ts") {
|
|
39
|
+
const sf = ts.createSourceFile(fileName, source, ts.ScriptTarget.Latest, true);
|
|
40
|
+
const out = [];
|
|
41
|
+
const exports = [];
|
|
42
|
+
const isExported = (node) => ts.canHaveModifiers(node) &&
|
|
43
|
+
(ts.getModifiers(node)?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) ?? false);
|
|
44
|
+
sf.forEachChild((node) => {
|
|
45
|
+
// import … (kept verbatim — cheap, and clarifies the file's dependencies)
|
|
46
|
+
if (ts.isImportDeclaration(node)) {
|
|
47
|
+
out.push(node.getText(sf));
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
// export { a, b } from "x" / export * from "x" / export { a }
|
|
51
|
+
if (ts.isExportDeclaration(node)) {
|
|
52
|
+
out.push(node.getText(sf));
|
|
53
|
+
if (node.exportClause && ts.isNamedExports(node.exportClause)) {
|
|
54
|
+
for (const el of node.exportClause.elements)
|
|
55
|
+
exports.push(el.name.text);
|
|
56
|
+
}
|
|
57
|
+
// `export *` re-exports unknown names; the line itself is the signal.
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
// export = x / export default …
|
|
61
|
+
if (ts.isExportAssignment(node)) {
|
|
62
|
+
out.push(node.getText(sf).split("\n")[0]);
|
|
63
|
+
exports.push(node.isExportEquals ? "export=" : "default");
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (ts.isInterfaceDeclaration(node) ||
|
|
67
|
+
ts.isTypeAliasDeclaration(node) ||
|
|
68
|
+
ts.isEnumDeclaration(node)) {
|
|
69
|
+
out.push(node.getText(sf)); // type-level: pure signal, keep whole
|
|
70
|
+
if (isExported(node) && node.name)
|
|
71
|
+
exports.push(node.name.text);
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (ts.isFunctionDeclaration(node)) {
|
|
75
|
+
out.push(stubSignature(node, sf));
|
|
76
|
+
if (isExported(node)) {
|
|
77
|
+
if (node.name)
|
|
78
|
+
exports.push(node.name.text);
|
|
79
|
+
else
|
|
80
|
+
exports.push("default"); // export default function (anon)
|
|
81
|
+
}
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (ts.isClassDeclaration(node)) {
|
|
85
|
+
const heritage = node.heritageClauses?.map((h) => h.getText(sf)).join(" ") ?? "";
|
|
86
|
+
const members = node.members
|
|
87
|
+
.filter((m) => {
|
|
88
|
+
// Drop private members — not part of the consumable API.
|
|
89
|
+
const mods = ts.canHaveModifiers(m) ? ts.getModifiers(m) : undefined;
|
|
90
|
+
return !mods?.some((mod) => mod.kind === ts.SyntaxKind.PrivateKeyword);
|
|
91
|
+
})
|
|
92
|
+
.map((m) => ` ${stubSignature(m, sf)}`)
|
|
93
|
+
.join("\n");
|
|
94
|
+
const name = node.name?.text ?? "";
|
|
95
|
+
const decl = isExported(node) ? "export class" : "class";
|
|
96
|
+
const heritagePart = heritage ? ` ${heritage}` : "";
|
|
97
|
+
out.push(`${decl} ${name}${heritagePart} {\n${members}\n}`);
|
|
98
|
+
if (isExported(node))
|
|
99
|
+
exports.push(name || "default");
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
if (ts.isVariableStatement(node)) {
|
|
103
|
+
const exported = node.modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) ?? false;
|
|
104
|
+
if (!exported)
|
|
105
|
+
return; // internal consts aren't API
|
|
106
|
+
for (const d of node.declarationList.declarations) {
|
|
107
|
+
out.push(stubVariable(d, sf, true));
|
|
108
|
+
exports.push(d.name.getText(sf));
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
const skeleton = out.join("\n\n");
|
|
113
|
+
return { skeleton, exports, empty: out.length === 0 };
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=code-skeleton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-skeleton.js","sourceRoot":"","sources":["../../src/tools/code-skeleton.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-skeleton.test.d.ts","sourceRoot":"","sources":["../../src/tools/code-skeleton.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import ts from "typescript";
|
|
3
|
+
import { extractSkeleton } from "./code-skeleton.js";
|
|
4
|
+
/**
|
|
5
|
+
* Strong fidelity check: re-parse the skeleton and confirm `name` resolves to a
|
|
6
|
+
* real declaration (not a comment or substring). For callables we also assert
|
|
7
|
+
* the signature text carries a parameter list, so "name kept, signature lost"
|
|
8
|
+
* fails here instead of slipping through a regex.
|
|
9
|
+
*/
|
|
10
|
+
function skeletonDeclares(skeleton, name) {
|
|
11
|
+
const sf = ts.createSourceFile("skel.ts", skeleton, ts.ScriptTarget.Latest, true);
|
|
12
|
+
let found = false;
|
|
13
|
+
const walk = (node) => {
|
|
14
|
+
if (found)
|
|
15
|
+
return;
|
|
16
|
+
if ((ts.isFunctionDeclaration(node) ||
|
|
17
|
+
ts.isClassDeclaration(node) ||
|
|
18
|
+
ts.isInterfaceDeclaration(node) ||
|
|
19
|
+
ts.isTypeAliasDeclaration(node) ||
|
|
20
|
+
ts.isEnumDeclaration(node)) &&
|
|
21
|
+
node.name?.getText(sf) === name) {
|
|
22
|
+
found = true;
|
|
23
|
+
}
|
|
24
|
+
else if (ts.isVariableDeclaration(node) && node.name.getText(sf) === name) {
|
|
25
|
+
found = true;
|
|
26
|
+
}
|
|
27
|
+
else if (ts.isExportDeclaration(node)) {
|
|
28
|
+
if (node.exportClause && ts.isNamedExports(node.exportClause)) {
|
|
29
|
+
if (node.exportClause.elements.some((e) => e.name.text === name))
|
|
30
|
+
found = true;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
ts.forEachChild(node, walk);
|
|
34
|
+
};
|
|
35
|
+
walk(sf);
|
|
36
|
+
return found;
|
|
37
|
+
}
|
|
38
|
+
describe("extractSkeleton", () => {
|
|
39
|
+
it("keeps re-export barrels (export {} from / export *) — does NOT render them empty", () => {
|
|
40
|
+
const src = `
|
|
41
|
+
export { foo, bar } from "./other.js";
|
|
42
|
+
export * from "./barrel.js";
|
|
43
|
+
`;
|
|
44
|
+
const r = extractSkeleton(src);
|
|
45
|
+
expect(r.empty).toBe(false);
|
|
46
|
+
expect(r.skeleton).toContain('export { foo, bar } from "./other.js"');
|
|
47
|
+
expect(r.skeleton).toContain('export * from "./barrel.js"');
|
|
48
|
+
expect(skeletonDeclares(r.skeleton, "foo")).toBe(true);
|
|
49
|
+
expect(skeletonDeclares(r.skeleton, "bar")).toBe(true);
|
|
50
|
+
});
|
|
51
|
+
it("preserves the callable signature of an exported arrow const", () => {
|
|
52
|
+
const src = `export const handler = async (req: Request, opts: Opts): Promise<Response> => {
|
|
53
|
+
return new Response("hi");
|
|
54
|
+
};`;
|
|
55
|
+
const r = extractSkeleton(src);
|
|
56
|
+
expect(r.skeleton).toContain("req: Request");
|
|
57
|
+
expect(r.skeleton).toContain("opts: Opts");
|
|
58
|
+
expect(r.skeleton).toContain("Promise<Response>");
|
|
59
|
+
expect(r.skeleton).not.toContain('new Response("hi")'); // body gone
|
|
60
|
+
expect(r.skeleton).toContain("/* … */"); // stub marked
|
|
61
|
+
});
|
|
62
|
+
it("keeps function declarations' params/return and stubs the body", () => {
|
|
63
|
+
const src = `export function add(a: number, b: number): number {
|
|
64
|
+
const sum = a + b;
|
|
65
|
+
return sum;
|
|
66
|
+
}`;
|
|
67
|
+
const r = extractSkeleton(src);
|
|
68
|
+
expect(r.skeleton).toContain("add(a: number, b: number): number");
|
|
69
|
+
expect(r.skeleton).not.toContain("const sum");
|
|
70
|
+
expect(r.skeleton).toContain("/* … */");
|
|
71
|
+
});
|
|
72
|
+
it("keeps public class members but drops private ones", () => {
|
|
73
|
+
const src = `export class Svc extends Base {
|
|
74
|
+
private secret = 42;
|
|
75
|
+
async run(x: string): Promise<void> { await this.secret; }
|
|
76
|
+
}`;
|
|
77
|
+
const r = extractSkeleton(src);
|
|
78
|
+
expect(r.skeleton).toContain("class Svc extends Base");
|
|
79
|
+
expect(r.skeleton).toContain("run(x: string): Promise<void>");
|
|
80
|
+
expect(r.skeleton).not.toContain("secret");
|
|
81
|
+
});
|
|
82
|
+
it("keeps interfaces and type aliases whole (pure signal)", () => {
|
|
83
|
+
const src = `export interface User { id: string; name: string; }
|
|
84
|
+
export type ID = string | number;`;
|
|
85
|
+
const r = extractSkeleton(src);
|
|
86
|
+
expect(r.skeleton).toContain("id: string");
|
|
87
|
+
expect(r.skeleton).toContain("type ID = string | number");
|
|
88
|
+
});
|
|
89
|
+
it("omits internal (non-exported) consts and functions' bodies", () => {
|
|
90
|
+
const src = `const internal = computeThing();
|
|
91
|
+
export function api(): void { internal(); }`;
|
|
92
|
+
const r = extractSkeleton(src);
|
|
93
|
+
expect(r.skeleton).not.toContain("computeThing");
|
|
94
|
+
expect(r.skeleton).toContain("api(): void");
|
|
95
|
+
});
|
|
96
|
+
it("never fabricates: every line traces to source or is a marked stub", () => {
|
|
97
|
+
const src = `import { z } from "zod";
|
|
98
|
+
export function f(a: string): string { return a.trim(); }`;
|
|
99
|
+
const r = extractSkeleton(src);
|
|
100
|
+
const srcText = src;
|
|
101
|
+
for (const line of r.skeleton.split("\n")) {
|
|
102
|
+
const t = line.trim();
|
|
103
|
+
if (!t)
|
|
104
|
+
continue;
|
|
105
|
+
const isStub = t.includes("/* … */");
|
|
106
|
+
const tracesBack = srcText.includes(t.replace(/\s*\{ \/\* … \*\/ \}.*$/, "").trim());
|
|
107
|
+
expect(isStub || tracesBack).toBe(true);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
it("reports empty for a file with no extractable API", () => {
|
|
111
|
+
const r = extractSkeleton(`const x = 1; console.log(x);`);
|
|
112
|
+
expect(r.empty).toBe(true);
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
//# sourceMappingURL=code-skeleton.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-skeleton.test.js","sourceRoot":"","sources":["../../src/tools/code-skeleton.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compress-integration.test.d.ts","sourceRoot":"","sources":["../../src/tools/compress-integration.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { compressToolOutput } from "./compress.js";
|
|
3
|
+
import { truncateTail, MAX_LINES } from "./truncate.js";
|
|
4
|
+
/**
|
|
5
|
+
* Integration-level guarantees for the live tool path (bash / task_output).
|
|
6
|
+
* The contract: compression only fires on output that was ALREADY going to be
|
|
7
|
+
* truncated, and on that branch it must keep more signal than a blind tail
|
|
8
|
+
* slice — never less — while staying reversible (caller keeps the overflow file).
|
|
9
|
+
*/
|
|
10
|
+
describe("compressToolOutput (live tool-output seam)", () => {
|
|
11
|
+
it("keeps a FATAL line that blind tail-truncation would drop", () => {
|
|
12
|
+
const lines = [];
|
|
13
|
+
for (let i = 0; i < 5000; i++) {
|
|
14
|
+
if (i === 1200)
|
|
15
|
+
lines.push("ERROR FATAL: segfault in worker pool");
|
|
16
|
+
else
|
|
17
|
+
lines.push(`INFO step ${i} ok`);
|
|
18
|
+
}
|
|
19
|
+
const raw = lines.join("\n");
|
|
20
|
+
// Today's behaviour: tail slice keeps only the last MAX_LINES — the FATAL at
|
|
21
|
+
// line 1200 is in the discarded head.
|
|
22
|
+
const tail = truncateTail(raw);
|
|
23
|
+
expect(tail.content).not.toContain("FATAL: segfault");
|
|
24
|
+
// Compression keeps it.
|
|
25
|
+
const c = compressToolOutput(raw);
|
|
26
|
+
expect(c.content).toContain("FATAL: segfault in worker pool");
|
|
27
|
+
expect(c.notice).toMatch(/fewer tokens/);
|
|
28
|
+
});
|
|
29
|
+
it("preserves the very end of the output (tail semantics)", () => {
|
|
30
|
+
const lines = Array.from({ length: 6000 }, (_, i) => `line ${i}`);
|
|
31
|
+
const c = compressToolOutput(lines.join("\n"));
|
|
32
|
+
expect(c.content).toContain("line 5999");
|
|
33
|
+
expect(c.content).toContain("line 5998");
|
|
34
|
+
});
|
|
35
|
+
it("collapses repeated spam into a count", () => {
|
|
36
|
+
const lines = ["boot"];
|
|
37
|
+
for (let i = 0; i < 3000; i++)
|
|
38
|
+
lines.push("WARN socket hang up");
|
|
39
|
+
lines.push("ERROR aborted");
|
|
40
|
+
const c = compressToolOutput(lines.join("\n"));
|
|
41
|
+
expect(c.content).toMatch(/×\d+/);
|
|
42
|
+
expect(c.content).toContain("ERROR aborted");
|
|
43
|
+
});
|
|
44
|
+
it("produces fewer tokens than the original on large output", () => {
|
|
45
|
+
const lines = Array.from({ length: 8000 }, (_, i) => `compiled module ${i} ok in ${i}ms`);
|
|
46
|
+
const raw = lines.join("\n");
|
|
47
|
+
const c = compressToolOutput(raw);
|
|
48
|
+
expect(c.content.length).toBeLessThan(raw.length / 2);
|
|
49
|
+
});
|
|
50
|
+
it("only the over-limit branch is affected — small output is never compressed here", () => {
|
|
51
|
+
// The tools call compressToolOutput ONLY when truncateTail reports truncated.
|
|
52
|
+
// A small output stays below MAX_LINES, so the branch never runs. Assert the
|
|
53
|
+
// gate, not the compressor: small output is not truncated.
|
|
54
|
+
const small = Array.from({ length: 10 }, (_, i) => `line ${i}`).join("\n");
|
|
55
|
+
expect(truncateTail(small).truncated).toBe(false);
|
|
56
|
+
expect(MAX_LINES).toBeGreaterThan(10);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
//# sourceMappingURL=compress-integration.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compress-integration.test.js","sourceRoot":"","sources":["../../src/tools/compress-integration.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Content-aware tool-output compression.
|
|
3
|
+
*
|
|
4
|
+
* Today's tool path shrinks oversized output with blunt head/tail line cuts
|
|
5
|
+
* (`truncate.ts`). That throws away whichever half the model didn't get — a
|
|
6
|
+
* stack trace buried in the middle of a 10k-line log, the one failing assertion
|
|
7
|
+
* between thousands of passing ones, the shape of a giant JSON array.
|
|
8
|
+
*
|
|
9
|
+
* `compressOutput` keeps the *signal* instead of a positional slice:
|
|
10
|
+
* - logs: collapse repeated runs, keep every error/warn line + local context,
|
|
11
|
+
* keep head and tail, drop only the boring middle.
|
|
12
|
+
* - JSON: keep array shape + a sample, replace the long tail with a count.
|
|
13
|
+
* - text: middle-out (head + tail) so the command/context AND the result survive.
|
|
14
|
+
*
|
|
15
|
+
* It is lossy by design but information-preserving: the goal is fewer tokens
|
|
16
|
+
* with the same understanding. Pair with an overflow file for full reversibility.
|
|
17
|
+
*/
|
|
18
|
+
export interface CompressResult {
|
|
19
|
+
content: string;
|
|
20
|
+
/** Which strategy fired — for telemetry / benchmarking. */
|
|
21
|
+
strategy: "json" | "log" | "text" | "none";
|
|
22
|
+
originalTokens: number;
|
|
23
|
+
compressedTokens: number;
|
|
24
|
+
}
|
|
25
|
+
export interface CompressOptions {
|
|
26
|
+
/** Don't compress below this token count — small output isn't worth touching. */
|
|
27
|
+
minTokens?: number;
|
|
28
|
+
/** Lines of context to keep on each side of an important log line. */
|
|
29
|
+
contextLines?: number;
|
|
30
|
+
/** Head/tail lines always retained. */
|
|
31
|
+
headLines?: number;
|
|
32
|
+
tailLines?: number;
|
|
33
|
+
/** Max elements kept per JSON array before summarising the rest. */
|
|
34
|
+
jsonArraySample?: number;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Compress a tool output string, auto-detecting its content type.
|
|
38
|
+
*/
|
|
39
|
+
export declare function compressOutput(raw: string, opts?: CompressOptions): CompressResult;
|
|
40
|
+
export interface ToolOutputCompression {
|
|
41
|
+
content: string;
|
|
42
|
+
/** Human/agent-facing summary of what was kept, for the truncation notice. */
|
|
43
|
+
notice: string;
|
|
44
|
+
strategy: CompressResult["strategy"];
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Compress output that a tool was ALREADY going to truncate.
|
|
48
|
+
*
|
|
49
|
+
* This is the only sanctioned live integration point. It is invoked solely on
|
|
50
|
+
* the over-limit branch of a tool (bash / task_output) — where today's
|
|
51
|
+
* alternative is a blind tail slice that discards the head and any mid-stream
|
|
52
|
+
* error. It keeps generous head/tail (tool output is tail-oriented) plus every
|
|
53
|
+
* error line and collapses repeats. The caller still writes the full original
|
|
54
|
+
* to an overflow file, so this stays fully reversible.
|
|
55
|
+
*/
|
|
56
|
+
export declare function compressToolOutput(raw: string): ToolOutputCompression;
|
|
57
|
+
//# sourceMappingURL=compress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compress.d.ts","sourceRoot":"","sources":["../../src/tools/compress.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;IAC3C,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uCAAuC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oEAAoE;IACpE,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AA+BD;;GAEG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,eAAoB,GAAG,cAAc,CAkBtF;AA2HD,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,8EAA8E;IAC9E,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;CACtC;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,qBAAqB,CAQrE"}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { estimateTokens } from "../core/compaction/token-estimator.js";
|
|
2
|
+
const DEFAULTS = {
|
|
3
|
+
minTokens: 400,
|
|
4
|
+
contextLines: 2,
|
|
5
|
+
headLines: 8,
|
|
6
|
+
tailLines: 8,
|
|
7
|
+
jsonArraySample: 5,
|
|
8
|
+
};
|
|
9
|
+
/** Lines that must never be dropped from a log. */
|
|
10
|
+
const IMPORTANT = /\b(error|fatal|panic|exception|traceback|fail(?:ed|ure)?|warn(?:ing)?|assert|fault|denied|refused|timeout|unhandled|rejected|✗|✖|❌)\b|^\s*at\s+|Error:|Caused by:/i;
|
|
11
|
+
function tokens(text) {
|
|
12
|
+
return estimateTokens(text);
|
|
13
|
+
}
|
|
14
|
+
function result(content, strategy, original) {
|
|
15
|
+
return {
|
|
16
|
+
content,
|
|
17
|
+
strategy,
|
|
18
|
+
originalTokens: tokens(original),
|
|
19
|
+
compressedTokens: tokens(content),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Compress a tool output string, auto-detecting its content type.
|
|
24
|
+
*/
|
|
25
|
+
export function compressOutput(raw, opts = {}) {
|
|
26
|
+
const o = { ...DEFAULTS, ...opts };
|
|
27
|
+
if (tokens(raw) < o.minTokens)
|
|
28
|
+
return result(raw, "none", raw);
|
|
29
|
+
const trimmed = raw.trim();
|
|
30
|
+
if (trimmed.length > 1 && (trimmed[0] === "{" || trimmed[0] === "[")) {
|
|
31
|
+
const json = tryCompressJson(trimmed, o);
|
|
32
|
+
if (json !== null)
|
|
33
|
+
return result(json, "json", raw);
|
|
34
|
+
}
|
|
35
|
+
const lines = raw.split("\n");
|
|
36
|
+
const importantCount = lines.reduce((n, l) => (IMPORTANT.test(l) ? n + 1 : n), 0);
|
|
37
|
+
// Treat as a log when it's many lines OR carries error signal worth isolating.
|
|
38
|
+
if (lines.length > o.headLines + o.tailLines + 10 && (importantCount > 0 || lines.length > 200)) {
|
|
39
|
+
return result(compressLog(lines, o), "log", raw);
|
|
40
|
+
}
|
|
41
|
+
return result(compressText(lines, o), "text", raw);
|
|
42
|
+
}
|
|
43
|
+
/* ----------------------------------------------------------------------- */
|
|
44
|
+
/* Log: keep error lines + context, collapse repeats, drop the boring middle */
|
|
45
|
+
/* ----------------------------------------------------------------------- */
|
|
46
|
+
function compressLog(lines, o) {
|
|
47
|
+
// 1. Collapse consecutive identical / near-identical runs into one entry.
|
|
48
|
+
// `exact` tracks whether every line in the run was byte-identical, so the
|
|
49
|
+
// emitted marker can be honest: "(×N)" only when truly identical, otherwise
|
|
50
|
+
// "(×N similar)" so the model never assumes the shown text (e.g. a single
|
|
51
|
+
// timestamp) was repeated verbatim across the whole run.
|
|
52
|
+
const collapsed = [];
|
|
53
|
+
for (let i = 0; i < lines.length; i++) {
|
|
54
|
+
const prev = collapsed[collapsed.length - 1];
|
|
55
|
+
if (prev && normalize(prev.text) === normalize(lines[i])) {
|
|
56
|
+
prev.count++;
|
|
57
|
+
if (lines[i] !== prev.text)
|
|
58
|
+
prev.exact = false;
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
collapsed.push({ text: lines[i], count: 1, idx: i, exact: true });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// 2. Mark which collapsed entries to keep: head, tail, important + context.
|
|
65
|
+
const keep = new Set();
|
|
66
|
+
for (let i = 0; i < Math.min(o.headLines, collapsed.length); i++)
|
|
67
|
+
keep.add(i);
|
|
68
|
+
for (let i = Math.max(0, collapsed.length - o.tailLines); i < collapsed.length; i++)
|
|
69
|
+
keep.add(i);
|
|
70
|
+
for (let i = 0; i < collapsed.length; i++) {
|
|
71
|
+
if (IMPORTANT.test(collapsed[i].text)) {
|
|
72
|
+
for (let j = i - o.contextLines; j <= i + o.contextLines; j++) {
|
|
73
|
+
if (j >= 0 && j < collapsed.length)
|
|
74
|
+
keep.add(j);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// 3. Emit, replacing dropped gaps with a single omission marker.
|
|
79
|
+
const out = [];
|
|
80
|
+
let droppedLines = 0;
|
|
81
|
+
let gapStart = -1;
|
|
82
|
+
const flushGap = () => {
|
|
83
|
+
if (droppedLines > 0) {
|
|
84
|
+
out.push(`… ${droppedLines} line${droppedLines === 1 ? "" : "s"} omitted …`);
|
|
85
|
+
droppedLines = 0;
|
|
86
|
+
gapStart = -1;
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
for (let i = 0; i < collapsed.length; i++) {
|
|
90
|
+
if (keep.has(i)) {
|
|
91
|
+
flushGap();
|
|
92
|
+
const e = collapsed[i];
|
|
93
|
+
if (e.count > 1)
|
|
94
|
+
out.push(`${e.text} (×${e.count}${e.exact ? "" : " similar"})`);
|
|
95
|
+
else
|
|
96
|
+
out.push(e.text);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
if (gapStart === -1)
|
|
100
|
+
gapStart = i;
|
|
101
|
+
droppedLines += collapsed[i].count;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
flushGap();
|
|
105
|
+
return out.join("\n");
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Strip only *volatile noise* (timestamps, hex addresses) so lines that differ
|
|
109
|
+
* solely by a leading timestamp collapse as repeats. Deliberately does NOT nuke
|
|
110
|
+
* arbitrary integers: when the number IS the content (`line 5998` vs `line 5999`,
|
|
111
|
+
* a port, an id), the lines must stay distinct so the tail isn't flattened into
|
|
112
|
+
* a single "(×N)" and genuinely different output isn't reported as repetition.
|
|
113
|
+
*/
|
|
114
|
+
function normalize(line) {
|
|
115
|
+
return line
|
|
116
|
+
.replace(/\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}(?:\.\d+)?Z?/g, "<ts>")
|
|
117
|
+
.replace(/\b\d{2}:\d{2}:\d{2}(?:\.\d+)?\b/g, "<ts>")
|
|
118
|
+
.replace(/0x[0-9a-f]+/gi, "<addr>")
|
|
119
|
+
.trim();
|
|
120
|
+
}
|
|
121
|
+
/* ----------------------------------------------------------------------- */
|
|
122
|
+
/* JSON: keep shape + a sample of long arrays, summarise the rest */
|
|
123
|
+
/* ----------------------------------------------------------------------- */
|
|
124
|
+
function tryCompressJson(text, o) {
|
|
125
|
+
let parsed;
|
|
126
|
+
try {
|
|
127
|
+
parsed = JSON.parse(text);
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
return null;
|
|
131
|
+
}
|
|
132
|
+
const shrunk = shrinkJson(parsed, o);
|
|
133
|
+
return JSON.stringify(shrunk, null, 2);
|
|
134
|
+
}
|
|
135
|
+
function shrinkJson(value, o) {
|
|
136
|
+
if (Array.isArray(value)) {
|
|
137
|
+
if (value.length <= o.jsonArraySample)
|
|
138
|
+
return value.map((v) => shrinkJson(v, o));
|
|
139
|
+
const sample = value.slice(0, o.jsonArraySample).map((v) => shrinkJson(v, o));
|
|
140
|
+
sample.push(`… ${value.length - o.jsonArraySample} more of ${value.length} items omitted …`);
|
|
141
|
+
return sample;
|
|
142
|
+
}
|
|
143
|
+
if (value && typeof value === "object") {
|
|
144
|
+
const out = {};
|
|
145
|
+
for (const [k, v] of Object.entries(value))
|
|
146
|
+
out[k] = shrinkJson(v, o);
|
|
147
|
+
return out;
|
|
148
|
+
}
|
|
149
|
+
return value;
|
|
150
|
+
}
|
|
151
|
+
/* ----------------------------------------------------------------------- */
|
|
152
|
+
/* Text: middle-out so both the command/context and the result survive */
|
|
153
|
+
/* ----------------------------------------------------------------------- */
|
|
154
|
+
function compressText(lines, o) {
|
|
155
|
+
const budget = o.headLines + o.tailLines;
|
|
156
|
+
if (lines.length <= budget)
|
|
157
|
+
return lines.join("\n");
|
|
158
|
+
const head = lines.slice(0, o.headLines);
|
|
159
|
+
const tail = lines.slice(lines.length - o.tailLines);
|
|
160
|
+
const dropped = lines.length - budget;
|
|
161
|
+
return [...head, `… ${dropped} lines omitted …`, ...tail].join("\n");
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Compress output that a tool was ALREADY going to truncate.
|
|
165
|
+
*
|
|
166
|
+
* This is the only sanctioned live integration point. It is invoked solely on
|
|
167
|
+
* the over-limit branch of a tool (bash / task_output) — where today's
|
|
168
|
+
* alternative is a blind tail slice that discards the head and any mid-stream
|
|
169
|
+
* error. It keeps generous head/tail (tool output is tail-oriented) plus every
|
|
170
|
+
* error line and collapses repeats. The caller still writes the full original
|
|
171
|
+
* to an overflow file, so this stays fully reversible.
|
|
172
|
+
*/
|
|
173
|
+
export function compressToolOutput(raw) {
|
|
174
|
+
const r = compressOutput(raw, { headLines: 12, tailLines: 30, minTokens: 0 });
|
|
175
|
+
const saved = r.originalTokens - r.compressedTokens;
|
|
176
|
+
const notice = r.strategy === "none"
|
|
177
|
+
? ""
|
|
178
|
+
: `Compressed (${r.strategy}): kept errors + head/tail, collapsed repeats — ~${saved} fewer tokens.`;
|
|
179
|
+
return { content: r.content, notice, strategy: r.strategy };
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=compress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compress.js","sourceRoot":"","sources":["../../src/tools/compress.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AAwCvE,MAAM,QAAQ,GAAG;IACf,SAAS,EAAE,GAAG;IACd,YAAY,EAAE,CAAC;IACf,SAAS,EAAE,CAAC;IACZ,SAAS,EAAE,CAAC;IACZ,eAAe,EAAE,CAAC;CACiB,CAAC;AAEtC,mDAAmD;AACnD,MAAM,SAAS,GACb,oKAAoK,CAAC;AAEvK,SAAS,MAAM,CAAC,IAAY;IAC1B,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;AAC9B,CAAC;AAED,SAAS,MAAM,CACb,OAAe,EACf,QAAoC,EACpC,QAAgB;IAEhB,OAAO;QACL,OAAO;QACP,QAAQ;QACR,cAAc,EAAE,MAAM,CAAC,QAAQ,CAAC;QAChC,gBAAgB,EAAE,MAAM,CAAC,OAAO,CAAC;KAClC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW,EAAE,OAAwB,EAAE;IACpE,MAAM,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,IAAI,EAAE,CAAC;IACnC,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,SAAS;QAAE,OAAO,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;IAE/D,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAC3B,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;QACrE,MAAM,IAAI,GAAG,eAAe,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACzC,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,cAAc,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAClF,+EAA+E;IAC/E,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,GAAG,EAAE,IAAI,CAAC,cAAc,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,GAAG,CAAC,EAAE,CAAC;QAChG,OAAO,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;IACnD,CAAC;IAED,OAAO,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;AACrD,CAAC;AAED,6EAA6E;AAC7E,+EAA+E;AAC/E,6EAA6E;AAE7E,SAAS,WAAW,CAAC,KAAe,EAAE,CAA4B;IAChE,0EAA0E;IAC1E,6EAA6E;IAC7E,+EAA+E;IAC/E,6EAA6E;IAC7E,4DAA4D;IAC5D,MAAM,SAAS,GAAmE,EAAE,CAAC;IACrF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC7C,IAAI,IAAI,IAAI,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACzD,IAAI,CAAC,KAAK,EAAE,CAAC;YACb,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,IAAI;gBAAE,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACjD,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE;QAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC9E,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IACjG,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,IAAI,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;YACtC,KAAK,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,YAAY,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC9D,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,MAAM;oBAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAClD,CAAC;QACH,CAAC;IACH,CAAC;IAED,iEAAiE;IACjE,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,IAAI,QAAQ,GAAG,CAAC,CAAC,CAAC;IAClB,MAAM,QAAQ,GAAG,GAAG,EAAE;QACpB,IAAI,YAAY,GAAG,CAAC,EAAE,CAAC;YACrB,GAAG,CAAC,IAAI,CAAC,KAAK,YAAY,QAAQ,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC;YAC7E,YAAY,GAAG,CAAC,CAAC;YACjB,QAAQ,GAAG,CAAC,CAAC,CAAC;QAChB,CAAC;IACH,CAAC,CAAC;IACF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAChB,QAAQ,EAAE,CAAC;YACX,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;YACvB,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC;gBAAE,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC;;gBAC7E,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACxB,CAAC;aAAM,CAAC;YACN,IAAI,QAAQ,KAAK,CAAC,CAAC;gBAAE,QAAQ,GAAG,CAAC,CAAC;YAClC,YAAY,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;QACrC,CAAC;IACH,CAAC;IACD,QAAQ,EAAE,CAAC;IACX,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC;AAED;;;;;;GAMG;AACH,SAAS,SAAS,CAAC,IAAY;IAC7B,OAAO,IAAI;SACR,OAAO,CAAC,qDAAqD,EAAE,MAAM,CAAC;SACtE,OAAO,CAAC,kCAAkC,EAAE,MAAM,CAAC;SACnD,OAAO,CAAC,eAAe,EAAE,QAAQ,CAAC;SAClC,IAAI,EAAE,CAAC;AACZ,CAAC;AAED,6EAA6E;AAC7E,+EAA+E;AAC/E,6EAA6E;AAE7E,SAAS,eAAe,CAAC,IAAY,EAAE,CAA4B;IACjE,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACrC,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,SAAS,UAAU,CAAC,KAAc,EAAE,CAA4B;IAC9D,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,eAAe;YAAE,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACjF,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,eAAe,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC9E,MAAM,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,eAAe,YAAY,KAAK,CAAC,MAAM,kBAAkB,CAAC,CAAC;QAC7F,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,MAAM,GAAG,GAA4B,EAAE,CAAC;QACxC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;YAAE,GAAG,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACtE,OAAO,GAAG,CAAC;IACb,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,6EAA6E;AAC7E,+EAA+E;AAC/E,6EAA6E;AAE7E,SAAS,YAAY,CAAC,KAAe,EAAE,CAA4B;IACjE,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC;IACzC,IAAI,KAAK,CAAC,MAAM,IAAI,MAAM;QAAE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC;IACzC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC;IACrD,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;IACtC,OAAO,CAAC,GAAG,IAAI,EAAE,KAAK,OAAO,kBAAkB,EAAE,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACvE,CAAC;AAaD;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,MAAM,CAAC,GAAG,cAAc,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC;IAC9E,MAAM,KAAK,GAAG,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC,gBAAgB,CAAC;IACpD,MAAM,MAAM,GACV,CAAC,CAAC,QAAQ,KAAK,MAAM;QACnB,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,eAAe,CAAC,CAAC,QAAQ,oDAAoD,KAAK,gBAAgB,CAAC;IACzG,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC;AAC9D,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compress.test.d.ts","sourceRoot":"","sources":["../../src/tools/compress.test.ts"],"names":[],"mappings":""}
|