context-mode 1.0.32 → 1.0.34
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/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/.openclaw-plugin/openclaw.plugin.json +1 -1
- package/.openclaw-plugin/package.json +1 -1
- package/build/server.js +36 -1
- package/cli.bundle.mjs +282 -93
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/server.bundle.mjs +242 -71
- package/skills/ctx-cloud-setup/SKILL.md +0 -98
- package/skills/ctx-cloud-status/SKILL.md +0 -96
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "Claude Code plugins by Mert Koseoğlu",
|
|
9
|
-
"version": "1.0.
|
|
9
|
+
"version": "1.0.34"
|
|
10
10
|
},
|
|
11
11
|
"plugins": [
|
|
12
12
|
{
|
|
13
13
|
"name": "context-mode",
|
|
14
14
|
"source": "./",
|
|
15
15
|
"description": "Claude Code MCP plugin that saves 98% of your context window. Sandboxed code execution in 11 languages, FTS5 knowledge base with BM25 ranking, and intent-driven search.",
|
|
16
|
-
"version": "1.0.
|
|
16
|
+
"version": "1.0.34",
|
|
17
17
|
"author": {
|
|
18
18
|
"name": "Mert Koseoğlu"
|
|
19
19
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "context-mode",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.34",
|
|
4
4
|
"description": "MCP server that saves 98% of your context window with session continuity. Sandboxed code execution in 11 languages, FTS5 knowledge base with BM25 ranking, and automatic state restore across compactions.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Mert Koseoğlu",
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"name": "Context Mode",
|
|
4
4
|
"kind": "tool",
|
|
5
5
|
"description": "OpenClaw plugin that saves 98% of your context window. Sandboxed code execution in 11 languages, FTS5 knowledge base with BM25 ranking, and intent-driven search.",
|
|
6
|
-
"version": "1.0.
|
|
6
|
+
"version": "1.0.34",
|
|
7
7
|
"sandbox": {
|
|
8
8
|
"mode": "permissive",
|
|
9
9
|
"filesystem_access": "full",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "context-mode",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.34",
|
|
4
4
|
"description": "OpenClaw plugin that saves 98% of your context window. Sandboxed code execution in 11 languages, FTS5 knowledge base with BM25 ranking, and intent-driven search.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Mert Koseoğlu",
|
package/build/server.js
CHANGED
|
@@ -115,6 +115,8 @@ const sessionStats = {
|
|
|
115
115
|
bytesReturned: {},
|
|
116
116
|
bytesIndexed: 0,
|
|
117
117
|
bytesSandboxed: 0, // network I/O consumed inside sandbox (never enters context)
|
|
118
|
+
cacheHits: 0,
|
|
119
|
+
cacheBytesSaved: 0, // bytes avoided by TTL cache hits
|
|
118
120
|
sessionStart: Date.now(),
|
|
119
121
|
};
|
|
120
122
|
function trackResponse(toolName, response) {
|
|
@@ -802,7 +804,8 @@ function coerceCommandsArray(val) {
|
|
|
802
804
|
}
|
|
803
805
|
server.registerTool("ctx_search", {
|
|
804
806
|
title: "Search Indexed Content",
|
|
805
|
-
description: "Search indexed content.
|
|
807
|
+
description: "Search indexed content. Requires prior indexing via ctx_batch_execute, ctx_index, or ctx_fetch_and_index. " +
|
|
808
|
+
"Pass ALL search questions as queries array in ONE call.\n\n" +
|
|
806
809
|
"TIPS: 2-4 specific terms per query. Use 'source' to scope results.",
|
|
807
810
|
inputSchema: z.object({
|
|
808
811
|
queries: z.preprocess(coerceJsonArray, z
|
|
@@ -826,6 +829,23 @@ server.registerTool("ctx_search", {
|
|
|
826
829
|
}, async (params) => {
|
|
827
830
|
try {
|
|
828
831
|
const store = getStore();
|
|
832
|
+
// Guard: redirect when the index is empty — ctx_search is a follow-up
|
|
833
|
+
// tool that requires prior indexing. Guide the model to the right tool.
|
|
834
|
+
if (store.getStats().chunks === 0) {
|
|
835
|
+
return trackResponse("ctx_search", {
|
|
836
|
+
content: [{
|
|
837
|
+
type: "text",
|
|
838
|
+
text: "Knowledge base is empty — no content has been indexed yet.\n\n" +
|
|
839
|
+
"ctx_search is a follow-up tool that queries previously indexed content. " +
|
|
840
|
+
"To gather and index content first, use:\n" +
|
|
841
|
+
" • ctx_batch_execute(commands, queries) — run commands, auto-index output, and search in one call\n" +
|
|
842
|
+
" • ctx_fetch_and_index(url) — fetch a URL, index it, then search with ctx_search\n" +
|
|
843
|
+
" • ctx_index(content, source) — manually index text content\n\n" +
|
|
844
|
+
"After indexing, ctx_search becomes available for follow-up queries.",
|
|
845
|
+
}],
|
|
846
|
+
isError: true,
|
|
847
|
+
});
|
|
848
|
+
}
|
|
829
849
|
const raw = params;
|
|
830
850
|
// Normalize: accept both query (string) and queries (array)
|
|
831
851
|
const queryList = [];
|
|
@@ -1025,6 +1045,10 @@ server.registerTool("ctx_fetch_and_index", {
|
|
|
1025
1045
|
const ageHours = Math.floor(ageMs / (60 * 60 * 1000));
|
|
1026
1046
|
const ageMin = Math.floor(ageMs / (60 * 1000));
|
|
1027
1047
|
const ageStr = ageHours > 0 ? `${ageHours}h ago` : ageMin > 0 ? `${ageMin}m ago` : "just now";
|
|
1048
|
+
// Track cache savings — estimate ~1.6KB per chunk (average indexed content size)
|
|
1049
|
+
const estimatedBytes = meta.chunkCount * 1600;
|
|
1050
|
+
sessionStats.cacheHits++;
|
|
1051
|
+
sessionStats.cacheBytesSaved += estimatedBytes;
|
|
1028
1052
|
return trackResponse("ctx_fetch_and_index", {
|
|
1029
1053
|
content: [{
|
|
1030
1054
|
type: "text",
|
|
@@ -1366,6 +1390,17 @@ server.registerTool("ctx_stats", {
|
|
|
1366
1390
|
if (keptOut > 0) {
|
|
1367
1391
|
lines.push("", `Without context-mode, **${kb(totalProcessed)}** of raw output would flood your context window. Instead, **${reductionPct}%** stayed in sandbox.`);
|
|
1368
1392
|
}
|
|
1393
|
+
// Cache savings section
|
|
1394
|
+
if (sessionStats.cacheHits > 0 || sessionStats.cacheBytesSaved > 0) {
|
|
1395
|
+
const totalWithCache = totalProcessed + sessionStats.cacheBytesSaved;
|
|
1396
|
+
const totalSavingsRatio = totalWithCache / Math.max(totalBytesReturned, 1);
|
|
1397
|
+
const ttlHoursLeft = Math.max(0, 24 - Math.floor((Date.now() - sessionStats.sessionStart) / (60 * 60 * 1000)));
|
|
1398
|
+
lines.push("", `### TTL Cache`, "", `| Metric | Value |`, `|--------|------:|`, `| Cache hits | **${sessionStats.cacheHits}** |`, `| Data avoided by cache | **${kb(sessionStats.cacheBytesSaved)}** |`, `| Network requests saved | **${sessionStats.cacheHits}** |`, `| TTL remaining | **~${ttlHoursLeft}h** |`, "", `Content was already indexed in the knowledge base — ${sessionStats.cacheHits} fetch${sessionStats.cacheHits > 1 ? "es" : ""} skipped entirely. **${kb(sessionStats.cacheBytesSaved)}** of network I/O avoided. Search results served directly from local FTS5 index.`);
|
|
1399
|
+
// Update total savings to include cache
|
|
1400
|
+
if (totalSavingsRatio > savingsRatio) {
|
|
1401
|
+
lines.push("", `**Total context savings (sandbox + cache): ${totalSavingsRatio.toFixed(1)}x** — ${kb(totalWithCache)} processed, only ${kb(totalBytesReturned)} entered context.`);
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1369
1404
|
}
|
|
1370
1405
|
// ── Session Continuity ──
|
|
1371
1406
|
try {
|