vexp-cli 1.3.8 → 2.0.3

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/README.md CHANGED
@@ -1,18 +1,24 @@
1
1
  # vexp — Context Engine for AI Coding Agents
2
2
 
3
- **Save 70% of tokens. Get 2x better answers. Your code never leaves your machine.**
3
+ **58% Less Cost. 90% Fewer Tool Calls. 100% On Your Machine.**
4
4
 
5
5
  vexp is a local-first context engine that gives AI coding agents the right code context — automatically. One install, and every agent gets smarter answers with fewer tokens.
6
6
 
7
- Works with **12+ AI coding agents** and **30 programming languages** out of the box.
7
+ Works with **14+ AI coding agents** and **30 programming languages** out of the box.
8
+
9
+ → [SWE-bench Verified: 73% pass@1 at $0.67/task](https://vexp.dev/benchmark)
8
10
 
9
11
  ## Why vexp?
10
12
 
11
- AI coding agents dump entire files into their context window, burning tokens and getting confused. vexp solves this with a local code graph that delivers only the relevant symbols, call chains, and dependencies — compressed to 70% fewer tokens.
13
+ AI coding agents waste more than half their budget exploring codebases before writing a single line of code — 23 tool calls on average just to orient themselves. vexp pre-indexes your project into a dependency graph and delivers only the code that matters, ranked by relevance.
12
14
 
15
+ - **23 tool calls → 2** — the agent stops guessing and starts coding
16
+ - **$0.78 → $0.33 per task** — measured on SWE-bench Verified
17
+ - **117s → 74s per task** — less context to process = faster answers
13
18
  - **Local-first** — your code never leaves your machine
14
19
  - **Zero config** — auto-detects your agents and configures MCP
15
20
  - **Universal** — works with any agent that supports MCP or custom rules
21
+ - **Optional local AI** — unlock +30% extra savings with `vexp-devmind`, a ~3.5 GB model that runs 100% on your machine. GPU-accelerated on NVIDIA (CUDA) and Apple Silicon (Metal). Opt in with one command.
16
22
 
17
23
  ## Supported AI Coding Agents
18
24
 
@@ -26,11 +32,15 @@ AI coding agents dump entire files into their context window, burning tokens and
26
32
  | Augment | ✓ |
27
33
  | Zed | ✓ |
28
34
  | Codex (OpenAI) | ✓ |
35
+ | Cline | ✓ |
36
+ | Aider | ✓ |
29
37
  | Kilo Code | ✓ |
30
38
  | Kiro | ✓ |
31
39
  | Antigravity | ✓ |
32
40
  | Opencode | ✓ |
33
41
 
42
+ Your agents don't compete with each other — they all share the same context layer.
43
+
34
44
  ## Supported Languages (30)
35
45
 
36
46
  TypeScript, JavaScript, Python, Go, Rust, Java, C#, C, C++, Ruby, Kotlin, Scala, Swift, Dart, Elixir, Haskell, OCaml, Lua, R, PHP, Zig, HCL/Terraform, Objective-C, Bash/Shell, Dockerfile, Clojure, F#, SQL, HTML/CSS, YAML/JSON
@@ -44,18 +54,50 @@ vexp
44
54
 
45
55
  That's it. The interactive CLI guides you through setup, indexing, and agent configuration.
46
56
 
57
+ ## What You Get
58
+
59
+ - **Semantic + graph-ranked context** — finds the right symbols even when keywords don't match
60
+ - **Intent detection in 15 languages** — English, Italian, French, German, Spanish, Portuguese, Russian, Chinese, Japanese, Korean, Arabic, Hindi, Turkish, Dutch, Polish
61
+ - **Cross-session memory** — your agent picks up exactly where it left off, even days later
62
+ - **Stale-knowledge alerts** — when code changes, outdated memory is automatically flagged
63
+ - **Pattern & anti-pattern detection** — recurring changes surface as guidelines; dead-end explorations get flagged early
64
+ - **Change awareness** — files frequently modified together are automatically linked
65
+ - **Security filter** — `.env`, credentials, and SSH keys are excluded automatically
66
+
47
67
  ## Platforms
48
68
 
49
- | Platform | Architecture |
50
- |----------|:-:|
51
- | Linux | x64, ARM64 |
52
- | macOS | x64, ARM64 (Apple Silicon) |
53
- | Windows | x64 |
69
+ Native binaries no runtime dependencies:
70
+
71
+ | Platform | Architecture | GPU Acceleration |
72
+ |----------|:-:|:-:|
73
+ | Linux | x64, ARM64 | CUDA (NVIDIA) |
74
+ | macOS | x64, ARM64 (Apple Silicon) | Metal (built-in) |
75
+ | Windows | x64 | CUDA (NVIDIA) |
76
+
77
+ GPU acceleration applies to the optional local AI layer. Vexp's core context engine runs on any modern CPU.
54
78
 
55
79
  ## VS Code Extension
56
80
 
57
81
  For the best experience, install the [vexp VS Code extension](https://marketplace.visualstudio.com/items?itemName=Vexp.vexp-vscode) — it manages the daemon automatically and adds a sidebar dashboard with token savings tracking.
58
82
 
83
+ ## Local AI — Optional +30% Savings
84
+
85
+ Turn on `vexp-devmind` — a code-specialised AI model that runs entirely on your machine — for an extra +30% token savings on top of the baseline.
86
+
87
+ - **100% local** — the model never calls out. Your code stays on your hardware.
88
+ - **GPU-accelerated** — Metal on Apple Silicon, CUDA on NVIDIA. Auto-detected.
89
+ - **One-command install** — ~3.5 GB one-time download. Minimum 6 GB RAM.
90
+ - **Always up to date** — `--check-updates` compares your local version to the published release without downloading anything.
91
+
92
+ Sharper context ranking, higher-quality session memory, smarter prompt preprocessing. All without sending a single byte to any server.
93
+
94
+ ```bash
95
+ vexp setup-llm --install # ~3.5 GB one-time download
96
+ vexp setup-llm --check-updates # no-op if already up to date
97
+ vexp setup-llm --status # show current config + hardware
98
+ vexp setup-llm --disable # turn it off any time
99
+ ```
100
+
59
101
  ## Links
60
102
 
61
103
  - [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=Vexp.vexp-vscode)
@@ -9,6 +9,7 @@
9
9
  import * as fs from "fs";
10
10
  import * as path from "path";
11
11
  import * as os from "os";
12
+ import * as crypto from "crypto";
12
13
  import { VEXP_GUARD_HOOK } from "./hook-template.js";
13
14
  // ---------------------------------------------------------------------------
14
15
  // Constants
@@ -206,9 +207,9 @@ export function configureAgents(workspaceRoot, binaryPath, version, agentFilter,
206
207
  });
207
208
  }
