context-mode 0.5.26 → 0.6.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/.claude-plugin/hooks/hooks.json +11 -2
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +63 -23
- package/build/server.js +419 -88
- package/build/store.d.ts +5 -0
- package/build/store.js +20 -0
- package/hooks/hooks.json +25 -0
- package/hooks/pretooluse.sh +73 -0
- package/package.json +2 -1
- package/server.bundle.mjs +86 -65
- package/skills/context-mode/SKILL.md +8 -42
package/build/store.d.ts
CHANGED
|
@@ -44,6 +44,11 @@ export declare class ContentStore {
|
|
|
44
44
|
label: string;
|
|
45
45
|
chunkCount: number;
|
|
46
46
|
}>;
|
|
47
|
+
/**
|
|
48
|
+
* Get all chunks for a given source by ID — bypasses FTS5 MATCH entirely.
|
|
49
|
+
* Use this for inventory/listing where you need all sections, not search.
|
|
50
|
+
*/
|
|
51
|
+
getChunksBySource(sourceId: number): SearchResult[];
|
|
47
52
|
getDistinctiveTerms(sourceId: number, maxTerms?: number): string[];
|
|
48
53
|
getStats(): StoreStats;
|
|
49
54
|
close(): void;
|
package/build/store.js
CHANGED
|
@@ -195,6 +195,26 @@ export class ContentStore {
|
|
|
195
195
|
.prepare("SELECT label, chunk_count as chunkCount FROM sources ORDER BY id DESC")
|
|
196
196
|
.all();
|
|
197
197
|
}
|
|
198
|
+
/**
|
|
199
|
+
* Get all chunks for a given source by ID — bypasses FTS5 MATCH entirely.
|
|
200
|
+
* Use this for inventory/listing where you need all sections, not search.
|
|
201
|
+
*/
|
|
202
|
+
getChunksBySource(sourceId) {
|
|
203
|
+
const rows = this.#db
|
|
204
|
+
.prepare(`SELECT c.title, c.content, c.content_type, s.label
|
|
205
|
+
FROM chunks c
|
|
206
|
+
JOIN sources s ON s.id = c.source_id
|
|
207
|
+
WHERE c.source_id = ?
|
|
208
|
+
ORDER BY c.rowid`)
|
|
209
|
+
.all(sourceId);
|
|
210
|
+
return rows.map((r) => ({
|
|
211
|
+
title: r.title,
|
|
212
|
+
content: r.content,
|
|
213
|
+
source: r.label,
|
|
214
|
+
rank: 0,
|
|
215
|
+
contentType: r.content_type,
|
|
216
|
+
}));
|
|
217
|
+
}
|
|
198
218
|
// ── Vocabulary ──
|
|
199
219
|
getDistinctiveTerms(sourceId, maxTerms = 40) {
|
|
200
220
|
const stats = this.#db
|
package/hooks/hooks.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"description": "Context-mode PreToolUse — intercepts Bash data-fetching and injects subagent routing",
|
|
3
|
+
"hooks": {
|
|
4
|
+
"PreToolUse": [
|
|
5
|
+
{
|
|
6
|
+
"matcher": "Bash",
|
|
7
|
+
"hooks": [
|
|
8
|
+
{
|
|
9
|
+
"type": "command",
|
|
10
|
+
"command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/pretooluse.sh"
|
|
11
|
+
}
|
|
12
|
+
]
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"matcher": "Task",
|
|
16
|
+
"hooks": [
|
|
17
|
+
{
|
|
18
|
+
"type": "command",
|
|
19
|
+
"command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/pretooluse.sh"
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Unified PreToolUse hook for context-mode
|
|
3
|
+
# - Bash: blocks data-fetching commands (curl, wget, inline fetch)
|
|
4
|
+
# - Task: injects context-mode routing into subagent prompts
|
|
5
|
+
|
|
6
|
+
INPUT=$(cat /dev/stdin)
|
|
7
|
+
TOOL=$(echo "$INPUT" | jq -r '.tool_name // ""')
|
|
8
|
+
|
|
9
|
+
# ─── Bash: block data-fetching commands ───
|
|
10
|
+
if [ "$TOOL" = "Bash" ]; then
|
|
11
|
+
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // ""')
|
|
12
|
+
|
|
13
|
+
# curl/wget
|
|
14
|
+
if echo "$COMMAND" | grep -qiE '(^|\s|&&|\||\;)(curl|wget)\s'; then
|
|
15
|
+
cat <<'EOF'
|
|
16
|
+
{
|
|
17
|
+
"decision": "block",
|
|
18
|
+
"reason": "BLOCKED: curl/wget floods context window. Use context-mode execute instead.\n\nExample:\nmcp__context-mode__execute(language: \"javascript\", code: \"const resp = await fetch('http://...'); const data = await resp.json(); console.log(JSON.stringify(data, null, 2));\")\n\nThis runs in sandbox — only stdout enters context."
|
|
19
|
+
}
|
|
20
|
+
EOF
|
|
21
|
+
exit 0
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
# inline fetch (node -e, python -c, etc.)
|
|
25
|
+
if echo "$COMMAND" | grep -qiE 'fetch\s*\(\s*['"'"'"](https?://|http)' || \
|
|
26
|
+
echo "$COMMAND" | grep -qiE 'requests\.(get|post|put)\s*\(' || \
|
|
27
|
+
echo "$COMMAND" | grep -qiE 'http\.(get|request)\s*\('; then
|
|
28
|
+
cat <<'EOF'
|
|
29
|
+
{
|
|
30
|
+
"decision": "block",
|
|
31
|
+
"reason": "BLOCKED: Inline HTTP fetch via Bash floods context window. Use context-mode execute instead.\n\nExample:\nmcp__context-mode__execute(language: \"javascript\", code: \"const resp = await fetch('http://...'); const data = await resp.json(); console.log(JSON.stringify(data, null, 2));\")\n\nThis runs in sandbox — only stdout enters context."
|
|
32
|
+
}
|
|
33
|
+
EOF
|
|
34
|
+
exit 0
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
# allow all other Bash commands
|
|
38
|
+
exit 0
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
# ─── Task: inject context-mode routing into subagent prompts ───
|
|
42
|
+
if [ "$TOOL" = "Task" ]; then
|
|
43
|
+
ROUTING_BLOCK='
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
CONTEXT WINDOW PROTECTION — USE CONTEXT-MODE MCP TOOLS
|
|
47
|
+
|
|
48
|
+
Raw Bash/Read/WebFetch output floods your context. You have context-mode tools that keep data in sandbox.
|
|
49
|
+
|
|
50
|
+
STEP 1 — GATHER: mcp__context-mode__batch_execute(commands, queries)
|
|
51
|
+
commands: [{label: "Name", command: "shell cmd"}, ...]
|
|
52
|
+
queries: ["query1", "query2", ...] — put 5-8 queries covering everything you need.
|
|
53
|
+
Runs all commands, indexes output, returns search results. ONE call, no follow-ups.
|
|
54
|
+
|
|
55
|
+
STEP 2 — FOLLOW-UP: mcp__context-mode__search(queries: ["q1", "q2", "q3", ...])
|
|
56
|
+
Pass ALL follow-up questions as queries array. ONE call, not separate calls.
|
|
57
|
+
|
|
58
|
+
OTHER: execute(language, code) | execute_file(path, language, code) | fetch_and_index(url) + search
|
|
59
|
+
|
|
60
|
+
FORBIDDEN: Bash for output, Read for files, WebFetch. Bash is ONLY for git/mkdir/rm/mv.
|
|
61
|
+
---'
|
|
62
|
+
|
|
63
|
+
echo "$INPUT" | jq --arg routing "$ROUTING_BLOCK" '{
|
|
64
|
+
"hookSpecificOutput": {
|
|
65
|
+
"hookEventName": "PreToolUse",
|
|
66
|
+
"updatedInput": (.tool_input + { "prompt": (.tool_input.prompt + $routing) })
|
|
67
|
+
}
|
|
68
|
+
}'
|
|
69
|
+
exit 0
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
# Unknown tool — pass through
|
|
73
|
+
exit 0
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "context-mode",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Claude Code MCP plugin that saves 98% of your context window. Sandboxed code execution, FTS5 knowledge base, and intent-driven search.",
|
|
6
6
|
"author": "Mert Koseoğlu",
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
},
|
|
28
28
|
"files": [
|
|
29
29
|
"build",
|
|
30
|
+
"hooks",
|
|
30
31
|
"server.bundle.mjs",
|
|
31
32
|
"skills",
|
|
32
33
|
".claude-plugin",
|