@kolisachint/hoocode-agent-core 0.4.105 → 0.4.107
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/harness/agent-harness.d.ts +1 -0
- package/dist/harness/agent-harness.d.ts.map +1 -1
- package/dist/harness/agent-harness.js +1 -1
- package/dist/harness/agent-harness.js.map +1 -1
- package/dist/harness/compaction/branch-summarization.d.ts +10 -2
- package/dist/harness/compaction/branch-summarization.d.ts.map +1 -1
- package/dist/harness/compaction/branch-summarization.js +1 -4
- package/dist/harness/compaction/branch-summarization.js.map +1 -1
- package/dist/harness/compaction/compaction.d.ts +5 -0
- package/dist/harness/compaction/compaction.d.ts.map +1 -1
- package/dist/harness/compaction/compaction.js +22 -2
- package/dist/harness/compaction/compaction.js.map +1 -1
- package/dist/harness/compaction/utils.d.ts.map +1 -1
- package/dist/harness/compaction/utils.js +8 -5
- package/dist/harness/compaction/utils.js.map +1 -1
- package/dist/harness/messages.d.ts +73 -1
- package/dist/harness/messages.d.ts.map +1 -1
- package/dist/harness/messages.js +119 -0
- package/dist/harness/messages.js.map +1 -1
- package/dist/harness/session/session.d.ts +1 -1
- package/dist/harness/session/session.d.ts.map +1 -1
- package/dist/harness/session/session.js +3 -2
- package/dist/harness/session/session.js.map +1 -1
- package/dist/harness/types.d.ts +7 -42
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/harness/utils/output-compression.d.ts +53 -0
- package/dist/harness/utils/output-compression.d.ts.map +1 -0
- package/dist/harness/utils/output-compression.js +392 -0
- package/dist/harness/utils/output-compression.js.map +1 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lossless output compression utilities for tool outputs.
|
|
3
|
+
*
|
|
4
|
+
* All compression is strictly lossless - no useful information is removed.
|
|
5
|
+
* Compression is command-aware where possible, and general-purpose otherwise.
|
|
6
|
+
*/
|
|
7
|
+
/** Minimum output size (in bytes) to apply compression. Below this, overhead exceeds savings. */
|
|
8
|
+
const MIN_COMPRESSION_SIZE = 1024; // 1KB
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// General Compression (applied to all outputs)
|
|
11
|
+
// ============================================================================
|
|
12
|
+
/**
|
|
13
|
+
* Collapse 3+ consecutive blank lines to 2 (preserves paragraph separation).
|
|
14
|
+
*/
|
|
15
|
+
export function collapseBlankLines(text) {
|
|
16
|
+
return text.replace(/\n{3,}/g, "\n\n");
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Strip trailing whitespace from each line.
|
|
20
|
+
*/
|
|
21
|
+
export function stripTrailingWhitespace(text) {
|
|
22
|
+
return text
|
|
23
|
+
.split("\n")
|
|
24
|
+
.map((line) => line.trimEnd())
|
|
25
|
+
.join("\n");
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Remove duplicate consecutive lines (keeps first occurrence).
|
|
29
|
+
*/
|
|
30
|
+
export function removeDuplicateLines(text) {
|
|
31
|
+
const lines = text.split("\n");
|
|
32
|
+
const result = [];
|
|
33
|
+
let prevLine;
|
|
34
|
+
for (const line of lines) {
|
|
35
|
+
if (line !== prevLine) {
|
|
36
|
+
result.push(line);
|
|
37
|
+
prevLine = line;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return result.join("\n");
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Apply general lossless compression to any output.
|
|
44
|
+
* Single-pass implementation for efficiency.
|
|
45
|
+
*/
|
|
46
|
+
export function compressGeneral(text) {
|
|
47
|
+
const lines = text.split("\n");
|
|
48
|
+
const result = [];
|
|
49
|
+
let blankCount = 0;
|
|
50
|
+
for (const line of lines) {
|
|
51
|
+
const trimmed = line.trimEnd();
|
|
52
|
+
if (trimmed === "") {
|
|
53
|
+
blankCount++;
|
|
54
|
+
// Allow at most 2 consecutive blank lines
|
|
55
|
+
if (blankCount <= 2) {
|
|
56
|
+
result.push(trimmed);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
blankCount = 0;
|
|
61
|
+
result.push(trimmed);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return result.join("\n");
|
|
65
|
+
}
|
|
66
|
+
// ============================================================================
|
|
67
|
+
// Command-Specific Compression (bash only)
|
|
68
|
+
// ============================================================================
|
|
69
|
+
/**
|
|
70
|
+
* Detect the primary command from a bash command string.
|
|
71
|
+
*/
|
|
72
|
+
function detectCommand(command) {
|
|
73
|
+
const trimmed = command.trim();
|
|
74
|
+
// Strip leading env vars (FOO=bar command)
|
|
75
|
+
const withoutEnv = trimmed.replace(/^[A-Z_]+=\S+\s+/, "");
|
|
76
|
+
// Strip leading sudo
|
|
77
|
+
const withoutSudo = withoutEnv.replace(/^sudo\s+/, "");
|
|
78
|
+
// Get first word (the actual command)
|
|
79
|
+
const firstWord = withoutSudo.split(/\s+/)[0] ?? "";
|
|
80
|
+
// Strip path prefix if any
|
|
81
|
+
return firstWord.split("/").pop() ?? "";
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Compress npm/yarn/pnpm install output.
|
|
85
|
+
* - Remove download progress lines
|
|
86
|
+
* - Collapse "added N packages" summaries
|
|
87
|
+
*/
|
|
88
|
+
function compressNpmInstall(output) {
|
|
89
|
+
const lines = output.split("\n");
|
|
90
|
+
const result = [];
|
|
91
|
+
for (const line of lines) {
|
|
92
|
+
// Skip download progress (e.g., "fetchMetadata: ...", "reify: ...")
|
|
93
|
+
if (/^(fetchMetadata|reify|audit|idealTree|sill|warn)\b/.test(line)) {
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
// Skip verbose fetch/cache lines
|
|
97
|
+
if (/^\s*(http|https|fetch|cache|tarball|extract)\b/.test(line)) {
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
// Keep everything else (errors, warnings, summaries)
|
|
101
|
+
result.push(line);
|
|
102
|
+
}
|
|
103
|
+
return result.join("\n");
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Compress git diff output.
|
|
107
|
+
* - Strip file headers (diff --git, index, ---, +++)
|
|
108
|
+
* - Collapse unchanged context lines
|
|
109
|
+
*/
|
|
110
|
+
function compressGitDiff(output) {
|
|
111
|
+
const lines = output.split("\n");
|
|
112
|
+
const result = [];
|
|
113
|
+
let contextCount = 0;
|
|
114
|
+
for (const line of lines) {
|
|
115
|
+
// Skip git diff metadata
|
|
116
|
+
if (/^(diff --git|index [0-9a-f]+|--- a\/|\+\+\+ b\/)/.test(line)) {
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
// Count context lines (lines starting with space)
|
|
120
|
+
if (line.startsWith(" ") && !line.startsWith(" ")) {
|
|
121
|
+
contextCount++;
|
|
122
|
+
// Only show first 2 context lines per hunk, then skip
|
|
123
|
+
if (contextCount > 2) {
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
contextCount = 0;
|
|
129
|
+
}
|
|
130
|
+
result.push(line);
|
|
131
|
+
}
|
|
132
|
+
return result.join("\n");
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Compress cargo/rustc test output.
|
|
136
|
+
* - Collapse passing tests, keep failures
|
|
137
|
+
*/
|
|
138
|
+
function compressCargoTest(output) {
|
|
139
|
+
const lines = output.split("\n");
|
|
140
|
+
const result = [];
|
|
141
|
+
let passingCount = 0;
|
|
142
|
+
for (const line of lines) {
|
|
143
|
+
// Count passing test lines (e.g., "test foo ... ok")
|
|
144
|
+
if (/^test\s+.+\s+\.\.\.\s+ok\s*$/.test(line)) {
|
|
145
|
+
passingCount++;
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
// Count ignored tests
|
|
149
|
+
if (/^test\s+.+\s+\.\.\.\s+ignored\s*$/.test(line)) {
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
// Show test summary line
|
|
153
|
+
if (/^test result:/.test(line)) {
|
|
154
|
+
result.push(line);
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
// Keep failures, errors, and everything else
|
|
158
|
+
if (passingCount > 0 && line === "") {
|
|
159
|
+
// Add summary before blank line
|
|
160
|
+
result.push(` (${passingCount} passing tests omitted)`);
|
|
161
|
+
passingCount = 0;
|
|
162
|
+
}
|
|
163
|
+
result.push(line);
|
|
164
|
+
}
|
|
165
|
+
// Handle case where output ends with passing tests
|
|
166
|
+
if (passingCount > 0) {
|
|
167
|
+
result.push(` (${passingCount} passing tests omitted)`);
|
|
168
|
+
}
|
|
169
|
+
return result.join("\n");
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Compress docker build output.
|
|
173
|
+
* - Strip layer download progress
|
|
174
|
+
* - Keep build steps and errors
|
|
175
|
+
*/
|
|
176
|
+
function compressDockerBuild(output) {
|
|
177
|
+
const lines = output.split("\n");
|
|
178
|
+
const result = [];
|
|
179
|
+
for (const line of lines) {
|
|
180
|
+
// Skip download progress (e.g., "Downloading layer...")
|
|
181
|
+
if (/^(Downloading|Pulling|Extracting|Waiting|Verifying)/.test(line)) {
|
|
182
|
+
continue;
|
|
183
|
+
}
|
|
184
|
+
// Skip progress bars
|
|
185
|
+
if (/[\u2588\u2591\u2592]{10,}/.test(line)) {
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
// Keep build steps (FROM, RUN, COPY, etc.) and errors
|
|
189
|
+
result.push(line);
|
|
190
|
+
}
|
|
191
|
+
return result.join("\n");
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Compress jest/mocha test output.
|
|
195
|
+
* - Collapse passing tests
|
|
196
|
+
* - Keep failures
|
|
197
|
+
*/
|
|
198
|
+
function compressJsTest(output) {
|
|
199
|
+
const lines = output.split("\n");
|
|
200
|
+
const result = [];
|
|
201
|
+
let passingCount = 0;
|
|
202
|
+
for (const line of lines) {
|
|
203
|
+
// Skip passing test indicators (✓, ✔, ○)
|
|
204
|
+
if (/^\s*[✓✔○●]\s+/.test(line)) {
|
|
205
|
+
passingCount++;
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
// Skip passing test lines (e.g., " PASS src/foo.test.ts")
|
|
209
|
+
if (/^\s*PASS\s+/.test(line)) {
|
|
210
|
+
passingCount++;
|
|
211
|
+
continue;
|
|
212
|
+
}
|
|
213
|
+
// Show test summary
|
|
214
|
+
if (/^(Tests|Test Suites):/.test(line)) {
|
|
215
|
+
result.push(line);
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
// Keep failures (×, ✗, FAIL) and everything else
|
|
219
|
+
if (passingCount > 0 && (line.includes("FAIL") || line.includes("×") || line.includes("✗"))) {
|
|
220
|
+
result.push(` (${passingCount} passing tests omitted)`);
|
|
221
|
+
passingCount = 0;
|
|
222
|
+
}
|
|
223
|
+
result.push(line);
|
|
224
|
+
}
|
|
225
|
+
if (passingCount > 0) {
|
|
226
|
+
result.push(` (${passingCount} passing tests omitted)`);
|
|
227
|
+
}
|
|
228
|
+
return result.join("\n");
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Compress go test output.
|
|
232
|
+
* - Collapse passing tests
|
|
233
|
+
* - Keep failures
|
|
234
|
+
*/
|
|
235
|
+
function compressGoTest(output) {
|
|
236
|
+
const lines = output.split("\n");
|
|
237
|
+
const result = [];
|
|
238
|
+
let passingCount = 0;
|
|
239
|
+
for (const line of lines) {
|
|
240
|
+
// Skip passing test lines (e.g., "--- PASS: TestFoo (0.00s)")
|
|
241
|
+
if (/^---\s+PASS:/.test(line)) {
|
|
242
|
+
passingCount++;
|
|
243
|
+
continue;
|
|
244
|
+
}
|
|
245
|
+
// Skip PASS lines
|
|
246
|
+
if (/^PASS$/.test(line)) {
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
// Show test summary
|
|
250
|
+
if (/^(ok|FAIL)\s+/.test(line)) {
|
|
251
|
+
result.push(line);
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
// Keep failures and everything else
|
|
255
|
+
if (passingCount > 0 && line.includes("FAIL")) {
|
|
256
|
+
result.push(` (${passingCount} passing tests omitted)`);
|
|
257
|
+
passingCount = 0;
|
|
258
|
+
}
|
|
259
|
+
result.push(line);
|
|
260
|
+
}
|
|
261
|
+
if (passingCount > 0) {
|
|
262
|
+
result.push(` (${passingCount} passing tests omitted)`);
|
|
263
|
+
}
|
|
264
|
+
return result.join("\n");
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Apply command-specific compression based on the detected command.
|
|
268
|
+
*/
|
|
269
|
+
function compressCommandSpecific(command, output) {
|
|
270
|
+
const cmd = detectCommand(command);
|
|
271
|
+
switch (cmd) {
|
|
272
|
+
case "npm":
|
|
273
|
+
case "yarn":
|
|
274
|
+
case "pnpm":
|
|
275
|
+
// Check if it's an install/add command
|
|
276
|
+
if (/\b(install|add|i)\b/.test(command)) {
|
|
277
|
+
return compressNpmInstall(output);
|
|
278
|
+
}
|
|
279
|
+
break;
|
|
280
|
+
case "git":
|
|
281
|
+
// Check if it's a diff command
|
|
282
|
+
if (/\bdiff\b/.test(command)) {
|
|
283
|
+
return compressGitDiff(output);
|
|
284
|
+
}
|
|
285
|
+
break;
|
|
286
|
+
case "cargo":
|
|
287
|
+
// Check if it's a test command
|
|
288
|
+
if (/\btest\b/.test(command)) {
|
|
289
|
+
return compressCargoTest(output);
|
|
290
|
+
}
|
|
291
|
+
break;
|
|
292
|
+
case "docker":
|
|
293
|
+
// Check if it's a build command
|
|
294
|
+
if (/\bbuild\b/.test(command)) {
|
|
295
|
+
return compressDockerBuild(output);
|
|
296
|
+
}
|
|
297
|
+
break;
|
|
298
|
+
case "jest":
|
|
299
|
+
case "mocha":
|
|
300
|
+
case "vitest":
|
|
301
|
+
case "pytest":
|
|
302
|
+
return compressJsTest(output);
|
|
303
|
+
case "go":
|
|
304
|
+
// Check if it's a test command
|
|
305
|
+
if (/\btest\b/.test(command)) {
|
|
306
|
+
return compressGoTest(output);
|
|
307
|
+
}
|
|
308
|
+
break;
|
|
309
|
+
}
|
|
310
|
+
return output;
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Strip common noise patterns from any bash output.
|
|
314
|
+
* This is applied to all commands regardless of detection.
|
|
315
|
+
*/
|
|
316
|
+
function stripNoisePatterns(text) {
|
|
317
|
+
return (text
|
|
318
|
+
// Strip npm warnings (keep errors)
|
|
319
|
+
.replace(/^npm (warn|notice) .+$/gm, "")
|
|
320
|
+
// Strip yarn warnings
|
|
321
|
+
.replace(/^warning .+$/gm, "")
|
|
322
|
+
// Strip pnpm warnings
|
|
323
|
+
.replace(/^pnpm (warn|notice) .+$/gm, "")
|
|
324
|
+
// Strip common shell warnings
|
|
325
|
+
.replace(/^bash: .+ warning: .+$/gm, "")
|
|
326
|
+
// Strip "The command completed with non-zero exit status" noise
|
|
327
|
+
.replace(/^The command exited with exit code .+$/gm, ""));
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Apply all compression to a bash command output.
|
|
331
|
+
* This is the main entry point for bash output compression.
|
|
332
|
+
*
|
|
333
|
+
* @param command - The bash command that was executed
|
|
334
|
+
* @param output - The raw output from the command
|
|
335
|
+
* @returns Compressed output (lossless)
|
|
336
|
+
*/
|
|
337
|
+
export function compressBashOutput(command, output) {
|
|
338
|
+
// Skip compression for small outputs (overhead > savings)
|
|
339
|
+
if (Buffer.byteLength(output, "utf-8") < MIN_COMPRESSION_SIZE) {
|
|
340
|
+
return output;
|
|
341
|
+
}
|
|
342
|
+
let result = output;
|
|
343
|
+
// Phase 1: Strip noise patterns
|
|
344
|
+
result = stripNoisePatterns(result);
|
|
345
|
+
// Phase 2: Command-specific compression
|
|
346
|
+
result = compressCommandSpecific(command, result);
|
|
347
|
+
// Phase 3: General compression
|
|
348
|
+
result = compressGeneral(result);
|
|
349
|
+
return result;
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Apply compression to grep output.
|
|
353
|
+
* This strips redundant context and normalizes output.
|
|
354
|
+
*/
|
|
355
|
+
export function compressGrepOutput(output) {
|
|
356
|
+
if (Buffer.byteLength(output, "utf-8") < MIN_COMPRESSION_SIZE) {
|
|
357
|
+
return output;
|
|
358
|
+
}
|
|
359
|
+
return compressGeneral(output);
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Apply compression to read output.
|
|
363
|
+
* This normalizes whitespace but preserves content.
|
|
364
|
+
*/
|
|
365
|
+
export function compressReadOutput(output) {
|
|
366
|
+
// For read, we only do light compression - no line collapsing
|
|
367
|
+
if (Buffer.byteLength(output, "utf-8") < MIN_COMPRESSION_SIZE) {
|
|
368
|
+
return output;
|
|
369
|
+
}
|
|
370
|
+
return stripTrailingWhitespace(output);
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Apply compression to find output.
|
|
374
|
+
* This normalizes paths and removes duplicates.
|
|
375
|
+
*/
|
|
376
|
+
export function compressFindOutput(output) {
|
|
377
|
+
if (Buffer.byteLength(output, "utf-8") < MIN_COMPRESSION_SIZE) {
|
|
378
|
+
return output;
|
|
379
|
+
}
|
|
380
|
+
return compressGeneral(output);
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Apply compression to ls output.
|
|
384
|
+
* This normalizes formatting.
|
|
385
|
+
*/
|
|
386
|
+
export function compressLsOutput(output) {
|
|
387
|
+
if (Buffer.byteLength(output, "utf-8") < MIN_COMPRESSION_SIZE) {
|
|
388
|
+
return output;
|
|
389
|
+
}
|
|
390
|
+
return compressGeneral(output);
|
|
391
|
+
}
|
|
392
|
+
//# sourceMappingURL=output-compression.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output-compression.js","sourceRoot":"","sources":["../../../src/harness/utils/output-compression.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Lossless output compression utilities for tool outputs.\n *\n * All compression is strictly lossless - no useful information is removed.\n * Compression is command-aware where possible, and general-purpose otherwise.\n */\n\n/** Minimum output size (in bytes) to apply compression. Below this, overhead exceeds savings. */\nconst MIN_COMPRESSION_SIZE = 1024; // 1KB\n\n// ============================================================================\n// General Compression (applied to all outputs)\n// ============================================================================\n\n/**\n * Collapse 3+ consecutive blank lines to 2 (preserves paragraph separation).\n */\nexport function collapseBlankLines(text: string): string {\n\treturn text.replace(/\\n{3,}/g, \"\\n\\n\");\n}\n\n/**\n * Strip trailing whitespace from each line.\n */\nexport function stripTrailingWhitespace(text: string): string {\n\treturn text\n\t\t.split(\"\\n\")\n\t\t.map((line) => line.trimEnd())\n\t\t.join(\"\\n\");\n}\n\n/**\n * Remove duplicate consecutive lines (keeps first occurrence).\n */\nexport function removeDuplicateLines(text: string): string {\n\tconst lines = text.split(\"\\n\");\n\tconst result: string[] = [];\n\tlet prevLine: string | undefined;\n\n\tfor (const line of lines) {\n\t\tif (line !== prevLine) {\n\t\t\tresult.push(line);\n\t\t\tprevLine = line;\n\t\t}\n\t}\n\n\treturn result.join(\"\\n\");\n}\n\n/**\n * Apply general lossless compression to any output.\n * Single-pass implementation for efficiency.\n */\nexport function compressGeneral(text: string): string {\n\tconst lines = text.split(\"\\n\");\n\tconst result: string[] = [];\n\tlet blankCount = 0;\n\n\tfor (const line of lines) {\n\t\tconst trimmed = line.trimEnd();\n\n\t\tif (trimmed === \"\") {\n\t\t\tblankCount++;\n\t\t\t// Allow at most 2 consecutive blank lines\n\t\t\tif (blankCount <= 2) {\n\t\t\t\tresult.push(trimmed);\n\t\t\t}\n\t\t} else {\n\t\t\tblankCount = 0;\n\t\t\tresult.push(trimmed);\n\t\t}\n\t}\n\n\treturn result.join(\"\\n\");\n}\n\n// ============================================================================\n// Command-Specific Compression (bash only)\n// ============================================================================\n\n/**\n * Detect the primary command from a bash command string.\n */\nfunction detectCommand(command: string): string {\n\tconst trimmed = command.trim();\n\t// Strip leading env vars (FOO=bar command)\n\tconst withoutEnv = trimmed.replace(/^[A-Z_]+=\\S+\\s+/, \"\");\n\t// Strip leading sudo\n\tconst withoutSudo = withoutEnv.replace(/^sudo\\s+/, \"\");\n\t// Get first word (the actual command)\n\tconst firstWord = withoutSudo.split(/\\s+/)[0] ?? \"\";\n\t// Strip path prefix if any\n\treturn firstWord.split(\"/\").pop() ?? \"\";\n}\n\n/**\n * Compress npm/yarn/pnpm install output.\n * - Remove download progress lines\n * - Collapse \"added N packages\" summaries\n */\nfunction compressNpmInstall(output: string): string {\n\tconst lines = output.split(\"\\n\");\n\tconst result: string[] = [];\n\n\tfor (const line of lines) {\n\t\t// Skip download progress (e.g., \"fetchMetadata: ...\", \"reify: ...\")\n\t\tif (/^(fetchMetadata|reify|audit|idealTree|sill|warn)\\b/.test(line)) {\n\t\t\tcontinue;\n\t\t}\n\t\t// Skip verbose fetch/cache lines\n\t\tif (/^\\s*(http|https|fetch|cache|tarball|extract)\\b/.test(line)) {\n\t\t\tcontinue;\n\t\t}\n\t\t// Keep everything else (errors, warnings, summaries)\n\t\tresult.push(line);\n\t}\n\n\treturn result.join(\"\\n\");\n}\n\n/**\n * Compress git diff output.\n * - Strip file headers (diff --git, index, ---, +++)\n * - Collapse unchanged context lines\n */\nfunction compressGitDiff(output: string): string {\n\tconst lines = output.split(\"\\n\");\n\tconst result: string[] = [];\n\tlet contextCount = 0;\n\n\tfor (const line of lines) {\n\t\t// Skip git diff metadata\n\t\tif (/^(diff --git|index [0-9a-f]+|--- a\\/|\\+\\+\\+ b\\/)/.test(line)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Count context lines (lines starting with space)\n\t\tif (line.startsWith(\" \") && !line.startsWith(\" \")) {\n\t\t\tcontextCount++;\n\t\t\t// Only show first 2 context lines per hunk, then skip\n\t\t\tif (contextCount > 2) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t} else {\n\t\t\tcontextCount = 0;\n\t\t}\n\n\t\tresult.push(line);\n\t}\n\n\treturn result.join(\"\\n\");\n}\n\n/**\n * Compress cargo/rustc test output.\n * - Collapse passing tests, keep failures\n */\nfunction compressCargoTest(output: string): string {\n\tconst lines = output.split(\"\\n\");\n\tconst result: string[] = [];\n\tlet passingCount = 0;\n\n\tfor (const line of lines) {\n\t\t// Count passing test lines (e.g., \"test foo ... ok\")\n\t\tif (/^test\\s+.+\\s+\\.\\.\\.\\s+ok\\s*$/.test(line)) {\n\t\t\tpassingCount++;\n\t\t\tcontinue;\n\t\t}\n\t\t// Count ignored tests\n\t\tif (/^test\\s+.+\\s+\\.\\.\\.\\s+ignored\\s*$/.test(line)) {\n\t\t\tcontinue;\n\t\t}\n\t\t// Show test summary line\n\t\tif (/^test result:/.test(line)) {\n\t\t\tresult.push(line);\n\t\t\tcontinue;\n\t\t}\n\t\t// Keep failures, errors, and everything else\n\t\tif (passingCount > 0 && line === \"\") {\n\t\t\t// Add summary before blank line\n\t\t\tresult.push(` (${passingCount} passing tests omitted)`);\n\t\t\tpassingCount = 0;\n\t\t}\n\t\tresult.push(line);\n\t}\n\n\t// Handle case where output ends with passing tests\n\tif (passingCount > 0) {\n\t\tresult.push(` (${passingCount} passing tests omitted)`);\n\t}\n\n\treturn result.join(\"\\n\");\n}\n\n/**\n * Compress docker build output.\n * - Strip layer download progress\n * - Keep build steps and errors\n */\nfunction compressDockerBuild(output: string): string {\n\tconst lines = output.split(\"\\n\");\n\tconst result: string[] = [];\n\n\tfor (const line of lines) {\n\t\t// Skip download progress (e.g., \"Downloading layer...\")\n\t\tif (/^(Downloading|Pulling|Extracting|Waiting|Verifying)/.test(line)) {\n\t\t\tcontinue;\n\t\t}\n\t\t// Skip progress bars\n\t\tif (/[\\u2588\\u2591\\u2592]{10,}/.test(line)) {\n\t\t\tcontinue;\n\t\t}\n\t\t// Keep build steps (FROM, RUN, COPY, etc.) and errors\n\t\tresult.push(line);\n\t}\n\n\treturn result.join(\"\\n\");\n}\n\n/**\n * Compress jest/mocha test output.\n * - Collapse passing tests\n * - Keep failures\n */\nfunction compressJsTest(output: string): string {\n\tconst lines = output.split(\"\\n\");\n\tconst result: string[] = [];\n\tlet passingCount = 0;\n\n\tfor (const line of lines) {\n\t\t// Skip passing test indicators (✓, ✔, ○)\n\t\tif (/^\\s*[✓✔○●]\\s+/.test(line)) {\n\t\t\tpassingCount++;\n\t\t\tcontinue;\n\t\t}\n\t\t// Skip passing test lines (e.g., \" PASS src/foo.test.ts\")\n\t\tif (/^\\s*PASS\\s+/.test(line)) {\n\t\t\tpassingCount++;\n\t\t\tcontinue;\n\t\t}\n\t\t// Show test summary\n\t\tif (/^(Tests|Test Suites):/.test(line)) {\n\t\t\tresult.push(line);\n\t\t\tcontinue;\n\t\t}\n\t\t// Keep failures (×, ✗, FAIL) and everything else\n\t\tif (passingCount > 0 && (line.includes(\"FAIL\") || line.includes(\"×\") || line.includes(\"✗\"))) {\n\t\t\tresult.push(` (${passingCount} passing tests omitted)`);\n\t\t\tpassingCount = 0;\n\t\t}\n\t\tresult.push(line);\n\t}\n\n\tif (passingCount > 0) {\n\t\tresult.push(` (${passingCount} passing tests omitted)`);\n\t}\n\n\treturn result.join(\"\\n\");\n}\n\n/**\n * Compress go test output.\n * - Collapse passing tests\n * - Keep failures\n */\nfunction compressGoTest(output: string): string {\n\tconst lines = output.split(\"\\n\");\n\tconst result: string[] = [];\n\tlet passingCount = 0;\n\n\tfor (const line of lines) {\n\t\t// Skip passing test lines (e.g., \"--- PASS: TestFoo (0.00s)\")\n\t\tif (/^---\\s+PASS:/.test(line)) {\n\t\t\tpassingCount++;\n\t\t\tcontinue;\n\t\t}\n\t\t// Skip PASS lines\n\t\tif (/^PASS$/.test(line)) {\n\t\t\tcontinue;\n\t\t}\n\t\t// Show test summary\n\t\tif (/^(ok|FAIL)\\s+/.test(line)) {\n\t\t\tresult.push(line);\n\t\t\tcontinue;\n\t\t}\n\t\t// Keep failures and everything else\n\t\tif (passingCount > 0 && line.includes(\"FAIL\")) {\n\t\t\tresult.push(` (${passingCount} passing tests omitted)`);\n\t\t\tpassingCount = 0;\n\t\t}\n\t\tresult.push(line);\n\t}\n\n\tif (passingCount > 0) {\n\t\tresult.push(` (${passingCount} passing tests omitted)`);\n\t}\n\n\treturn result.join(\"\\n\");\n}\n\n/**\n * Apply command-specific compression based on the detected command.\n */\nfunction compressCommandSpecific(command: string, output: string): string {\n\tconst cmd = detectCommand(command);\n\n\tswitch (cmd) {\n\t\tcase \"npm\":\n\t\tcase \"yarn\":\n\t\tcase \"pnpm\":\n\t\t\t// Check if it's an install/add command\n\t\t\tif (/\\b(install|add|i)\\b/.test(command)) {\n\t\t\t\treturn compressNpmInstall(output);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase \"git\":\n\t\t\t// Check if it's a diff command\n\t\t\tif (/\\bdiff\\b/.test(command)) {\n\t\t\t\treturn compressGitDiff(output);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase \"cargo\":\n\t\t\t// Check if it's a test command\n\t\t\tif (/\\btest\\b/.test(command)) {\n\t\t\t\treturn compressCargoTest(output);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase \"docker\":\n\t\t\t// Check if it's a build command\n\t\t\tif (/\\bbuild\\b/.test(command)) {\n\t\t\t\treturn compressDockerBuild(output);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase \"jest\":\n\t\tcase \"mocha\":\n\t\tcase \"vitest\":\n\t\tcase \"pytest\":\n\t\t\treturn compressJsTest(output);\n\t\tcase \"go\":\n\t\t\t// Check if it's a test command\n\t\t\tif (/\\btest\\b/.test(command)) {\n\t\t\t\treturn compressGoTest(output);\n\t\t\t}\n\t\t\tbreak;\n\t}\n\n\treturn output;\n}\n\n/**\n * Strip common noise patterns from any bash output.\n * This is applied to all commands regardless of detection.\n */\nfunction stripNoisePatterns(text: string): string {\n\treturn (\n\t\ttext\n\t\t\t// Strip npm warnings (keep errors)\n\t\t\t.replace(/^npm (warn|notice) .+$/gm, \"\")\n\t\t\t// Strip yarn warnings\n\t\t\t.replace(/^warning .+$/gm, \"\")\n\t\t\t// Strip pnpm warnings\n\t\t\t.replace(/^pnpm (warn|notice) .+$/gm, \"\")\n\t\t\t// Strip common shell warnings\n\t\t\t.replace(/^bash: .+ warning: .+$/gm, \"\")\n\t\t\t// Strip \"The command completed with non-zero exit status\" noise\n\t\t\t.replace(/^The command exited with exit code .+$/gm, \"\")\n\t);\n}\n\n/**\n * Apply all compression to a bash command output.\n * This is the main entry point for bash output compression.\n *\n * @param command - The bash command that was executed\n * @param output - The raw output from the command\n * @returns Compressed output (lossless)\n */\nexport function compressBashOutput(command: string, output: string): string {\n\t// Skip compression for small outputs (overhead > savings)\n\tif (Buffer.byteLength(output, \"utf-8\") < MIN_COMPRESSION_SIZE) {\n\t\treturn output;\n\t}\n\n\tlet result = output;\n\n\t// Phase 1: Strip noise patterns\n\tresult = stripNoisePatterns(result);\n\n\t// Phase 2: Command-specific compression\n\tresult = compressCommandSpecific(command, result);\n\n\t// Phase 3: General compression\n\tresult = compressGeneral(result);\n\n\treturn result;\n}\n\n/**\n * Apply compression to grep output.\n * This strips redundant context and normalizes output.\n */\nexport function compressGrepOutput(output: string): string {\n\tif (Buffer.byteLength(output, \"utf-8\") < MIN_COMPRESSION_SIZE) {\n\t\treturn output;\n\t}\n\treturn compressGeneral(output);\n}\n\n/**\n * Apply compression to read output.\n * This normalizes whitespace but preserves content.\n */\nexport function compressReadOutput(output: string): string {\n\t// For read, we only do light compression - no line collapsing\n\tif (Buffer.byteLength(output, \"utf-8\") < MIN_COMPRESSION_SIZE) {\n\t\treturn output;\n\t}\n\treturn stripTrailingWhitespace(output);\n}\n\n/**\n * Apply compression to find output.\n * This normalizes paths and removes duplicates.\n */\nexport function compressFindOutput(output: string): string {\n\tif (Buffer.byteLength(output, \"utf-8\") < MIN_COMPRESSION_SIZE) {\n\t\treturn output;\n\t}\n\treturn compressGeneral(output);\n}\n\n/**\n * Apply compression to ls output.\n * This normalizes formatting.\n */\nexport function compressLsOutput(output: string): string {\n\tif (Buffer.byteLength(output, \"utf-8\") < MIN_COMPRESSION_SIZE) {\n\t\treturn output;\n\t}\n\treturn compressGeneral(output);\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export * from "./agent.js";
|
|
2
2
|
export * from "./agent-loop.js";
|
|
3
3
|
export * from "./harness/agent-harness.js";
|
|
4
|
-
export
|
|
5
|
-
export
|
|
4
|
+
export * from "./harness/compaction/branch-summarization.js";
|
|
5
|
+
export * from "./harness/compaction/compaction.js";
|
|
6
6
|
export * from "./harness/execution-env.js";
|
|
7
7
|
export * from "./harness/messages.js";
|
|
8
8
|
export * from "./harness/prompt-templates.js";
|
|
@@ -13,6 +13,7 @@ export * from "./harness/session/session.js";
|
|
|
13
13
|
export * from "./harness/skills.js";
|
|
14
14
|
export * from "./harness/system-prompt.js";
|
|
15
15
|
export * from "./harness/types.js";
|
|
16
|
+
export * from "./harness/utils/output-compression.js";
|
|
16
17
|
export * from "./harness/utils/shell-output.js";
|
|
17
18
|
export * from "./harness/utils/truncate.js";
|
|
18
19
|
export * from "./proxy.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,YAAY,CAAC;AAE3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,YAAY,CAAC;AAE3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,4BAA4B,CAAC;AAE3C,cAAc,8CAA8C,CAAC;AAC7D,cAAc,oCAAoC,CAAC;AACnD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iCAAiC,CAAC;AAChD,cAAc,kCAAkC,CAAC;AACjD,cAAc,kCAAkC,CAAC;AACjD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAE3C,cAAc,oBAAoB,CAAC;AACnC,cAAc,uCAAuC,CAAC;AACtD,cAAc,iCAAiC,CAAC;AAChD,cAAc,6BAA6B,CAAC;AAE5C,cAAc,YAAY,CAAC;AAE3B,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AAErC,cAAc,YAAY,CAAC","sourcesContent":["// Core Agent\nexport * from \"./agent.js\";\n// Loop functions\nexport * from \"./agent-loop.js\";\nexport * from \"./harness/agent-harness.js\";\n// Compaction and branch summarization\nexport * from \"./harness/compaction/branch-summarization.js\";\nexport * from \"./harness/compaction/compaction.js\";\nexport * from \"./harness/execution-env.js\";\nexport * from \"./harness/messages.js\";\nexport * from \"./harness/prompt-templates.js\";\nexport * from \"./harness/session/repo/jsonl.js\";\nexport * from \"./harness/session/repo/memory.js\";\nexport * from \"./harness/session/repo/shared.js\";\nexport * from \"./harness/session/session.js\";\nexport * from \"./harness/skills.js\";\nexport * from \"./harness/system-prompt.js\";\n// Harness\nexport * from \"./harness/types.js\";\nexport * from \"./harness/utils/output-compression.js\";\nexport * from \"./harness/utils/shell-output.js\";\nexport * from \"./harness/utils/truncate.js\";\n// Proxy utilities\nexport * from \"./proxy.js\";\n// Headless tool bundles\nexport * from \"./tools/default-tools.js\";\nexport * from \"./tools/mcp-tools.js\";\n// Types\nexport * from \"./types.js\";\n"]}
|
package/dist/index.js
CHANGED
|
@@ -3,8 +3,9 @@ export * from "./agent.js";
|
|
|
3
3
|
// Loop functions
|
|
4
4
|
export * from "./agent-loop.js";
|
|
5
5
|
export * from "./harness/agent-harness.js";
|
|
6
|
-
|
|
7
|
-
export
|
|
6
|
+
// Compaction and branch summarization
|
|
7
|
+
export * from "./harness/compaction/branch-summarization.js";
|
|
8
|
+
export * from "./harness/compaction/compaction.js";
|
|
8
9
|
export * from "./harness/execution-env.js";
|
|
9
10
|
export * from "./harness/messages.js";
|
|
10
11
|
export * from "./harness/prompt-templates.js";
|
|
@@ -16,6 +17,7 @@ export * from "./harness/skills.js";
|
|
|
16
17
|
export * from "./harness/system-prompt.js";
|
|
17
18
|
// Harness
|
|
18
19
|
export * from "./harness/types.js";
|
|
20
|
+
export * from "./harness/utils/output-compression.js";
|
|
19
21
|
export * from "./harness/utils/shell-output.js";
|
|
20
22
|
export * from "./harness/utils/truncate.js";
|
|
21
23
|
// Proxy utilities
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,aAAa;AACb,cAAc,YAAY,CAAC;AAC3B,iBAAiB;AACjB,cAAc,iBAAiB,CAAC;AAChC,cAAc,4BAA4B,CAAC;AAC3C,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,aAAa;AACb,cAAc,YAAY,CAAC;AAC3B,iBAAiB;AACjB,cAAc,iBAAiB,CAAC;AAChC,cAAc,4BAA4B,CAAC;AAC3C,sCAAsC;AACtC,cAAc,8CAA8C,CAAC;AAC7D,cAAc,oCAAoC,CAAC;AACnD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iCAAiC,CAAC;AAChD,cAAc,kCAAkC,CAAC;AACjD,cAAc,kCAAkC,CAAC;AACjD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,UAAU;AACV,cAAc,oBAAoB,CAAC;AACnC,cAAc,uCAAuC,CAAC;AACtD,cAAc,iCAAiC,CAAC;AAChD,cAAc,6BAA6B,CAAC;AAC5C,kBAAkB;AAClB,cAAc,YAAY,CAAC;AAC3B,wBAAwB;AACxB,cAAc,0BAA0B,CAAC;AACzC,cAAc,sBAAsB,CAAC;AACrC,QAAQ;AACR,cAAc,YAAY,CAAC","sourcesContent":["// Core Agent\nexport * from \"./agent.js\";\n// Loop functions\nexport * from \"./agent-loop.js\";\nexport * from \"./harness/agent-harness.js\";\n// Compaction and branch summarization\nexport * from \"./harness/compaction/branch-summarization.js\";\nexport * from \"./harness/compaction/compaction.js\";\nexport * from \"./harness/execution-env.js\";\nexport * from \"./harness/messages.js\";\nexport * from \"./harness/prompt-templates.js\";\nexport * from \"./harness/session/repo/jsonl.js\";\nexport * from \"./harness/session/repo/memory.js\";\nexport * from \"./harness/session/repo/shared.js\";\nexport * from \"./harness/session/session.js\";\nexport * from \"./harness/skills.js\";\nexport * from \"./harness/system-prompt.js\";\n// Harness\nexport * from \"./harness/types.js\";\nexport * from \"./harness/utils/output-compression.js\";\nexport * from \"./harness/utils/shell-output.js\";\nexport * from \"./harness/utils/truncate.js\";\n// Proxy utilities\nexport * from \"./proxy.js\";\n// Headless tool bundles\nexport * from \"./tools/default-tools.js\";\nexport * from \"./tools/mcp-tools.js\";\n// Types\nexport * from \"./types.js\";\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kolisachint/hoocode-agent-core",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.107",
|
|
4
4
|
"description": "General-purpose agent with transport abstraction, state management, and attachment support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"prepublishOnly": "npm run clean && npm run build"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@kolisachint/hoocode-ai": "^0.4.
|
|
20
|
+
"@kolisachint/hoocode-ai": "^0.4.107",
|
|
21
21
|
"ignore": "^7.0.5",
|
|
22
22
|
"typebox": "^1.1.24",
|
|
23
23
|
"uuid": "^14.0.0",
|