208
209
  }
209
- // Codex: configure MCP in ~/.codex/config.toml (global, TOML format)
210
+ // Codex: configure MCP in ~/.codex/config.toml (global, HTTP + bearer token)
210
211
  if (detector.agent === "Codex") {
211
- const wrote = configureCodexGlobal(binaryPath, mcpServerPath);
212
+ const wrote = configureCodexGlobal(binaryPath, mcpServerPath, workspaceRoot);
212
213
  if (wrote)
213
214
  mcpConfigs.push("~/.codex/config.toml");
214
215
  }
@@ -315,7 +316,7 @@ export function configureSelectedAgents(workspaceRoot, binaryPath, version, sele
315
316
  installClaudeCodeHook(workspaceRoot);
316
317
  }
317
318
  if (detector.agent === "Codex") {
318
- const wrote = configureCodexGlobal(binaryPath, mcpServerPath);
319
+ const wrote = configureCodexGlobal(binaryPath, mcpServerPath, workspaceRoot);
319
320
  if (wrote)
320
321
  mcpConfigs.push("~/.codex/config.toml");
321
322
  }
@@ -426,14 +427,22 @@ function writeMcpConfig(mcpConfigPath, binaryPath, alwaysAllow, mcpServerPath) {
426
427
  }
427
428
  }
428
429
  const servers = existing.mcpServers;
429
- if (servers && "vexp" in servers)
430
- return false;
431
430
  const useNode = mcpServerPath && fs.existsSync(mcpServerPath);
