vexp-cli 2.1.0 → 2.1.2
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/dist/autostart.js +0 -54
- package/dist/cli.js +64 -26
- package/package.json +6 -6
package/dist/autostart.js
CHANGED
|
@@ -311,60 +311,6 @@ export function uninstallAutostart() {
|
|
|
311
311
|
}
|
|
312
312
|
catch { /* absent */ }
|
|
313
313
|
}
|
|
314
|
-
/**
|
|
315
|
-
* Idempotent install guard used by `vexp` preAction / REPL / plugin activate.
|
|
316
|
-
*
|
|
317
|
-
* First invocation after an upgrade installs autostart + writes a marker.
|
|
318
|
-
* Subsequent invocations (including `vexp setup`, any subcommand, multiple
|
|
319
|
-
* VS Code windows) short-circuit on the marker → zero extra work, zero
|
|
320
|
-
* process duplication.
|
|
321
|
-
*
|
|
322
|
-
* Respects `VEXP_NO_AUTOSTART_INSTALL=1` as opt-out.
|
|
323
|
-
*/
|
|
324
|
-
export function installAutostartIfNeeded() {
|
|
325
|
-
if (process.env.VEXP_NO_AUTOSTART_INSTALL === "1")
|
|
326
|
-
return;
|
|
327
|
-
// 2.0.12 shipped a broken Windows VBS template; rewrite any existing
|
|
328
|
-
// file matching that signature regardless of marker state, so upgraded
|
|
329
|
-
// users get fixed without manual autostart uninstall/install.
|
|
330
|
-
if (process.platform === "win32") {
|
|
331
|
-
try {
|
|
332
|
-
const p = windowsStartupPath();
|
|
333
|
-
if (fs.existsSync(p)) {
|
|
334
|
-
const existing = fs.readFileSync(p, "utf-8");
|
|
335
|
-
if (/sh\.Run\s+"cmd \/c "\s*&/.test(existing)) {
|
|
336
|
-
installWindowsStartup();
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
catch { /* non-fatal */ }
|
|
341
|
-
}
|
|
342
|
-
const marker = installMarkerPath();
|
|
343
|
-
if (fs.existsSync(marker))
|
|
344
|
-
return;
|
|
345
|
-
// Previous install by a different path (e.g. user ran older `vexp setup`
|
|
346
|
-
// that called installAutostart directly). Record the marker so we don't
|
|
347
|
-
// probe the filesystem again on every invocation.
|
|
348
|
-
if (autostartStatus().installed) {
|
|
349
|
-
try {
|
|
350
|
-
fs.mkdirSync(path.dirname(marker), { recursive: true });
|
|
351
|
-
fs.writeFileSync(marker, new Date().toISOString());
|
|
352
|
-
}
|
|
353
|
-
catch { /* non-fatal */ }
|
|
354
|
-
return;
|
|
355
|
-
}
|
|
356
|
-
try {
|
|
357
|
-
const r = installAutostart();
|
|
358
|
-
if (r.installed) {
|
|
359
|
-
try {
|
|
360
|
-
fs.mkdirSync(path.dirname(marker), { recursive: true });
|
|
361
|
-
fs.writeFileSync(marker, new Date().toISOString());
|
|
362
|
-
}
|
|
363
|
-
catch { /* non-fatal */ }
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
catch { /* non-fatal — opt-in best effort */ }
|
|
367
|
-
}
|
|
368
314
|
const CLAUDE_UNPIN_MARKER_FILE = "claude-unpin-migrated";
|
|
369
315
|
function claudeUnpinMarkerPath() {
|
|
370
316
|
return path.join(homedir(), ".vexp", CLAUDE_UNPIN_MARKER_FILE);
|
package/dist/cli.js
CHANGED
|
@@ -6,14 +6,14 @@ import { spawn, spawnSync, execFileSync } from "child_process";
|
|
|
6
6
|
import * as path from "path";
|
|
7
7
|
import * as fs from "fs";
|
|
8
8
|
import * as net from "net";
|
|
9
|
-
import { checkbox } from "@inquirer/prompts";
|
|
9
|
+
import { checkbox, confirm } from "@inquirer/prompts";
|
|
10
10
|
import { getBinaryPath, getInstalledVersion, getMcpServerPath, binaryEnv } from "./binary.js";
|
|
11
11
|
import { detectAgents, getAgentList, configureSelectedAgents } from "./agent-config.js";
|
|
12
12
|
import { CLI_VERSION } from "./version.js";
|
|
13
13
|
import { activateLicense, deactivateLicense, readLicenseLimits, readDeviceBlocked, } from "./license.js";
|
|
14
14
|
import { checkForUpdate } from "./update-check.js";
|
|
15
15
|
import { ensureMcpHttpServer, mcpHttpStatus } from "./mcp-supervisor.js";
|
|
16
|
-
import { installAutostart,
|
|
16
|
+
import { installAutostart, uninstallAutostart, autostartStatus, migrateClaudeUnpinIfNeeded } from "./autostart.js";
|
|
17
17
|
import { runServe } from "./serve.js";
|
|
18
18
|
import { runDoctor } from "./doctor.js";
|
|
19
19
|
import { isTraceEnabled } from "./trace.js";
|
|
@@ -218,11 +218,17 @@ async function ensureDaemonRunning(workspaceRoot, binaryPath) {
|
|
|
218
218
|
* REPL, setup) can never spawn duplicates:
|
|
219
219
|
* - `ensureDaemonRunning` → socket probe, skips spawn if alive
|
|
220
220
|
* - `ensureMcpHttpServer` → ~/.vexp/mcp.pid + port probe, no-op if live
|
|
221
|
-
* - `installAutostartIfNeeded` → marker ~/.vexp/autostart-installed
|
|
222
221
|
*
|
|
223
222
|
* The point of this wrapper is to ensure users who upgraded via
|
|
224
223
|
* `npm update` and then just typed `vexp` (never re-running `setup`) still
|
|
225
|
-
* get
|
|
224
|
+
* get the daemon up and MCP :7821 up for this session. The daemon cold-starts
|
|
225
|
+
* lazily on the first invocation, so no OS-level login persistence is needed
|
|
226
|
+
* for interactive use.
|
|
227
|
+
*
|
|
228
|
+
* OS login autostart is NOT installed here — it is strictly opt-in via
|
|
229
|
+
* `vexp autostart install` or the setup wizard prompt, so vexp never writes
|
|
230
|
+
* LaunchAgent/systemd/Startup-folder persistence behind the user's back
|
|
231
|
+
* (which security tooling flags as a persistence anomaly).
|
|
226
232
|
*
|
|
227
233
|
* Honors VEXP_NO_AUTOSTART=1 as a global bypass.
|
|
228
234
|
*/
|
|
@@ -234,10 +240,6 @@ async function ensureBootstrap(workspaceRoot, binaryPath) {
|
|
|
234
240
|
await ensureMcpHttpServer({ owner: "cli" });
|
|
235
241
|
}
|
|
236
242
|
catch { /* non-fatal */ }
|
|
237
|
-
try {
|
|
238
|
-
installAutostartIfNeeded();
|
|
239
|
-
}
|
|
240
|
-
catch { /* non-fatal */ }
|
|
241
243
|
}
|
|
242
244
|
/**
|
|
243
245
|
* Start the vexp daemon and MCP HTTP server in the background.
|
|
@@ -625,20 +627,40 @@ program
|
|
|
625
627
|
}
|
|
626
628
|
}
|
|
627
629
|
}
|
|
628
|
-
// Step 5:
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
630
|
+
// Step 5: Optionally install login autostart (per-user, no admin required).
|
|
631
|
+
// Opt-in only — writing OS persistence (LaunchAgent / systemd / Startup
|
|
632
|
+
// folder) without asking is flagged as an anomaly by security tooling, and
|
|
633
|
+
// the daemon already cold-starts on the first `vexp` invocation, so this is
|
|
634
|
+
// purely a convenience for post-reboot warm-up. Skip entirely when the user
|
|
635
|
+
// opted out via env or when stdin is not a TTY (non-interactive install).
|
|
636
|
+
if (process.env.VEXP_NO_AUTOSTART_INSTALL === "1") {
|
|
637
|
+
// Explicit opt-out — do nothing.
|
|
638
|
+
}
|
|
639
|
+
else if (!process.stdin.isTTY) {
|
|
640
|
+
console.log(chalk.dim(" Skipping login autostart (non-interactive). Run 'vexp autostart install' to enable."));
|
|
641
|
+
}
|
|
642
|
+
else {
|
|
643
|
+
const wantAutostart = await confirm({
|
|
644
|
+
message: "Start the vexp daemon automatically at login? (optional — it also starts on demand)",
|
|
645
|
+
default: false,
|
|
646
|
+
});
|
|
647
|
+
if (wantAutostart) {
|
|
648
|
+
const spinnerAuto = ora("Installing login autostart...").start();
|
|
649
|
+
try {
|
|
650
|
+
const r = installAutostart();
|
|
651
|
+
if (r.installed) {
|
|
652
|
+
spinnerAuto.succeed(`Login autostart installed (${r.mechanism})`);
|
|
653
|
+
}
|
|
654
|
+
else {
|
|
655
|
+
spinnerAuto.warn("Autostart not installed on this platform");
|
|
656
|
+
}
|
|
635
657
|
}
|
|
636
|
-
|
|
637
|
-
spinnerAuto.warn(
|
|
658
|
+
catch (err) {
|
|
659
|
+
spinnerAuto.warn(`Autostart install failed: ${err instanceof Error ? err.message : err}`);
|
|
638
660
|
}
|
|
639
661
|
}
|
|
640
|
-
|
|
641
|
-
|
|
662
|
+
else {
|
|
663
|
+
console.log(chalk.dim(" Login autostart skipped. Enable later with 'vexp autostart install'."));
|
|
642
664
|
}
|
|
643
665
|
}
|
|
644
666
|
// Final summary
|
|
@@ -782,14 +804,30 @@ async function runSetupInteractive(rl) {
|
|
|
782
804
|
}
|
|
783
805
|
console.log(chalk.green(`\n ✓ Setup complete — ${result.agents.length} agent(s) configured\n`));
|
|
784
806
|
}
|
|
785
|
-
// Login autostart — opt-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
807
|
+
// Login autostart — opt-in only. The daemon already cold-starts on demand,
|
|
808
|
+
// so OS login persistence is a convenience the user must explicitly request;
|
|
809
|
+
// installing it silently is flagged as a persistence anomaly by security
|
|
810
|
+
// tooling. Env opt-out and non-TTY both skip the prompt without installing.
|
|
811
|
+
if (process.env.VEXP_NO_AUTOSTART_INSTALL === "1" || !process.stdin.isTTY) {
|
|
812
|
+
// Opted out or non-interactive — leave autostart uninstalled.
|
|
813
|
+
}
|
|
814
|
+
else {
|
|
815
|
+
rl.resume();
|
|
816
|
+
const answer = (await ask(rl, "\n Start the vexp daemon automatically at login? (optional — starts on demand too) [y/N]: ")).trim().toLowerCase();
|
|
817
|
+
rl.pause();
|
|
818
|
+
if (answer === "y" || answer === "yes") {
|
|
819
|
+
try {
|
|
820
|
+
const r = installAutostart();
|
|
821
|
+
if (r.installed)
|
|
822
|
+
console.log(chalk.green(` ✓ Login autostart installed (${r.mechanism})`));
|
|
823
|
+
else
|
|
824
|
+
console.log(chalk.yellow(" ⚠ Autostart not installed on this platform"));
|
|
825
|
+
}
|
|
826
|
+
catch { /* non-fatal */ }
|
|
827
|
+
}
|
|
828
|
+
else {
|
|
829
|
+
console.log(chalk.dim(" Login autostart skipped. Enable later with 'vexp autostart install'."));
|
|
791
830
|
}
|
|
792
|
-
catch { /* non-fatal */ }
|
|
793
831
|
}
|
|
794
832
|
}
|
|
795
833
|
// ────────────────────────────────────────────────────
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vexp-cli",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.2",
|
|
4
4
|
"description": "Vexp — Context Engine for AI Coding Agents. Pre-indexes your codebase into a dependency graph and delivers ranked context to any MCP-compatible agent. 58% lower cost per task, 90% fewer tool calls (SWE-bench Verified). Works with Claude Code, Cursor, Copilot, Windsurf, Codex, Cline, Aider, and 12+ agents. Local-first. Your code never leaves your machine.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -100,10 +100,10 @@
|
|
|
100
100
|
"node": ">=20.0.0"
|
|
101
101
|
},
|
|
102
102
|
"optionalDependencies": {
|
|
103
|
-
"@vexp/core-linux-x64": "2.1.
|
|
104
|
-
"@vexp/core-linux-arm64": "2.1.
|
|
105
|
-
"@vexp/core-darwin-x64": "2.1.
|
|
106
|
-
"@vexp/core-darwin-arm64": "2.1.
|
|
107
|
-
"@vexp/core-win32-x64": "2.1.
|
|
103
|
+
"@vexp/core-linux-x64": "2.1.2",
|
|
104
|
+
"@vexp/core-linux-arm64": "2.1.2",
|
|
105
|
+
"@vexp/core-darwin-x64": "2.1.2",
|
|
106
|
+
"@vexp/core-darwin-arm64": "2.1.2",
|
|
107
|
+
"@vexp/core-win32-x64": "2.1.2"
|
|
108
108
|
}
|
|
109
109
|
}
|