u-foo 2.4.12 → 2.4.13

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "u-foo",
3
- "version": "2.4.12",
3
+ "version": "2.4.13",
4
4
  "description": "Multi-Agent Workspace Protocol. Just add u. claude → uclaude, codex → ucodex.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "homepage": "https://ufoo.dev",
@@ -219,15 +219,18 @@ function sameProjectRoot(a, b) {
219
219
  }
220
220
  }
221
221
 
222
+ function matchesDaemonArgs(text) {
223
+ const lower = typeof text === "string" ? text.toLowerCase() : "";
224
+ if (/\bufoo\s+daemon\s+(--start|start)\b/.test(lower)) return true;
225
+ if (/\bufoo\.js\s+daemon\s+(--start|start)\b/.test(lower)) return true;
226
+ if (lower.includes("/src/runtime/daemon/run.js")) return true;
227
+ return false;
228
+ }
229
+
222
230
  function isLikelyDaemonProcess(pid) {
223
231
  const args = readProcessArgs(pid);
224
232
  if (!args || args === "__EPERM__") return null;
225
- const text = args.toLowerCase();
226
- const hasCliPattern = /\bufoo\s+daemon\s+(--start|start)\b/.test(text);
227
- const hasNodePattern = /\bufoo\.js\s+daemon\s+(--start|start)\b/.test(text);
228
- if (hasCliPattern || hasNodePattern) return true;
229
- if (text.includes("/src/runtime/daemon/run.js")) return true;
230
- return false;
233
+ return matchesDaemonArgs(args);
231
234
  }
232
235
 
233
236
  function isPidFileDaemonForProject(projectRoot, pid, socketOwnerPids = new Set()) {
@@ -261,6 +264,31 @@ function socketOwnerDaemonPids(projectRoot) {
261
264
  return Array.from(out);
262
265
  }
263
266
 
267
+ function findAllProjectDaemonPids(projectRoot) {
268
+ const out = new Set();
269
+ try {
270
+ const res = spawnSync("ps", ["-eo", "pid,args"], {
271
+ encoding: "utf8",
272
+ stdio: ["ignore", "pipe", "ignore"],
273
+ });
274
+ if (!res || res.status !== 0 || !res.stdout) return [];
275
+ for (const line of String(res.stdout || "").split(/\r?\n/)) {
276
+ const trimmed = line.trim();
277
+ if (!trimmed) continue;
278
+ if (!matchesDaemonArgs(trimmed)) continue;
279
+ const pid = parseInt(trimmed.split(/\s+/)[0], 10);
280
+ if (!Number.isFinite(pid) || pid <= 0 || pid === process.pid) continue;
281
+ const cwd = readProcessCwd(pid);
282
+ if (cwd && sameProjectRoot(cwd, projectRoot)) {
283
+ out.add(pid);
284
+ }
285
+ }
286
+ } catch {
287
+ // ignore ps failures
288
+ }
289
+ return Array.from(out);
290
+ }
291
+
264
292
  function looksLikeRunningDaemon(projectRoot, pid) {
265
293
  const state = checkPid(pid);
266
294
  if (!state.alive) return false;
@@ -2617,6 +2645,9 @@ function stopDaemon(projectRoot, options = {}) {
2617
2645
  if (pid && isPidFileDaemonForProject(projectRoot, pid, pids)) {
2618
2646
  pids.add(pid);
2619
2647
  }
2648
+ for (const p of findAllProjectDaemonPids(projectRoot)) {
2649
+ pids.add(p);
2650
+ }
2620
2651
  const source = String(
2621
2652
  options.source
2622
2653
  || process.env.UFOO_DAEMON_STOP_SOURCE