431
+ const targetCmd = useNode ? "node" : binaryPath;
432
+ const targetArgs = useNode ? [mcpServerPath] : ["mcp"];
433
+ if (servers && "vexp" in servers) {
434
+ const cur = servers["vexp"];
435
+ if (cur?.["command"] === targetCmd &&
436
+ Array.isArray(cur?.["args"]) &&
437
+ JSON.stringify(cur["args"]) === JSON.stringify(targetArgs)) {
438
+ return false; // Already up to date
439
+ }
440
+ }
432
441
  existing.mcpServers = {
433
442
  ...(servers ?? {}),
434
443
  vexp: {
435
- command: useNode ? "node" : binaryPath,
436
- args: useNode ? [mcpServerPath] : ["mcp"],
444
+ command: targetCmd,
445
+ args: targetArgs,
437
446
  ...(alwaysAllow && alwaysAllow.length > 0 ? { alwaysAllow } : {}),
438
447
  },
439
448
  };
@@ -441,29 +450,76 @@ function writeMcpConfig(mcpConfigPath, binaryPath, alwaysAllow, mcpServerPath) {
441
450
  fs.writeFileSync(mcpConfigPath, JSON.stringify(existing, null, 2), "utf-8");
442
451
  return true;
443
452
  }
453
+ /**
454
+ * Read or generate a bearer token for MCP HTTP auth.
455
+ * Persists to ~/.vexp/mcp.token so the MCP server and Codex config share it.
456
+ */
457
+ function resolveCodexToken() {
458
+ const home = os.homedir();
459
+ const tokenPath = home ? path.join(home, ".vexp", "mcp.token") : "";
460
+ if (tokenPath) {
461
+ try {
462
+ const existing = fs.readFileSync(tokenPath, "utf-8").trim();
463
+ if (existing)
464
+ return existing;
465
+ }
466
+ catch { /* not yet created */ }
467
+ }
468
+ const token = crypto.randomUUID();
469
+ if (tokenPath) {
470
+ try {
471
+ fs.mkdirSync(path.dirname(tokenPath), { recursive: true });
472
+ fs.writeFileSync(tokenPath, token, { mode: 0o600 });
473
+ }
474
+ catch { /* non-fatal */ }
475
+ }
476
+ return token;
477
+ }
478
+ /**
479
+ * Read the MCP HTTP port from .vexp/mcp.port, or return the default.
480
+ */
481
+ function readMcpPort(workspaceRoot) {
482
+ const DEFAULT_PORT = 7821;
483
+ if (workspaceRoot) {
484
+ try {
485
+ const portStr = fs.readFileSync(path.join(workspaceRoot, ".vexp", "mcp.port"), "utf-8").trim();
486
+ const port = parseInt(portStr, 10);
487
+ if (port > 0)
488
+ return port;
489
+ }
490
+ catch { /* file doesn't exist */ }
491
+ }
492
+ return DEFAULT_PORT;
493
+ }
444
494
  /**
445
495
  * Configure MCP in ~/.codex/config.toml (global).
446
496
  * Codex only reads the global config, not project-level .codex/config.toml.
497
+ * Uses HTTP transport with bearer token so Codex shows "Auth: BearerToken"
498
+ * instead of "Auth: Unsupported" (which is hardcoded for stdio servers).
447
499
  * Uses TOML format with [mcp_servers.<name>] sections.
448
500
  */
