context-compress 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +275 -0
- package/dist/cli/doctor.d.ts +2 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/doctor.js +131 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/index.d.ts +12 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +31 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/setup.d.ts +2 -0
- package/dist/cli/setup.d.ts.map +1 -0
- package/dist/cli/setup.js +43 -0
- package/dist/cli/setup.js.map +1 -0
- package/dist/cli/uninstall.d.ts +2 -0
- package/dist/cli/uninstall.d.ts.map +1 -0
- package/dist/cli/uninstall.js +102 -0
- package/dist/cli/uninstall.js.map +1 -0
- package/dist/config.d.ts +37 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +79 -0
- package/dist/config.js.map +1 -0
- package/dist/executor.d.ts +21 -0
- package/dist/executor.d.ts.map +1 -0
- package/dist/executor.js +301 -0
- package/dist/executor.js.map +1 -0
- package/dist/hooks/pretooluse.d.ts +10 -0
- package/dist/hooks/pretooluse.d.ts.map +1 -0
- package/dist/hooks/pretooluse.js +117 -0
- package/dist/hooks/pretooluse.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +4 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +13 -0
- package/dist/logger.js.map +1 -0
- package/dist/runtime/index.d.ts +22 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +81 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/languages/elixir.d.ts +3 -0
- package/dist/runtime/languages/elixir.d.ts.map +1 -0
- package/dist/runtime/languages/elixir.js +15 -0
- package/dist/runtime/languages/elixir.js.map +1 -0
- package/dist/runtime/languages/go.d.ts +3 -0
- package/dist/runtime/languages/go.d.ts.map +1 -0
- package/dist/runtime/languages/go.js +29 -0
- package/dist/runtime/languages/go.js.map +1 -0
- package/dist/runtime/languages/javascript.d.ts +3 -0
- package/dist/runtime/languages/javascript.d.ts.map +1 -0
- package/dist/runtime/languages/javascript.js +13 -0
- package/dist/runtime/languages/javascript.js.map +1 -0
- package/dist/runtime/languages/perl.d.ts +3 -0
- package/dist/runtime/languages/perl.d.ts.map +1 -0
- package/dist/runtime/languages/perl.js +13 -0
- package/dist/runtime/languages/perl.js.map +1 -0
- package/dist/runtime/languages/php.d.ts +3 -0
- package/dist/runtime/languages/php.d.ts.map +1 -0
- package/dist/runtime/languages/php.js +24 -0
- package/dist/runtime/languages/php.js.map +1 -0
- package/dist/runtime/languages/python.d.ts +3 -0
- package/dist/runtime/languages/python.d.ts.map +1 -0
- package/dist/runtime/languages/python.js +13 -0
- package/dist/runtime/languages/python.js.map +1 -0
- package/dist/runtime/languages/r.d.ts +3 -0
- package/dist/runtime/languages/r.d.ts.map +1 -0
- package/dist/runtime/languages/r.js +13 -0
- package/dist/runtime/languages/r.js.map +1 -0
- package/dist/runtime/languages/ruby.d.ts +3 -0
- package/dist/runtime/languages/ruby.d.ts.map +1 -0
- package/dist/runtime/languages/ruby.js +13 -0
- package/dist/runtime/languages/ruby.js.map +1 -0
- package/dist/runtime/languages/rust.d.ts +3 -0
- package/dist/runtime/languages/rust.d.ts.map +1 -0
- package/dist/runtime/languages/rust.js +28 -0
- package/dist/runtime/languages/rust.js.map +1 -0
- package/dist/runtime/languages/shell.d.ts +3 -0
- package/dist/runtime/languages/shell.d.ts.map +1 -0
- package/dist/runtime/languages/shell.js +14 -0
- package/dist/runtime/languages/shell.js.map +1 -0
- package/dist/runtime/languages/typescript.d.ts +3 -0
- package/dist/runtime/languages/typescript.d.ts.map +1 -0
- package/dist/runtime/languages/typescript.js +15 -0
- package/dist/runtime/languages/typescript.js.map +1 -0
- package/dist/runtime/plugin.d.ts +38 -0
- package/dist/runtime/plugin.d.ts.map +1 -0
- package/dist/runtime/plugin.js +2 -0
- package/dist/runtime/plugin.js.map +1 -0
- package/dist/server.bundle.mjs +22769 -0
- package/dist/server.bundle.mjs.map +7 -0
- package/dist/server.d.ts +5 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +405 -0
- package/dist/server.js.map +1 -0
- package/dist/snippet.d.ts +15 -0
- package/dist/snippet.d.ts.map +1 -0
- package/dist/snippet.js +92 -0
- package/dist/snippet.js.map +1 -0
- package/dist/stats.d.ts +10 -0
- package/dist/stats.d.ts.map +1 -0
- package/dist/stats.js +65 -0
- package/dist/stats.js.map +1 -0
- package/dist/store.d.ts +44 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +590 -0
- package/dist/store.js.map +1 -0
- package/dist/types.d.ts +75 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +14 -0
- package/dist/types.js.map +1 -0
- package/hooks/hooks.json +52 -0
- package/hooks/pretooluse.mjs +94 -0
- package/package.json +55 -0
- package/skills/context-compress/SKILL.md +118 -0
- package/skills/doctor/SKILL.md +15 -0
- package/skills/stats/SKILL.md +11 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
export type Language = "javascript" | "typescript" | "python" | "shell" | "ruby" | "go" | "rust" | "php" | "perl" | "r" | "elixir";
|
|
2
|
+
export declare const ALL_LANGUAGES: readonly Language[];
|
|
3
|
+
export interface ExecOptions {
|
|
4
|
+
language: Language;
|
|
5
|
+
code: string;
|
|
6
|
+
timeout?: number;
|
|
7
|
+
intent?: string;
|
|
8
|
+
maxOutputBytes?: number;
|
|
9
|
+
}
|
|
10
|
+
export interface ExecFileOptions extends ExecOptions {
|
|
11
|
+
filePath: string;
|
|
12
|
+
}
|
|
13
|
+
export interface ExecResult {
|
|
14
|
+
stdout: string;
|
|
15
|
+
stderr: string;
|
|
16
|
+
exitCode: number | null;
|
|
17
|
+
truncated: boolean;
|
|
18
|
+
killed: boolean;
|
|
19
|
+
networkBytes?: number;
|
|
20
|
+
}
|
|
21
|
+
export interface IndexOptions {
|
|
22
|
+
content?: string;
|
|
23
|
+
path?: string;
|
|
24
|
+
source?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface IndexResult {
|
|
27
|
+
sourceId: number;
|
|
28
|
+
label: string;
|
|
29
|
+
totalChunks: number;
|
|
30
|
+
codeChunks: number;
|
|
31
|
+
}
|
|
32
|
+
export interface SearchOptions {
|
|
33
|
+
queries: string[];
|
|
34
|
+
source?: string;
|
|
35
|
+
limit?: number;
|
|
36
|
+
}
|
|
37
|
+
export interface SearchResult {
|
|
38
|
+
query: string;
|
|
39
|
+
results: SearchHit[];
|
|
40
|
+
corrected?: string;
|
|
41
|
+
}
|
|
42
|
+
export interface SearchHit {
|
|
43
|
+
title: string;
|
|
44
|
+
snippet: string;
|
|
45
|
+
source: string;
|
|
46
|
+
score: number;
|
|
47
|
+
}
|
|
48
|
+
export interface StoreStats {
|
|
49
|
+
totalSources: number;
|
|
50
|
+
totalChunks: number;
|
|
51
|
+
vocabularySize: number;
|
|
52
|
+
hasTrigramTable: boolean;
|
|
53
|
+
}
|
|
54
|
+
export interface Chunk {
|
|
55
|
+
title: string;
|
|
56
|
+
content: string;
|
|
57
|
+
hasCode: boolean;
|
|
58
|
+
}
|
|
59
|
+
export interface SessionStats {
|
|
60
|
+
calls: Record<string, number>;
|
|
61
|
+
bytesReturned: Record<string, number>;
|
|
62
|
+
bytesIndexed: number;
|
|
63
|
+
bytesSandboxed: number;
|
|
64
|
+
sessionStart: number;
|
|
65
|
+
}
|
|
66
|
+
export interface BatchCommand {
|
|
67
|
+
label: string;
|
|
68
|
+
command: string;
|
|
69
|
+
}
|
|
70
|
+
export interface BatchExecuteOptions {
|
|
71
|
+
commands: BatchCommand[];
|
|
72
|
+
queries: string[];
|
|
73
|
+
timeout?: number;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GACjB,YAAY,GACZ,YAAY,GACZ,QAAQ,GACR,OAAO,GACP,MAAM,GACN,IAAI,GACJ,MAAM,GACN,KAAK,GACL,MAAM,GACN,GAAG,GACH,QAAQ,CAAC;AAEZ,eAAO,MAAM,aAAa,EAAE,SAAS,QAAQ,EAYnC,CAAC;AAEX,MAAM,WAAW,WAAW;IAC3B,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,eAAgB,SAAQ,WAAW;IACnD,QAAQ,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,UAAU;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,KAAK;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,YAAY;IAC5B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,YAAY;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IACnC,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAaA,MAAM,CAAC,MAAM,aAAa,GAAwB;IACjD,YAAY;IACZ,YAAY;IACZ,QAAQ;IACR,OAAO;IACP,MAAM;IACN,IAAI;IACJ,MAAM;IACN,KAAK;IACL,MAAM;IACN,GAAG;IACH,QAAQ;CACC,CAAC"}
|
package/hooks/hooks.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "context-compress PreToolUse — intercepts data-fetching tools, nudges toward sandbox execution",
|
|
3
|
+
"hooks": {
|
|
4
|
+
"PreToolUse": [
|
|
5
|
+
{
|
|
6
|
+
"matcher": "Bash",
|
|
7
|
+
"hooks": [
|
|
8
|
+
{
|
|
9
|
+
"type": "command",
|
|
10
|
+
"command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/pretooluse.mjs"
|
|
11
|
+
}
|
|
12
|
+
]
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"matcher": "WebFetch",
|
|
16
|
+
"hooks": [
|
|
17
|
+
{
|
|
18
|
+
"type": "command",
|
|
19
|
+
"command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/pretooluse.mjs"
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"matcher": "Read",
|
|
25
|
+
"hooks": [
|
|
26
|
+
{
|
|
27
|
+
"type": "command",
|
|
28
|
+
"command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/pretooluse.mjs"
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"matcher": "Grep",
|
|
34
|
+
"hooks": [
|
|
35
|
+
{
|
|
36
|
+
"type": "command",
|
|
37
|
+
"command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/pretooluse.mjs"
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"matcher": "Task",
|
|
43
|
+
"hooks": [
|
|
44
|
+
{
|
|
45
|
+
"type": "command",
|
|
46
|
+
"command": "node ${CLAUDE_PLUGIN_ROOT}/hooks/pretooluse.mjs"
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/hooks/pretooluse.ts
|
|
4
|
+
var TOOL_PREFIX = "context-compress";
|
|
5
|
+
var blockCurl = process.env.CONTEXT_COMPRESS_BLOCK_CURL !== "0";
|
|
6
|
+
var blockWebFetch = process.env.CONTEXT_COMPRESS_BLOCK_WEBFETCH !== "0";
|
|
7
|
+
var nudgeOnRead = process.env.CONTEXT_COMPRESS_NUDGE_READ !== "0";
|
|
8
|
+
var nudgeOnGrep = process.env.CONTEXT_COMPRESS_NUDGE_GREP !== "0";
|
|
9
|
+
var raw = "";
|
|
10
|
+
process.stdin.setEncoding("utf-8");
|
|
11
|
+
for await (const chunk of process.stdin) raw += chunk;
|
|
12
|
+
var input = JSON.parse(raw);
|
|
13
|
+
var tool = input.tool_name ?? "";
|
|
14
|
+
var toolInput = input.tool_input ?? {};
|
|
15
|
+
function respond(output) {
|
|
16
|
+
console.log(JSON.stringify({ hookSpecificOutput: { hookEventName: "PreToolUse", ...output } }));
|
|
17
|
+
process.exit(0);
|
|
18
|
+
}
|
|
19
|
+
if (tool === "Bash") {
|
|
20
|
+
const command = toolInput.command ?? "";
|
|
21
|
+
if (blockCurl && /(^|\s|&&|\||\;)(curl|wget)\s/i.test(command)) {
|
|
22
|
+
respond({
|
|
23
|
+
updatedInput: {
|
|
24
|
+
command: `echo "${TOOL_PREFIX}: curl/wget blocked. Use mcp__${TOOL_PREFIX}__fetch_and_index(url, source) to fetch URLs, or mcp__${TOOL_PREFIX}__execute(language, code) to run HTTP calls in sandbox. Set CONTEXT_COMPRESS_BLOCK_CURL=0 to disable this."`
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
if (blockCurl && (/fetch\s*\(\s*['"](https?:\/\/|http)/i.test(command) || /requests\.(get|post|put)\s*\(/i.test(command) || /http\.(get|request)\s*\(/i.test(command))) {
|
|
29
|
+
respond({
|
|
30
|
+
updatedInput: {
|
|
31
|
+
command: `echo "${TOOL_PREFIX}: Inline HTTP blocked. Use mcp__${TOOL_PREFIX}__execute(language, code) to run HTTP calls in sandbox, or mcp__${TOOL_PREFIX}__fetch_and_index(url, source) for web pages."`
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
process.exit(0);
|
|
36
|
+
}
|
|
37
|
+
if (tool === "Read" && nudgeOnRead) {
|
|
38
|
+
respond({
|
|
39
|
+
additionalContext: `CONTEXT TIP: If this file is large (>50 lines), prefer mcp__${TOOL_PREFIX}__execute_file(path, language, code) \u2014 processes in sandbox, only stdout enters context.`
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
if (tool === "Grep" && nudgeOnGrep) {
|
|
43
|
+
respond({
|
|
44
|
+
additionalContext: `CONTEXT TIP: If results may be large, prefer mcp__${TOOL_PREFIX}__execute(language: "shell", code: "grep ...") \u2014 runs in sandbox, only stdout enters context.`
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
if (tool === "WebFetch" && blockWebFetch) {
|
|
48
|
+
const url = toolInput.url ?? "";
|
|
49
|
+
respond({
|
|
50
|
+
permissionDecision: "deny",
|
|
51
|
+
reason: `${TOOL_PREFIX}: WebFetch blocked. Use mcp__${TOOL_PREFIX}__fetch_and_index(url: "${url}", source: "...") to fetch this URL in sandbox. Then use mcp__${TOOL_PREFIX}__search(queries: [...]) to query results.`
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
if (tool === "Task" || tool === "Agent") {
|
|
55
|
+
const subagentType = toolInput.subagent_type ?? "";
|
|
56
|
+
const prompt = toolInput.prompt ?? "";
|
|
57
|
+
const ROUTING_BLOCK = `
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
CONTEXT WINDOW PROTECTION \u2014 USE CONTEXT-COMPRESS MCP TOOLS
|
|
61
|
+
|
|
62
|
+
Raw Bash/Read/WebFetch output floods your context. You have context-compress tools that keep data in sandbox.
|
|
63
|
+
|
|
64
|
+
STEP 1 \u2014 GATHER: mcp__${TOOL_PREFIX}__batch_execute(commands, queries)
|
|
65
|
+
commands: [{label: "Name", command: "shell cmd"}, ...]
|
|
66
|
+
queries: ["query1", "query2", ...] \u2014 put 5-8 queries covering everything you need.
|
|
67
|
+
Runs all commands, indexes output, returns search results. ONE call, no follow-ups.
|
|
68
|
+
|
|
69
|
+
STEP 2 \u2014 FOLLOW-UP: mcp__${TOOL_PREFIX}__search(queries: ["q1", "q2", "q3", ...])
|
|
70
|
+
Pass ALL follow-up questions as queries array. ONE call, not separate calls.
|
|
71
|
+
|
|
72
|
+
OTHER: execute(language, code) | execute_file(path, language, code) | fetch_and_index(url) + search
|
|
73
|
+
|
|
74
|
+
FORBIDDEN: Bash for output, Read for files, WebFetch. Bash is ONLY for git/mkdir/rm/mv.
|
|
75
|
+
|
|
76
|
+
OUTPUT FORMAT \u2014 KEEP YOUR FINAL RESPONSE UNDER 500 WORDS:
|
|
77
|
+
The parent agent context window is precious. Your full response gets injected into it.
|
|
78
|
+
|
|
79
|
+
1. ARTIFACTS (PRDs, configs, code files) \u2192 Write to FILES, never return as inline text.
|
|
80
|
+
Return only: file path + 1-line description.
|
|
81
|
+
2. DETAILED FINDINGS \u2192 Index into knowledge base:
|
|
82
|
+
mcp__${TOOL_PREFIX}__index(content: "...", source: "descriptive-label")
|
|
83
|
+
The parent agent shares the SAME knowledge base and can search() your indexed content.
|
|
84
|
+
3. YOUR RESPONSE must be a concise summary:
|
|
85
|
+
- What you did (2-3 bullets)
|
|
86
|
+
- File paths created/modified (if any)
|
|
87
|
+
- Source labels you indexed (so parent can search)
|
|
88
|
+
- Key findings in bullet points
|
|
89
|
+
Do NOT return raw data, full file contents, or lengthy explanations.
|
|
90
|
+
---`;
|
|
91
|
+
const updatedInput = subagentType === "Bash" ? { ...toolInput, prompt: prompt + ROUTING_BLOCK, subagent_type: "general-purpose" } : { ...toolInput, prompt: prompt + ROUTING_BLOCK };
|
|
92
|
+
respond({ updatedInput });
|
|
93
|
+
}
|
|
94
|
+
process.exit(0);
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "context-compress",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Context-aware MCP server that compresses tool output for Claude Code",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/server.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"context-compress": "dist/cli/index.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc && node esbuild.config.ts",
|
|
12
|
+
"build:hooks": "esbuild src/hooks/pretooluse.ts --bundle --platform=node --format=esm --outfile=hooks/pretooluse.mjs --target=node18",
|
|
13
|
+
"dev": "tsx src/index.ts",
|
|
14
|
+
"typecheck": "tsc --noEmit",
|
|
15
|
+
"lint": "biome check src/",
|
|
16
|
+
"lint:fix": "biome check --write src/",
|
|
17
|
+
"test": "node --import tsx --test tests/**/*.test.ts",
|
|
18
|
+
"test:unit": "node --import tsx --test tests/unit/*.test.ts",
|
|
19
|
+
"test:integration": "node --import tsx --test tests/integration/*.test.ts"
|
|
20
|
+
},
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">=18.0.0"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
26
|
+
"better-sqlite3": "^12.6.0",
|
|
27
|
+
"zod": "^3.25.0"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@biomejs/biome": "^1.9.0",
|
|
31
|
+
"@types/better-sqlite3": "^7.6.0",
|
|
32
|
+
"@types/node": "^20.0.0",
|
|
33
|
+
"esbuild": "^0.27.0",
|
|
34
|
+
"tsx": "^4.21.0",
|
|
35
|
+
"typescript": "^5.7.0"
|
|
36
|
+
},
|
|
37
|
+
"files": [
|
|
38
|
+
"dist/",
|
|
39
|
+
"hooks/",
|
|
40
|
+
"skills/",
|
|
41
|
+
"LICENSE",
|
|
42
|
+
"README.md"
|
|
43
|
+
],
|
|
44
|
+
"license": "MIT",
|
|
45
|
+
"repository": {
|
|
46
|
+
"type": "git",
|
|
47
|
+
"url": "https://github.com/Open330/context-compress"
|
|
48
|
+
},
|
|
49
|
+
"keywords": [
|
|
50
|
+
"mcp",
|
|
51
|
+
"claude",
|
|
52
|
+
"context",
|
|
53
|
+
"compression"
|
|
54
|
+
]
|
|
55
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: context-compress
|
|
3
|
+
description: |
|
|
4
|
+
Use context-compress tools (execute, execute_file) instead of Bash/cat when processing
|
|
5
|
+
large outputs. Trigger phrases: "analyze logs", "summarize output", "process data",
|
|
6
|
+
"parse JSON", "filter results", "extract errors", "check build output",
|
|
7
|
+
"analyze dependencies", "process API response", "large file analysis",
|
|
8
|
+
"extract elements", "page snapshot", "browser snapshot", "take a snapshot",
|
|
9
|
+
"DOM structure", "inspect page", "form fields", "element selectors",
|
|
10
|
+
"web page structure", "accessibility tree", "Playwright snapshot",
|
|
11
|
+
"run tests", "test output", "coverage report", "git log", "recent commits",
|
|
12
|
+
"diff between branches", "list containers", "pod status", "disk usage",
|
|
13
|
+
"fetch docs", "API reference", "index documentation", "hit endpoint",
|
|
14
|
+
"call API", "check response", "query results", "show tables",
|
|
15
|
+
"find TODOs", "count lines", "codebase statistics", "security audit",
|
|
16
|
+
"outdated packages", "dependency tree", "cloud resources", "CI/CD output".
|
|
17
|
+
Also triggers on ANY MCP tool output (Playwright, Context7, GitHub API) that
|
|
18
|
+
may exceed 20 lines, and any operation where output size is uncertain.
|
|
19
|
+
Subagent routing is handled automatically via PreToolUse hook — no manual tool names needed in prompts.
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
# Context Compress: Default for All Large Output
|
|
23
|
+
|
|
24
|
+
## MANDATORY RULE
|
|
25
|
+
|
|
26
|
+
**Default to context-compress for ALL commands. Only use Bash for guaranteed-small-output operations.**
|
|
27
|
+
|
|
28
|
+
Bash whitelist (safe to run directly):
|
|
29
|
+
- **File mutations**: `mkdir`, `mv`, `cp`, `rm`, `touch`, `chmod`
|
|
30
|
+
- **Git writes**: `git add`, `git commit`, `git push`, `git checkout`, `git branch`, `git merge`
|
|
31
|
+
- **Navigation**: `cd`, `pwd`, `which`
|
|
32
|
+
- **Process control**: `kill`, `pkill`
|
|
33
|
+
- **Package management**: `npm install`, `npm publish`, `pip install`
|
|
34
|
+
- **Simple output**: `echo`, `printf`
|
|
35
|
+
|
|
36
|
+
**Everything else → `execute` or `execute_file`.** Any command that reads, queries, fetches, lists, logs, tests, builds, diffs, inspects, or calls an external service.
|
|
37
|
+
|
|
38
|
+
**When uncertain, use context-compress.** Every KB of unnecessary context reduces the quality and speed of the entire session.
|
|
39
|
+
|
|
40
|
+
## Decision Tree
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
About to run a command / read a file / call an API?
|
|
44
|
+
│
|
|
45
|
+
├── Command is on the Bash whitelist?
|
|
46
|
+
│ └── Use Bash
|
|
47
|
+
│
|
|
48
|
+
├── Output MIGHT be large or you're UNSURE?
|
|
49
|
+
│ └── Use context-compress execute or execute_file
|
|
50
|
+
│
|
|
51
|
+
├── Fetching web documentation or HTML page?
|
|
52
|
+
│ └── Use fetch_and_index → search
|
|
53
|
+
│
|
|
54
|
+
├── Using Playwright (navigate, snapshot, console, network)?
|
|
55
|
+
│ └── ALWAYS use filename parameter to save to file, then:
|
|
56
|
+
│ browser_snapshot(filename) → index(path) or execute_file(path)
|
|
57
|
+
│
|
|
58
|
+
├── Processing output from another MCP tool?
|
|
59
|
+
│ ├── Output already in context? → Use it directly
|
|
60
|
+
│ ├── Need to search multiple times? → Save to file → index(path) → search
|
|
61
|
+
│ └── One-shot extraction? → Save to file → execute_file(path)
|
|
62
|
+
│
|
|
63
|
+
└── Reading a file to analyze/summarize (not edit)?
|
|
64
|
+
└── Use execute_file (file loads into FILE_CONTENT, not context)
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## When to Use Each Tool
|
|
68
|
+
|
|
69
|
+
| Situation | Tool | Example |
|
|
70
|
+
|-----------|------|---------|
|
|
71
|
+
| Hit an API endpoint | `execute` | `fetch('http://localhost:3000/api/orders')` |
|
|
72
|
+
| Run CLI that returns data | `execute` | `gh pr list`, `aws s3 ls`, `kubectl get pods` |
|
|
73
|
+
| Run tests | `execute` | `npm test`, `pytest`, `go test ./...` |
|
|
74
|
+
| Git operations | `execute` | `git log --oneline -50`, `git diff HEAD~5` |
|
|
75
|
+
| Read a log file | `execute_file` | Parse access.log, error.log, build output |
|
|
76
|
+
| Read a data file | `execute_file` | Analyze CSV, JSON, YAML, XML |
|
|
77
|
+
| Fetch web docs | `fetch_and_index` | Index React/Next.js/Zod docs, then search |
|
|
78
|
+
|
|
79
|
+
## Language Selection
|
|
80
|
+
|
|
81
|
+
| Situation | Language | Why |
|
|
82
|
+
|-----------|----------|-----|
|
|
83
|
+
| HTTP/API calls, JSON | `javascript` | Native fetch, JSON.parse, async/await |
|
|
84
|
+
| Data analysis, CSV, stats | `python` | csv, statistics, collections, re |
|
|
85
|
+
| Shell commands with pipes | `shell` | grep, awk, jq, native tools |
|
|
86
|
+
| File pattern matching | `shell` | find, wc, sort, uniq |
|
|
87
|
+
|
|
88
|
+
## Search Query Strategy
|
|
89
|
+
|
|
90
|
+
- BM25 uses **OR semantics** — results matching more terms rank higher automatically
|
|
91
|
+
- Use 2-4 specific technical terms per query
|
|
92
|
+
- **Always use `source` parameter** when multiple docs are indexed
|
|
93
|
+
- **Always use `queries` array** — batch ALL search questions in ONE call:
|
|
94
|
+
- `search(queries: ["transform pipe", "refine superRefine"], source: "Zod")`
|
|
95
|
+
- NEVER make multiple separate search() calls
|
|
96
|
+
|
|
97
|
+
## Critical Rules
|
|
98
|
+
|
|
99
|
+
1. **Always console.log/print your findings.** stdout is all that enters context.
|
|
100
|
+
2. **Write analysis code, not just data dumps.** Analyze first, print findings.
|
|
101
|
+
3. **Be specific in output.** Print bug details with IDs, line numbers, exact values.
|
|
102
|
+
4. **For files you need to EDIT**: Use the normal Read tool.
|
|
103
|
+
5. **For Bash whitelist commands only**: Use Bash. Everything else → context-compress.
|
|
104
|
+
6. **Never use `index(content: large_data)`.** Use `index(path: ...)` to read files server-side.
|
|
105
|
+
7. **Always use `filename` parameter** on Playwright tools.
|
|
106
|
+
|
|
107
|
+
## Subagent Usage
|
|
108
|
+
|
|
109
|
+
Subagents automatically receive context-compress tool routing via a PreToolUse hook. You do NOT need to manually add tool names to subagent prompts — the hook injects them.
|
|
110
|
+
|
|
111
|
+
## Anti-Patterns
|
|
112
|
+
|
|
113
|
+
- Using `curl` via Bash → Use `execute` with fetch or `fetch_and_index`
|
|
114
|
+
- Using `cat large-file` → Use `execute_file` instead
|
|
115
|
+
- Piping Bash output through `| head -20` → Use `execute` to analyze ALL data
|
|
116
|
+
- Running `npm test` via Bash → Use `execute` to capture and summarize
|
|
117
|
+
- Calling `browser_snapshot()` WITHOUT `filename` → Always use `filename` parameter
|
|
118
|
+
- Passing large data to `index(content: ...)` → Always use `index(path: ...)`
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: context-compress:doctor
|
|
3
|
+
description: Run diagnostics to check context-compress health
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Run the context-compress doctor diagnostic:
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
mcp__context-compress__execute({
|
|
10
|
+
language: "shell",
|
|
11
|
+
code: "node dist/cli/index.js doctor"
|
|
12
|
+
})
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Report the results as-is in markdown format.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: context-compress:stats
|
|
3
|
+
description: Show session statistics for context-compress
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Call the `mcp__context-compress__stats` tool to get session statistics.
|
|
7
|
+
|
|
8
|
+
CRITICAL: Copy-paste the ENTIRE tool output as markdown. Do NOT summarize or truncate any tables.
|
|
9
|
+
|
|
10
|
+
After the raw output, add one summary line:
|
|
11
|
+
"Context-compress has processed X data and kept Y% out of context this session."
|