context-mode 0.9.6 → 0.9.8

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.
@@ -13,7 +13,7 @@
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": "0.9.6",
16
+ "version": "0.9.8",
17
17
  "author": {
18
18
  "name": "Mert Koseoğlu"
19
19
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "context-mode",
3
- "version": "0.9.6",
3
+ "version": "0.9.8",
4
4
  "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.",
5
5
  "author": {
6
6
  "name": "Mert Koseoğlu",
package/build/cli.js CHANGED
@@ -370,21 +370,34 @@ async function upgrade() {
370
370
  timeout: 30000,
371
371
  });
372
372
  s.stop("Built successfully");
373
- // Step 3: Copy to plugin root
374
- s.start("Installing files");
375
- const items = [
376
- "build", "src", "hooks", "skills", ".claude-plugin",
377
- "start.mjs", "server.bundle.mjs", "package.json", ".mcp.json",
378
- ];
379
- for (const item of items) {
380
- try {
381
- rmSync(resolve(pluginRoot, item), { recursive: true, force: true });
382
- cpSync(resolve(srcDir, item), resolve(pluginRoot, item), { recursive: true });
373
+ // Step 3: Install fresh into new version directory (don't touch old dir - process runs from it)
374
+ s.start("Installing fresh");
375
+ const cacheParentMatch = pluginRoot.match(/^(.*[\\/]plugins[\\/]cache[\\/][^\\/]+[\\/][^\\/]+[\\/])/);
376
+ const freshDir = cacheParentMatch
377
+ ? resolve(cacheParentMatch[1], newVersion)
378
+ : pluginRoot;
379
+ // If fresh dir is different from current, create it. Otherwise update in-place.
380
+ if (freshDir !== pluginRoot) {
381
+ rmSync(freshDir, { recursive: true, force: true });
382
+ cpSync(srcDir, freshDir, { recursive: true });
383
+ pluginRoot = freshDir;
384
+ }
385
+ else {
386
+ // Same dir — copy files in-place
387
+ const items = [
388
+ "build", "src", "hooks", "skills", ".claude-plugin",
389
+ "start.mjs", "server.bundle.mjs", "package.json", ".mcp.json",
390
+ ];
391
+ for (const item of items) {
392
+ try {
393
+ rmSync(resolve(pluginRoot, item), { recursive: true, force: true });
394
+ cpSync(resolve(srcDir, item), resolve(pluginRoot, item), { recursive: true });
395
+ }
396
+ catch { /* some files may not exist */ }
383
397
  }
384
- catch { /* some files may not exist */ }
385
398
  }
386
- s.stop(color.green("Files installed"));
387
- // Install production deps in plugin root
399
+ s.stop(color.green(`Installed to ${freshDir.split("/").pop() ?? newVersion}`));
400
+ // Install production deps in fresh dir
388
401
  s.start("Installing production dependencies");
389
402
  execSync("npm install --production --no-audit --no-fund", {
390
403
  cwd: pluginRoot,
@@ -392,13 +405,12 @@ async function upgrade() {
392
405
  timeout: 60000,
393
406
  });
394
407
  s.stop("Dependencies ready");
395
- // Step 2.5: Write temp script and spawn to update registry & clean cache
396
- // Uses a file instead of node -e to avoid shell escaping issues
408
+ // Step 4: Update installed_plugins.json via spawned script (works from any old version)
397
409
  s.start("Updating plugin registry");
398
410
  try {
399
411
  const scriptPath = resolve(tmpDir + "-post-upgrade.mjs");
400
412
  const scriptContent = [
401
- `import { readFileSync, writeFileSync, readdirSync, rmSync } from "fs";`,
413
+ `import { readFileSync, writeFileSync, readdirSync, rmSync as rm } from "fs";`,
402
414
  `import { resolve } from "path";`,
403
415
  `import { homedir } from "os";`,
404
416
  `const pluginRoot = ${JSON.stringify(pluginRoot)};`,
@@ -422,16 +434,13 @@ async function upgrade() {
422
434
  ` console.log("REGISTRY_UPDATED");`,
423
435
  ` }`,
424
436
  `} catch (e) { console.error("REGISTRY_FAILED:" + e.message); }`,
425
- `const m = pluginRoot.match(/^(.*[\\\\/]plugins[\\\\/]cache[\\\\/][^\\\\/]+[\\\\/][^\\\\/]+[\\\\/])([^\\\\/]+)$/);`,
426
- `if (m) {`,
427
- ` try {`,
428
- ` const dirs = readdirSync(m[1]).filter(d => d !== m[2]);`,
429
- ` for (const old of dirs) {`,
430
- ` try { rmSync(resolve(m[1], old), { recursive: true, force: true }); } catch {}`,
431
- ` }`,
432
- ` if (dirs.length > 0) console.log("CLEANED:" + dirs.length);`,
433
- ` } catch {}`,
434
- `}`,
437
+ `const curDir = pluginRoot.split(/[\\/\\\\]/).pop();`,
438
+ `const parDir = pluginRoot.replace(/[\\/\\\\][^\\/\\\\]+$/, "");`,
439
+ `try {`,
440
+ ` for (const d of readdirSync(parDir).filter(x => x !== curDir)) {`,
441
+ ` try { rm(resolve(parDir, d), { recursive: true, force: true }); console.log("CLEANED:" + d); } catch {}`,
442
+ ` }`,
443
+ `} catch {}`,
435
444
  ].join("\n");
436
445
  writeFileSync(scriptPath, scriptContent, "utf-8");
437
446
  const result = execSync(`node ${scriptPath}`, {
@@ -450,10 +459,6 @@ async function upgrade() {
450
459
  else {
451
460
  s.stop(color.yellow("Plugin registry unchanged"));
452
461
  }
453
- const cleanMatch = result.match(/CLEANED:(\d+)/);
454
- if (cleanMatch) {
455
- p.log.info(color.dim(` Cleaned ${cleanMatch[1]} old cache dir(s)`));
456
- }
457
462
  }
458
463
  catch (err) {
459
464
  s.stop(color.yellow("Plugin registry update skipped"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "context-mode",
3
- "version": "0.9.6",
3
+ "version": "0.9.8",
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",