449
- function configureCodexGlobal(binaryPath, mcpServerPath) {
501
+ function configureCodexGlobal(binaryPath, mcpServerPath, workspaceRoot) {
450
502
  const home = os.homedir();
451
503
  if (!home)
452
504
  return false;
453
505
  const configPath = path.join(home, ".codex", "config.toml");
506
+ const mcpPort = readMcpPort(workspaceRoot);
507
+ const token = resolveCodexToken();
508
+ const newSection = `\n[mcp_servers.vexp]\nurl = "http://127.0.0.1:${mcpPort}/mcp"\ntool_timeout_sec = 120\n\n[mcp_servers.vexp.http_headers]\nAuthorization = "Bearer ${token}"\n`;
454
509
  let content = "";
455
510
  if (fs.existsSync(configPath)) {
456
511
  content = fs.readFileSync(configPath, "utf-8");
457
- if (content.includes("[mcp_servers.vexp]"))
458
- return false; // already configured
459
512
  }
460
513
  fs.mkdirSync(path.dirname(configPath), { recursive: true });
461
- const useNode = mcpServerPath && fs.existsSync(mcpServerPath);
462
- const cmd = useNode ? "node" : binaryPath;
463
- const arg = useNode ? mcpServerPath : "mcp";
464
- const escapedCmd = cmd.replace(/\\/g, "\\\\");
465
- const escapedArg = arg.replace(/\\/g, "\\\\");
466
- content += `\n[mcp_servers.vexp]\ncommand = "${escapedCmd}"\nargs = ["${escapedArg}"]\nstartup_timeout_sec = 30\ntool_timeout_sec = 120\n`;
514
+ if (content.includes("[mcp_servers.vexp]")) {
515
+ // Check if already up to date (same URL and token)
516
+ if (content.includes(`url = "http://127.0.0.1:${mcpPort}/mcp"`) &&
517
+ content.includes(`Authorization = "Bearer ${token}"`))
518
+ return false;
519
+ // Remove old section(s) handles both stdio (command=) and http (url=) formats
520
+ content = content.replace(/\n?\[mcp_servers\.vexp(?:\.http_headers)?\][^\[]*/g, "");
521
+ }
522
+ content += newSection;
467
523
  fs.writeFileSync(configPath, content, "utf-8");
468
524
  return true;
469
525
  }
@@ -482,12 +538,20 @@ function writeVsCodeMcpConfig(p, binaryPath, mcpServerPath) {
482
538
  }
483
539
  }
484
540
  const servers = existing.servers;
485
- if (servers && "vexp" in servers)
486
- return false;
487
541
  const useNode = mcpServerPath && fs.existsSync(mcpServerPath);
542
+ const targetCmd = useNode ? "node" : binaryPath;
543
+ const targetArgs = useNode ? [mcpServerPath] : ["mcp"];
544
+ if (servers && "vexp" in servers) {
545
+ const cur = servers["vexp"];
546
+ if (cur?.["command"] === targetCmd &&
547
+ Array.isArray(cur?.["args"]) &&
548
+ JSON.stringify(cur["args"]) === JSON.stringify(targetArgs)) {
549
+ return false; // Already up to date
550
+ }
551
+ }
488
552
  existing.servers = {
489
553
  ...(servers ?? {}),
490
- vexp: { type: "stdio", command: useNode ? "node" : binaryPath, args: useNode ? [mcpServerPath] : ["mcp"] },
554
+ vexp: { type: "stdio", command: targetCmd, args: targetArgs },
491
555
  };
492
556
  fs.mkdirSync(path.dirname(p), { recursive: true });
493
557
  fs.writeFileSync(p, JSON.stringify(existing, null, 2), "utf-8");
@@ -507,12 +571,21 @@ function writeZedMcpConfig(p, binaryPath, mcpServerPath) {
507
571
  }
508
572
  }
509
573
  const cs = settings.context_servers;
510
- if (cs && "vexp" in cs)
511
- return false;
512
574
  const useNode = mcpServerPath && fs.existsSync(mcpServerPath);
575
+ const targetCmd = useNode ? "node" : binaryPath;
576
+ const targetArgs = useNode ? [mcpServerPath] : ["mcp"];
577
+ if (cs && "vexp" in cs) {
578
+ const cur = cs["vexp"];
579
+ const curCmd = cur?.["command"];
580
+ if (curCmd?.["path"] === targetCmd &&
581
+ Array.isArray(curCmd?.["args"]) &&
582
+ JSON.stringify(curCmd["args"]) === JSON.stringify(targetArgs)) {
583
+ return false; // Already up to date
584
+ }
585
+ }
513
586
  settings.context_servers = {
514
587
  ...(cs ?? {}),
515
- vexp: { command: { path: useNode ? "node" : binaryPath, args: useNode ? [mcpServerPath] : ["mcp"] } },
588
+ vexp: { command: { path: targetCmd, args: targetArgs } },
516
589
  };
