context-mode 1.0.95 → 1.0.97

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.
@@ -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.95",
6
+ "version": "1.0.97",
7
7
  "sandbox": {
8
8
  "mode": "permissive",
9
9
  "filesystem_access": "full",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "context-mode",
3
- "version": "1.0.95",
3
+ "version": "1.0.97",
4
4
  "type": "module",
5
5
  "description": "MCP plugin that saves 98% of your context window. Works with Claude Code, Gemini CLI, VS Code Copilot, OpenCode, and Codex CLI. Sandboxed code execution, FTS5 knowledge base, and intent-driven search.",
6
6
  "author": "Mert Koseoğlu",
@@ -8,10 +8,11 @@
8
8
  * Creates a directory junction so npm's %~dp0\node_modules\... resolves.
9
9
  */
10
10
 
11
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
11
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, symlinkSync, lstatSync, unlinkSync } from "node:fs";
12
12
  import { execSync } from "node:child_process";
13
- import { dirname, resolve, join } from "node:path";
13
+ import { dirname, resolve, join, sep } from "node:path";
14
14
  import { fileURLToPath } from "node:url";
15
+ import { homedir } from "node:os";
15
16
 
16
17
  const __dirname = dirname(fileURLToPath(import.meta.url));
17
18
  const pkgRoot = resolve(__dirname, "..");
@@ -24,6 +25,33 @@ function isSafeWindowsPath(p) {
24
25
  return !/[&|<>"^%\r\n]/.test(p);
25
26
  }
26
27
 
28
+ // ── 0. Self-heal Layer 3: Backward symlink for stale registry (anthropics/claude-code#46915) ──
29
+ // When this install completes, installed_plugins.json may still point to an old
30
+ // non-existent path. Create a symlink from that old path → our new directory.
31
+ try {
32
+ const ipPath = resolve(homedir(), ".claude", "plugins", "installed_plugins.json");
33
+ if (existsSync(ipPath)) {
34
+ const ip = JSON.parse(readFileSync(ipPath, "utf-8"));
35
+ const cacheRoot = resolve(homedir(), ".claude", "plugins", "cache");
36
+ for (const [key, entries] of Object.entries(ip.plugins || {})) {
37
+ if (key !== "context-mode@context-mode") continue;
38
+ for (const entry of entries) {
39
+ const rp = entry.installPath;
40
+ if (!rp || existsSync(rp)) continue;
41
+ // Path traversal guard
42
+ if (!resolve(rp).startsWith(cacheRoot + sep)) continue;
43
+ // Remove dangling symlink
44
+ try { if (lstatSync(rp).isSymbolicLink()) unlinkSync(rp); } catch {}
45
+ const rpParent = dirname(rp);
46
+ if (!existsSync(rpParent)) mkdirSync(rpParent, { recursive: true });
47
+ try {
48
+ symlinkSync(pkgRoot, rp, process.platform === "win32" ? "junction" : undefined);
49
+ } catch { /* may fail if path is locked or permissions */ }
50
+ }
51
+ }
52
+ }
53
+ } catch { /* best effort — don't block install */ }
54
+
27
55
  // ── 1. OpenClaw detection ────────────────────────────────────────────
28
56
  if (process.env.OPENCLAW_STATE_DIR) {
29
57
  console.log("\n OpenClaw detected. Run: npm run install:openclaw\n");