context-mode 1.0.92 → 1.0.94

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.
@@ -51,16 +51,17 @@ export function ensureDeps() {
51
51
  if (!existsSync(pkgDir)) {
52
52
  // Package not installed at all
53
53
  try {
54
- execSync(`npm install ${pkg} --no-package-lock --no-save --silent`, {
54
+ execSync(`${process.platform === "win32" ? "npm.cmd" : "npm"} install ${pkg} --no-package-lock --no-save --silent`, {
55
55
  cwd: root,
56
56
  stdio: "pipe",
57
57
  timeout: 120000,
58
+ shell: true,
58
59
  });
59
60
  } catch { /* best effort — hook degrades gracefully without DB */ }
60
61
  } else if (!existsSync(resolve(pkgDir, ...NATIVE_BINARIES[pkg]))) {
61
62
  // Package installed but native binary missing (e.g., npm ignore-scripts=true)
62
63
  try {
63
- execSync(`npm rebuild ${pkg} --ignore-scripts=false`, {
64
+ execSync(`${process.platform === "win32" ? "npm.cmd" : "npm"} rebuild ${pkg} --ignore-scripts=false`, {
64
65
  cwd: root,
65
66
  stdio: "pipe",
66
67
  timeout: 120000,
@@ -121,10 +122,11 @@ export function ensureNativeCompat(pluginRoot) {
121
122
  copyFileSync(binaryPath, abiCachePath);
122
123
  } else {
123
124
  // ABI mismatch or missing native binary — rebuild for current Node version
124
- execSync("npm rebuild better-sqlite3 --ignore-scripts=false", {
125
+ execSync(`${process.platform === "win32" ? "npm.cmd" : "npm"} rebuild better-sqlite3 --ignore-scripts=false`, {
125
126
  cwd: pluginRoot,
126
127
  stdio: "pipe",
127
128
  timeout: 60000,
129
+ shell: true,
128
130
  });
129
131
  codesignBinary(binaryPath);
130
132
  if (existsSync(binaryPath) && probeNativeInChildProcess(pluginRoot)) {
@@ -783,6 +783,27 @@ function serveStaticFile(pathname) {
783
783
  } catch { return null; }
784
784
  }
785
785
 
786
+ // ── On-demand build: install + build if dist/ is missing ─
787
+ if (!existsSync(join(DIST_DIR, "index.html"))) {
788
+ const { execSync } = await import("node:child_process");
789
+ const shellOpts = { cwd: __dirname, stdio: "pipe", shell: true };
790
+ try {
791
+ console.error("\n ┌─ Insight Dashboard ─────────────────────────────┐");
792
+ console.error(" │ First run — building the dashboard UI. │");
793
+ console.error(" │ This only happens once. │");
794
+ console.error(" └─────────────────────────────────────────────────┘\n");
795
+ console.error(" [1/2] Installing dependencies...");
796
+ execSync("npm install --no-package-lock --no-save --silent", { ...shellOpts, timeout: 120000 });
797
+ console.error(" [2/2] Building dashboard...");
798
+ execSync("npm run build", { ...shellOpts, timeout: 60000 });
799
+ console.error(" ✓ Ready.\n");
800
+ } catch (e) {
801
+ console.error(" ✗ Build failed:", e.message);
802
+ console.error(" Try manually: cd insight && npm install && npm run build");
803
+ process.exit(1);
804
+ }
805
+ }
806
+
786
807
  // ── Server (dual runtime) ────────────────────────────────
787
808
 
788
809
  const indexHTML = readFileSync(join(DIST_DIR, "index.html"), "utf8");
@@ -502,33 +502,27 @@ function Dashboard() {
502
502
  <CardDescription>Where your AI time goes</CardDescription>
503
503
  </CardHeader>
504
504
  <CardContent>
505
- <div className="grid grid-cols-3 gap-4 mb-4">
505
+ <div className="grid grid-cols-2 gap-4 mb-4">
506
506
  <Mini label="Projects" value={t.uniqueProjects} />
507
- <Mini label="Top Project" value={topProject?.project_dir?.split("/").pop() || "-"} color="text-emerald-500" />
508
- <Mini label="Match Quality" value={data.attribution?.avgConfidencePct != null ? (data.attribution.avgConfidencePct >= 80 ? "Strong" : data.attribution.avgConfidencePct >= 55 ? "Fair" : "Weak") : "-"} color={data.attribution && data.attribution.avgConfidencePct >= 80 ? "text-emerald-500" : data.attribution && data.attribution.avgConfidencePct >= 55 ? "text-amber-500" : "text-red-400"} />
507
+ <Mini label="Top Project" value={topProject?.project_dir === "__unknown__" ? "Unknown" : topProject?.project_dir?.split("/").pop() || "-"} color="text-emerald-500" />
509
508
  </div>
510
509
  {data.attribution?.isFallbackOnly && (
511
510
  <div className="mb-3 px-3 py-2 rounded-md bg-muted/50 border border-border text-xs text-muted-foreground flex items-center gap-1.5">
512
511
  <Lightbulb className="h-3 w-3 shrink-0" />
513
- Limited tracking detail — project time is estimated from session data
512
+ Some project times are estimated
514
513
  </div>
515
514
  )}
516
515
  <div className="space-y-2.5 pt-2 border-t border-border">
517
516
  {data.projectActivity.slice(0, 6).map((p, i) => {
518
517
  const maxEv = data.projectActivity[0]?.events || 1;
519
518
  const pct = Math.round((p.events / maxEv) * 100);
520
- const name = p.project_dir?.split("/").filter(Boolean).slice(-2).join("/") || "Unknown";
521
- const conf = p.avg_confidence != null ? Math.round(p.avg_confidence * 100) : null;
522
- const qualityLabel = conf != null ? (conf >= 80 ? "Strong" : conf >= 55 ? "Fair" : "Weak") : null;
523
- const qualityIcon = conf != null ? (conf >= 80 ? "✓" : conf >= 55 ? "~" : "!") : null;
524
- const qualityColor = conf != null ? (conf >= 80 ? "text-emerald-500" : conf >= 55 ? "text-amber-500" : "text-red-400") : "";
519
+ const name = p.project_dir === "__unknown__" ? "Unknown" : p.project_dir?.split("/").filter(Boolean).slice(-2).join("/") || "Unknown";
525
520
  return (
526
521
  <div key={i}>
527
522
  <div className="flex justify-between text-xs mb-1">
528
523
  <span className="font-mono truncate max-w-[200px]">{name}</span>
529
524
  <span className="text-muted-foreground tabular-nums">
530
525
  {p.sessions} sessions · {p.events} events
531
- {qualityLabel != null && <span className={`ml-1.5 text-[11px] font-medium ${qualityColor}`} title={`Match quality: ${conf}%`}>{qualityIcon} {qualityLabel}</span>}
532
526
  </span>
533
527
  </div>
534
528
  <div className="h-1.5 bg-secondary rounded-full overflow-hidden">
@@ -845,7 +839,7 @@ function Dashboard() {
845
839
  data.gitActivity.forEach(g => {
846
840
  if (!sessions.has(g.session_id)) {
847
841
  sessions.set(g.session_id, {
848
- project: g.project_dir?.split("/").filter(Boolean).slice(-2).join("/") || "-",
842
+ project: g.project_dir === "__unknown__" ? "Unknown" : g.project_dir?.split("/").filter(Boolean).slice(-2).join("/") || "-",
849
843
  actions: [],
850
844
  time: g.created_at,
851
845
  });
@@ -121,9 +121,9 @@ function Sessions() {
121
121
  }
122
122
 
123
123
  // Project name: last 2 path segments
124
- const projectName = s.projectDir
125
- ? s.projectDir.split("/").filter(Boolean).slice(-2).join("/")
126
- : "Unknown";
124
+ const projectName = !s.projectDir || s.projectDir === "__unknown__"
125
+ ? "Unknown"
126
+ : s.projectDir.split("/").filter(Boolean).slice(-2).join("/") || "Unknown";
127
127
 
128
128
  return (
129
129
  <Link
@@ -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.92",
6
+ "version": "1.0.94",
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.92",
3
+ "version": "1.0.94",
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",
@@ -55,7 +55,14 @@
55
55
  "build",
56
56
  "hooks",
57
57
  "configs",
58
- "insight",
58
+ "insight/server.mjs",
59
+ "insight/package.json",
60
+ "insight/tsconfig.json",
61
+ "insight/vite.config.ts",
62
+ "insight/tailwind.config.ts",
63
+ "insight/postcss.config.js",
64
+ "insight/index.html",
65
+ "insight/src",
59
66
  "server.bundle.mjs",
60
67
  "cli.bundle.mjs",
61
68
  "skills",