vexp-cli 3.2.1 → 3.2.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.
Files changed (2) hide show
  1. package/dist/serve.js +49 -5
  2. package/package.json +6 -6
package/dist/serve.js CHANGED
@@ -60,6 +60,36 @@ function rotateLogIfLarge() {
60
60
  }
61
61
  catch { /* missing */ }
62
62
  }
63
+ /** The daemon's log, opened the way `vexp-core daemon-cmd start` opens it:
64
+ * the previous boot rotated to daemon.log.1, this boot in daemon.log. The
65
+ * daemon writes its log to stderr and nowhere else, so a launcher that
66
+ * spawns it with stdio ignored gets a daemon that logs nothing at all — a
67
+ * 3.2.1 daemon answered requests for hours while daemon.log still ended at
68
+ * the crash of the day before, until a `daemon-cmd restart` brought the log
69
+ * back (field report, 2026-09-18). A rotation that fails (the file is still
70
+ * held open) appends instead: the evidence of the last boot is what a user
71
+ * restarting a daemon needs most. "ignore" when the file cannot be opened
72
+ * at all: a daemon without a log beats no daemon. */
73
+ export function openDaemonLog(workspaceRoot) {
74
+ const dir = path.join(workspaceRoot, ".vexp");
75
+ const log = path.join(dir, "daemon.log");
76
+ let flags = "w";
77
+ if (fs.existsSync(log)) {
78
+ try {
79
+ fs.rmSync(path.join(dir, "daemon.log.1"), { force: true });
80
+ fs.renameSync(log, path.join(dir, "daemon.log.1"));
81
+ }
82
+ catch {
83
+ flags = "a";
84
+ }
85
+ }
86
+ try {
87
+ return fs.openSync(log, flags);
88
+ }
89
+ catch {
90
+ return "ignore";
91
+ }
92
+ }
63
93
  async function resurrectDaemon(workspaceRoot, socketPath) {
64
94
  const manifest = path.join(workspaceRoot, ".vexp", "manifest.json");
65
95
  if (!fs.existsSync(manifest))
@@ -83,11 +113,25 @@ async function resurrectDaemon(workspaceRoot, socketPath) {
83
113
  // in vexp-core, which spawns every child with CREATE_NO_WINDOW
84
114
  // (packages/vexp-core/src/proc.rs). `windowsHide` would not help here:
85
115
  // Windows ignores it next to DETACHED_PROCESS.
86
- const child = spawn(binary, ["daemon", "--workspace", workspaceRoot, "--socket", socketPath], {
87
- detached: true,
88
- stdio: "ignore",
89
- env: binaryEnv(binary),
90
- });
116
+ //
117
+ // stdout/stderr go to the daemon's own log file, never to a terminal:
118
+ // a file handle is not a console, and it is what `daemon-cmd start`
119
+ // hands the same detached daemon. See openDaemonLog.
120
+ const log = openDaemonLog(workspaceRoot);
121
+ let child;
122
+ try {
123
+ child = spawn(binary, ["daemon", "--workspace", workspaceRoot, "--socket", socketPath], {
124
+ detached: true,
125
+ stdio: ["ignore", log, log],
126
+ env: binaryEnv(binary),
127
+ });
128
+ }
129
+ finally {
130
+ // The child holds its own handle from here; ours would only keep the
131
+ // file open (and unrotatable on Windows) for the supervisor's lifetime.
132
+ if (typeof log === "number")
133
+ fs.closeSync(log);
134
+ }
91
135
  child.unref();
92
136
  appendLog(`daemon spawned: ${workspaceRoot} (pid=${child.pid})`);
93
137
  return true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vexp-cli",
3
- "version": "3.2.1",
3
+ "version": "3.2.2",
4
4
  "description": "Local-first context engine for AI coding agents. Pre-indexes your codebase into a dependency graph and feeds any MCP agent only the code that matters — 87% fewer tokens per call. New in 2.5: mechanical work verification and a PII/secret scanner. Works with Claude Code, Cursor, Codex, Copilot, Windsurf, Cline, Aider and 14 agents. Your code never leaves your machine.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -105,10 +105,10 @@
105
105
  },
106
106
  "homepage": "https://vexp.dev",
107
107
  "optionalDependencies": {
108
- "@vexp/core-linux-x64": "3.2.1",
109
- "@vexp/core-linux-arm64": "3.2.1",
110
- "@vexp/core-darwin-x64": "3.2.1",
111
- "@vexp/core-darwin-arm64": "3.2.1",
112
- "@vexp/core-win32-x64": "3.2.1"
108
+ "@vexp/core-linux-x64": "3.2.2",
109
+ "@vexp/core-linux-arm64": "3.2.2",
110
+ "@vexp/core-darwin-x64": "3.2.2",
111
+ "@vexp/core-darwin-arm64": "3.2.2",
112
+ "@vexp/core-win32-x64": "3.2.2"
113
113
  }
114
114
  }