517
590
  // Pre-approve all vexp tools
518
591
  const agent = (settings.agent ?? {});
@@ -685,14 +758,9 @@ Only use Read when you need exact raw content to edit a specific line.
685
758
  - \`run_pipeline({ "task": "add auth", "observation": "using JWT" })\` — save insight in same call
686
759
 
687
760
  ### Other MCP tools (use only when run_pipeline is insufficient)
688
- - \`get_context_capsule\` — lightweight alternative for simple questions only
689
- - \`get_impact_graph\` — standalone deep impact analysis of a specific symbol
690
- - \`search_logic_flow\` — trace execution paths between two specific symbols
691
761
  - \`get_skeleton\` — **preferred over Read** for inspecting files (minimal/standard/detailed detail levels, 70-90% token savings)
692
762
  - \`index_status\` — indexing status and health check
693
- - \`get_session_context\` — recall observations from current/previous sessions
694
- - \`search_memory\` — cross-session search for past decisions
695
- - \`save_observation\` — persist insights (prefer using run_pipeline's observation param instead)
763
+ - \`expand_vexp_ref\` — expand V-REF hash placeholders in v2 compact output
696
764
 
697
765
  ### Workflow
698
766
  1. \`run_pipeline("your task")\` — ALWAYS FIRST. Returns pivots + impact + memories in 1 call
@@ -745,14 +813,9 @@ vexp returns pre-indexed, graph-ranked context in a single call.
745
813
  ### Available MCP tools
746
814
  - \`run_pipeline\` — **PRIMARY TOOL**. Runs capsule + impact + memory in 1 call.
747
815
  Auto-detects intent. Includes file content. Example: \`run_pipeline({ "task": "fix auth bug" })\`
748
- - \`get_context_capsule\` — lightweight, for simple questions only
749
- - \`get_impact_graph\` — impact analysis of a specific symbol
750
- - \`search_logic_flow\` — execution paths between functions
751
816
  - \`get_skeleton\` — compact file structure
752
817
  - \`index_status\` — indexing status
753
- - \`get_session_context\` — recall observations from sessions
754
- - \`search_memory\` — cross-session search
755
- - \`save_observation\` — persist insights (prefer run_pipeline's observation param)
818
+ - \`expand_vexp_ref\` — expand V-REF placeholders in v2 output
756
819
 
757
820
  ### Agentic search
758
821
  - Do NOT use built-in file search, grep, or codebase indexing — always call \`run_pipeline\` first
@@ -789,14 +852,9 @@ vexp returns pre-indexed, graph-ranked context in a single call.
789
852
  ### Available MCP tools
790
853
  - \`run_pipeline\` — **PRIMARY TOOL**. Runs capsule + impact + memory in 1 call.
791
854
  Auto-detects intent. Includes file content. Example: \`run_pipeline({ "task": "fix auth bug" })\`
792
- - \`get_context_capsule\` — lightweight, for simple questions only
793
- - \`get_impact_graph\` — impact analysis of a specific symbol
794
- - \`search_logic_flow\` — execution paths between functions
795
855
  - \`get_skeleton\` — compact file structure
796
856
  - \`index_status\` — indexing status
797
- - \`get_session_context\` — recall observations from sessions
798
- - \`search_memory\` — cross-session search
799
- - \`save_observation\` — persist insights (prefer run_pipeline's observation param)
857
+ - \`expand_vexp_ref\` — expand V-REF placeholders in v2 output
800
858
 
801
859
  ### Agentic search
802
860
  - Do NOT use built-in file search, grep, or codebase indexing — always call \`run_pipeline\` first
@@ -843,14 +901,9 @@ When working on this codebase:
843
901
  ### Available MCP tools
844
902
  - \`run_pipeline\` — **PRIMARY TOOL**. Runs capsule + impact + memory in 1 call.
845
903
  Example: \`run_pipeline({ "task": "fix auth bug" })\`
846
- - \`get_context_capsule\` — lightweight, for simple questions only
847
- - \`get_impact_graph\` — standalone impact analysis
848
- - \`search_logic_flow\` — execution paths between functions
849
904
  - \`get_skeleton\` — token-efficient file structure
850
905
  - \`index_status\` — indexing status
851
- - \`get_session_context\` — recall observations from sessions
852
- - \`search_memory\` — cross-session search
853
- - \`save_observation\` — persist insights (prefer run_pipeline's observation param)
906
+ - \`expand_vexp_ref\` — expand V-REF placeholders in v2 output
854
907
 
855
908
  ### Agentic search
856
909
  - Do NOT use built-in file search, grep, or codebase indexing — always call \`run_pipeline\` first
@@ -878,14 +931,9 @@ vexp returns pre-indexed, graph-ranked context in a single call.
878
931
  ### Available MCP tools
879
932
  - \`run_pipeline\` — **PRIMARY TOOL**. Runs capsule + impact + memory in 1 call.
880
933
  Auto-detects intent. Includes file content. Example: \`run_pipeline({ "task": "fix auth bug" })\`
881
- - \`get_context_capsule\` — lightweight, for simple questions only
882
- - \`get_impact_graph\` — impact analysis of a specific symbol
883
- - \`search_logic_flow\` — execution paths between functions
884
934
  - \`get_skeleton\` — compact file structure
885
935
  - \`index_status\` — indexing status
886
- - \`get_session_context\` — recall observations from sessions
887
- - \`search_memory\` — cross-session search
888
- - \`save_observation\` — persist insights (prefer run_pipeline's observation param)
936
+ - \`expand_vexp_ref\` — expand V-REF placeholders in v2 output
889
937
 
890
938
  ### Agentic search
891
939
  - Do NOT use built-in file search, grep, or codebase indexing — always call \`run_pipeline\` first
@@ -913,14 +961,9 @@ vexp returns pre-indexed, graph-ranked context in a single call.
913
961
  ### Available MCP tools
914
962
  - \`run_pipeline\` — **PRIMARY TOOL**. Runs capsule + impact + memory in 1 call.
915
963
  Example: \`run_pipeline({ "task": "fix auth bug" })\`
916
- - \`get_context_capsule\` — lightweight, for simple questions only
917
- - \`get_impact_graph\` — impact analysis of a specific symbol
918
- - \`search_logic_flow\` — execution paths between functions
919
964
  - \`get_skeleton\` — compact file structure
920
965
  - \`index_status\` — indexing status
921
- - \`get_session_context\` — recall observations from sessions
922
- - \`search_memory\` — cross-session search
923
- - \`save_observation\` — persist insights (prefer run_pipeline's observation param)
966
+ - \`expand_vexp_ref\` — expand V-REF placeholders in v2 output
924
967
 
925
968
  ### Agentic search
926
969
  - Do NOT use built-in file search, grep, or codebase indexing — always call \`run_pipeline\` first
@@ -948,14 +991,9 @@ vexp returns pre-indexed, graph-ranked context in a single call.
948
991
  ### Available MCP tools
949
992
  - \`run_pipeline\` — **PRIMARY TOOL**. Runs capsule + impact + memory in 1 call.
950
993
  Auto-detects intent. Includes file content. Example: \`run_pipeline({ "task": "fix auth bug" })\`
951
- - \`get_context_capsule\` — lightweight, for simple questions only
952
- - \`get_impact_graph\` — impact analysis of a specific symbol
953
- - \`search_logic_flow\` — execution paths between functions
954
994
  - \`get_skeleton\` — compact file structure
955
995
  - \`index_status\` — indexing status
956
- - \`get_session_context\` — recall observations from sessions
957
- - \`search_memory\` — cross-session search
958
- - \`save_observation\` — persist insights (prefer run_pipeline's observation param)
996
+ - \`expand_vexp_ref\` — expand V-REF placeholders in v2 output
959
997
 
960
998
  ### Agentic search
961
999
  - Do NOT use built-in file search, grep, or codebase indexing — always call \`run_pipeline\` first
@@ -983,14 +1021,9 @@ vexp returns pre-indexed, graph-ranked context in a single call.
983
1021
  ## Available vexp tools
984
1022
  - \`run_pipeline\` — **PRIMARY TOOL**. Runs capsule + impact + memory in 1 call.
985
1023
  Example: \`run_pipeline({ "task": "fix auth bug" })\`
986
- - \`get_context_capsule\` — lightweight, for simple questions only
987
- - \`get_impact_graph\` — impact analysis of a specific symbol
988
- - \`search_logic_flow\` — trace execution paths
989
1024
  - \`get_skeleton\` — compact file structure
990
1025
  - \`index_status\` — indexing status
991
- - \`get_session_context\` — recall observations from sessions
992
- - \`search_memory\` — cross-session search
993
- - \`save_observation\` — persist insights (prefer run_pipeline's observation param)
1026
+ - \`expand_vexp_ref\` — expand V-REF placeholders in v2 output
994
1027
 
995
1028
  ## Agentic search
996
1029
  - Do NOT use built-in file search, grep, or codebase indexing — always call \`run_pipeline\` first
@@ -1018,14 +1051,9 @@ vexp returns pre-indexed, graph-ranked context in a single call.
1018
1051
  ### Available MCP tools
1019
1052
  - \`run_pipeline\` — **PRIMARY TOOL**. Runs capsule + impact + memory in 1 call.
1020
1053
  Example: \`run_pipeline({ "task": "fix auth bug" })\`
1021
- - \`get_context_capsule\` — lightweight, for simple questions only
1022
- - \`get_impact_graph\` — impact analysis of a specific symbol
1023
- - \`search_logic_flow\` — execution paths between functions
1024
1054
  - \`get_skeleton\` — compact file structure
1025
1055
  - \`index_status\` — indexing status
1026
- - \`get_session_context\` — recall observations from sessions
1027
- - \`search_memory\` — cross-session search
1028
- - \`save_observation\` — persist insights (prefer run_pipeline's observation param)
1056
+ - \`expand_vexp_ref\` — expand V-REF placeholders in v2 output
1029
1057
 
1030
1058
  ### Agentic search
1031
1059
  - Do NOT use built-in file search, grep, or codebase indexing — always call \`run_pipeline\` first
@@ -1039,4 +1067,3 @@ Intent auto-detection, hybrid ranking, session memory, auto-expanding budget.
1039
1067
  \`run_pipeline\` auto-queries all indexed repos. Use \`repos: ["alias"]\` to scope. Run \`index_status\` to see aliases.
1040
1068
  <!-- /vexp -->`;
1041
1069
  }
1042
- //# sourceMappingURL=agent-config.js.map
package/dist/binary.js CHANGED
@@ -10,6 +10,24 @@ const PLATFORM_PACKAGES = {
10
10
  "win32-x64": "@vexp/core-win32-x64",
11
11
  "win32-arm64": "@vexp/core-win32-x64", // ARM64 Windows uses x64 binary via emulation
12
12
  };
13
+ // A single core binary per OS/arch decides at RUNTIME which backend to
14
+ // use (CPU, Metal, CUDA) via ggml's dynamic plugin loader. The CUDA
15
+ // plugin is downloaded on-demand by `vexp setup-llm` when an NVIDIA
16
+ // driver is detected — no separate GPU binary package.
17
+ //
18
+ // The `--gpu` / `--cuda` flags and VEXP_GPU / VEXP_CUDA env vars are
19
+ // forwarded to the Rust core as VEXP_PREFER_GPU=1, which flips
20
+ // prefer_gpu=true on the llama.cpp load. If no GPU plugin is present,
21
+ // llama.cpp silently falls back to CPU.
22
+ function gpuRequested() {
23
+ return (process.env.VEXP_GPU === "1" ||
24
+ process.env.VEXP_CUDA === "1" ||
25
+ process.argv.includes("--gpu") ||
26
+ process.argv.includes("--cuda"));
27
+ }
28
+ export function preferGpuEnv() {
29
+ return gpuRequested() ? { VEXP_PREFER_GPU: "1" } : {};
30
+ }
13
31
  export function getBinaryPath() {
14
32
  // Dev override: use VEXP_CORE_PATH env var to point to a local binary
15
33
  const envPath = process.env.VEXP_CORE_PATH;
@@ -93,4 +111,3 @@ export async function getInstalledVersion() {
93
111
  return null;
94
112
  }
95
113
  }
96
- //# sourceMappingURL=binary.js.map